4.6.1 — Rooms, and a grid that keeps up with a flood

A snapshot of 4.6.1 as released on 2026-08-06. 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. The performance work is on the moment you run 4.6.1. Rooms add one box to a form you already use and one icon to the toolbar. The only number worth a look is sessionIdleReapDays, below.


The room — where a conversation is kept

Round table (4.6.0) carried one cell’s reply into the next cell’s input box. It worked, but the conversation existed only while it ran: nothing held it, and nothing that was not a cell could take part.

A room is that conversation kept apart from the cells having it — one append-only file at ~/.mulmoterminal/rooms/<id>.jsonl, one JSON object per line.

Starting one

Rooms appear in the round-table picker as a single room box:

  • Leave it empty and you get a fresh room each run (table-2026-08-06-…).
  • Type a name and the table talks there — and if that room already exists, the conversation continues: the seats read the earlier turns back before they speak. A standup you return to is a table started on standup again.

A name is lowercase letters, digits and -, starting with a letter or digit, up to 64 characters. Anything else is refused rather than quietly turned into a new room.

Reading it, and joining it yourself

Rooms in the toolbar — the forum icon, beside Pull requests — opens every conversation: rooms on the left, messages on the right, and a box at the bottom to say something yourself. The running table’s own room is one click away with read the conversation in a cell’s forum menu. The trash icon beside a room deletes it.

Posting from that box is not a convenience. The agents are typed into by the runner and can call nothing, so a person joins from outside — through the same door a shell or a CI job uses, and whatever you write is in the window the next speaker reads.

From a shell, or from CI

mulmoterminal room list
mulmoterminal room read standup
mulmoterminal room post standup --from ci "tests passed on main"

Everything after -- is message text, so a post can carry flags without losing them:

mulmoterminal room post standup -- we should use --force carefully here

It talks to a running MulmoTerminal over loopback (--port if you moved it). --from is a display label and nothing authenticates it.

The full reference — including the HTTP surface (GET /api/rooms, and GET / POST / DELETE on /api/rooms/:room) — is in Making the cells talk to each other, which is kept current.

Two round-table changes that come with it

  • A speaker now reads the whole conversation so far, not just the previous speaker’s reply. That is the room doing the work: there is a log to read back.
  • A seat that uses tools before answering now contributes its real answer. On 4.6.0 it could contribute the wrong thing.

What this still does not do

The limit from 4.6.0 holds, deliberately: an agent gains no new capability. There is no MCP tool for rooms, no way for an agent to discover that a room exists, and no way for one to start a conversation. A human seats the cells. See Limits worth knowing.


Sessions that outlived the app

Two related things, both about sessions you did not know were still running.

Listed, and stoppable. Settings gained Sessions that survived a restart — every terminal still running from an earlier server, across all directories. Each row says where it runs, what it is, how long it has been idle, and whether ending it loses anything. Stop ends that one session; a conversation with a transcript can be resumed afterwards. Before this the process was still running and no screen admitted it — tmux ls was the only way to find it.

Ended at the next start when nobody wants them. The same section carries sessionIdleReapDays: how long a terminal may sit with nobody attached and no output before the server ends it at its next start. Default 7 days, 0 disables it, range 0–365. Rows that number will take are marked ends at next start, so the sweep is visible in the list it acts on.

The conversation is not what gets ended — a transcript on disk resumes without the tmux session. The process and its scrollback are what you lose.

Both are in Configuration.


The terminal no longer slows down the command it is showing

Nothing to turn on, but worth knowing why the grid feels different.

What was wrong. The server keeps a tail of each cell’s output so it can redraw the screen when a browser reattaches. Adding to that tail cost the size of the whole tail on every chunk the terminal produced — about a megabyte of copying for a few dozen bytes of new text. During a big test run or build, that one function used 86% of a CPU core, and the CPU it burned was CPU that was not reading the terminal. The program you were running then waited for its own output to be collected.

What it means in practice. The effect grows with how many cells are busy. The same heavy command in several cells at once:

Cells running it Before After
1 2.0 s 2.0 s
3 3.9 s 2.1 s
6 8.2 s 2.2 s

One cell on its own is unchanged — there was never a queue. Six cells now finish in the time one used to take, because the server has stopped being the thing in the way. For reference, the six shell processes alone, with no app involved at all, take 1.9 s; 2.2 s is within a rounding error of that floor.

How to tell you have it. Run something noisy in three or four cells at once — a test suite, a build, find / — and compare how long they take together versus one at a time. On 4.6.0 the total climbs with every cell you add. On 4.6.1 it does not.

Nothing about what you see changed: the same output arrives in the same order, and reattaching a browser redraws the same screen. Only the cost changed.


Smaller fixes

  • A killed tmux client no longer takes the session with it. Losing the client is not the same event as the program finishing, and the two are now told apart instead of tearing down a session that is still working.
  • Turn boundaries are read, not guessed. Whether Claude has finished a turn comes from what Claude reports rather than from inference over its output.
  • A model id may carry Claude Code’s [1m] extended-context suffix. claude-opus-4-5[1m] in a provider config is accepted instead of rejected as malformed — see Providers and models.
  • Tool-call history costs less to keep. The panel’s per-session history was rewritten to disk in full on every tool call, twice per call. Quick tool calls now share one write.
  • A collection record with a pending completion bell shows it in the board — the Kanban card accents (red for urgent, amber for a nudge), including for a bell MulmoClaude published.
  • Custom views reach the rest of core’s host surface — translations, a stored image resolved for display, and a declared mutate action.
  • Collection and feed records on the phone go through the store seam, and REST item writes are checked against the schema before anything is written.
  • Two Windows CI fixes, both about the tests rather than the app.


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