Skip to content

Releases: mu-crew/mu

mu 3.13.3

Choose a tag to compare

@github-actions github-actions released this 22 Oct 06:26

Test upkeep leaves a record. An upkeep pass now ends by committing a
dated report to the repo, so its findings outlive the workstream.

Upgrade with npm i -g @mu-crew/mu@3.13.3. New agent sessions load the updated
skill. No CLI, API, schema or extension change.

Changed

  • Skill: test upkeep ends with a committed report. The
    test-health loop gains a
    sixth step: a dated docs/test-health/ report in the repo, holding the
    findings and every refuted or rejected verdict, so the next pass starts
    from them instead of from scratch when the workstream's notes are gone.

mu 3.13.2

Choose a tag to compare

@github-actions github-actions released this 21 Oct 14:44

Keep verification useful as projects grow. The mu skill now defines
fast/slow gate responsibilities, scoped evidence reuse and routine test upkeep.

Upgrade with npm i -g @mu-crew/mu@3.13.2. New agent sessions load the updated
skill. Existing workers need updated briefs; no schema or extension change.

Changed

  • Skill: fast/slow gates and routine test upkeep. Canonical
    test-health guidance assigns targeted
    worker/reviewer checks, equivalent gate records and one full merged-tree
    gate per batch. Milestones and budget crossings prioritise upkeep without
    a crew-wide barrier; auth/build isolation and required pre-push checks stay.
    mu's own gate commands remain unchanged pending review.
    Pilot baseline supplied for swaywardlock 90c3f1c: cold full 557.885 s,
    fast 216.140 s, slow 341.696 s (e2e 255.561 s, release 82.414 s);
    223 unit tests ~1 s, 64 e2e cases / 422 assertions, no skips. Converters
    initially cost ~28 s in fast: fast is not universally seconds. This is
    pilot timing, not an equivalent gate record for mu. A separate targeted
    vibrancy-wait follow-up preserved all seven assertions and reduced that
    case's mean from 3.350 s to 2.140 s; it does not establish a full-gate
    speedup or a solved budget.

mu 3.13.1

Choose a tag to compare

@github-actions github-actions released this 20 Oct 17:55

jj 0.46: recreating a deleted workspace works again. A spawn that reuses
the name of a jj workspace whose directory was deleted failed on jj 0.46.

Upgrade with npm i -g @mu-crew/mu@3.13.1. No schema or extension change.

Fixed

  • A jj workspace whose directory was deleted can be recreated (jj 0.46).
    mu agent spawn --workspace forgets a stale jj workspace of the same
    name first. jj 0.46 keeps printing the deleted path as the workspace
    root, so mu missed it, and in a colocated repo the workspace is also a
    Git worktree that jj workspace forget leaves registered. mu now checks
    the root on disk and runs git worktree prune after the forget, so the
    re-add no longer fails with "Workspace named … already exists" or
    "missing but already registered worktree".

mu 3.13.0

Choose a tag to compare

@github-actions github-actions released this 20 Oct 17:10

Faster everyday verbs. tmux-touching verbs no longer load execa (about
50-60 ms each), pure-JS dependencies are bundled, and a bare verb in a
mu-spawned pane skips the tmux workstream lookup. mu doctor counts ops by
key range (~250 ms less), peer sync resumes from where it stopped, and the
TUI launches faster and stops re-detecting the VCS every 10 s.

Upgrade with npm i -g @mu-crew/mu@3.13.0, then /reload in running pi
sessions to pick up the extension. No schema change. Task, track and peer
lists now sort names by code unit (a-b, a0, a_b; uppercase first).

