@mu-crew/mu 3.1.0 → 3.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (43) hide show
  1. package/AGENTS.md +203 -588
  2. package/README.md +80 -308
  3. package/dist/cli.js +6106 -4716
  4. package/dist/cli.js.map +1 -1
  5. package/dist/extension/mu-pi.js +786 -0
  6. package/dist/extension/mu-pi.js.map +1 -0
  7. package/dist/index.d.ts +738 -536
  8. package/dist/index.js +6617 -5785
  9. package/dist/index.js.map +1 -1
  10. package/docs/ARCHITECTURE.md +178 -1008
  11. package/docs/ROADMAP.md +88 -169
  12. package/docs/VISION.md +206 -407
  13. package/docs/VOCABULARY.md +202 -455
  14. package/docs/architecture/control-socket.md +119 -0
  15. package/docs/architecture/dag.md +113 -0
  16. package/docs/architecture/mux.md +163 -0
  17. package/docs/architecture/ops-log.md +140 -0
  18. package/docs/architecture/sdk.md +185 -0
  19. package/docs/architecture/sync.md +129 -0
  20. package/docs/architecture/tui.md +146 -0
  21. package/docs/guide/README.md +25 -0
  22. package/docs/guide/backends.md +61 -0
  23. package/docs/guide/cleanup.md +74 -0
  24. package/docs/guide/delegate.md +87 -0
  25. package/docs/guide/dispatch.md +137 -0
  26. package/docs/guide/getting-started.md +177 -0
  27. package/docs/guide/recovery.md +133 -0
  28. package/docs/guide/remote.md +74 -0
  29. package/docs/guide/sql.md +76 -0
  30. package/docs/guide/stop-a-worker.md +64 -0
  31. package/docs/guide/sync.md +78 -0
  32. package/docs/guide/tui.md +98 -0
  33. package/docs/guide/upgrade.md +76 -0
  34. package/docs/history/CHANGELOG-pre-3.md +4866 -0
  35. package/docs/reference/env.md +87 -0
  36. package/docs/reference/naming.md +82 -0
  37. package/docs/specs/2026-09-28-agent-state-from-murmur.md +1 -1
  38. package/docs/specs/2026-09-29-task-substates.md +1 -1
  39. package/package.json +4 -4
  40. package/skills/mu/REMOTE_WORKERS.md +186 -491
  41. package/skills/mu/SKILL.md +142 -217
  42. package/docs/HANDOVER.md +0 -486
  43. package/docs/USAGE_GUIDE.md +0 -2637
