@mu-crew/mu 4.2.0 → 4.2.2
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.
- package/dist/{chunk-SFV5RPZW.js → chunk-4ZWBLTZK.js} +1 -1
- package/dist/chunk-4ZWBLTZK.js.map +1 -0
- package/dist/{chunk-UL2QE43S.js → chunk-EIE5OKZZ.js} +9 -6
- package/dist/chunk-EIE5OKZZ.js.map +1 -0
- package/dist/{chunk-3ZLI6YTV.js → chunk-FHGYHXFB.js} +3 -3
- package/dist/{chunk-RVWNQLFE.js → chunk-FOWIQ4TP.js} +32 -10
- package/dist/{chunk-RVWNQLFE.js.map → chunk-FOWIQ4TP.js.map} +1 -1
- package/dist/{cli-72EJ3CKW.js → cli-HKBFJISN.js} +58 -14
- package/dist/cli-HKBFJISN.js.map +1 -0
- package/dist/cli.js +1 -1
- package/dist/{errors-LY4OZVQU.js → errors-MDQZHB42.js} +2 -2
- package/dist/extension/mu-pi.js +35 -62
- package/dist/extension/mu-pi.js.map +1 -1
- package/dist/index.d.ts +14 -3
- package/dist/index.js +4 -4
- package/dist/{tui-3ZPLSLDW.js → tui-32NIE76L.js} +5 -5
- package/dist/{tui-3ZPLSLDW.js.map → tui-32NIE76L.js.map} +1 -1
- package/docs/ARCHITECTURE.md +3 -3
- package/docs/VOCABULARY.md +2 -2
- package/docs/guide/cleanup.md +3 -0
- package/docs/guide/dispatch.md +3 -1
- package/docs/reference/surface-contract.md +3 -2
- package/package.json +1 -1
- package/skills/mu/SKILL.md +2 -1
- package/skills/mu/recipes/course-correct.md +1 -1
- package/dist/chunk-SFV5RPZW.js.map +0 -1
- package/dist/chunk-UL2QE43S.js.map +0 -1
- package/dist/cli-72EJ3CKW.js.map +0 -1
- /package/dist/{chunk-3ZLI6YTV.js.map → chunk-FHGYHXFB.js.map} +0 -0
- /package/dist/{errors-LY4OZVQU.js.map → errors-MDQZHB42.js.map} +0 -0
package/docs/ARCHITECTURE.md
CHANGED
|
@@ -91,7 +91,7 @@ are re-export hubs.
|
|
|
91
91
|
| `src/op-context.ts` | `withOpContext` (intent, actor, group) and the `withCaptureSuppressed` echo guard; both own the transaction around the `op_ctx` row |
|
|
92
92
|
| `src/fold.ts` | the one definition of a portable row: pure per-key folds of the ops log (horizon, per-field LWW including `kind` and `wave`, substate, notes, edges) |
|
|
93
93
|
| `src/apply.ts` | apply one op: re-fold the keys it touches and make their rows equal the fold; `projectLog` folds every key |
|
|
94
|
-
| `src/human-needed.ts`, `src/cli/human-needed.ts` | `recordHumanNeeded` / `openHumanNeeds`: a `human` task (OPEN/parked, brief = reason) plus the machine-local `human_needs(task_id, caller)` row in one transaction; `mu human-needed <reason
|
|
94
|
+
| `src/human-needed.ts`, `src/cli/human-needed.ts` | `recordHumanNeeded` / `openHumanNeeds`: a `human` task (OPEN/parked, brief = reason) plus the machine-local `human_needs(task_id, caller)` row in one transaction; `mu human-needed <reason>`; `stop: false` (`--no-stop`) writes the task without the row (a to-do, one per reason). `HumanTaskError` (tasks/errors.ts) refuses unpark, claim and the CLOSE block on such a task |
|
|
95
95
|
| `src/wait-actions.ts`, `src/wait-action-receipts.ts` | stall actions of a wait (`handleStall` implementations). `releaseStall` / `releaseStallHandler`: the guarded release, every guard rechecked in the SAME immediate transaction as `releaseTask(expectedOwnerId, ifRevision)` (no await inside; a refusal writes nothing). `wait_action_receipts` storage: `reserveActionReceipt` (INSERT OR IGNORE on task, owner, incarnation, action), `transitionActionReceipt` (compare-and-set along legal edges only). Pure SQL. `steerStall` / `steerStallHandler`: the crash-safe steer: plan and reserve in one immediate transaction (the msgId is saved with the row), then ctl hello and incarnation bind, then the transport's `beforeWrite` fence re-runs every guard and CASes `reserved -> sending` in one synchronous immediate transaction: only the CAS winner writes. A row past `reserved` is only probed (`status {msgId}`, same registry id, pane and incarnation), never resent, never turned into a release. `waitWithActions`: `waitForEvents` plus the handler `onStall` names (a composition, not a loop) |
|
|
96
96
|
| `src/wait-registration.ts` | `wait_registrations`: `registerOwnedWait` (typed refs that exist now, checked in its transaction; merged and deduped), `beginWait`/`endWait` (one active wait per caller: generation compare-and-set, delivered refs and their baselines only removed), per-agent-ref unconsumed baselines (`baselines_json`); `dropOwnedRefs`/`callersOwing` for the done-agent drop; every write one short transaction, never across an await; writes `wait_cursors` only to clear a DONE mark (new work armed, ref dropped), never a consumed token |
|
|
97
97
|
| `src/wait.ts` | `waitForEvents`: the ONE wait loop (tasks, agents, delegates, the caller's registration; with no ref it also discovers what the caller spawned, by `agents.spawner`, and registers it with a zero run baseline; `scope` narrows what is owned to one workstream; `onStall: warn` flags and goes on). Each iteration: `beforePoll`, bounded `ambientIngest`, DB reads, one batched agent read, CLOSE application, pick; then races an agent ctl watch, the poll sleep, abort and the deadline (every await raced, no transaction across one). first/all, urgent events, engine-owned stall detection with a raced `handleStall`, the callers SET (union of owned refs, delegates, human needs), typed cursor delivery in one transaction guarded by each caller's registration generation, flush on return. There is no other wait code: `mu task wait`, `mu agent wait` and `mu wait` all call it (`setWaitSleepForTests` is its sleep seam) |
|
|
@@ -180,7 +180,7 @@ are re-export hubs.
|
|
|
180
180
|
| `extension/delegate.ts` | pi extension, parent side: `mu_delegate` / `mu_delegate_reissue` / `mu_delegate_cancel`: admission (running, queued, refused), spawn through `agent spawn --task` (on `NoMultiplexerError` only: `mu delegates run <call-id>`, a child pi with no pane), the wait, the record (`mu delegates finish` before the pane closes) and the **wake**: answers no settle showed (`DelegateHandle.delivered`) get one pointer message when pi is idle, resent once if pi's queue loses it, dropped with a note on Escape; all state changes go through `mu delegates` |
|
|
181
181
|
| `extension/delegate-calls.ts` | the extension's wrappers over `mu delegates register / mark / finish / show` |
|
|
182
182
|
| `extension/delegate-format.ts`, `delegate-process-format.ts`, `delegate-args.ts`, `delegate-trace.ts`, `mu-run.ts` | pure wording of a gap's report, the wake and the dropped-wake note; the mux-free delegate's tool result and failure wording; label and model arguments; the `MU_DELEGATE_TRACE` log; the `mu` runner seam (per-call env, opt-in SIGTERM drain on abort) and envelope readers |
|
|
183
|
-
| `extension/nudge.ts` | pi extension: the keep-driving **settle wait** and the close nudge. Every completed `agent_before_settle` reads the caller identities' open human needs (`mu state --me`, one per identity) and runs `mu wait --first --on-stall exit --json` as this session (managed identity + `PI_SESSION_ID` through the runner's per-call env); an event continues the turn with the wait's result under the SKILL.md rule; a `delegate` event adds that call's report (`mu task notes`, capped, with a pointer), and one of a wave keeps waiting while siblings run, then shows ONE **wave summary** in place of the first wait's result (stale by then), keeping the waits' `notices`;
|
|
183
|
+
| `extension/nudge.ts` | pi extension: the keep-driving **settle wait** and the close nudge. Every completed `agent_before_settle` reads the caller identities' open human needs (`mu state --me`, one per identity) and runs `mu wait --first --on-stall exit --json` as this session (managed identity + `PI_SESSION_ID` through the runner's per-call env); an event continues the turn with the wait's result under the SKILL.md rule; a `delegate` event adds that call's report (`mu task notes`, capped, with a pointer), and one of a wave keeps waiting while siblings run, then shows ONE **wave summary** in place of the first wait's result (stale by then), keeping the waits' `notices`; under an open human stop (read first, or in the wait's `humanNeeds`) the settle still waits and continues, its entry led by `HUMAN_STOP_DRAIN` and the stops' reasons instead of the rule. Esc, input, a dialog or shutdown aborts only that wait, which drains through SIGTERM. Holds (`input`, `wake`, `blocked`) skip a wait's start, never a consumed result's entries. Close nudge: a worker settles owning a task. `parallelSettle` runs the settle checks in parallel behind one handler and merges their entries (a consumed wait result survives a late hold); `mu log` breadcrumbs are not awaited |
|
|
184
184
|
| `src/pi-migrate.ts`, `src/pi-known-skills.ts`, `src/cli/pi.ts` | `mu pi migrate`: move the old link-pi shim and skill link aside, only when ownership is proven (byte-exact generated shim template, link into this install, released-skill digest). pi loads mu as a package: `package.json` `pi` manifest |
|
|
185
185
|
|
|
186
186
|
### Tasks, worktrees and workstreams
|
|
@@ -212,7 +212,7 @@ are re-export hubs.
|
|
|
212
212
|
| `src/vcs/git.ts` | git primitives (plain functions, git only): toplevel, `worktree add --detach` / remove, dirty files, the upstream ref set, `isAncestor`, `createBranch` |
|
|
213
213
|
| `src/worktree.ts` | per-agent worktrees: `createWorktree`, `removeWorktree`, `worktreeState`, the machine-local `worktrees` registry (outlives the agent; the reaper never touches it), the one close rule (`releaseWorktree`: park at `<path>.mu-removing`, scan holders with `worktreeHolders` (/proc, else lsof): a writer or an unprovable scan refuses unless `--force`, a cwd or reader is a warning; re-judge, then pin a create-only branch and remove), name reuse (`reclaimWorktreePath`); `WorktreeDirtyError`, `WorktreeHeldError`, `WorktreeBranchExistsError`, `WorktreePathNotEmptyError`, `WorktreeVcsRequiredError` |
|
|
214
214
|
| `src/state.ts` | `stateSnapshot`: the canonical READ-ONLY state read (SQL column names; no reconcile, no reap, no write; async only for ctl probes) of tasks (ordered by raw `MAX(ops.seq)` activity), registry agents (host/cwd/base/collected_head), the caller's own delegate queue and waves (`verdictTally(..., caller)`), and its open human needs; `mu state`, `mu me` and the dashboard share it |
|
|
215
|
-
| `src/dashboard-data.ts` | `loadDashboard`: the dashboard's ONE read-only projection (live workstreams incl. scratch; every task by status with qualified keys and raw `MAX(ops.seq)` activity; open frontier; registry agents with owned task; canonical log items; the caller's own human needs and delegates, empty for a null caller). No reconcile, reap, ingest or write. `next` is `computeNext` over the caller set (`computed`; `unavailable` only when it throws), and an agent's `tool` is the ctl status's running tool with `elapsed_ms` at read (null = none, absent = old extension or no ctl). every `kind=delegate` task carries its `call` (state, verdict, judged task, wave; any caller), and `waves` tallies each read workstream's five newest waves over every caller (`tallyCalls`); each delegate read is bounded in SQL (shown task statuses, newest waves, refused calls only), so a tick does not grow with `scratch`'s history. `attention` (dead/permission/input
|
|
215
|
+
| `src/dashboard-data.ts` | `loadDashboard`: the dashboard's ONE read-only projection (live workstreams incl. scratch; every task by status with qualified keys and raw `MAX(ops.seq)` activity; open frontier; registry agents with owned task; canonical log items; the caller's own human needs and delegates, empty for a null caller). No reconcile, reap, ingest or write. `next` is `computeNext` over the caller set (`computed`; `unavailable` only when it throws), and an agent's `tool` is the ctl status's running tool with `elapsed_ms` at read and the extension's `quiet_ms` (time since its last output) (null = none, absent = old extension or no ctl). every `kind=delegate` task carries its `call` (state, verdict, judged task, wave; any caller), and `waves` tallies each read workstream's five newest waves over every caller (`tallyCalls`); each delegate read is bounded in SQL (shown task statuses, newest waves, refused calls only), so a tick does not grow with `scratch`'s history. `attention` (dead/permission/input agents, stalled ones whose tool has been quiet 15 min, refused delegate calls, OPEN human tasks of any recorder, next unavailable, sync warnings) reads every live workstream and ignores every filter; an item that a `mu` command clears carries it as `fix` (dead: `agent close`, refused: `delegates finish --outcome cancelled`, human: `task close`), which `y` copies on the Overview. `scopeWorkstream` reads tasks, edges and frontier of the shown workstream only (agents, log, caller panels and attention stay machine-wide; human tasks and task owners come from one SQL pass each), so a tick costs the shown workstream, not the whole database |
|
|
216
216
|
|
|
217
217
|
### CLI, output and packaging
|
|
218
218
|
|
package/docs/VOCABULARY.md
CHANGED
|
@@ -42,7 +42,7 @@ agent names, and file paths are in [reference/naming.md](reference/naming.md).
|
|
|
42
42
|
| **role** | Advisory label, `full-access` or `read-only`: recorded and shown, not enforced and not a security boundary. A read-only auditor simply gets no worktree. | "permission", "tier", "capability" |
|
|
43
43
|
| **persistent** | An agent that stays alive across tasks. | "long-lived" (prose only) |
|
|
44
44
|
| **one-shot** | An agent that exists for one task. | "ephemeral", "transient" |
|
|
45
|
-
| **nudge** | A pi extension continuation at settle. The keep-driving one is the **settle wait**: every completed settle of an orchestrator runs `mu wait` as its callers and continues the turn with the event, until nothing is owed
|
|
45
|
+
| **nudge** | A pi extension continuation at settle. The keep-driving one is the **settle wait**: every completed settle of an orchestrator runs `mu wait` as its callers and continues the turn with the event, until nothing is owed or the user cancels (under a `mu human-needed` stop it still collects owned work, led by the drain rule, and starts nothing). The close nudge tells a worker once per prompt to close the task it still owns (never a delegate's own `kind=delegate` task: its call closes it). | "goal", "loop" |
|
|
46
46
|
| **delegate** | A scratch agent started for one check. Its call is a `delegate`-kind task; its answer is that task's report, and the settle wait shows it to pi (a wave's as one **wave summary**). The `mu_delegate` tool does it in one call; the pane stays attachable, and its pi session is kept under `<DB dir>/delegate-sessions/`, out of the caller's `/resume` list. With no tmux or herdr the tool runs it as a **delegate process** instead (no pane). | "subagent", "child agent" |
|
|
47
47
|
| **wake** | The one pi message the delegate side sends for a recorded answer when no settle wait will show it (pi idle, `MU_NUDGE=0`): a pointer per answer (`mu task notes <task> -w <ws>`), no answer text, that starts a turn whose settle shows the report. Losing or repeating one loses or repeats nothing. | "echo", "follow-up answer" |
|
|
48
48
|
| **wave summary** | What the settle wait shows for a delegate of a wave: it waits while siblings run (never on refused ones), then ONE entry with counts per verdict, a line per call and the answers, instead of one per call. | "wave echo" |
|
|
@@ -76,7 +76,7 @@ agent names, and file paths are in [reference/naming.md](reference/naming.md).
|
|
|
76
76
|
| **substate** | What the status means, shown as `STATUS/substate`; never null. `OPEN`: `todo`, `parked`, `triage`. `IN_PROGRESS`: `active`. `CLOSED`: `done`, `rejected`, `wontfix`, `duplicate`, `superseded`. | "resolution", "reason" |
|
|
77
77
|
| **park** / **unpark** | `OPEN/todo` ↔ `OPEN/parked` (park needs `--why`). Parked tasks leave **ready**. | "defer", "snooze" |
|
|
78
78
|
| **triage** / **accept** | `OPEN/triage` is a proposed task, usually a review **finding**, not yet accepted as work: out of **ready**, refused by `claim`, but it blocks its dependents. `mu task add --triage` creates one; `mu task accept` moves it to `OPEN/todo`; declining is `close --as rejected` or `--as duplicate`. | "inbox", "pending" |
|
|
79
|
-
| **human-needed** | `mu human-needed <reason>`: the caller records a `human` task, `OPEN/parked`, whose brief is the reason; the loop's only legitimate stop. Scoped to the caller (`human_needs`, machine-local: managed `<ws>/<agent>` or `pi:<session>`, never a note author; a rebuild keeps the task but loses the caller). Same reason is a no-op; a new reason appends a brief. A `human` task resolves only by an explicit `mu task close`: unpark, claim (even `--force`) and a CLOSE block are refused. Never created on an error or a queue refusal. | "blocker", "escalation" |
|
|
79
|
+
| **human-needed** | `mu human-needed <reason>`: the caller records a `human` task, `OPEN/parked`, whose brief is the reason; the loop's only legitimate stop. Scoped to the caller (`human_needs`, machine-local: managed `<ws>/<agent>` or `pi:<session>`, never a note author; a rebuild keeps the task but loses the caller). Same reason is a no-op; a new reason appends a brief. A `human` task resolves only by an explicit `mu task close`: unpark, claim (even `--force`) and a CLOSE block are refused. Never created on an error or a queue refusal. Under an open stop the settle still collects owned work (continues each event under the drain rule); it starts nothing. `--no-stop` records the `human` task without the `human_needs` row: a human to-do, never a stop, one task per reason. | "blocker", "escalation" |
|
|
80
80
|
| **finding** | One problem a reviewer, checker, or auditor reports. Recorded as an `OPEN/triage` task (the mu way), or as an answer line when a **delegate** reviews something nobody will track. | "issue", "comment" |
|
|
81
81
|
| **task DAG** / **graph** | The directed acyclic graph of tasks. | "task list", "tree" |
|
|
82
82
|
| **edge** | The single edge type: `A blocks B` means A must close before B starts. | "dependency" (prose only) |
|
package/docs/guide/cleanup.md
CHANGED
|
@@ -118,6 +118,9 @@ mu delegates prune # dry run: what goes, and what is kept
|
|
|
118
118
|
mu delegates prune --yes # backs up beside the DB first; irreversible
|
|
119
119
|
```
|
|
120
120
|
|
|
121
|
+
`--older-than 0` takes every closed delegate task, however fresh. Workstream
|
|
122
|
+
teardown never touches `scratch`, so this is how scratch gets cleaned.
|
|
123
|
+
|
|
121
124
|
## Free disk space
|
|
122
125
|
|
|
123
126
|
```bash
|
package/docs/guide/dispatch.md
CHANGED
|
@@ -226,7 +226,9 @@ mu task release build -w auth
|
|
|
226
226
|
- A parked task leaves the ready set, and its dependents keep waiting.
|
|
227
227
|
- `mu human-needed <reason>` records a parked `human` task for a decision only a
|
|
228
228
|
person can make. It never becomes ready and resolves only by `mu task close`
|
|
229
|
-
(unpark, claim and a CLOSE block are refused).
|
|
229
|
+
(unpark, claim and a CLOSE block are refused). The settle still collects
|
|
230
|
+
work already running; nothing new starts. `--no-stop` records a human to-do
|
|
231
|
+
that stops nothing.
|
|
230
232
|
- `release` clears the owner and returns `IN_PROGRESS` to `OPEN`.
|
|
231
233
|
|
|
232
234
|
## Authorise tasks for the executor
|
|
@@ -47,8 +47,9 @@ their guarantees:
|
|
|
47
47
|
wait (`extension/nudge.ts`): every completed settle of an orchestrator
|
|
48
48
|
runs `mu wait --first --on-stall exit --json` as its callers (no shell
|
|
49
49
|
line parsed, no once-per-prompt latch) and continues the turn with the
|
|
50
|
-
event. It stops when nothing is owed,
|
|
51
|
-
|
|
50
|
+
event. It stops when nothing is owed, the user cancels, or the wait
|
|
51
|
+
fails. Under a `mu human-needed` stop it still collects owned work, led
|
|
52
|
+
by a drain rule (start nothing new) instead of the keep-driving rule. A cancelled wait drains through
|
|
52
53
|
`MuRunOpts.drainMs`. Skipped under `MU_REMOTE=1` and in a nested pi.
|
|
53
54
|
Delegate answers arrive through it (`v_settle_delivery`): a `delegate`
|
|
54
55
|
event's continuation carries that call's report (capped, with the
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mu-crew/mu",
|
|
3
|
-
"version": "4.2.
|
|
3
|
+
"version": "4.2.2",
|
|
4
4
|
"description": "A persistent, observable crew of pi agents running in one tmux or herdr session per workstream, coordinated through a built-in task DAG.",
|
|
5
5
|
"publishConfig": {
|
|
6
6
|
"access": "public"
|
package/skills/mu/SKILL.md
CHANGED
|
@@ -28,7 +28,8 @@ show` do not); workers get it.
|
|
|
28
28
|
**While workers run, keep driving.** Your turn ends only when everything you own
|
|
29
29
|
is closed, or only a human can decide (scope, spend, irreversible or external
|
|
30
30
|
action, hardware-key handback): record it with `mu human-needed -w <ws>
|
|
31
|
-
"<reason>"`, then stop. A
|
|
31
|
+
"<reason>"`, then stop. A to-do for the human that blocks nothing ("tag it",
|
|
32
|
+
"the rollout week") is `--no-stop`. A status summary is a `mu log` line, not a stopping
|
|
32
33
|
point: one per wave, then back to waiting. An error never means a
|
|
33
34
|
human is needed. Ending a turn mid-run stalls the crew.
|
|
34
35
|
<!-- /mu:keep-driving -->
|
|
@@ -19,5 +19,5 @@ Use when a hint says `course check due: <n> closed since <date>`, or a human ask
|
|
|
19
19
|
- Code budget: `src/` vs baseline; units >30% over budget.
|
|
20
20
|
- Real use: last dogfood date; what it found that review missed.
|
|
21
21
|
4. **Propose at most 7 changes**, each tied to a number.
|
|
22
|
-
5. **Stop**: `mu human-needed -w <ws> "course check: <n> proposed changes, see note"
|
|
22
|
+
5. **Stop**: `mu human-needed -w <ws> "course check: <n> proposed changes, see note"`.
|
|
23
23
|
6. **Approved**: one umbrella note starting `COURSE CHECK <date>` (the hint counts from it) and the DAG diff, then dispatch.
|