Skip to content

Muster 0.10.1

Choose a tag to compare

@github-actions github-actions released this 28 Sep 14:51
· 558 commits to main since this release

Muster now runs its own session daemon, muster-daemon, in place of herdr. Read this before updating: the
panes you have open now do not carry over.

  • Your open panes stay with the old daemon. The herdr daemon an earlier Muster started keeps running after you
    update, and so does everything in its panes, but no window of this Muster can show them. Finish that work before
    you update.
  • Your windows come back without their tabs. Each window's size and place, whether its agent list was open, and
    the SSH machines it was attached to are read from the old arrangement. The tabs are not, since they lived in
    herdr.
  • muster daemons lists each old daemon as herdr, with the command that ends it:
    kill $(lsof -t <socket>). Ending one ends every pane it holds.
  • On an SSH machine, the old herdr under ~/.muster/herdr/ keeps running too. Muster installs its new daemon
    beside it the first time you attach, with nothing for you to install. pkill -f "$HOME/.muster/herdr/" on that
    machine ends the old one and its panes, and leaves alone any herdr you run yourself.
  • What the old daemon left behind is read by nothing once it has ended: ~/.muster/cache/herdr/ and
    ~/.muster/state/herdr.toml here, and ~/.muster/herdr/ and ~/.muster/bin/herdr on an SSH machine.
  • An agent is recognized by $MUSTER_AGENT, where it was $HERDR_AGENT. Detection rules are built into Muster
    rather than fetched, and ~/.muster/agent-detection/ still overrides them.
  • A pane on an SSH machine no longer inherits SSH_AUTH_SOCK. It named the agent forwarding of the connection
    that started the daemon, which ends when that connection does.

New

  • Sessions survive a daemon restart as far as they can be written down: tabs, pane names, directories, sizes
    and settings come back, each pane with a fresh shell. A process cannot be written down, so a pane's program and
    its scrollback do not.
  • Updating Muster keeps your agents running from now on. A new Muster that finds an older muster-daemon asks it
    to hand its panes to the new one, processes and all. Since 0.9.0 had no muster-daemon, the first update this
    helps with is the one after this.
  • A pane can be waiting: an agent that ended its turn to wait on its own work, a build or a gate, rather than
    on you. "$MUSTER_DAEMON" report --waiting "<what>" declares it, and the agent list shows it in its own color
    ([colors] agent_waiting).
  • Agents can report on themselves. "$MUSTER_DAEMON" report gives a pane its agent's own state and facts:
    context used, sub-agents, model, cost. A fresh report outranks what the screen suggests. extras/claude-code is a
    Claude Code plugin that reports this way, installed from a checkout of this repository.
  • The agent list shows more: a ring for context used, a count of sub-agents, a bell, a progress bar, and a mark
    on an agent whose screen Muster cannot read. muster window shows the same, and --json adds reported,
    unreadable, facts, progress and rang.
  • cmd+shift+a goes to the pane most urgently asking for you, in this window's tabs or a closed window's:
    blocked first, then a program's notification, then done, the longest waiting first within each. It walks every
    pane the agent list shows as asking, including one whose banner [notifications] mutes, since a mute silences
    the banner and nothing else.
    muster focus --asking does the same from a pane.
  • Programs' own notifications (OSC 9 and OSC 777) raise a banner in the program's words.
    [notifications] programs silences the banner.
  • Programs that ask for the mouse get it: vim with mouse=a, htop and the like see clicks, drags and motion.
    Shift-drag still selects.
  • Programs can set the clipboard with OSC 52. clipboard_write = "deny" stops them. Reading the clipboard is
    never offered.
  • Pasting several lines into a program that cannot tell a paste from typing asks first, since each line would
    run as you pasted it.
  • Panes are Ghostty terminals: TERM=xterm-ghostty, with the terminfo entry Muster carries, and Ghostty's
    shell integration for bash, zsh and fish. [shell] ssh_terminfo and ssh_env carry the terminal to machines you
    ssh to from a pane.
  • Keymap actions for scrolling to the top, the bottom and by page, jumping between prompts, selecting all,
    clearing the screen and resetting the terminal. A Ghostty action name in [keymap] is refused with the name of
    Muster's own.
  • muster pane wait --until waiting waits for an agent to settle into waiting.

