4.7.2 — The terminal comes back on the right process

A snapshot of 4.7.2 as released on 2026-08-08. It will go out of date as the app moves on; that is fine and expected. For the reference that is kept current, follow the links to the living guide in each section.

npx mulmoterminal@latest

Almost nothing to configure in this release. It is mostly repair, and all of it is on the moment you run 4.7.2. The one thing you may want to do by hand is a bit of tidying — see Clearing the worktree chips you already have.


The bug this release is built around

A terminal could come back on the wrong backend process. Concretely: you had a codex (or Antigravity, or Muse) conversation whose backend was still running in tmux; the launcher showed it as free; you clicked resume — and that started a second backend on the same conversation. From then on a cold reconnect could land on either process, so the same cell showed you different states on different days.

It was found on a live instance and it was not rare there: the probe turned up the double-session state in all three non-Claude agents’ logs, plus nineteen more sessions running detached and invisible to the app.

You do not have to do anything to get the fix. What follows is how to tell it is working.

How to tell you have it

Start an agent in a worktree, close the browser tab (do not close the cell — that ends the session), and open the app again.

  • The worktree row now says resume rather than offering to start a fresh session. Before, it read as free and would have started a second agent beside the running one.
  • Clicking resume reattaches the process that was already there. You land back in the same conversation, mid-scrollback.

The second half is a server restart. Restart MulmoTerminal while a codex cell is mid-task, wait for the cell to reconnect, and drive the session further:

  • The cell’s working / waiting dot moves again. Before this release a codex session that survived a restart reattached fine but its activity tracking never restarted, so the dot stayed frozen and turn-finished notifications never arrived until you restarted the session itself.
  • If the session was mid-turn when the server went down, the cell shows it as working — not idle-until-the-turn-ends.

Sessions and reconnecting in the living guide.

A session you cannot open is now cleaned up

A session id that was never set produced a tmux session literally named mt-undefined — a shared bucket that every defective spawn attached to, and that nothing could open, resume or end, because every route validates the id first. Two changes: a spawn with an invalid id now fails with a message instead of silently sharing a terminal, and the idle sweep ends an unreachable one immediately rather than waiting out a grace period no amount of recency could satisfy.

If you had one, it is gone after the next start. Nothing to do.

Ending sessions you are not using — the sessionIdleReapDays switch still turns the whole sweep off, and still protects a session someone is attached to.


Worktrees no longer pile up as working-directory chips

The chips under WORKING DIRECTORY in a cell’s launcher are recorded automatically from wherever you launch. A worktree launches like any other directory, so every isolated task left a chip behind — for a directory that exists for one branch, one task, and is deleted when the task is done. Nothing removed the chip when the directory went, either, so the row filled up with paths that no longer exist and pushed your real projects out of reach.

From 4.7.2 a managed worktree is not recorded. Both routes into that list are covered: the automatic record on every launch, and the reseed mulmoterminal init does from your Claude history.

It only skips worktrees this app created. The test is anchored on the managed root — the directory MulmoTerminal makes worktrees in — and requires the <repo>-<8hex> name it mints there. A directory of your own that happens to be laid out the same way, or one you put under that root by hand, is still recorded as before.

Clearing the worktree chips you already have

Chips already saved are left exactly where they are. That is deliberate: your saved configuration is yours, and this release will not quietly delete entries from it.

So a list that has been collecting them for a while still shows them. Remove the ones you do not want with the × on the chip — the same button as always. There is nothing else to do; new ones will not appear.

The launcher form — the working-directory field and its chips → Worktrees — what a managed worktree is and where it lives


One file dialog, however many times you click

Clicking the folder button beside the working-directory field used to open one OS file dialog per click. A native dialog does not answer until you dismiss it, and nothing stopped the clicks in the meantime, so an impatient double-click left you dismissing two dialogs — and a frustrated handful left you dismissing a handful.

There is one file dialog per machine, so there is now one piece of state behind it: every picker button in the app reads the same flag, and the server refuses a second concurrent dialog as well.

Nothing to turn on.


The cockpit roster

Two changes to the enlarged view’s roster, both visible the moment you zoom a cell.

Every row wears the Agent Picker’s mark

The row used to show a non-Claude agent’s name in a bordered pill — codex, agy, grok, mu — and nothing at all for Claude. It now shows the same drawn mark the Agent Picker and the rate-limit gauge use, so one agent looks the same everywhere in the app.

A row that runs no agent is marked with nothing. That is the careful part: a launcher chip, a run-command cell and a cell you have not launched in yet all have no agent, and the obvious shortcut — treat “no agent” as Claude — would have put Anthropic’s burst on a yarn dev chip. The row’s status dot and its directory already say what it is.

Zooming into one (the cockpit roster) in the living guide

One border geometry, so a ring means a state and not a bug

The ring around a row was 2px for blocked, 1px for done, and absent for the other three states. In a vertical list the eye reads a difference in width before it reads colour, so three thicknesses did not read as three meanings — they read as a drawing bug.

Every state now rings at the same 2px, drawn transparent where there is nothing to say, and the 3px stripe down the left edge is gone: once a ring surrounds the row, a fourth side of a different width only made the border disagree with itself. Rows sit 9px apart instead of 5px, because neighbouring rings had closed to within a pixel and the column read as one block.

Nothing to configure; it is how the roster draws now.


Collection chats can choose their agent again

A chat started from Collections was Claude-only, twice over.

The three-button agent toggle that used to sit in the collection browser was replaced by the pinned favourites, and nothing took over writing the setting — so it was frozen at whatever your browser last stored, which for anyone who never used the old toggle meant Claude, permanently.

A compact Launch with dropdown now shares that row with the pins. It offers the built-in agents and only those, because that is exactly what the spawn route can host: no Shell (a seeded chat needs an agent to seed) and no custom agents (the route builds no custom argv). The row now shows even when you have nothing pinned, since the picker always has something in it.

The other half was invisible: the workspace skills those chats lean on could not be seen by some of the agents you might pick. Every agent now sees them.

Features — Collections and the other in-app views → Which coding agent — all five, kept current


Also in this release

  • Windows CI is green again (#1540). The Windows test run had been failing since the previous release’s session work: a new test passed a raw POSIX path where the function takes a normalized one, so on Windows it compared /wt/fix-login against D:\wt\fix-login and never matched. The shipped code was correct — only the test was wrong — so nothing about the app behaved differently on Windows. Worth recording because four of that test’s six cases had been passing there for the wrong reason, which is the kind of green that hides the next bug.
  • The code review bot runs on the current Codex CLI and model (#1526, #1529). Repository tooling; no effect on the app.
  • A blog cover image moved into this repository (#1530), because the private one 404’d from outside and the article rendered without its cover.


This site uses Just the Docs, a documentation theme for Jekyll.