pi-crew 0.11.2 → 0.11.5

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 (69) hide show
  1. package/CHANGELOG.md +83 -1
  2. package/README.md +1 -1
  3. package/dist/index.mjs +492 -493
  4. package/docs/actions-reference.md +22 -0
  5. package/index.ts +9 -5
  6. package/package.json +12 -9
  7. package/scripts/analyze-run.mjs +6 -3
  8. package/skills/real-test-pi-crew/SKILL.md +20 -12
  9. package/src/extension/async-notifier.ts +32 -8
  10. package/src/extension/crew-input-router.ts +9 -2
  11. package/src/extension/plan-orchestrate.ts +19 -3
  12. package/src/extension/registration/commands/shared.ts +11 -10
  13. package/src/extension/registration/foreground-run-controller.ts +2 -2
  14. package/src/extension/registration/lazy-configurers.ts +4 -1
  15. package/src/extension/registration/lifecycle-handlers.ts +16 -10
  16. package/src/extension/registration/lifecycle.ts +2 -0
  17. package/src/extension/registration/observability.ts +27 -18
  18. package/src/extension/registration/team-tool.ts +9 -2
  19. package/src/extension/registration/wire-cross-extension.ts +2 -0
  20. package/src/extension/team-manager-command.ts +3 -2
  21. package/src/extension/team-tool/dispatch/index.ts +4 -3
  22. package/src/extension/team-tool/dispatch/status.ts +7 -3
  23. package/src/extension/team-tool/goal-wrap.ts +7 -0
  24. package/src/extension/team-tool/goal.ts +12 -0
  25. package/src/extension/team-tool/inspect.ts +90 -0
  26. package/src/extension/team-tool/parallel-dispatch.ts +16 -1
  27. package/src/extension/team-tool/run-intent.ts +1 -1
  28. package/src/extension/team-tool/run.ts +1 -1
  29. package/src/runtime/async-runner.ts +36 -0
  30. package/src/runtime/broker/crew-broker.ts +61 -62
  31. package/src/runtime/broker/delegate/delegate-event.ts +12 -8
  32. package/src/runtime/broker/protocol/connection-state.ts +10 -0
  33. package/src/runtime/broker/protocol/lock-busy.ts +76 -0
  34. package/src/runtime/delegate-spawn.ts +16 -2
  35. package/src/runtime/deterministic-ast.ts +14 -2
  36. package/src/runtime/goal-workflow/dynamic-workflow-context.ts +78 -58
  37. package/src/runtime/goal-workflow/dynamic-workflow-runner.ts +14 -2
  38. package/src/runtime/goal-workflow/goal-loop-runner.ts +32 -0
  39. package/src/runtime/group-join.ts +11 -3
  40. package/src/runtime/live-session/live-session-runtime.ts +1 -1
  41. package/src/runtime/model/runtime-warmup.ts +2 -0
  42. package/src/runtime/output/output-validator.ts +10 -5
  43. package/src/runtime/plan-approval.ts +14 -1
  44. package/src/runtime/recovery/crash-recovery.ts +80 -52
  45. package/src/runtime/stale-reconciler.ts +8 -0
  46. package/src/runtime/subagent-manager.ts +43 -13
  47. package/src/runtime/task-output-context.ts +11 -1
  48. package/src/runtime/task-runner/child-executor.ts +17 -6
  49. package/src/runtime/task-runner/post-execution.ts +46 -14
  50. package/src/runtime/task-runner/pre-execution.ts +29 -21
  51. package/src/runtime/task-runner/prompt-builder.ts +8 -0
  52. package/src/runtime/task-runner/retrieval-orchestrator.ts +36 -14
  53. package/src/runtime/task-runner.ts +7 -0
  54. package/src/runtime/team-runner.ts +4 -1
  55. package/src/runtime/verification/verification-worktree.ts +3 -0
  56. package/src/schema/team-tool-schema.ts +2 -1
  57. package/src/state/coordination/mailbox.ts +7 -2
  58. package/src/state/stores/state-store.ts +8 -1
  59. package/src/ui/dashboard-panes/agents-pane.ts +11 -8
  60. package/src/ui/inline-panel/index.ts +1 -1
  61. package/src/ui/render-diff.ts +19 -6
  62. package/src/ui/run-dashboard.ts +11 -1
  63. package/src/ui/run-snapshot-cache.ts +9 -3
  64. package/src/ui/widget/task-list.ts +8 -5
  65. package/src/ui/widget/widget-model.ts +3 -1
  66. package/tsconfig.json +2 -0
  67. package/src/ui/card-colors.ts +0 -168
  68. package/src/utils/completion-dedupe.ts +0 -63
  69. package/src/utils/resolve-shell.ts +0 -36
