pi-legion 0.16.0 → 2.0.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 (93) hide show
  1. package/CHANGELOG.md +117 -0
  2. package/CONTRIBUTING.md +109 -18
  3. package/README.md +389 -630
  4. package/agents/advisor.md +7 -5
  5. package/agents/centurion.md +53 -0
  6. package/agents/designer.md +33 -33
  7. package/agents/planner.md +1 -2
  8. package/agents/prototype.md +2 -2
  9. package/agents/reviewer.md +66 -31
  10. package/agents/scout.md +6 -2
  11. package/agents/worker.md +11 -3
  12. package/docs/contracts/esc-abort-v1.md +131 -0
  13. package/docs/contracts/esc-cascade-v2.md +101 -0
  14. package/docs/design.md +73 -37
  15. package/docs/legion-v2-contract.md +461 -0
  16. package/docs/legion-v2-delivery.md +62 -0
  17. package/docs/retire-hardening-contract.md +125 -0
  18. package/docs/subagents-teams.md +76 -0
  19. package/docs/tui-viewer-contract.md +276 -0
  20. package/docs/vexillatio-contract.md +162 -0
  21. package/index.ts +1568 -288
  22. package/package.json +19 -12
  23. package/skills/pi-legion/SKILL.md +86 -94
  24. package/src/agents/agents.ts +66 -16
  25. package/src/agents/overrides.ts +2 -1
  26. package/src/agents/paths.ts +1 -1
  27. package/src/agents/settings.ts +268 -20
  28. package/src/api.ts +49 -48
  29. package/src/{herdr → backends/legacy}/client.ts +14 -69
  30. package/src/{shared → backends/legacy}/cursor-chat.ts +2 -2
  31. package/src/{herdr → backends/legacy}/runner.ts +22 -9
  32. package/src/backends/legacy/types.ts +138 -0
  33. package/src/extension/auto-doctor.ts +144 -0
  34. package/src/extension/budget.ts +2 -2
  35. package/src/extension/child-guard.ts +214 -201
  36. package/src/extension/event-bus.ts +263 -0
  37. package/src/extension/legion-commands.ts +773 -0
  38. package/src/extension/legion-doctor.ts +975 -0
  39. package/src/extension/legion-status.ts +172 -0
  40. package/src/extension/legion-stop.ts +150 -0
  41. package/src/extension/legion-tools.ts +816 -0
  42. package/src/extension/notify.ts +24 -19
  43. package/src/extension/playbook.ts +20 -89
  44. package/src/extension/recycle.ts +2 -7
  45. package/src/extension/runtime.ts +736 -107
  46. package/src/extension/scout-guard.ts +492 -0
  47. package/src/extension/slash.ts +89 -438
  48. package/src/extension/spawn-hints.ts +79 -0
  49. package/src/extension/summary.ts +17 -58
  50. package/src/legion/budget.ts +165 -0
  51. package/src/legion/db.ts +242 -0
  52. package/src/legion/events.ts +150 -0
  53. package/src/legion/mail.ts +412 -0
  54. package/src/legion/nodes.ts +461 -0
  55. package/src/legion/rebuild.ts +533 -0
  56. package/src/legion/state-machine.ts +313 -0
  57. package/src/legion/usage.ts +101 -0
  58. package/src/runs/acceptance.ts +82 -25
  59. package/src/runs/args.ts +117 -15
  60. package/src/runs/hygiene.ts +335 -0
  61. package/src/runs/orchestrator.ts +808 -1681
  62. package/src/runs/owner.ts +61 -0
  63. package/src/runs/provider-pin.ts +59 -0
  64. package/src/runs/provision.ts +135 -0
  65. package/src/runs/role-tool-gates.ts +103 -0
  66. package/src/runs/store.ts +44 -17
  67. package/src/runs/verify-queue.ts +195 -0
  68. package/src/shared/name.ts +29 -0
  69. package/src/shared/output-cap.ts +57 -0
  70. package/src/shared/progress.ts +57 -135
  71. package/src/shared/session.ts +280 -173
  72. package/src/shared/types.ts +115 -208
  73. package/src/supervisor/child-memory.ts +140 -0
  74. package/src/supervisor/proc-tree.ts +103 -0
  75. package/src/supervisor/rpc-supervisor.ts +1033 -0
  76. package/src/supervisor/types.ts +153 -0
  77. package/src/supervisor/ui-proxy.ts +226 -0
  78. package/src/tui/chat-items.ts +330 -0
  79. package/src/tui/live-overlay.ts +874 -0
  80. package/src/tui/status.ts +553 -27
  81. package/src/tui/tree-view.ts +808 -0
  82. package/src/tui/viz/canvas.ts +119 -0
  83. package/src/tui/viz/layout.ts +111 -0
  84. package/src/tui/viz/model.ts +123 -0
  85. package/src/tui/viz/palette.ts +188 -0
  86. package/src/tui/viz/panels.ts +532 -0
  87. package/src/tui/viz/railway.ts +313 -0
  88. package/src/tui/viz/rate.ts +211 -0
  89. package/src/tui/viz/view.ts +228 -0
  90. package/src/extension/parent-label.ts +0 -115
  91. package/src/profiles/classify.ts +0 -375
  92. package/src/profiles/profiles.ts +0 -730
  93. package/src/runs/layout.ts +0 -258