Behaves differently

  • Eight chords are Muster's now, as they are in Ghostty. cmd+k clears the screen, cmd+a selects the
    pane's text, cmd+home and cmd+end scroll to the top and bottom, cmd+pageup and cmd+pagedown scroll a
    page, and cmd+shift+up and cmd+shift+down jump between prompts. If your config's [text] or [keymap]
    already puts something on one of them, yours keeps it, and that action goes without a shortcut.
  • muster pane wait --until idle no longer returns for an agent that is waiting on its own work. Add waiting
    to the list to hear of that too.
  • A window opens even when none of its daemons answer. It waits a second for them, then opens and says which it
    is still connecting to and why, and keeps trying. A daemon that arrives later puts its tabs back where they were
    without taking the keyboard. An SSH machine that does not answer is given 15 seconds a try, rather than the
    minute or more a connection otherwise waits.
  • A recognized agent's own notifications raise no banner, since its done and blocked states already say the
    same thing. A bell raises none either: it marks the pane's row until you look.
  • muster pane read --rows N counts back from the last row with anything on it, so a quiet pane at a prompt
    answers with text rather than blank rows, and asks the daemon for only those rows. A whole read reaches up to
    4 MiB of a pane's newest text, where herdr handed back a thousand rows.
  • Find is Ghostty's own, over everything the pane's surface holds, rather than the last thousand rows.
  • Muster keeps working while nobody looks. macOS no longer naps it when its windows are hidden or the screen is
    locked, which is when agents drive it hardest; under a heavy build a pane read took 13 seconds.
  • muster pane send exits 1 when nothing could be queued, such as while its daemon is disconnected, where it
    exited 0. The text arrives as a paste, fenced when the program asked for that.
  • muster pane new --run hands the command to the new shell as it starts, rather than typing it after the
    prompt, and the pane stays open in a shell when the command exits.
  • Exit 4 means a daemon gave no answer for ten seconds, where the window gave it half a second.
  • Right and middle click no longer select a word or paste. They reach a program that asked for the mouse, and
    otherwise do nothing.
  • scroll_multiplier also scales what a program such as less is sent for the wheel.

Fixed

  • A config written in place, as printf > config.toml or some editors do, is picked up.
  • MUSTER_HOME moves the run log too.
  • The agent list's marks follow a switch between light and dark.
  • A muster pane read of more than a mebibyte of text works.

Agents messaging each other

  • muster msg lets agents on one machine post to each other and be woken when a message arrives, in place of
    typing into another agent's pane. A message of any length arrives whole, and nobody waits in a loop for it.
    muster msg post --to <pane> reaches the agent in a pane that muster pane new just made, whether or not it
    has started; join, read, who, log, leave and wait do the rest, and muster docs msg covers them.
    It talks to the daemon rather than a window, so it works with no window open.
  • An agent is woken with one line, never the message, and ten messages arriving while it works cost it one
    wake. A post is refused while its author has unread messages in that group, so nobody answers what they have
    not read. post says who was woken, and exits 6 when nobody who could hear it was there.
  • The doorbell wakes an agent in a pane by typing that line into its prompt, and only into a Claude Code prompt
    the daemon has just read as empty, with nothing typed into the pane for three seconds. A dialog, a menu or a
    prompt holding a draft is never rung; the wake waits until the pane allows it. An agent of any other harness in
    a pane is not woken, and the post says its prompt cannot be read.
  • A Claude Code session outside any pane is woken through its inbox instead. One started with
    --dangerously-skip-permissions holds each wake for approval unless it was also started with
    --settings '{"crossSessionInbound":"accept"}'.
  • An SSH machine gets a muster of its own, at ~/.muster/bin/muster, installed beside its daemon so that
    agents there can message each other. Every pane there finds it on its PATH, even where a login profile such as
    Debian's /etc/profile resets PATH, and a daemon that was already running gets the command at its next
    install.
  • A pane on an SSH machine drives the window it is drawn in. muster run there makes, types into, reads,
    waits on and closes panes on either machine, focuses tabs and posts messages, as it does in a laptop pane. The
    window forwards its socket back over the ssh connection it already holds, so nothing needs setting up.
  • Not there yet: an agent on an SSH machine and one on your laptop cannot share a group, Muster does not notify
    you of messages, and groups have no policy but the permissive default, where every member reads every message.

Apple Silicon, macOS 14 or newer. Notarized and stapled.

brew install amterp/tap/muster

sha256 7bfd34ccfbfad8c6acfd586ef185a43dcf59f4416605d393a5381f3492d09c17

Full Changelog: v0.10.0...v0.10.1