package/CHANGELOG.md CHANGED
@@ -1,6 +1,88 @@
1
1
  # Changelog
2
2
 
3
- ## [Unreleased]
3
+ ## [0.11.5] — Phase A + Buổi 1 quick wins: G1 fence, NEW-1 data-loss, G18 breakdown, Node-24 matrix (2026-09-30)
4
+
5
+ ### fix(security): G1 — sanitize the dependency-output fence body (mirror ADR-5 seams)
6
+
7
+ - `renderDependencyOutputContext` (`src/runtime/task-output-context.ts`) inlined worker-controlled text (dependency `resultSummary`, `structuredResults` JSON, sharedRead content) into the next worker's prompt with only a `.trim()` — the last of the 4 prompt seams without the trust fence. A malicious/compromised dependency could smuggle a literal `</dependency-context>` to close the fence early and promote its payload to the instruction channel, or smuggle control chars. Now a local `sanitizeFencedBody()` (mirroring `renderAskAnswer`/`renderDelegateResult` in `src/prompt/prompt-runtime.ts`) strips control chars and neutralizes the closing-tag literal, applied once at the return so future fields are covered automatically. Pinned RED-first by `test/unit/runtime/core/task-output-context-fence.test.ts` (6 cases: 3 smuggling sinks, control-char strip, benign-unchanged snapshot, wrapper-opens/closes-once).
8
+
9
+ ### fix(state): NEW-1 — persist the FULL task array on individual-stale repair (data-loss)
10
+
11
+ - The individual-stale branch of `reconcileStaleRun` returned `repairedTasks` already FILTERED to the stale subset, and the crash-recovery caller full-overwrote `tasks.json` with it — every healthy task silently vanished from disk until the parent merged (permanent loss if the parent crashed in that window; the 12m27s heartbeat-freeze trigger was observed live). New `persistTasks` field (option A2): the individual-stale branch also returns the full mutated array, the caller persists `persistTasks ?? repairedTasks`, while `repairedTasks` keeps its exact meaning (what was repaired — the upsert/detail loop is untouched). Pinned RED-first by 3 new cases in `test/unit/runtime/core/stale-reconciler.test.ts` (full-shape, caller-persists-all-4-tasks via `reconcileAllStaleRuns`, regression guard that the other 4 branches leave `persistTasks` unset).
12
+
13
+ ### feat(inspect): G18 — `breakdown` action reads per-task prompt-breakdown artifacts
14
+
15
+ - New status-domain action `{ action: 'breakdown', runId, taskId? }` (57th schema action) surfaces the opt-in `metadata/<taskId>.prompt-breakdown.json` artifacts (recorded when the host session starts with `PI_CREW_PROMPT_BREAKDOWN=1`): per-task `estTokens` totals, top-5 largest sections, run total — text table + structured `data.perTask`/`data.runTotal` for the leader prompt and W-F token decisions. Runs without breakdowns get a pointer to the env gate instead of an error. Schema/dispatch/docs synced in one commit: `STATUS_ACTIONS` + `STATUS_DOMAIN_ACTIONS` + `domainForAction`, `docs/actions-reference.md` Quick Reference + section, CLAUDE.md domain table (status 16→17), README count, `team-tool-schema-actions.test.ts` 56→57 derivation guard. Follow-up fix in this release: `pre-execution.ts` used to discard the breakdown `writeArtifact` descriptor, so live-run manifests never indexed it — the descriptor now flows through `ctx.breakdownArtifact` into the manifest merge (pinned by `post-execution-breakdown-index.test.ts`, 2 cases).
16
+
17
+ ### docs: correct stale bundle comments
18
+
19
+ - `index.ts` + `scripts/bench-cold-start.mjs` carried 2025-era numbers: "2.9MB single file", "1100 .ts files", "src/ is excluded by the files field, ~5MB instead of ~16MB", "~19% faster total cold-start". Re-measured 2026-09-30 at this commit: `dist/index.mjs` = 1,614,662 B ≈ 1.6MB, `src/` = 520 `.ts` files, and the `files` field DOES include `src/`. Comments now state the tarball ships the bundle as entry AND includes src/, and the bundle's value is correctness + deterministic startup (warm `NODE_COMPILE_CACHE` shrinks the speed gap to ~2%).
20
+
21
+ ### fix(test): Node-24 compatible cancelled-suite fixtures
22
+
23
+ - Node 24 changed `node:test` to hold event-loop refs while subtests are pending, so the RR-021 unref'd-timer loop-drain fixtures no longer produced cancelled tests (verified: v24.21.0 `cancelled 0` vs v22 `cancelled 2`) — caught by the first-ever Node-24 CI run of the matrix added earlier in this release. The two empirical cancelled-suite cases in `test-runner-exit.test.ts` now use the AbortSignal-abort shape, which yields `# cancelled 2` deterministically on BOTH Node 22 and Node 24 (21/21 on both locally; CI 33/33 green).
24
+
25
+ ### ci: Node 24 added to the test matrices
26
+
27
+ - `.github/workflows/ci.yml`: both matrix jobs (`unit`, `test`) now run `[22, 24]` — Node 24 (LTS since 2025-10) gets first-class coverage while engines stay `>=22.0.0` and `.nvmrc` stays `22`. Nightly/smoke/weekly pins intentionally untouched. Opens the door for the strip-types-flag removal and tsconfig ES2023 bump once the ≥22.18 floor decision lands (upgrade plan §5 Q3).
28
+
29
+ ### chore(deps): semver-in-range batch
30
+
31
+ - In-range bumps only: `@biomejs/biome` 2.5.3→2.5.14, `@sinclair/typebox` 0.34.50→0.34.52, `acorn` 8.17.0→8.18.0, `esbuild` 0.28.1→0.28.2, `yaml` 2.9.0→2.9.1, `tsx` 4.23.0→4.23.15, `@types/node` 25.9.5→25.9.8. Deliberately NOT bumped (per plan): `diff` (P1-4), `@earendil-works/*` (Phase D), `@types/node` 26 (floor decision). `test:critical` 116/116 green under the new deps.
32
+
33
+ ### docs: action-count truth-sync + drift gate
34
+
35
+ - The repo carried five different action totals (53/54/55/56, and "28 total" in CLAUDE.md). Verified programmatically via `allActionLiterals.length === 56` (10 run + 16 status + 7 control + 17 manage + 6 automate, incl. `compare`), then synced the header comment in `src/schema/team-tool-schema.ts`, `README.md`, `CLAUDE.md`, `docs/actions-reference.md`, and `skills/real-test-pi-crew/SKILL.md`; fixed the `child-pi.ts`→`child-pi/` reference drift and backfilled the missing `compare` row in the actions reference.
36
+ - New gate `test/unit/schema/team-tool-docs-sync.test.ts` (precedent: `config-schema-sync.test.ts`) fails when docs drift from `allActionLiterals` again — negative-tested before landing.
37
+
38
+ ### chore(perf): perf-report runtime writes leave `docs/` root
39
+
40
+ - `scripts/analyze-run.mjs` now writes runtime perf reports to `docs/perf/` (existed, now the default write target) with a narrow `.gitignore` pattern (`docs/perf/perf-report-team_*`) so curated `docs/perf/` content stays tracked. Verified 0 runtime perf-report files tracked; audit suite 28/28 + live smoke confirm the new path.
41
+
42
+ ## [0.11.4] — test-gate hardening + RR-023 battery fixes (2026-09-29)
43
+
44
+ ### fix: grandchild relay empty — inherit the parent task's model on model-less delegate (RR-023, 2026-09-29 battery finding #3)
45
+
46
+ - **Root cause (run `team_20260929041427_5c40c4fd7e950443`)**: the relay/capture chain (`delegate-spawn.ts` capture → broker fence/mailbox → prompt-runtime poll) was FAITHFUL — all 3 delegate calls omitted `model`, so the broker spawned the grandchild model-less, the child pi booted on the pi GLOBAL default (`minimax/MiniMax-M3` while the parents ran `zai/glm-5.3`), and that model returned empty completions (assistant `content: []` ×3, per the gc session jsonl) — `rawFinalText` undefined + stdout `""` → the relay delivered an empty fenced body as `ok:true`. Same family as finding #1 (75502b68). **Fix**: the `delegate.request` admission now threads the parent task's `model` out of the locked record read and the spawner inherits it when the request omits `model` (explicit `model` still wins; no-model-everywhere passthrough unchanged) — the grandchild can no longer silently fall through to the global default. **Diagnosability guard**: the capture expression is extracted as pure `grandchildResultText()` and an exit-0-with-zero-assistant-text result now renders `[grandchild exited 0 with no assistant output]` instead of an empty mailbox body indistinguishable from a relay bug. Pinned RED-first by `test/unit/runtime/broker/delegate-grandchild-model.test.ts` (fake-spawner harness, 3 ACs) + `test/unit/runtime/delegate-grandchild-result-text.test.ts` (5 unit cases on the helper).
47
+
48
+ ### fix: broker run.lock contention — typed busy frame instead of connection kill (RR-023, 2026-09-29 battery finding #4)
49
+
50
+ - **`wait.request`/`delegate.request` busy degradation**: both handlers ran their state RMW inside `withRunLockSync`; a live cross-process run.lock holder (e.g. the detached runner persisting task state) made `acquireLockWithRetry` throw immediately and the throw escaped `handleData` → `closeConnection` — direct-async workers saw an untyped `code=close` socket death within ~5ms (evidence: `team_20260929041005` ask-probe / `team_20260929041020` delegate-probe; the sync foreground run was the zero-contention control). New `protocol/lock-busy.ts` classifies the lock-busy throw by its exported message identity, retries on a bounded async-back-off schedule (new `CrewBrokerOptions.lockBusyRetryDelaysMs`, default 50/100/200/400/800ms), then answers a typed `busy` error frame with the connection SURVIVING (ping still answers); the delegate path additionally records `delegate.rejected(reason=run-lock-busy)` in events.jsonl — never silent. `locks.ts` steal semantics untouched (lock family v0.9.26 invariant). Pinned by `test/unit/runtime/broker/crew-broker-lock-contention.test.ts` (3 tests incl. the default-schedule retry-absorbs-transient-hold case).
51
+
52
+ ### fix: test-gate integrity (RR-021 review rounds 2-3)
53
+
54
+ - **Test runner cancelled-test guard** (`scripts/test-runner.mjs`): a dual reporter keeps stdout UX unchanged (spec under TTY, TAP otherwise) while a full TAP stream is written to a temp file; `# cancelled N > 0` now fails the run loudly in BOTH the single-run and batch paths — independent of node:test's exit-code mapping. Belt-and-suspenders against the round-1 incident class (unref'd-race-timer tests cancelled while the harness reported green).
55
+ - **Test runner missing-file pre-check** (round-3 B1): node:test v22 silently skips an explicitly-listed file that does not exist (when other files still run) and exits 0 — a renamed/deleted test file would silently drop out of `test:critical`-style gates forever. The runner now refuses to spawn and names the missing paths; glob-shaped args are left to node:test's own expansion.
56
+ - **`test:bundle` now routes through the guarded runner** (was a bare `node --test` bypass — the only CI gate without the cancelled/missing-file/fail-closed wrappers).
57
+ - **`check:lazy-imports` hardened**: composite `import()` forms that escaped every earlier rule are now caught (`[(,\[\{]\s*import(`, `>\s*import(`, `=\s*import(`); a zero-match `git grep` (fully-clean `src/`) no longer crashes the gate; the type-annotation skip now requires a member-access suffix `import("...").T` so compound runtime forms are never false-skipped; dist-side regex is whitespace-proof. Remaining gaps (ternary-else, object-property, case/label) are documented in the script.
58
+
59
+ ## [0.11.3] — optimization audit fixes: correctness, hang-risks, bundle, DX, dead code (2026-09-27)
60
+
61
+ ### fix: correctness + hang-risks (RR-021 M1)
62
+
63
+ - **`classifyReviewOutcome` word-boundary bug**: the `"\baccept\b"`/`"\breject\b"` signals were TS string literals — `\b` is a BACKSPACE char there, so the two strongest verdict signals never matched anything. All 49 signals are now precompiled module-scope regex literals, and a negation guard stops "I cannot accept this" counting as approval. Reject-first precedence unchanged.
64
+ - **Git precondition probes** (`rev-parse`/`status` in the verification worktree sandbox) gained a 5s timeout — a wedged git no longer blocks the extension forever; the existing catch degrades to `available:false`.
65
+ - **`detectRipgrep` hardening**: a spawned-but-wedged `rg --version` is SIGKILLed by an unref'd 3s timer (defaults to unavailable); concurrent first calls share ONE in-flight detection promise instead of spawning one rg per caller.
66
+ - **`markDeadAsyncRunIfNeeded`** reroutes to the async `withRunLock` (same v0.9.26 lock family — live-token interop); the 5s notifier tick no longer holds the event loop on a sync acquisition. The notifier tick keeps no-overlap semantics. `async-runner.ts`'s in-process test seam keeps its one-shot sync lock by design.
67
+ - **`reconcileAllStaleRuns`** is async and reconciles runs with `mapConcurrent` bound 4 (per-run lock files are independent); results keep snapshot order, plan-approval re-check and re-read-inside-lock semantics unchanged.
68
+
69
+ ### perf: bundle + startup hygiene (RR-021 M2)
70
+
71
+ - esbuild/acorn/diff load lazily through sync `createRequire` shims (model: `syntax-highlight.ts`) — three eager module-scope imports no longer paid on every extension load; `diff` wildcard import narrowed to `diffWords` (+ type-only `Change`).
72
+ - `ajv` marked external (it is only reached via a lazy `await import`) — the bundle shrank 1.65 MB → 1.53 MB and skips parse cost for a rarely-taken path.
73
+ - `check:lazy-imports` catches the common runtime `import()` positions (the old gate matched only `await import(` — audit blind-spot #2) and asserts the committed `dist/index.mjs` contains no module-scope hoisted import of esbuild/acorn/diff/jiti/cli-highlight/yaml/ajv. 23 runtime import sites across 9 files gained `// LAZY:` markers. (Wording corrected post-0.11.3: exotic positions — ternary-else, object-property, case/label — remain documented gaps; see Unreleased.)
74
+
75
+ ### perf(dx): incremental typecheck + flake-resistant waits (RR-021 M3)
76
+
77
+ - `tsconfig.json` enables `incremental` + a cached `tsBuildInfoFile` (gitignored) — measured with TS 7.0.2: cold 4.10s → warm 1.41s.
78
+ - Three flake-prone suites (`post-exit-stdio-guard`, `preload-idle-render`, `prompt-runtime-steer-boot-window`) replace fixed sleeps with poll-based `waitFor`/`waitForQuiet` (25ms poll, deadlines sized ≥2× the worst-case timer, quiet windows derived from a measured render timeline). Each file verified ×3 consecutive runs with zero flakes.
79
+
80
+ ### perf: scale + hygiene (RR-021 M4)
81
+
82
+ - The notifier tick and run picker read a bounded `listRecentRuns` window (40→20 after the session filter) instead of scanning the full run index every debounce window; the startup seed keeps its full scan by design.
83
+ - Dead code deleted (−1.6k lines, all verified 0-production-consumer): `src/benchmark/` + its two test files, `ui/card-colors.ts`, `utils/completion-dedupe.ts`, `utils/resolve-shell.ts` + their tests; the affected suites were trimmed to their live checks.
84
+ - Eleven drive-by fixes: Set/Map lookups for hot `includes`/`find` loops (settled batch filter, task-list dependency labels, agents-pane first-wins live-handle map, group-join task resolution), allocation-free reverse scans replacing `[...arr].reverse().find()` copies (×3), a 256-entry cap for `stableComponentCache`, `TypeCompiler.Compile(TeamToolParams)` compiled once (STATIC) instead of per-call `Value.Check` schema walks, a 30-min WALL-CLOCK poll deadline (the old 1800-poll cap silently assumed a 1s configurable interval), a bounded `waitForRecord` (300s deadline racing wedged promises; expiry returns the current record — never undefined), collision-free `msg_<randomUUID>` mailbox ids, and module-scope precompiled regexes for the crew-input router + implicit-tag detector.
85
+ - Spinner isolation (`run-dashboard` `spinnerBucket`/`metricsSig`) deferred to a follow-up — needs a live TUI profile first.
4
86
 
5
87
  ## [0.11.2] — runtime hygiene, in-process async test seam, slash-command fixes (2026-09-26)
6
88
 
package/README.md CHANGED
@@ -34,7 +34,7 @@ repo: https://github.com/baphuongna/pi-crew
34
34
 
35
35
  ## Features
36
36
 
37
- - **One `team` tool, 55 actions** — run, monitor, steer, schedule, and manage agents/teams/workflows ([actions reference](docs/actions-reference.md)).
37
+ - **One `team` tool, 57 actions** — run, monitor, steer, schedule, and manage agents/teams/workflows ([actions reference](docs/actions-reference.md)).
38
38
  - **Real child Pi workers** — each task spawns an isolated `pi` process; `runtime.mode: "scaffold"` gives a dry-run with prompts only.
39
39
  - **Built-in teams & adaptive planning** — 6 teams and 11 workflows ship in the box; the `default` and `implementation` workflows let a planner agent pick the smallest effective crew.
40
40
  - **Parallel execution + worktree isolation** — tasks in the same phase run concurrently; `workspaceMode: "worktree"` gives each task its own git worktree for safe parallel edits.