@@ -0,0 +1,87 @@
1
+ # How to delegate a one-off task
2
+
3
+ ## Delegate from pi
4
+
5
+ `mu link pi` installs the `mu_delegate` and `mu_delegate_cancel` tools
6
+ in every pi session. Ask pi in plain words:
7
+
8
+ - "Delegate a review of src/x.ts to a helper."
9
+ - "Have three helpers investigate A, B, and C."
10
+
11
+ pi calls `mu_delegate`. It spawns a pi agent in the reserved `scratch`
12
+ workstream and returns at once with the delegate's name and attach
13
+ command. The answer arrives later as a follow-up message; do not poll.
14
+ Delegates called in one turn run in parallel.
15
+
16
+ | Option | Meaning |
17
+ | ------ | ------- |
18
+ | `task` (required) | All the context. The delegate starts empty. |
19
+ | `label` | Names the delegate: `review` gives `delegate-review`. |
20
+ | `brief` | Ad hoc persona or ground rules, sent first. Not enforced. |
21
+ | `cwd` | Start directory. Default: the caller's. Must exist. |
22
+ | `timeout` | Seconds to wait for the answer (default 3600). After it, the answer does not come back; the follow-up gives the `mu agent wait` command. |
23
+ | `workspace` | Own VCS checkout, for delegates that edit files. The follow-up names its path. It isolates repository edits only. |
24
+ | `cli` | Key for `$MU_<CLI>_COMMAND` (default `pi`), e.g. a cheaper model. |
25
+ | `keep` | Keep the pane after it finishes, to talk to it again. |
26
+
27
+ - Watch or steer: run the attach command.
28
+ - Stop: `mu_delegate_cancel`, or `mu agent abort <name> -w scratch`.
29
+ - The pane closes after a clean finish; died or timed-out panes stay
30
+ as evidence.
31
+ - pi's footer shows how many delegates this session is waiting on.
32
+ - Each delegate costs a pane and a pi process.
33
+
34
+ `MU_DELEGATE=0` hides the tool ([env vars](../reference/env.md)).
35
+
36
+ ## Delegate without pi
37
+
38
+ From a script or other shell, run what the tool runs:
39
+
40
+ ```bash
41
+ mu agent spawn helper-1 -w scratch
42
+ mu agent send helper-1 -w scratch --fresh 'Investigate why foo.spec.ts fails. Report the cause.'
43
+ mu agent wait helper-1 -w scratch --json
44
+ ```
45
+
46
+ Use `--fresh`: a plain send to a reused agent carries the previous
47
+ task's context.
48
+
49
+ `mu agent wait` fires when the agent leaves busy (including to
50
+ `needs_input`), never on an already idle agent. For pi, the `--json`
51
+ row carries:
52
+
53
+ - `outcome`: `done`, `empty`, `died`, `timeout`, or `pending`.
54
+ - `lastText`: the final message, capped at 64 KiB.
55
+
56
+ Exit codes: `0` met, `5` timeout, `6` pane died. Non-pi agents have no
57
+ `lastText`; read the pane with `mu agent read helper-1 -w scratch -n 80`.
58
+
59
+ ## Keep a helper
60
+
61
+ Pass `keep: true`, or spawn a named agent in `scratch`. It is created
62
+ on first spawn, needs no tasks, and cannot be `init`ed.
63
+
64
+ ```bash
65
+ mu agent spawn helper -w scratch
66
+ mu agent send helper -w scratch 'Watch CI on PR 1234 and tell me when it is green'
67
+ mu agent read helper -w scratch -n 50
68
+ mu agent close helper -w scratch
69
+ ```
70
+
71
+ A watcher's chat context does not survive compaction. Log each tick
72
+ under your own `--kind`; read the latest entry on the next:
73
+
74
+ ```bash
75
+ mu log -w scratch --kind pr-state 'pr=1234 sha=abc ci=red -> spawned fixer-1'
76
+ mu log -w scratch --kind pr-state -n 1 --json
77
+ ```
78
+
79
+ Act only on change. `--since <seq>` replays entries a dead watcher
80
+ missed.
81
+
82
+ ## When to stop delegating
83
+
84
+ Dependencies, several agents, or review need a real workstream: see
85
+ [Getting started](getting-started.md) and
86
+ [How to dispatch work](dispatch.md). There, `mu task wait` keys on the
87
+ task and has `--on-stall`.
@@ -0,0 +1,137 @@
1
+ # How to dispatch work to a worker
2
+
3
+ This guide assumes you finished [Getting started](getting-started.md).
4
+ The orchestrator loop and its traps are in
5
+ [skills/mu/SKILL.md](../../skills/mu/SKILL.md).
6
+
7
+ ## Claim before you send
8
+
9
+ Always claim the task for the worker before the first send, even for a
10
+ one-shot reviewer:
11
+
12
+ ```bash
13
+ mu task claim build -w auth --for worker-1
14
+ ```
15
+
16
+ `mu task wait` watches tasks, and the reaper returns a claimed task to
17
+ `OPEN` when its pane dies. An unclaimed task gets neither. If no task
18
+ exists, create one with `mu task add --note '<brief>'`.
19
+
20
+ - `--for` takes a worker name or a qualified `<workstream>/<name>`.
21
+ The worker stays in its own workstream. Only the ownership crosses.
22
+ - Inside a worker's pane, bare `mu task claim <id>` uses the pane
23
+ title as the worker name.
24
+ - To do the task yourself, use `mu task claim <id> --self`.
25
+
26
+ ## Pick the send mode
27
+
28
+ For a pi agent, `mu agent send` goes through the agent's control
29
+ socket. Pick the mode by what the agent is doing:
30
+
31
+ | Situation | Command |
32
+ | --------- | ------- |
33
+ | New task, any state | `mu agent send worker-1 --fresh '<brief>'` |
34
+ | Busy, and you want to interrupt the current run | `mu agent send worker-1 --steer '<text>'` |
35
+ | Answering a question, or adding to the same task | `mu agent send worker-1 '<text>'` |
36
+
37
+ - `--fresh` starts a new pi session and sends the prompt into it as
38
+ one operation. It refuses with exit 4 while pi is busy. Run
39
+ `mu agent abort` first, or pass `--force` to drop the running turn.
40
+ - Never send `/new` and then the prompt as two sends to pi. The prompt
41
+ can land during the reset and vanish.
42
+ - A plain send to a busy agent queues as a follow-up.
43
+ - If the socket does not answer, the send fails with exit 1 and
44
+ pastes nothing. `--via mux` pastes into the pane on purpose.
45
+
46
+ After a claim, spawn, or wait, the `Next:` block prints the right send.
47
+
48
+ ### Non-pi agents
49
+
50
+ Agents other than pi have no control socket, so mu pastes the text
51
+ into the pane. To start a new session, send `/new` (codex: `/clear`),
52
+ then the prompt. If mu prints `warning: ... was NOT submitted`, the
53
+ agent has not seen the text. Read the pane before you wait. On a slow
54
+ tmux link, raise `MU_SEND_DELAY_MS` (default 500 ms).
55
+
56
+ ## Write the brief
57
+
58
+ Put the full brief in a task note, so it survives context compaction
59
+ and the next agent can read it. Send a short prompt that points at it:
60
+
61
+ ```bash
62
+ mu task note build -w auth 'FILES: src/auth/\nVERIFY: npm test\nSCOPE: no schema changes'
63
+ mu agent send worker-1 -w auth --fresh 'Work on build. Read: mu task notes build -w auth'
64
+ ```
65
+
66
+ End the brief with the exact final action, for example:
67
+
68
+ ```text
69
+ ⚠️ FINAL ACTION
70
+ git commit -am '...' THEN
71
+ mu task close build -w auth --evidence '...'
72
+ ```
73
+
74
+ Single-quote prompts that contain `$` or backticks. To see only what the worker wrote after the claim, run
75
+ `mu task notes build -w auth --since-claim`.
76
+
77
+ ## Give each worker a workspace
78
+
79
+ `mu agent spawn --workspace` creates a jj, sl, or git worktree for the
80
+ agent (`cp -a` outside a repo). You cherry-pick from it.
81
+
82
+ Refresh the workspace between tasks. The rebase keeps the agent's pi
83
+ context:
84
+
85
+ ```bash
86
+ mu workspace refresh worker-1 -w auth
87
+ ```
88
+
89
+ It refuses on a dirty tree. On a conflict it exits 5 with a `cd`
90
+ hint. To throw the workspace away instead, run
91
+ `mu workspace free worker-1 -w auth`.
92
+
93
+ Claim and send warn when the worker's workspace is 10 or more commits
94
+ behind main. `--strict-staleness` makes that a refusal (exit 4).
95
+
96
+ ## Wait for the first task to close
97
+
98
+ Wait on every in-flight task and handle the first one that closes:
99
+
100
+ ```bash
101
+ mu task wait auth/build auth/docs --first --on-stall exit --json
102
+ ```
103
+
104
+ - `--first` prints the closed ref and fills `firing` in `--json`.
105
+ `--any` leaves `firing` null even on success.
106
+ - `nextSteps[0]` is the cherry-pick command for the worker's new
107
+ commits. If the worker closed without committing, it says so.
108
+ - Exit codes: `0` met, `5` timeout, `6` the owner's pane died,
109
+ `7` the owner sat in `needs_input` for `--stuck-after` seconds
110
+ (default 300).
111
+
112
+ Exit 7 has several causes: the worker finished but did not close, it
113
+ asked a question, or it hit a prompt. In each case, run
114
+ `mu agent read <owner>` first.
115
+
116
+ Pipeline the work: merge one task, run your tests on the merged tree,
117
+ then dispatch the next task. Waiting for a whole wave hides partial
118
+ progress.
119
+
120
+ ## Close and park tasks
121
+
122
+ ```bash
123
+ mu task close spike -w auth --as wontfix --why "superseded by v2"
124
+ mu task close umbrella -w auth --if-ready
125
+ mu task park polish -w auth --why "after the release"
126
+ mu task release build -w auth
127
+ ```
128
+
129
+ - Closed substates other than `done` need `--why`. Every `CLOSED`
130
+ substate satisfies a blocker.
131
+ - `--if-ready` closes only when every blocker is closed. Otherwise it
132
+ lists the open blockers and exits 0.
133
+ - A parked task leaves the ready set, and its dependents keep waiting.
134
+ - `release` clears the owner and returns `IN_PROGRESS` to `OPEN`.
135
+
136
+ To wait on something outside the repo, such as an upstream release,
137
+ block on a placeholder task and close it when the thing lands.
@@ -0,0 +1,177 @@
1
+ # Getting started
2
+
3
+ In this tutorial we install mu, plan two tasks where one blocks the
4
+ other, hand the first task to a pi worker, and merge its commit. It
5
+ takes about ten minutes.
6
+
7
+ You need Node.js, the pi coding agent, tmux 3.0
8
+ or later, and a git repository to work in. Run every command from
9
+ inside a tmux session, in the root of that repository.
10
+
11
+ ## Install mu and link pi
12
+
13
+ First, install mu and connect it to pi:
14
+
15
+ ```bash
16
+ npm i -g @mu-crew/mu
17
+ mu link pi
18
+ mu doctor
19
+ ```
20
+
21
+ `mu link pi` installs the mu pi extension and the mu skill. In the
22
+ output of `mu doctor`, the extension, skill, and `ctl` rows say `ok`.
23
+ If pi was already running, restart it so it loads the extension.
24
+
25
+ ## Create a workstream
26
+
27
+ A workstream is one project: one tmux session, its agents, and its
28
+ task graph.
29
+
30
+ ```bash
31
+ mu workstream init auth
32
+ ```
33
+
34
+ ```
35
+ Created workstream auth (mux session mu-auth)
36
+ Next:
37
+ Attach the session : tmux attach -t mu-auth
38
+ ...
39
+ ```
40
+
41
+ Every verb ends with a `Next:` block of follow-up commands. We use
42
+ them as we go.
43
+
44
+ ## Plan two tasks
45
+
46
+ Now add two tasks. Each needs an impact (1–100) and an effort in
47
+ days. `--blocked-by` makes `build` wait for `design`:
48
+
49
+ ```bash
50
+ mu task add design -w auth -t "Design the auth module" -i 80 -e 2
51
+ mu task add build -w auth -t "Build the auth module" -i 80 -e 5 --blocked-by design
52
+ mu task next -w auth
53
+ ```
54
+
55
+ ```
56
+ ┌────────┬────────┬────────────────────────┬────────┬────────┬──────┬───────┐
57
+ │ name │ status │ title │ impact │ effort │ ROI │ owner │
58
+ ├────────┼────────┼────────────────────────┼────────┼────────┼──────┼───────┤
59
+ │ design │ OPEN │ Design the auth module │ 80 │ 2 │ 40.0 │ — │
60
+ └────────┴────────┴────────────────────────┴────────┴────────┴──────┴───────┘
61
+ ```
62
+
63
+ Only `design` is ready. `build` appears when `design` closes.
64
+
65
+ ## Spawn a worker
66
+
67
+ Spawn a pi agent with its own git worktree:
68
+
69
+ ```bash
70
+ mu agent spawn worker-1 -w auth --workspace
71
+ ```
72
+
73
+ ```
74
+ Spawned worker-1 (pi) in window worker-1 of mu-auth, pane %15 with auto-workspace
75
+ workspace: ~/.local/state/mu/workspaces/auth/worker-1 (git)
76
+ ```
77
+
78
+ The worker runs in a new window of the `mu-auth` session. To watch
79
+ it, run `tmux attach -t mu-auth`. Detach with `Ctrl+b d`.
80
+
81
+ ## Claim the task for the worker
82
+
83
+ Assign the task before you send any text. The claim is what
84
+ `mu task wait` watches.
85
+
86
+ ```bash
87
+ mu task note design -w auth 'SCOPE: write docs/auth.md with the token design'
88
+ mu task claim design -w auth --for worker-1
89
+ ```
90
+
91
+ ```
92
+ Claimed design for worker-1 (OPEN → IN_PROGRESS)
93
+ ```
94
+
95
+ ## Send the task
96
+
97
+ `--fresh` starts a new pi session and sends the prompt into it in
98
+ one step:
99
+
100
+ ```bash
101
+ mu agent send worker-1 -w auth --fresh 'Work on task design. Read: mu task notes design -w auth.
102
+ When done: git commit -am "Design auth", then mu task close design -w auth --evidence "<what you verified>"'
103
+ ```
104
+
105
+ The worker reads its notes, does the work, commits in its worktree,
106
+ and closes the task.
107
+
108
+ ## Wait for the task to close
109
+
110
+ ```bash
111
+ mu task wait design -w auth --first --on-stall exit
112
+ ```
113
+
114
+ ```
115
+ auth/design
116
+ any-of 1 reached CLOSED in 41094ms
117
+ Next:
118
+ Cherry-pick worker-1's commit onto your branch : git cherry-pick 26278f1...
119
+ Refresh worker-1's workspace onto current main : mu workspace refresh worker-1 -w auth
120
+ ```
121
+
122
+ The exit code tells you what happened:
123
+
124
+ | Exit | Meaning | Next move |
125
+ | ---- | ------- | --------- |
126
+ | `0` | the task closed | merge the work |
127
+ | `5` | `--timeout` expired (default 600 s) | wait again |
128
+ | `6` | the worker's pane died and the task went back to `OPEN` | spawn and claim again |
129
+ | `7` | the worker sat in `needs_input` for 5 minutes | `mu agent read worker-1 -w auth`, then answer it |
130
+
131
+ Without `--on-stall exit`, a stalled worker only prints a warning and
132
+ the wait keeps running.
133
+
134
+ ## Merge the commit
135
+
136
+ Run the cherry-pick command from the `Next:` block, then run your
137
+ tests on the result:
138
+
139
+ ```bash
140
+ git cherry-pick 26278f1
141
+ ```
142
+
143
+ Before the next task, rebase the worker's worktree onto the new main.
144
+ The worker keeps its pi context:
145
+
146
+ ```bash
147
+ mu workspace refresh worker-1 -w auth
148
+ ```
149
+
150
+ ## Check the graph
151
+
152
+ ```bash
153
+ mu task next -w auth
154
+ ```
155
+
156
+ `build` is ready now. You can claim it for `worker-1` and repeat the
157
+ claim, send, wait, and merge steps.
158
+
159
+ ## Close the worker
160
+
161
+ When you are done, free the worktree and close the agent:
162
+
163
+ ```bash
164
+ mu workspace free worker-1 -w auth
165
+ mu agent close worker-1 -w auth
166
+ ```
167
+
168
+ `mu agent close` refuses while the worktree has commits or edits that
169
+ mu has not freed. That protects work you have not merged.
170
+
171
+ ## Next steps
172
+
173
+ - [Dispatch work to a worker](dispatch.md) covers more than one
174
+ worker and the `--fresh`, `--steer`, and plain send choices.
175
+ - [Use the TUI dashboard](tui.md): run bare `mu` to see every
176
+ workstream at once.
177
+ - [Clean up](cleanup.md) when the workstream is finished.
@@ -0,0 +1,133 @@
1
+ # How to recover from a broken state
2
+
3
+ Start with `mu doctor`. Each row that is not `ok` prints the command
4
+ that fixes it. mu reports and never cleans up for you, because an
5
+ orphan directory can hold the only copy of uncommitted work.
6
+
7
+ ```bash
8
+ mu doctor # exit 0 healthy, 5 on drift
9
+ mu doctor --deep # rebuild the ops log and diff every field
10
+ mu doctor --disk # add per-workspace byte usage
11
+ ```
12
+
13
+ ## An agent's pane died
14
+
15
+ Run `mu agent list` or `mu state`. Each run reconciles the registry
16
+ with the multiplexer:
17
+
18
+ - An agent row whose pane is gone is a ghost. mu deletes the row, and
19
+ its `IN_PROGRESS` task returns to `OPEN`. A `mu task wait` on that
20
+ task exits 6.
21
+ - A pane in the session that runs an agent CLI but has no row is an
22
+ orphan. mu lists it with an adopt hint and does not adopt it.
23
+
24
+ To register an orphan pane, or a pi you started by hand:
25
+
26
+ ```bash
27
+ mu agent adopt %15 -w auth
28
+ mu agent adopt %15 -w auth --name investigator
29
+ ```
30
+
31
+ The pane title becomes the agent name. The pane must be in the
32
+ `mu-<workstream>` session. An adopted pi has no control socket until
33
+ you restart it with the `MU_CTL_SOCK` path that `adopt` prints.
34
+
35
+ ## A pi agent shows `ctl missing` or `ctl refused`
36
+
37
+ mu reaches pi agents only through the control socket, and never falls
38
+ back to pasting.
39
+
40
+ | State | Means | Fix |
41
+ | ----- | ----- | --- |
42
+ | `ctl missing` | no socket: the extension is not loaded | run `mu link pi`, then respawn the agent |
43
+ | `ctl refused` | the socket exists but does not answer | respawn the agent; for a remote agent, check the ssh forward |
44
+ | `extension X older than installed Y` | pi loaded an older mu build | type `/reload` in the pane, or respawn |
45
+
46
+ To send `/reload` without attaching:
47
+
48
+ ```bash
49
+ mu agent send worker-1 -w auth '/reload' --via mux
50
+ ```
51
+
52
+ `/reload` keeps the pi session. A `send --fresh` or `abort` against an
53
+ outdated extension fails with exit 4 and prints the same two fixes.
54
+
55
+ ## A new pi agent is stuck at `needs_input`
56
+
57
+ pi asks whether to trust a project folder on first start. Run
58
+ `/trust` in the pane once, or spawn with
59
+ `--command 'pi --approve'`. `--approve` trusts every directory,
60
+ including workspace forks, so use it only on your own code.
61
+
62
+ ## You closed your terminal
63
+
64
+ The tmux session keeps running. Reattach with `tmux attach -t mu-auth`.
65
+ Every `mu` command is a short process that reads the DB, so nothing
66
+ needs restarting.
67
+
68
+ ## You ran the wrong command
69
+
70
+ Every action is one group of ops. Find it, preview the inverse, then
71
+ apply:
72
+
73
+ ```bash
74
+ mu undo # list recent groups
75
+ mu undo 6380dd3d # preview
76
+ mu undo 6380dd3d --yes # apply
77
+ ```
78
+
79
+ - Any unique prefix of a group id works.
80
+ - The undo is its own group, so undoing it again is redo.
81
+ - If later work changed the same fields, undo exits 4 and names the
82
+ conflict. `--force --yes` overrides and discards the newer work.
83
+ - Undo restores rows only. Killed panes and freed workspace
84
+ directories do not come back.
85
+
86
+ ## `mu doctor` reports drift
87
+
88
+ Drift means the ops log and the live tables disagree. `--deep` names
89
+ the table, key, and field. Do not rebuild by reflex: if capture missed
90
+ a write, the live table holds real work that a rebuild would discard.
91
+
92
+ ```bash
93
+ mu db backup /tmp/mu-drift-evidence.db # 1. keep the evidence
94
+ mu rebuild /tmp/mu-rebuilt.db # 2. replay the log into a new file
95
+ MU_DB_PATH=/tmp/mu-rebuilt.db mu sql "SELECT local_id, title FROM tasks" # 3. compare
96
+ ```
97
+
98
+ Decide which side is right, then report the drift as a bug with the
99
+ named field. `mu rebuild` never writes in place. It prints the swap
100
+ command.
101
+
102
+ ## The `disk` section of `mu doctor` warns
103
+
104
+ | Row | Means |
105
+ | --- | ----- |
106
+ | `ws-rows` | a workspace row whose directory is gone; the next send fails in the VCS |
107
+ | `ws-dirs` | a workspace directory with no row; it blocks the next `--workspace` spawn with that name |
108
+ | `ws-empty` | a workstream directory with no checkouts |
109
+ | `db-copies` | stray `mu.db*` files that nothing reads |
110
+ | `exports` | output left by the removed export verb |
111
+ | `locks` | lock directories older than one hour, from a spawn or flush that died |
112
+
113
+ To list workspace orphans with cleanup commands, run
114
+ `mu workspace orphans -w auth`. Remove a git-backed orphan with
115
+ `git worktree remove --force <path>` from the project root.
116
+
117
+ ## Rename a workstream
118
+
119
+ There is no rename verb. Every child table cascades on the name:
120
+
121
+ ```bash
122
+ mu sql "UPDATE workstreams SET name='auth-refactor' WHERE name='auth-refator'"
123
+ tmux rename-session -t mu-auth-refator mu-auth-refactor
124
+ ```
125
+
126
+ Names start with a lowercase letter, use letters, digits, `_`, or
127
+ `-`, are at most 32 characters, and do not start with `mu-`.
128
+
129
+ ## Report a bug
130
+
131
+ Include the exact command, its full output, the `environment` block of
132
+ `mu doctor`, and your platform. To reproduce without your real data,
133
+ set `MU_DB_PATH=/tmp/mu-debug.db` and `MU_SYNC_DIR=` (empty).
@@ -0,0 +1,74 @@
1
+ # How to run a worker on another machine
2
+
3
+ The pane is local and the pi process is remote. mu runs no ssh
4
+ itself. `mu agent remote-env` prints the ssh pieces, and you put them
5
+ in the spawn command. The full recipe, with recording, collecting,
6
+ and the traps, is in
7
+ [skills/mu/REMOTE_WORKERS.md](../../skills/mu/REMOTE_WORKERS.md).
8
+ Read it before your first remote spawn.
9
+
10
+ ## Prepare the host
11
+
12
+ On the remote host:
13
+
14
+ 1. Install mu and run `mu link pi`, so the remote pi loads the mu
15
+ extension.
16
+ 2. Allow unix-socket forwards in the host's sshd:
17
+ `AllowStreamLocalForwarding yes`.
18
+ 3. Create the worker's checkout yourself. `--workspace` works only
19
+ for local agents:
20
+
21
+ ```bash
22
+ ssh dev 'git -C ~/repo worktree add ~/ws/worker-1'
23
+ ```
24
+
25
+ Use one orchestrator DB on your machine. Do not run a second mu on the
26
+ host for the same work: task ownership points into your local
27
+ `agents` table.
28
+
29
+ ## Spawn the agent
30
+
31
+ ```bash
32
+ eval "$(mu agent remote-env worker-1 -w auth --shell)" # sets MU_SSH_ARGS, MU_REMOTE_ENV
33
+ mu agent spawn worker-1 -w auth --command \
34
+ "ssh $MU_SSH_ARGS dev -t 'cd ~/ws/worker-1 && $MU_REMOTE_ENV \$SHELL -ilc \"pi --approve\"'"
35
+ ```
36
+
37
+ What each part does:
38
+
39
+ - `MU_SSH_ARGS` forwards the remote pi's control socket to the local
40
+ path mu connects to. It includes `-o ControlMaster=no -o
41
+ ControlPath=none`, because a multiplexed ssh connection never binds
42
+ the local end of the forward.
43
+ - `MU_REMOTE_ENV` sets the agent's identity inside the remote shell.
44
+ tmux `-e` variables do not cross the ssh hop.
45
+ - `$SHELL -ilc` starts pi in an interactive login shell, so the
46
+ remote `~/.zshrc` or `~/.bashrc` loads PATH and provider keys.
47
+ Without it, ssh's non-interactive shell skips them and pi can die at
48
+ startup.
49
+ - `pi --approve` skips pi's project-trust prompt. It trusts whatever
50
+ directory the pane starts in, so use it only on your own code.
51
+
52
+ If the spawn reports `ctl refused`, check `AllowStreamLocalForwarding`
53
+ on the host.
54
+
55
+ ## Drive it like a local agent
56
+
57
+ Claim, `mu agent send --fresh`, `mu agent wait`, and `mu agent abort`
58
+ all go through the forwarded socket and behave as they do locally:
59
+
60
+ ```bash
61
+ mu task note build -w auth 'REMOTE: dev:~/ws/worker-1'
62
+ mu task claim build -w auth --for worker-1
63
+ mu agent send worker-1 -w auth --fresh 'Work on build. Read: mu task notes build -w auth'
64
+ ```
65
+
66
+ The `REMOTE: <host>:<path>` note line is how `mu state` lists remote
67
+ workers. Collect the work by fetching from the remote checkout:
68
+
69
+ ```bash
70
+ git fetch "ssh://dev/~/ws/worker-1" HEAD && git cherry-pick FETCH_HEAD
71
+ ```
72
+
73
+ `mu agent kick` does not reach a remote process. Use `mu agent abort`,
74
+ or close the pane.
@@ -0,0 +1,76 @@
1
+ # How to query and script mu
2
+
3
+ Use typed verbs with `--json` first. Use `mu sql` for ad-hoc joins,
4
+ reports, and repairs that no verb covers.
5
+
6
+ ## Script with `--json`
7
+
8
+ Every verb takes `--json`.
9
+
10
+ - Collection reads print `{"items": [...], "count": N}`.
11
+ - Single objects, such as `mu task show`, print an object with named
12
+ fields.
13
+ - `mu sql --json` prints a bare array of rows.
14
+ - `mu log --tail --json` prints one JSON object per line.
15
+ - Errors go to stderr as `{error, message, nextSteps, exitCode}`.
16
+
17
+ ```bash
18
+ mu state -w auth --json
19
+ mu task list -w auth --json | jq '.count'
20
+ ```
21
+
22
+ Exit codes: `2` usage error, `3` not found, `4` conflict, `5`
23
+ timeout or a multiplexer, VCS, or drift failure, `6` reaped pane,
24
+ `7` stall.
25
+
26
+ ## Read the schema
27
+
28
+ The schema has 11 tables and 3 views (`ready`, `blocked`, `goals`).
29
+ Four tables travel between machines: `workstreams`, `tasks`,
30
+ `task_edges`, and `task_notes`. List them all:
31
+
32
+ ```bash
33
+ mu sql "SELECT type, name FROM sqlite_master WHERE type IN ('table','view') ORDER BY type, name"
34
+ ```
35
+
36
+ Task ids (`local_id`) are unique per workstream only. Join
37
+ `workstreams` in every query, or you hit a same-named task elsewhere.
38
+ Edges and notes reference `tasks.id`, not `local_id`.
39
+
40
+ ## Run common queries
41
+
42
+ Blocked tasks and the goals view, which replaced removed verbs:
43
+
44
+ ```bash
45
+ mu sql "SELECT b.local_id, b.title FROM blocked b JOIN workstreams w ON w.id = b.workstream_id WHERE w.name = 'auth'"
46
+ mu sql "SELECT g.local_id, g.title FROM goals g JOIN workstreams w ON w.id = g.workstream_id WHERE w.name = 'auth'"
47
+ ```
48
+
49
+ Search task titles:
50
+
51
+ ```bash
52
+ mu sql "SELECT t.local_id, t.status, t.title FROM tasks t JOIN workstreams w ON w.id = t.workstream_id
53
+ WHERE w.name = 'auth' AND LOWER(t.title) LIKE '%token%'"
54
+ ```
55
+
56
+ Every task that blocks `launch`, directly or not:
57
+
58
+ ```bash
59
+ mu sql "WITH RECURSIVE prereqs(id) AS (
60
+ SELECT t.id FROM tasks t JOIN workstreams w ON w.id = t.workstream_id
61
+ WHERE t.local_id = 'launch' AND w.name = 'auth'
62
+ UNION
63
+ SELECT e.from_task_id FROM task_edges e JOIN prereqs ON e.to_task_id = prereqs.id
64
+ )
65
+ SELECT t.local_id, t.title, t.status FROM prereqs JOIN tasks t ON t.id = prereqs.id"
66
+ ```
67
+
68
+ `mu sql` runs writes too and prints the number of rows changed. Writes
69
+ are captured as ops, so `mu undo` can revert them.
70
+
71
+ ## Pass list flags
72
+
73
+ A flag with `<value...>` in its help takes repeats, commas, or both:
74
+ `--blocked-by a,b` equals `--blocked-by a --blocked-by b`. An empty
75
+ fragment from a stray comma is dropped. A blank fragment such as
76
+ `" "` is a usage error.