package/CHANGELOG.md ADDED
@@ -0,0 +1,117 @@
1
+ # Changelog
2
+
3
+ All notable changes to this project are documented in this file.
4
+
5
+ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
6
+ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
+
8
+ Published GitHub Release notes remain available at
9
+ https://github.com/zzjcool/pi-legion/releases — this file is the in-repo
10
+ summary so you can see **2.x vs 0.16** without leaving the tree.
11
+
12
+ ## [Unreleased]
13
+
14
+ ### Fixed
15
+
16
+ - Dispatched children now receive `--provider` pinned from the parent's model
17
+ registry, so a bare model id (`workbuddy/…`) that also exists under a static
18
+ auth-less provider in `models.json` can no longer hijack the child start
19
+ (`No API key found for …`) (#123).
20
+ - Scout-guard now counts first-class `grep` / `find` / `ls` tool calls as reads (#87).
21
+ - Doctor diagnose help no longer repeats itself; storage section shows hygiene sweep state (#86).
22
+ - Bundled roles no longer advertise unloaded `lens_*` tools (#75).
23
+ - Non-interactive `pi --print` waits for async children before cascade retire (#77).
24
+ - Roles load `builtin:codemode`; doctor diagnose shows a dedicated section (#89 / #90 → #93).
25
+ - Doctor role-tool→extension gates are data-driven / extensible (#97 / #99).
26
+ - Launch honors `name=` so `/legion status <name>` matches the railway label (#101 / #104).
27
+ - Galaxy legend shows failed/retired glyphs only when those states are present (#102 / #103).
28
+ - Live child status leads with `alive · quiet Ns`; long quiet emphasizes living over a stale execution snapshot (#81 / #92 / #105).
29
+ - npm `package.json` description/keywords aligned with Legion 2.x RPC (no Herdr panes) (#106 / #111).
30
+
31
+ ### Added
32
+
33
+ - `/legion status` human-readable summary; doctor slash list covers team / agents / on|off / summary (#76).
34
+ - README documents scout-guard settings and `/scout-guard` / `/no-scout-guard` (#74 / #71).
35
+ - Scout-guard mock-llm e2e: notify ×1, cooldown, and dispatch clear (#108 / #113).
36
+
37
+ ### Changed
38
+
39
+ - Prefer `PI_LEGION_EXTRA_AGENT_DIRS` over legacy `PI_HERDR_SUBAGENTS_*` (alias; new name wins if both set) (#109 / #114).
40
+ - CONTRIBUTING/CI docs aligned with 2.x RPC; verify-12/13 paths point at `test/legacy/docker/` (#95 / #100, #107 / #112).
41
+ - README: remove duplicate Child extensions heading (#94 / #98).
42
+ - `design.md` historical banner; landed F38–F46 marked ✅ / Historical (#80 / #83 → #91).
43
+ - CI PR job runs `test:integration` (#79 / #88).
44
+
45
+ ## [2.0.0] - 2026-10-14
46
+
47
+ First **Pi Legion** line on headless Pi RPC. Relative to the final Herdr-era
48
+ **0.16.x** packages, this is a breaking transport and packaging change.
49
+
50
+ ### Breaking
51
+
52
+ - **RPC-only transport:** children run as headless `pi --mode rpc` processes
53
+ under `LegionSupervisor`. Herdr pane execution is archived under
54
+ `src/backends/legacy/` and is **not** a v2 runtime option.
55
+ - **Kinds:** only `kind: pi` is supported. Migrate non-Pi roles or stay on
56
+ `pi-legion@0.16.x`.
57
+ - **Shared tree ledger:** squad state lives in SQLite WAL `legion.db` (phases,
58
+ mail, resume), not pane-centric session bookkeeping alone.
59
+ - Bundled agent playbooks aligned with local RPC practice (#66).
60
+
61
+ ### Added
62
+
63
+ - Recursive centurion trees, four-phase
64
+ planning / implementing / reviewing / verifying machine, `legion_mail`,
65
+ three-layer `/legion` UI (resident tree, full view, live overlay), railway
66
+ strip, tok/s / galaxy / log panels.
67
+ - Scout-guard: remind the main session after a streak of read-class tools (#64).
68
+ - Storage hygiene sweep on startup: prune idle runs, orphan temp dirs, abandoned
69
+ nodes, event retention, WAL checkpoint (#37 / #38 / #40 → #47).
70
+ - `/legion doctor` (+ diagnose) self-check; auto-doctor snippets on gated spawn
71
+ failures (#52).
72
+ - Child memory gate (`NODE_OPTIONS` V8 flags, pre-spawn gate) and tree-wide
73
+ verify concurrency limit (#50).
74
+ - Children default to `--no-extensions` with explicit/role escape hatches (#43 / #48).
75
+ - User stop controls for async children (`/legion stop`, idle Esc, `x` in view) (#41).
76
+ - Mock LLM server for offline pi / legion smoke (`test/mock-llm`, #54 / #56).
77
+ - GitHub Actions CI (typecheck + unit + integration) and stage-only npm publish
78
+ on tag (#65 / #68).
79
+ - Project workflow docs in CONTRIBUTING (#69).
80
+
81
+ ### Changed
82
+
83
+ - Slash commands consolidated under `/legion` (#57).
84
+ - Status bar shows current-turn elapsed beside lifetime total (#62).
85
+ - tok/s uses output tokens / generationMs (decode throughput) (#61).
86
+
87
+ ### Fixed
88
+
89
+ - Railway: pin live spawn verticals when the strip scrolls left (#67); retire /
90
+ downward spawn connector regressions (#46).
91
+ - Live worker no longer marked retired on a transient Connection blip (#63).
92
+ - Session JSONL streamed + incrementally parsed (no full-file `readFileSync`) (#36 / #45).
93
+ - Per-stream child output byte cap; kill on overflow (#35 / #44).
94
+ - Bun SQLite `.get()` null treated as miss on root insert (#53).
95
+ - Vexillatio sibling naming scoped to the current parent (#42 / #51).
96
+
97
+ ### Security / robustness (design.md F38–F46, already on master)
98
+
99
+ - Model-scope globs use non-RegExp matching (ReDoS).
100
+ - Session create uses `writeFileSync` with `wx` (no fd leak / TOCTOU).
101
+ - Session decode swallows scalar JSON lines as torn.
102
+ - `tasks[]` / blank task validated before launch.
103
+ - Per-agent `timeoutMs`, pending criteria, nested YAML acceptance parsing;
104
+ `UNENFORCED_FIELDS` empty.
105
+
106
+ ## [0.16.x] - Herdr-era (final)
107
+
108
+ Last line that runs children in Herdr panes. Not developed further on this
109
+ branch — pin `pi-legion@0.16.x` if you still need that model. See
110
+ [Herdr transition](README.md#herdr-transition-and-role-migration) in the README.
111
+
112
+ Earlier 0.11–0.15 history (including the `pi-herdr-swarm` /
113
+ `@zzjcool/pi-herdr-subagents` renames) lives in git tags and older Releases.
114
+
115
+ [Unreleased]: https://github.com/zzjcool/pi-legion/compare/v2.0.0...HEAD
116
+ [2.0.0]: https://github.com/zzjcool/pi-legion/releases/tag/v2.0.0
117
+ [0.16.x]: https://github.com/zzjcool/pi-legion/releases
package/CONTRIBUTING.md CHANGED
@@ -4,6 +4,54 @@ This package is a Pi extension. The public surface is `index.ts` (the
4
4
  `subagent` tool) plus `src/api.ts` (programmatic imports). Please keep those
5
5
  two as the only things a downstream should need.
6
6
 
7
+ ## Project workflow
8
+
9
+ **Issues first.** A bug or feature found while dogfooding starts as a GitHub
10
+ issue. Include a repro, the expected behaviour, the actual behaviour, and the
11
+ environment (Node version, OS, and the Pi / pi-legion version).
12
+
13
+ **One concern per pull request.** Link the issue. Open the PR as a draft.
14
+ Mark it **Ready for review** when the change is ready and you expect the
15
+ required check `ci` to pass.
16
+
17
+ **Merge gate.** Alice (the maintainer bot) merges only after code review has
18
+ passed and the required GitHub Actions check `ci` is green. Do not push
19
+ directly to `master`. Implementers do not merge their own pull requests.
20
+
21
+ **Before you push.** Run:
22
+
23
+ ```bash
24
+ npm run typecheck
25
+ npm test
26
+ npm run test:integration # or npm run test:all
27
+ ```
28
+
29
+ The required GitHub Actions check `ci` runs typecheck, unit, integration, and
30
+ mock-llm. Run `npm run test:integration` (or `npm run test:all`) locally
31
+ before you push, especially when the change touches `src/runs/`, `src/legion/`,
32
+ or `src/extension/runtime.ts`.
33
+
34
+ Add the unit tests the change needs. Prefer **TDD** (see [Checks](#checks)):
35
+ a failing test in `test/unit` or `test/integration` first, then the production
36
+ code.
37
+
38
+ **Regression tests.** When you fix a bug, add a unit or integration test in
39
+ the same PR when that is feasible: failing first, then passing. Do not
40
+ `unref()` a timer that must keep the Node test runner alive. `unref()` drops
41
+ the timer from the event-loop refcount, so `node --test` can exit before the
42
+ callback runs. That is the rpc-supervisor retire-timer lesson (`waitForExit`
43
+ and the descendant-sweep delay in `src/supervisor/rpc-supervisor.ts`): a
44
+ timeout the caller is awaiting stays referenced, as with the wait timer in
45
+ `src/extension/runtime.ts`.
46
+
47
+ **npm release.** A `v*.*.*` tag runs the release workflow
48
+ (`.github/workflows/release.yml`). Publish from that workflow with
49
+ `npm stage publish` and a stage-only token. A maintainer promotes the staged
50
+ version on npm with 2FA. Do not use plain `npm publish` in GitHub Actions.
51
+
52
+ **Communication.** Coordinate in the team channel, or with Alice. Do not ping
53
+ the maintainer user for a routine review or merge ask.
54
+
7
55
  ## Setup
8
56
 
9
57
  ```bash
@@ -17,33 +65,68 @@ there is no compile step to ship).
17
65
 
18
66
  ## Checks
19
67
 
68
+ The required GitHub Actions check `ci` (`.github/workflows/ci.yml`, on pull
69
+ requests and pushes to `master`) runs, in order:
70
+
71
+ 1. `npm run typecheck`
72
+ 2. `npm test` (unit)
73
+ 3. `npm run test:integration`
74
+ 4. `npm run test:mock-llm`
75
+
76
+ A failing integration step fails `ci`, so nesting and orchestrator regressions
77
+ are blocked before merge. `test:live` and `test:docker` stay out of that job.
78
+
20
79
  ```bash
21
80
  npm run typecheck
22
81
  npm test # test/unit/*.test.ts
23
- npm run test:integration # fake herdr, no live binary
82
+ npm run test:integration # FakeSupervisor / nested fakes; no live `pi` binary
24
83
  npm run test:all # typecheck + unit + integration
84
+ npm run test:mock-llm # also part of the required ci check
25
85
  ```
26
86
 
27
- `npm run test:live` talks to a real herdr. It skips itself unless `HERDR_ENV=1`
28
- and `herdr` is on `PATH`. Do not fail CI on it.
87
+ `npm run test:live` is a **pi RPC live** smoke (`test/live/rpc-live.test.ts`).
88
+ It skips itself when the `pi` binary is missing from `PATH` (see the probe at
89
+ the top of that file). Do not fail CI on it.
29
90
 
30
91
  Prefer **TDD** for behaviour changes: a failing test in `test/unit` or
31
92
  `test/integration` first, then the production code. Integration tests should
32
- go through `createHerdrClient(createFakeRunner(fake))` so argv construction
33
- and JSON parsing stay covered.
93
+ drive the orchestrator through `FakeSupervisor` (`test/helpers/fake-supervisor.ts`)
94
+ so nesting / launch / collect stay covered without a live `pi`. The herdr-era
95
+ helpers `createHerdrClient` / `createFakeRunner` remain as **deprecated legacy**
96
+ exports (see `src/api.ts` and `test/legacy/`); use them only when touching the
97
+ archived Herdr backend.
98
+
99
+ ## Mock LLM
100
+
101
+ For offline Pi / legion smoke without provider quota, start the scriptable
102
+ OpenAI-compatible mock (see [`test/mock-llm/README.md`](test/mock-llm/README.md)):
103
+
104
+ ```bash
105
+ npm run mock-llm # default scenario=echo on :8765
106
+ npm run test:mock-llm # engine + HTTP + optional pi --print smoke
107
+ ```
108
+
109
+ `test/docker/mock-llm.mjs` launches the same CLI (default scenario `tool-once`
110
+ for legacy inside-*.sh). Point Pi at it with `writeMockPiHome({ baseUrl })` or
111
+ the `providers.mock` block in that README. Never commit real API keys; the
112
+ dummy key is always the literal `mock`.
34
113
 
35
114
  ## Docker verification
36
115
 
37
- `test/docker/` runs the package inside `pi-herdr-sandbox:latest` with a copy
38
- of the **host** Pi config (`~/.pi/agent/settings.json`, `models.json`,
39
- `auth.json` if present). The copy is disposable (`/tmp/pi-herdr-docker-home`
40
- by default); the container cannot write back to your real `~/.pi`.
116
+ `test/docker/` runs the package inside the RPC / pi-legion sandbox image.
117
+ Default image and staging path names are **historical** (`pi-herdr-sandbox:latest`,
118
+ `/tmp/pi-herdr-docker-home`; override with `PI_DOCKER_IMAGE` / `DOCKER_PI_HOME`).
119
+ Content is the 2.x RPC sandbox, not a live herdr pane host. The scripts copy
120
+ the **host** Pi config (`~/.pi/agent/settings.json`, `models.json`, `auth.json`
121
+ if present) into that disposable home; the container cannot write back to your
122
+ real `~/.pi`.
41
123
 
42
124
  ```bash
43
- # image must already exist
125
+ # image must already exist (historical default name; do not rename a local tag
126
+ # just to match docs — override with PI_DOCKER_IMAGE if yours differs)
44
127
  docker image inspect pi-herdr-sandbox:latest >/dev/null
45
128
 
46
- bash test/docker/verify-1-child-guard.sh # child herdr interceptor
129
+ bash test/docker/verify-1-child-guard.sh # RPC child-guard / ledger block
47
130
  bash test/docker/verify-2-task-appendix.sh # frozen task appendix
48
131
  bash test/docker/verify-3-readonly.sh # read-only bash denylist
49
132
  bash test/docker/verify-4-acceptance.sh # collect → verified
@@ -54,19 +137,26 @@ bash test/docker/verify-8-verify-command.sh # criterion.command + timeout
54
137
  bash test/docker/verify-9-worktree.sh # git worktree cwd
55
138
  bash test/docker/verify-10-fallback.sh # fallbackModels
56
139
  bash test/docker/verify-11-nested-alias.sh # nested + alias + completionGuard
57
- bash test/docker/verify-12-workspace.sh # pi install + child pinned to parent Space
58
- bash test/docker/verify-13-kinds.sh # kind/model matrix; live CodeBuddy when mounted
59
140
  ```
60
141
 
61
- Or all at once:
142
+ Or all at once (RPC mainline **1–11** only):
62
143
 
63
144
  ```bash
64
145
  npm run test:docker
65
146
  ```
66
147
 
67
- `verify-13-kinds.sh` is **not** in `npm run test:docker`: it bind-mounts host
68
- `codebuddy` / `cursor-agent` and (unless `LIVE_KIND_PROBES=0`) calls live
69
- CodeBuddy. The numbered 1–12 scripts stay offline/mock.
148
+ **Legacy Herdr / Space / kind checks** live under `test/legacy/docker/` (need
149
+ pi-legion **0.16.x** Herdr-era setup). They are **not** part of
150
+ `npm run test:docker`:
151
+
152
+ ```bash
153
+ bash test/legacy/docker/verify-12-workspace.sh # Herdr Space pin (legacy)
154
+ bash test/legacy/docker/verify-13-kinds.sh # kind/model matrix; live CodeBuddy when mounted
155
+ ```
156
+
157
+ `verify-13-kinds.sh` also bind-mounts host `codebuddy` / `cursor-agent` and
158
+ (unless `LIVE_KIND_PROBES=0`) calls live CodeBuddy. The numbered 1–11 scripts
159
+ under `test/docker/` stay offline/mock.
70
160
 
71
161
  Override paths with `HOST_PI_AGENT`, `DOCKER_PI_HOME`, `PI_DOCKER_IMAGE`.
72
162
 
@@ -86,8 +176,9 @@ them by hand.
86
176
  | `src/extension/runtime.ts` | status widget, watch, auto-recycle |
87
177
  | `src/extension/blocked.ts` | `onBlocked` confirm / auto-approve / notify |
88
178
  | `src/runs/acceptance.ts` | `verification-output` command |
179
+ | `test/mock-llm/` | Scriptable OpenAI mock for offline pi / legion |
89
180
  | `agents/*.md` | bundled roles |
90
- | `docs/design.md` | measured herdr findings (F1–F46) |
181
+ | `docs/design.md` | design notes / F1–F46 (incl. historical herdr-era measurements; see file banner) |
91
182
  | `README.md` | what is actually wired today |
92
183
 
93
184
  Do not import from `src/` in downstream packages — use