Changed

  • Spawn warns on Claude's folder-trust dialog. The dialog defaults to
    "No, exit", so the Enter that ends --send quit claude. The tmux
    startup scan now spots it (non-fatal): the pane and agent stay, the
    initial --send is skipped (send.error TrustDialogPending in
    --json), and a warning plus next step says to answer it in the pane
    and then mu agent send. It does not guard a later agent send or the
    herdr spawn path, and mu never presses a key for you.

  • TUI dashboard fills its space. A card's maxRows now caps only
    the first pass of the row allocator: leftover rows go to cards whose
    data still overflows, in proportion to the rows each hides, so a
    40-item Ready list at 80 rows shows all 40 instead of 15 above 60
    blank rows. Cards also move between columns: arrangeColumns
    (replacing balanceColumns, which only ran after a cull) searches
    single moves and swaps for the fewest hidden rows, even with all ten
    cards visible, and keeps the previous layout unless the new one hides
    max(3, 10%) fewer rows. The search also descends from the previous
    layout, so a retained layout never has a single move or swap that
    beats it by more than that margin. Among layouts that hide the same rows, the search
    prefers fewer cards away from their default column, then slot order. Footers and mouse hit regions read the same
    budgets (columnRowBudgets).

  • Skill: recipe wording from a prior runtime. An unknown owner
    is not a dead one: orchestrator-loop says to read the pane or run
    mu doctor before releasing its task. Reviews with only
    UNVERIFIED items go to the human, not into a REJECT round. findings § Record
    grades severity strictly (critical needs a concrete scenario).
    ultrathink and loop-until-done refute the umbrella's criteria on the
    merged tree before close --if-ready.
    watcher caps attempts per item and parks it with every attempt listed.
    long-run records DEAD-END: notes on the umbrella.
    backlog-triage re-verifies an item against the code before starting.
    dag.md states that every edge comes from a verb the caller ran (block, add/reparent --blocked-by) and no write adds edges on its own.
    VISION cites a prior runtime's transport and sentinel-marker lessons.

  • A changed peer segment is ingested from where the last read stopped.
    Every append used to make each other machine hash the whole segment,
    read it a second time as text and split it (~120 ms for this fleet's
    64 MB segment, ~9 ms of it needed). A clean read now saves the byte
    offset and running sha256 state next to the caught-up fingerprint; the
    next ambient ingest reads only the appended bytes, and accepts them
    only when their hash is the manifest's sha256 (~20 ms). A shrunk
    file, a stale manifest, a defect (which saves no offset) and mu sync
    take the full read and whole-file verify as before. The resumed hash
    trusts the prefix it already read: a local edit to those earlier bytes
    that keeps the file growing is caught only by mu sync, not by the
    ambient ingest. No
    schema change: the offset is extra fields in the existing
    sync_fingerprints value, which an older mu never matches and
    ignores.

  • mu workstream list reads mux liveness from one list-sessions.
    It also ran has-session once per workstream (6 spawns for 6
    workstreams). The listing now reuses the session names it already
    fetched, and falls back to per-workstream has-session when
    list-sessions fails, so a transient failure still never marks live
    sessions dead. ~22 ms CLI CPU saved; output is identical.

  • mu_delegate lists agents at most every 30 s while a failed delegate
    lingers.
    Each spawn ran mu agent list (~150 ms of CPU) only to prune
    the footer's failed count; the refresh is now throttled to once per
    30 s. Spawning and safety checks are unchanged; the footer may show a
    closed failure for up to 30 s longer.

  • mu agent spawn sets the tmux pane border in one tmux call. The four
    set-option -w calls are ;-chained into one invocation and target the
    pane directly, which drops the display-message #{window_id} lookup
    (the border helper's 5 tmux processes become 1, ~33-80 ms per spawn). Options, -w scope,
    MU_BANNER_QUIET, and the swallow-all-errors behaviour are unchanged.

  • The TUI detects the VCS backend once, not every 10 s. The slow tick
    ran jj root, sl root (twice) and git rev-parse before every
    git log just to learn the same backend again. It now caches the
    backend per project root for the TUI's lifetime (~4 of 5 processes per
    tick; ticks after the first dropped from ~690 to ~175 ms best case on
    a loaded machine). A none result is not cached, nor is a detection
    during which a root probe failed (spawn error, signal) rather than
    cleanly answering "not this VCS": a transient jj root failure in a
    colocated jj/git repo no longer pins git. mu state is unchanged (it
    never probes the VCS).

  • The TUI bundles ink and react into its lazy chunk. Importing the TUI
    resolved and compiled ~560 ESM files from node_modules per launch. tsup
    now inlines ink, react and their pure-JS deps into dist/tui-*.js (loaded
    only by bare mu and mu state --tui; other verbs are unchanged), using
    the createRequire banner from the commander/cli-table3 bundling. NODE_ENV
    is not defined at build time, so src/cli/tui-load.ts still picks react's
    production build at runtime and an explicit NODE_ENV still wins. TUI
    import ~470 -> ~67 ms, first Agents card ~890 -> ~440 ms (PTY, 20
    alternating launches on a copied DB). react-devtools-core stays external
    (ink loads it only under DEV=true).

  • Task, track and sync-peer sorts use code-unit order, not
    localeCompare.
    The first localeCompare call initialised ICU
    (~4 ms on nearly every list verb). Ties by name now sort by code unit,
    so a-b, a0, a_b replaces the locale order a_b, a-b, a0; uppercase
    sorts before lowercase. Sort keys, ROI order and everything else are
    unchanged.

  • mu doctor and mu db forget count a workstream's ops by key range.
    The per-workstream substr(key, …) test scanned all of ops once per
    torn-down workstream (27 scans of 61k rows, ~320 ms of SQL in
    mu doctor's size hint). It now seeks idx_ops_entity_key with a key
    range per entity (~28 ms); counts and deleted rows are identical.

  • A bare verb in a mu-spawned pane skips the tmux lookup. With no
    -w and no $MU_SESSION, resolveWorkstream ran tmux display-message -p '#S' (and loaded execa) even though spawn already
    put the workstream in $MU_WORKSTREAM. It now uses $MU_WORKSTREAM
    when $MU_MANAGED_AGENT=1 is also set: bare mu task list ~133 -> ~67
    ms from an agent pane. -w and $MU_SESSION still win, and a
    $MU_WORKSTREAM without $MU_MANAGED_AGENT (a stale export in a user
    shell) is ignored. User-started orchestrator panes are unchanged.

  • Spawn sees a pi agent's control socket within ~50 ms. The spawn
    handshake polled every 250 ms, so a socket pi bound just after a poll
    waited up to 250 ms to be noticed. It now stats the socket path every
    50 ms (no fork) and probes as soon as it exists: readiness overshoot
    132 -> 24 ms, ~100 ms less per pi spawn. The pane-alive check and
    scrollback capture keep their 250 ms cadence, plus one final check at
    the budget's deadline, so a pane dying in the last 250 ms keeps its
    crash scrollback.

  • mu_delegate closes the pane and writes the record note in
    parallel.
    A finished delegate with record waited for
    mu agent close before starting mu task note, though neither needs
    the other. They now overlap: ~70 ms less before the answer arrives
    (median of 25 pairs), on clean finishes that close and record. Failure
    reporting is unchanged: a refused close and a failed note are each
    named in the follow-up.

  • The keep-driving nudge reads mu task list, not mu state. At
    each armed settle the pi extension ran mu state --json only to read
    IN_PROGRESS task names, paying for the tmux pane listing and the
    orphan and workspace views it never used. It now runs
    mu task list --status IN_PROGRESS --json per dispatched workstream
    (--sort recency, newest first as state listed them), in parallel,
    deduplicated by task: ~56-69 ms less per armed settle (one
    workstream). A task still owned by a dead agent shows in the nudge until the next
    mu state or mu task wait reaps it.

  • Faster tmux-touching verbs. The tmux, herdr, kick and murmur-status
    executors run through node:child_process instead of lazily importing
    execa (~110 modules, 25-40 ms). mu state, mu agent list, and bare
    verbs that resolve the workstream via tmux drop by ~50-60 ms per call
    (state ~140 -> ~85 ms). Output and exit codes are unchanged; capture
    keeps execa's 100 MiB buffer cap.
    In-flight children are killed when mu exits or gets SIGTERM, SIGINT or
    SIGHUP, as execa's cleanup did, so no tmux or murmur process outlives mu.

  • Faster startup: pure-JS dependencies are bundled. Every verb
    resolved, read and compiled about 35 node_modules files (commander,
    cli-table3, string-width and their dependencies). tsup now bundles
    commander, cli-table3, string-width and picocolors into dist/
    (native better-sqlite3, execa, ink and react stay external;...

Read more

mu 3.12.0

Choose a tag to compare

@github-actions github-actions released this 11 Oct 12:41

A delegate that ends without an answer leaves its evidence. Timeout,
API error, empty finish, dead pane or cancel: the follow-up names the
delegate's pi session file and copies its last message so far to
~/.cache/mu/delegate-answers/.

Upgrade with npm i -g @mu-crew/mu@3.12.0, then /reload in running
pi sessions to pick up the extension. No schema change. The session
file is reported by the delegate's own extension, so delegates need
3.12.0 too; an older one still gets the mu agent read pointer.

Added

  • Delegates that end without an answer leave evidence. A
    mu_delegate follow-up for an API error, an empty finish, a
    timeout or a dead pane, and the mu_delegate_cancel result, now
    name the delegate's pi session file and copy its last message so far
    to ~/.cache/mu/delegate-answers/<ts>_<name>.partial.md. Before, the
    only pointer was mu agent read, which stops working once the pane
    is gone. Quitting pi or /reload lists each running delegate's
    session file too.
  • The control socket's status reports sessionFile, so the reply
    to mu agent spawn --send / mu agent send carries it before any
    run settles.

mu 3.11.3

Choose a tag to compare

@github-actions github-actions released this 11 Oct 09:04

Escape no longer loses delegate answers; spawn and DB-open fixes.
An Escape that drops queued delegate answers leaves a pointer to each
one. A fresh DB survives a parallel fan-out, and --next-free skips
names whose workspace dir is left on disk.

Upgrade with npm i -g @mu-crew/mu@3.11.3, then /reload in running
pi sessions to pick up the extension. No schema change. Both sides of a
delegate need 3.11.3 for the session-file pointer: an older delegate
falls back to the copy and mu agent read.

Added

  • Escape no longer loses queued delegate answers. Escape clears
    pi's follow-up queue, so an answer waiting there was gone. The
    extension now copies each dropped answer to
    ~/.cache/mu/delegate-answers/ ($XDG_CACHE_HOME/mu) and writes
    one line per answer into the conversation, without starting a turn,
    naming the copy and the delegate's pi session file. The copy is
    cache: the session file keeps the original.
  • mu agent wait --json reports a pi agent's sessionFile, the
    transcript of the run it waited for. The control socket's wait
    reply carries it.

Fixed

  • spawn --next-free skips a name whose workspace dir is left on
    disk.
    A dead agent's checkout outlives its row, kept as evidence.
    --next-free checked only agent rows, so it picked that name again,
    and --workspace then failed with WorkspacePathNotEmptyError
    instead of moving on. mu_delegate with workspace: true hit this
    when a label repeated. The leftover dir is untouched; the spawn takes
    the next name.
  • Parallel mu calls on a fresh DB no longer drop one. The first
    fan-out into a new DB (a new machine or MU_DB_PATH) could lose a
    process two ways. Switching the file to WAL returns SQLITE_BUSY
    without honouring busy_timeout, so a loser exited db locked; it is
    now retried for up to 5 s. A process reading the schema version while
    another created the tables could see a half-built DB and refuse it as
    v1 (SchemaTooOldError); the version is now read in one transaction.

mu 3.11.2

Choose a tag to compare

@github-actions github-actions released this 10 Oct 13:44

mu_delegate accepts model ids it used to refuse.
Upgrade with npm i -g @mu-crew/mu@3.11.2, then /reload in running
pi sessions to pick up the extension. No schema change.

Changed

  • mu_delegate is forgiving about model. It used to refuse any
    value outside [A-Za-z0-9._:/@+-], so real ids such as
    modelbridge/meta-openai/gpt-6.1-sol[1m]:high were rejected, and
    that happened in 12 past sessions. It now trims whitespace, drops
    surrounding quotes or backticks and a pasted --model / --model=
    prefix, and shell-quotes any other value inside --command, so pi
    decides whether the id exists. An empty model counts as unset. The
    only value still refused is one with whitespace inside it.

mu 3.11.1

Choose a tag to compare

@github-actions github-actions released this 10 Oct 11:18

pi's footer shows delegate results that have not arrived yet.
Upgrade with npm i -g @mu-crew/mu@3.11.1, then /reload in running
pi sessions to pick up the extension. No schema change.

Added

  • mu_delegate footer counts results pending. A delegate that
    finished while pi was mid-turn has its answer queued as a follow-up,
    and the footer used to drop it from the count, so it looked as if
    nothing was outstanding. The footer now reads 1 result pending until
    the answer enters the conversation. Escape, which clears pi's
    follow-up queue, also clears the count.

mu 3.11.0

Choose a tag to compare

@github-actions github-actions released this 09 Oct 11:01

The skill learns model tiers, and a review panel's fixes land. A new
recipes/models.md says which model tier each role needs; a five-angle
review of the skill found 41 problems, and the confirmed ones are fixed.
mu agent close no longer deletes edits in a cp -a workspace, and
mu agent send to a dead pane says so.

Upgrade with npm i -g @mu-crew/mu@3.11.0, then /reload in running pi
sessions to pick up the skill. No schema change.

Changed

  • Skill: one agent per ready task, not per track. An umbrella puts
    every unit on one track, so "one agent per ready track" read literally
    ran a fan-out with one worker. The skill now says to spawn per ready
    task, and to chain tasks that share files with block so only one is
    ready at a time.
  • Skill: wording fixes. REFUTED is the verdict that sends a brief
    back for rewrite (there was no AMEND); SKILL.md drops text that
    restates --help and the outside-pi spawn steps, uses VOCABULARY
    terms, and models, worker and brief recipes get checkable Done whens.
  • Skill: model tiers. New skills/mu/recipes/models.md ranks models
    by position in a lab's lineup (frontier, strong, mid, cheap, local),
    says which roles need which tier, and keeps local models as a last
    resort. Checkers run at the tier of whoever wrote what they check, or
    higher, from another family. SKILL.md and ten recipes point at it in
    place of the pi_mini/pi_big keys. Skill-only: /reload in running
    pi sessions to pick it up.

Fixed

  • Skill: review recipes keep blockers honest. UNVERIFIED findings
    no longer contradict --if-ready (umbrella stays open);
    adversarial-review re-blocks downstream work on review_x_2 after a
    rejection; findings Group blocks the umbrella on the fix before
    superseding; adversarial-review uses finding and scopes itself to
    commit-producing units; rules-audit splits delegate/workstream mode;
    tasks-or-calls defines delegate call for scratch and a satisfiable
    Done when.
  • Skill: drift-audit and recovery. The drift-audit late-note query
    no longer hides an unrelated CLOSE: note that follows a close;
    recovery's Done when is per operation and reachable on the DRIFT path;
    its teardown/undo bullets keep only what --help lacks.
  • Skill: codemode driver. The scratch script writes each note to a
    file and pipes it to mu task note, so answer text (e.g. a MU_EOF
    line) never runs as shell; the stale cap-refusal warning points to
    orchestrator-loop § Concurrency.
  • Skill: remote-workers recipe safety. Poll only after the worker
    reports done (the poll closes the task); gate on a scratch checkout
    via a temporary ref, never main; --after-runs takes the send's
    runs unchanged; no blanket pkill -f x2ssh.
  • mu agent close no longer deletes cp -a workspaces silently. A
    none-backend workspace can't prove it is clean, so close refuses
    (WorkspacePreservedError) unless --discard-workspace. SKILL.md and
    waves.md now give the safe workspace free path and the refresh --from fix for unpushed merges.
  • model examples with :<level> failed through a gateway
    provider.
    pi reads the first segment as the provider, so
    anthropic/…:high died with "No API key". The models recipe, delegate
    guide and mu_delegate help now say to copy <provider>/<model> from
    pi --list-models; a test pins that mu_delegate accepts
    provider/family/id:level.
  • mu agent send to a dead pane no longer says "ctl: refused". When
    the control socket is silent and the pane is gone (the CLI exited,
    e.g. no API key), ctl verbs now raise AgentPaneDeadError with next
    steps to read the log, close the row and respawn, not link/kick/ssh
    advice. A live pane whose socket refuses still raises
    AgentCtlUnreachableError.

mu 3.10.2

Choose a tag to compare

@github-actions github-actions released this 09 Oct 06:05

The TUI exits on q again with sync on. Upgrade with
npm i -g @mu-crew/mu@3.10.2. No schema or pi extension change.

Fixed

  • mu hung after q when MU_SYNC_DIR was set. The TUI stopped
    rendering but the process never exited: the 3.10.0 sync worker was
    unref'd before its message listener was attached, and attaching it
    re-refs the worker. It is now unref'd after its listeners.
  • The TUI's exit flush no longer waits for the segment lock. After
    q, the flush could wait up to 2 s on a lock held by another mu
    process. The TUI (bare mu, mu state --tui) now tries the lock
    once; if it is busy, nothing is written and the ops stay in the DB
    for the next flush. The TUI's worker has already flushed every 10 s.
    Other verbs keep the 2 s wait. Exit is ~150-450 ms when the segment
    manifest is sealed. A mu older than 3.10.0 still running on this
    machine rewrites it unsealed, which makes every flush rescan the
    segment, so restart those processes.