pi-crew 0.10.1 → 0.10.3

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 (127) hide show
  1. package/CHANGELOG.md +347 -0
  2. package/NOTICE.md +21 -0
  3. package/README.md +44 -2
  4. package/agents/executor.md +1 -1
  5. package/agents/test-engineer.md +1 -1
  6. package/dist/index.mjs +2555 -932
  7. package/package.json +2 -1
  8. package/schema.json +503 -94
  9. package/skills/real-test-pi-crew/REPORT-TEMPLATE.md +6 -2
  10. package/skills/real-test-pi-crew/SKILL.md +278 -79
  11. package/src/config/config-merge.ts +11 -1
  12. package/src/config/config-validation.ts +47 -2
  13. package/src/config/config.ts +28 -6
  14. package/src/config/defaults.ts +43 -11
  15. package/src/config/env-vars.ts +27 -2
  16. package/src/config/role-tools.ts +4 -2
  17. package/src/config/types.ts +55 -1
  18. package/src/extension/crew-cleanup.ts +13 -0
  19. package/src/extension/crew-vibes/footer.ts +19 -0
  20. package/src/extension/crew-vibes/index.ts +11 -1
  21. package/src/extension/register.ts +8 -0
  22. package/src/extension/registration/command-registration.ts +1 -0
  23. package/src/extension/registration/commands/run.ts +15 -1
  24. package/src/extension/registration/commands/shared.ts +8 -0
  25. package/src/extension/registration/foreground-run-controller.ts +10 -2
  26. package/src/extension/registration/lifecycle-handlers.ts +92 -11
  27. package/src/extension/registration/runtime-cleanup.ts +23 -5
  28. package/src/extension/registration/team-tool.ts +58 -6
  29. package/src/extension/registration/ui.ts +5 -4
  30. package/src/extension/team-tool/doctor.ts +364 -7
  31. package/src/extension/team-tool/handle-settings.ts +19 -0
  32. package/src/extension/team-tool/inspect.ts +10 -2
  33. package/src/extension/team-tool/run-deadline.ts +20 -3
  34. package/src/extension/team-tool/run.ts +26 -2
  35. package/src/extension/team-tool/status.ts +7 -0
  36. package/src/extension/team-tool.ts +35 -2
  37. package/src/hooks/registry.ts +59 -56
  38. package/src/prompt/inbox-poll.ts +90 -0
  39. package/src/prompt/message-tool.ts +166 -0
  40. package/src/prompt/prompt-runtime.ts +201 -18
  41. package/src/prompt/surface-worker.ts +720 -0
  42. package/src/prompt/worker-events-channel.ts +49 -3
  43. package/src/runtime/async-runner.ts +29 -1
  44. package/src/runtime/background-runner.ts +13 -7
  45. package/src/runtime/broker/broker-issuer.ts +27 -2
  46. package/src/runtime/broker/crew-broker-tokens.ts +56 -4
  47. package/src/runtime/broker/crew-broker.ts +261 -41
  48. package/src/runtime/child-pi/child-pi-constants.ts +8 -0
  49. package/src/runtime/child-pi/child-pi-spawn.ts +23 -9
  50. package/src/runtime/child-pi/child-pi-streams.ts +30 -2
  51. package/src/runtime/child-pi/child-pi.ts +353 -5
  52. package/src/runtime/crew-agent-records.ts +13 -1
  53. package/src/runtime/detached-run-results.ts +90 -0
  54. package/src/runtime/dispatch-batch.ts +12 -1
  55. package/src/runtime/event-log-tail-source.ts +374 -0
  56. package/src/runtime/finalize-run.ts +4 -0
  57. package/src/runtime/goal-workflow/adaptive-plan.ts +30 -3
  58. package/src/runtime/goal-workflow/dynamic-workflow-runner.ts +5 -1
  59. package/src/runtime/live-session/live-agent-manager.ts +34 -1
  60. package/src/runtime/live-session/live-control-realtime.ts +10 -0
  61. package/src/runtime/live-session/live-session-runtime.ts +47 -27
  62. package/src/runtime/manifest-cache.ts +128 -17
  63. package/src/runtime/merge-gate.ts +25 -9
  64. package/src/runtime/model/model-fallback.ts +7 -3
  65. package/src/runtime/model/pi-args.ts +54 -65
  66. package/src/runtime/output/sidechain-output.ts +61 -6
  67. package/src/runtime/process/proc-stat.ts +46 -0
  68. package/src/runtime/process/zombie-scanner.ts +32 -19
  69. package/src/runtime/process-status.ts +16 -1
  70. package/src/runtime/recovery/crash-recovery.ts +16 -0
  71. package/src/runtime/run-tracker.ts +77 -10
  72. package/src/runtime/spawn-policy.ts +27 -41
  73. package/src/runtime/surface/degrade.ts +776 -0
  74. package/src/runtime/surface/herdr-provider.ts +546 -0
  75. package/src/runtime/surface/launch-script.ts +172 -0
  76. package/src/runtime/surface/resolve-surface.ts +274 -0
  77. package/src/runtime/surface/surface-provider.ts +129 -0
  78. package/src/runtime/surface/surface-spawn.ts +475 -0
  79. package/src/runtime/surface/tmux-provider.ts +400 -0
  80. package/src/runtime/task-runner/child-executor.ts +47 -0
  81. package/src/runtime/task-runner/post-execution.ts +57 -2
  82. package/src/runtime/task-runner/prompt-builder.ts +1 -0
  83. package/src/runtime/task-runner/retrieval-orchestrator.ts +191 -56
  84. package/src/runtime/task-runner/state-helpers.ts +54 -30
  85. package/src/runtime/task-runner.ts +4 -2
  86. package/src/runtime/team-runner.ts +104 -2
  87. package/src/schema/config-schema.ts +25 -1
  88. package/src/state/atomic-write.ts +219 -40
  89. package/src/state/coordination/locks.ts +7 -5
  90. package/src/state/coordination/mailbox.ts +56 -10
  91. package/src/state/event-log/cursor.ts +413 -23
  92. package/src/state/event-log/event-log.ts +120 -113
  93. package/src/state/event-log/sequence-cache.ts +21 -3
  94. package/src/state/stores/plan-store.ts +1 -1
  95. package/src/state/stores/state-store.ts +171 -9
  96. package/src/state/types.ts +53 -0
  97. package/src/ui/dock-footer.ts +49 -0
  98. package/src/ui/inline-panel/agent-pane.ts +378 -0
  99. package/src/ui/inline-panel/agent-transcript.ts +338 -0
  100. package/src/ui/inline-panel/agent-view-overlay.ts +225 -0
  101. package/src/ui/inline-panel/crew-editor.ts +192 -0
  102. package/src/ui/inline-panel/index.ts +290 -0
  103. package/src/ui/inline-panel/panel-rows.ts +37 -0
  104. package/src/ui/inline-panel/panel-selection.ts +157 -0
  105. package/src/ui/inline-panel/panel-store.ts +111 -0
  106. package/src/ui/inline-panel/view-session-store.ts +36 -0
  107. package/src/ui/pi-ui-compat.ts +9 -0
  108. package/src/ui/render-diff.ts +16 -8
  109. package/src/ui/run-dashboard.ts +87 -42
  110. package/src/ui/run-event-bus.ts +10 -1
  111. package/src/ui/run-snapshot-cache.ts +83 -35
  112. package/src/ui/transcript-cache.ts +101 -13
  113. package/src/ui/transcript-viewer.ts +92 -24
  114. package/src/ui/widget/index.ts +203 -25
  115. package/src/ui/widget/task-list.ts +198 -0
  116. package/src/ui/widget/widget-formatters.ts +240 -4
  117. package/src/ui/widget/widget-renderer.ts +234 -37
  118. package/src/ui/widget/widget-types.ts +11 -0
  119. package/src/utils/child-process-shield.ts +106 -0
  120. package/src/utils/redaction.ts +7 -0
  121. package/src/utils/safe-abort.ts +45 -0
  122. package/src/utils/visual.ts +43 -0
  123. package/src/workflows/discover-workflows.ts +1 -0
  124. package/src/workflows/workflow-config.ts +7 -0
  125. package/src/worktree/worktree-manager.ts +65 -4
  126. package/workflows/default.workflow.md +36 -26
  127. package/workflows/strict-fast-fix.workflow.md +26 -0
package/CHANGELOG.md CHANGED
@@ -2,6 +2,353 @@
2
2
 
3
3
  > **Note:** `atomic-write-v2.ts` / `AtomicWriter` mentioned in historical entries below was consolidated into `atomic-write.ts` as of v0.9.42. This changelog is preserved as historical record — the migration was completed (the v2 class was never adopted; v1 won on simplicity + symlink-safety + link+unlink atomicity). See `docs/migration/atomic-write-v2-migration.md` for the decision rationale.
4
4
 
5
+ ## [0.10.3] — MuxSurface: workers in real panes + per-team-run tabs (2026-09-01)
6
+
7
+ 128 commits since v0.10.2. The headline feature is **MuxSurface A1** (spec
8
+ `docs/superpowers/specs/2026-08-26-mux-surface-design.md` v0.7.1, ADR
9
+ `docs/decisions/2026-08-26-mux-surface-a1.md`): crew workers can now live in
10
+ REAL multiplexer panes instead of headless stdio pipes.
11
+
12
+ ### MuxSurface A1 — pane-backed workers
13
+
14
+ - **SurfaceProvider abstraction** (`src/runtime/surface/`) with twin backends:
15
+ tmux (libtmux-style CLI) and herdr (socket API, newline-JSON). Fail-closed
16
+ by design: every failure (no mux, forced-mode detect fail, depth, cap, role)
17
+ degrades to the headless path and the run still completes — pane engagement
18
+ is proven by events (`worker.surface_spawned`/`worker.surface_closed`),
19
+ never by the run's green status alone.
20
+ - **Surface gating follows env + config, not run-mode**: `runtime.surface.mode`
21
+ (auto/tmux/herdr/off) + `runtime.surface.visibleAgents` opt-in (default
22
+ `[]` = nobody). Async runs engage panes exactly like sync runs — the detached
23
+ background runner forwards mux env (TMUX/HERDR_*) so `no-mux` detection sees
24
+ the host's multiplexer (fix `f0a41a16`, verified live: 3/3 workers in panes
25
+ on an async run, tab closed at run end).
26
+ - **Per-team-run tabs (tab-layout, spec 2026-08-27)**: every TEAM RUN gets its
27
+ own tab/window (tmux `new-window -d` / herdr `tab.create`), max 8 worker
28
+ panes per tab before a new tab opens, alternating down/right splits, and the
29
+ tab closes ONLY when the run ends/cancels/is killed — workers finishing do
30
+ not close panes. Doctor closes orphan tabs by id + mux liveness.
31
+ - **herdr pane-parent fix**: spawns target the caller's pane via
32
+ `HERDR_PANE_ID` (never the focused pane — `pane.current` without
33
+ `caller_pane_id` follows focus, verified live on herdr 0.8.2).
34
+ - **Worker-side recorder + host tail**: surface workers write per-agent
35
+ `events.jsonl` (same shape as the host); the host tails it via
36
+ `EventLogTailSource` (incremental byte-offset reads, drain-before-close for
37
+ fast-closing panes, ENOENT backoff + log-once, and a steady-poll safety net
38
+ for FSEvents append coalescing on macOS).
39
+ - **D5 full-loadout**: workers are FULL pi sessions by default — no
40
+ `--no-extensions`, no tool allowlists; restrictions are per-agent opt-in via
41
+ frontmatter. **D8 nesting**: every role gets the `delegate` tool
42
+ (`nesting.maxDepth: 4`, kill switch in user config only). **D9 `message`**
43
+ tool: non-blocking notify/DM/group via broker with anti-spoof `from`
44
+ override.
45
+ - **ask gate flip**: `broker.waitMethodsEnabled` now defaults `true` — the
46
+ worker→parent blocking question path works out of the box (it had silently
47
+ slept behind the old default-off gate).
48
+ - **Broker token revocation**: stale-token + secret-based checks; terminal
49
+ runs (completed/failed/cancelled) reject worker tokens by definition
50
+ (late-worker protection).
51
+
52
+ ### Verification for this release
53
+
54
+ - E2E real-mux suites: tmux 4/4 + herdr 5/5 (spawn/self-close,
55
+ kill-pane→degrade→headless resume, doctor orphan cleanup, tab per-run,
56
+ closeTabById fallback).
57
+ - Two full real-test batteries from live pi sessions
58
+ (`docs/real-test/reports/real-test-2026-08-30-post-tab-layout-live.md`,
59
+ `real-test-2026-08-31-post-fixes-live.md`): tab-layout verified with live
60
+ tmux polls (window per run, sequential worker panes, tab closed at run end),
61
+ async surface engagement verified post-fix, `set <array-key> []` config
62
+ round-trip fixed.
63
+ - CI all-green on ubuntu + macOS + Windows (first time since 2026-08-24);
64
+ lint/format drift and 5 layers of hidden cross-OS test failures cleared.
65
+
66
+ ### Perf rounds also shipping in 0.10.3
67
+
68
+ Retained verbatim below: round-3 retrieval single-pass, round-2 fsync cleanup
69
+ + polling latency, and the 2026-08-24 performance-review fixes.
70
+
71
+ ### [0.10.3] perf: round 3 retrieval single-pass (retrieval 7.1s → 2.0s cold / 0.28s warm per task)
72
+
73
+ Root cause (measured on real run `team_20260826002634`, 2026-08-26 real test):
74
+ `runRetrievalCycle` spent up to ~7s CPU per task — 3 unconditional cycles (the
75
+ 0.7 convergence threshold is unreachable with path-only scoring, observed
76
+ max 0.64), 55 keywords incl. filler over ~57k files, and a duplicate-
77
+ accumulating evaluation list (same file up to 3× in the top-10).
78
+
79
+ - Single discovery pass + dedupe by absolute path (`retrieval-orchestrator.ts`)
80
+ - STOPWORDS expanded (filler verbs/pronouns out; path-meaningful words kept)
81
+ - rg discovery cached per cwd, 60s TTL, cap 32 (fallback walk uncached)
82
+ - b13 bench guards cold <2s / cache-hit <400ms on the repo itself
83
+
84
+ | Metric (my_pi monorepo, full-length real-run goal) | Before (`745cf9f1`) | After | Delta |
85
+ |---|---|---|---|
86
+ | runRetrievalCycle cold | 7055 ms | 1980 ms | −72% |
87
+ | warm, new keywords (discovery cache) | 3335 ms | 275 ms | −92% |
88
+ | keywords from tokenize | 55 | 41 | −25% |
89
+ | duplicate paths in top-10 | up to 3×¹ | 0 | — |
90
+
91
+ ¹ Observed ×3 on the original real-run workload; the identical-input baseline
92
+ re-measure shows max 1 (score-tie ordering can keep cycle-2/3 duplicates out
93
+ of the top slice — the cross-cycle accumulation mechanism itself is what T1
94
+ removed). See the probe report footnote.
95
+
96
+ Prompt-pipeline impact: the measured 6-8s/task gap (real test) had retrieval
97
+ as its dominant component; post-fix retrieval is 2.0s cold / 0.28s warm —
98
+ the non-retrieval remainder was not re-measured end-to-end yet (next real
99
+ test will confirm).
100
+
101
+ b13 (`bench/b13-retrieval-latency.bench.ts`) runs on the small pi-crew repo
102
+ (cold 83 ms / cache-hit 8 ms) — it is a smoke guard, not the monorepo
103
+ context above; a regression back to 3-cycle behavior stays under its budget
104
+ at that scale. Full follow-up note: `docs/real-test/reports/perf-round3-probe.md`.
105
+ Every number above was measured, not estimated.
106
+
107
+ ### [0.10.3] perf round 2 (2026-08-25): fsync cleanup + polling latency
108
+
109
+ 13 commits after the 2026-08-24 round (45 after `v0.10.2`) (27 files, +3,094/−105, excluding the plan doc and this changelog). Continuation of the 2026-08-24 performance review work, focused on durability escalations and polling latency. Implementation plan: `.superpowers/sdd/2026-08-25-perf-round2-fsync-and-polling/`. Validation evidence: task reports T1-T8 + `bench/b12-fsync-counts.bench.ts`.
110
+
111
+ ### What changed (by area)
112
+
113
+ - **Pid files** — `withEventLogLockSync` writes lock pid files via `openSync(pidFile, "wx")` followed by plain write (0 fsyncs) instead of `atomicWriteFile` (2 fsyncs). The lock dir's `mkdir` is the mutex; pid files are mtime-stale-detected. Async `.alock` path unchanged.
114
+ - **Buffered event batch flush** — `appendBatchForBufferedWrite` skips fsync for all-non-terminal batches (terminal batches still fsync). Non-terminal buffered work now pays 0 fsyncs per batch.
115
+ - **Non-terminal tasks checkpoints** — opt-in best-effort fsync gate `PI_CREW_PERSISTENCE_SKIP_TASKS_FSYNC` (default `false`, beats config). When enabled, non-terminal `tasks.json` checkpoints are written with durability `"best-effort"` (0 fsyncs) while keeping the 50ms coalesced write grouping; terminal transitions and default-off path retain full durability. Reconstructible from the fsync'd event log.
116
+ - **Mailbox delivery marks** — `appendMailboxMessage` (regular sync delivery) now defaults to best-effort durability (delivery.json is informational; next message overwrites). Terminal `acknowledgeMailboxMessage` and `appendMailboxMessageAsync` paths keep explicit full durability.
117
+ - **Steering/ask polling** — event-driven adaptive cadence under live-session realtime: 50ms when realtime active (`hasLiveControlRealtimeListeners()`), 500ms when idle. Non-realtime workers stay at 500ms.
118
+ - **Events cursor tail reads** — verified watermark cache with inode-stamped entries (replaces unsound order-assumption fast path from first attempt). Unchanged stamps read zero bytes; growth reads only the appended delta `[verifiedOffset, size)` — the 4MB wide parse now happens only on cold/shrink/violation. Cache invalidates on inode change (compaction/rotation/rewrite) and drops entries on sinceSeq=0/no-limit reads.
119
+ - **Bench infra** — b5 (`deep-tracking`) repaired for deleted `observation-store` module; b11 (`dep-context-cache`) fixed NDJSON contract; new b12 (`b12.fsync-counts`) micro-bench spies `fs.fsyncSync` calls per operation.
120
+ - **Coalesced drain** — `flushPendingAtomicWrites` groups parent-dir fsyncs across all files in the drain (one `fsyncSync` per distinct dir, best-effort on win32). 4 files in one dir: 5 fsyncs total (4 data + 1 dir) vs 8 pre-grouping (4 data + 4 dir).
121
+
122
+ ### Bench results (Linux x86_64, Node v22.23.1, `npm run bench`)
123
+
124
+ b12 fsync counts per operation (deterministic across runs; "before" refers to pre-round2 baseline):
125
+
126
+ | Operation | Before | After | Expectation |
127
+ |---|---|---|---|
128
+ | `appendEventSyncNonTerminal` | 2 | **0** | ≤1 (T1 pid write) |
129
+ | `appendEventSyncTerminal` | 3 | **1** | ==1 (documented) |
130
+ | `appendEventBufferedNonTerminalBatch8` | 1 | **0** | ==0 (T2 batch skip) |
131
+ | `tasksCheckpointNonTerminalFlagOff` | 2 | **2** | ≥1 (full durability) |
132
+ | `tasksCheckpointNonTerminalFlagOn` | 2 | **0** | ==0 (opt-in best-effort) |
133
+ | `appendMailboxMessageDeliveryMark` | 2 | **0** | ==0 (T4 best-effort) |
134
+ | `coalescedDrain4FilesOneDir` | 8 | **5** | ==5 (4 data + 1 dir, T8) |
135
+
136
+ Coalesced drain A/B (4 files, one dir, heavily loaded machine — indicative): median 36.6 ms (post-T8) vs 55.6 ms (pre-T8) for 5 vs 8 fsyncs. Idle-machine measurement: −61% wall-clock (pre-implementation plan measurement: 59.4→22.9ms; task-8's loaded A/B was 36.6 vs 55.6ms). The deterministic contract is the fsync count.
137
+
138
+ ### Durability semantics
139
+
140
+ **Full durability retained** for: terminal event writes, terminal task transitions, all `acknowledgeMailboxMessage` calls, all direct `atomicWrite`/`atomicWriteJson` calls, and the default (flag-off) non-terminal checkpoint path. Every persistent state transition that is *not* reconstructible from the event log remains fsync'd.
141
+
142
+ **Best-effort (opt-in or informational-only)** for: pid files (lock dir is the mutex), non-terminal buffered event batches, non-terminal `tasks.json` checkpoints (when `PI_CREW_PERSISTENCE_SKIP_TASKS_FSYNC=1`), and `delivery.json` marks. These state components are reconstructible (pid files via mtime-stale detection; tasks.json from the fsync'd `events.jsonl`; delivery.json is informational and overwritten). A hard crash may lose the latest tail; recovery replays from the last fsync'd event.
143
+
144
+ ### Known residuals (discovered, documented, left for follow-up)
145
+
146
+ - `flushOnePendingAtomicWrite`'s retry path is dead code (pre-existing; surfaced by T8): coalesced entries are deleted before the write attempt, so the catch block's `retryCount++` and `MAX_FLUSH_RETRIES` rethrow never execute. Fixing requires behavioral changes to failure semantics (separate task). *(→ resolved by the follow-up fixes below)*
147
+ - Cursor cache ino-recycle coincidence: same-path in-place truncate+regrowth would pass the delta-branch check if the rewrite preserved the inode (no current writer does; same accepted-risk class as transcript-cache). Documented in `src/state/event-log/cursor.ts`.
148
+ - Async mailbox twin (`appendMailboxMessageAsync`) retains full durability; T4 scoped to regular sync delivery only. *(→ resolved by the follow-up fixes below)*
149
+ - Tasks-checkpoint `loadConfig()` reads the flag at every save (negligible via 2s TTL cache).
150
+
151
+ ### Follow-up fixes (branch `fix/round2-followups`, 2026-08-26)
152
+
153
+ - **Dead retry path fixed** — `flushOnePendingAtomicWrite`'s catch now re-queues the entry (the live map entry if a newer write arrived mid-flush, else the captured one) with exponential backoff, so a failed flush retries instead of silently dropping the buffered write; the error still propagates at `MAX_FLUSH_RETRIES`. Regression suite `test/unit/state/atomic-write-coalesced-retry.test.ts` (openSync ENOSPC injection; the coalescer contract is no-throw while retries remain).
154
+ - **Async mailbox twin aligned** — `appendMailboxMessageAsync` delivery marks drop to the best-effort default (mirror of the T4 sync-twin fix); third test in `mailbox-delivery-durability.test.ts` pins 0-fsync pure appends with init absorbed into the baseline.
155
+ - **Test isolation fix (not a production bug)** — `manifest-cache-list-active.test.ts` leaked the real user root into exact-membership assertions (listActive scans every run root by design, RT-F3); the suite now snapshots env and points `PI_CREW_HOME` at an empty temp home, deleting the precedence-winning `PI_TEAMS_HOME`.
156
+
157
+ ### What did NOT improve
158
+
159
+ - Broker fan-out and worktree git-spawn memoization: unchanged (already addressed in round 1).
160
+ - Async mailbox path (`appendMailboxMessageAsync`): intentionally left at full durability (T4 scoped to sync delivery only). *(→ resolved by the follow-up fixes above)*
161
+ - Tasks-checkpoint coalescing: already present; T3 only added durability control, the 50ms grouping predates this branch.
162
+
163
+ ### Verification
164
+
165
+ | Check | Result |
166
+ |---|---|
167
+ | `npm run typecheck` | pass |
168
+ | `npm run lint` | pass (2 warnings and 2 infos (all pre-existing)) |
169
+ | `npm run test:unit` | 7153 pass / 0 fail / 3 skipped (7156 total) (includes new T1/T2/T3/T4/T5/T6/T8 test suites) |
170
+ | `npm run bench` | legacy suite green; b5/b11 NDJSON contract repaired; b12 fsync-counts bench added (7 cases, all pass) |
171
+
172
+ ### [0.10.3] perf: fix 2026-08-24 performance review findings (state persistence syscall ceremony, UI sync I/O storms, mailbox/event-log hot paths, broker fan-out, worktree git-spawn memoization)
173
+
174
+ 28 commits after `v0.10.2` (53 files, +4,718/−433). Implements the plan at
175
+ `docs/superpowers/plans/2026-08-24-perf-review-fixes.md`: all Critical (C1–C3) and
176
+ High (H1–H6) findings from the 2026-08-24 performance review, plus the Medium sweep.
177
+ Validation evidence: `.superpowers/sdd/2026-08-24-perf-review-fixes/task-27-report.md`.
178
+
179
+ ### What changed (by area)
180
+
181
+ - **State persistence syscall ceremony** — `persistSingleTaskUpdate` does a scoped
182
+ flush + in-lock CAS baseline (only the file being read is drained, not the whole
183
+ process); atomic-write coalescer gains a dir-exists memo and lazy stringify;
184
+ `saveRunTasksCoalesced` keeps the manifest half of the run cache across coalesced
185
+ saves (only tasks stamps are zeroed); artifacts containment verdict memoized 10s
186
+ (positives only); event-log lock pid files written ceremony-free (no fsync'd
187
+ tmp+rename for pid files) and the redundant post-reserve monotonic seq persist is
188
+ skipped (R16-B1 advance-on-reserve untouched); pre-append stat hoisted and
189
+ reader-less sequenceCache upkeep dropped; lock acquire pre-check caches the
190
+ symlink verdict; mailbox reads go through a stat-gated parse cache.
191
+ - **UI sync I/O storms** — widget refresh is coalesced on the `fs.watch` path
192
+ (scheduleRefresh, one async refresh per tick); transcripts render through a
193
+ tail-windowed wrap + incremental byte-offset reads (no full-file re-read per
194
+ frame); the dashboard resolves run snapshots once per frame; the widget cache is
195
+ truncate-once; `visibleWidth` gets a short-string cache; render-diff does a
196
+ single `diffWords` pass per changed line pair; `listLiveAgents` memoizes its sort
197
+ with a plain string compare; worker events channel tail is a 1-byte read;
198
+ config store path does a single `readCacheMtimes` pass.
199
+ - **Broker fan-out / worktree / live-session** — `msg.send` fan-out is chunked
200
+ over concurrent recipients; sync git probes in the worktree path are memoized
201
+ (cleanLeader verdict, rev-parse) with throttled per-repo prune; live-session
202
+ sidechain/transcript writers are batched per 50ms window with bounded (512 KiB)
203
+ stdout capture and a gated control poll.
204
+
205
+ ### Bench results (Linux x86_64, Node v22.23.1, `npm run bench`)
206
+
207
+ Pre-fix = same-machine capture 2026-08-24 before the branch; post = this branch.
208
+ Fsync-dominated wall clocks drift ±10-25% day-to-day on this machine — a
209
+ same-day control run on `main` (see report) shows the b4 drift below is
210
+ environmental, not a regression. fsync intentionally remains in the durable path.
211
+
212
+ | Metric | Pre-fix (2026-08-24) | Post-fix (branch) | Δ |
213
+ |---|---|---|---|
214
+ | `atomic-write-json` warm p50 | 13.01 ms | 13.21 ms | ~flat (fsync floor; control-on-main 13.09 ms) |
215
+ | `b3.state-store-jsonl` n10 `atomicWriteMs` | 14.83 ms | 15.00 ms | ~flat; the "25% faster than same-day control (20.03 ms)" noted pre-merge was load drift — a post-merge interleaved A/B (main vs `519a5e4e`, same session) shows 16.6 vs 16.5 ms, no delta |
216
+ | `b4.event-log` n100 sync append | 1409 ms (70.96/s) | 1518 ms (65.89/s) | environmental drift (control-on-main 1503 ms, 66.53/s) |
217
+ | `b4.event-log` n100 async append | 156 ms (640.86/s) | 198 ms (506/s) | environmental drift (control-on-main 179 ms, 558.30/s); hoped-for async p50 drop did not materialize on wall clock |
218
+ | `b4.event-log` n100 buffered append | — | 261-263 ms (380/s) | new visibility |
219
+ | `snapshot-cache` cold / warm p50 | 1.12 / 1.13 ms | 0.79 / 0.79 ms | **−30%** |
220
+ | `render-flush` p50 | 0.10 ms | 0.10 ms | flat (already sub-budget) |
221
+ | `register-startup` import p50 | 1861.28 ms | 1739.55 ms | −6.5% (cold-cache import, high variance) |
222
+ | `event-append` serial p50 | 15.52 ms | 14.61 ms | −6% |
223
+ | `b2.broker-roundtrip` n1000 | — | 10,049 msgs/s | new visibility |
224
+ | `b7.startup` bundle load (warm avg) | — | 419.89 ms | new visibility |
225
+
226
+ The structural wins (syscall counts, stat storms, fan-out chunking, batched
227
+ writers) are mostly invisible to these wall-clock benches by design — they remove
228
+ kernel calls whose latency is dominated by the remaining fsync. See the task-27
229
+ report for run-to-run variance data, the same-day main control runs behind the
230
+ "environmental drift" rows, and the b5/b11 bench-infra notes.
231
+
232
+ Post-merge interleaved A/B (2026-08-25, main vs `519a5e4e` in a worktree, same
233
+ session, alternating runs — the CPU-bound paths the branch targeted, which the
234
+ fsync-floor rows above cannot show):
235
+
236
+ | Path | baseline | main | Δ |
237
+ |---|---|---|---|
238
+ | `readAllMailboxMessages` warm (160 msgs / 8 files) | 932-949 µs | 521-527 µs | **−44%** (stat-gated parse cache) |
239
+ | `readAllMailboxMessages` churn (60-msg file rewritten per read) | 1903-1970 µs | 1057-1088 µs | **−45%** |
240
+ | `b3` jsonl read n=100 | 1.32 ms | 0.23 ms | **−83%** (cache-keep + stamp reuse) |
241
+ | `b3` jsonl write (n10/100/1000) | 0.11/0.17/0.83 ms | 0.09/0.15/0.77 ms | ~−10% (lazy stringify) |
242
+ | manifest `list()` refresh after TTL (200 runs) | 61-64 µs | 45-66 µs | no measurable wall-time delta (win is syscall count, not latency) |
243
+
244
+ ### Verification
245
+
246
+ | Check | Result |
247
+ |---|---|
248
+ | `npm run typecheck` | pass |
249
+ | `npm run lint` | pass (2 branch-introduced import-sort errors fixed in `src/state/event-log/event-log.ts`, `src/runtime/live-session/live-session-runtime.ts`) |
250
+ | `npm run test:unit` | 7115-7117 pass / 0-1 fail / 3 skipped — the 1 fail (run 1 of 2) is a pre-existing environmental flake (`session-summary-cov` vector #11 reads the real user-level `~/.pi/.../state/runs`; reproduced identically on `main`; run 2 fully green) |
251
+ | `npm run test:integration` | 189 pass / 0 fail / 4 skipped (env-gated real-model + placeholders), 238.8 s |
252
+ | `npm run bench` | legacy suite green; perf suite requires per-bench invocation until b11 emits NDJSON (pre-existing, see report) |
253
+
254
+ ## [0.10.2] — UI rewrite + adaptive default team (2026-08-24)
255
+
256
+ 40 commits after `v0.10.1` (≈3,500 LOC, 54 files). Headline: the UI surface
257
+ goes from "two modal overlays + status widget" to a proper in-document
258
+ panel — task list above the editor, dock at the very bottom, and an inline
259
+ agent transcript that opens with `↓` from the empty prompt. The default
260
+ team also moves from a fixed 4-step chain to a single adaptive `assess` →
261
+ parallel-execute → verify DAG.
262
+
263
+ ### UI: task list above the editor (`src/ui/widget/task-list.ts`)
264
+
265
+ - **Pi-tasks style plan rows** (commits `3d930579`, `7434afd7`, `f37619c0`,
266
+ `54e638ef`). One numbered row per task painted in plan order: `#1`, `#2`,
267
+ … — no more `01_explore` style technical ids leaking into the user view.
268
+ Completed rows dim and strike through; the running row carries a spinner
269
+ frame with elapsed time and live token counts; queued rows name the open
270
+ dependencies they wait on (`› blocked by #2`).
271
+ - **Header is Claude-Code style**: `● 4 tasks (1 done, 1 in progress, 2 open)` —
272
+ plain counts, no agent/role identity (those belong to the dock).
273
+ - **Role/agent/model visibility removed from the row** — they live in the dock
274
+ below the editor. The list above the editor is the *plan*, not a worker
275
+ report.
276
+ - **10-row cap with `… and N more`** — unfinished work never falls out of the
277
+ cap; finished rows collapse behind the overflow marker.
278
+ - **Templated titles / descriptions** (commit `f51f7095`) — the task packet
279
+ emits `title` + `description` fields, `{goal}` substitution lands in the
280
+ persisted task record (not the run goal), so the list reflects what was
281
+ actually scoped per phase.
282
+
283
+ ### UI: inline agent panel (`src/ui/inline-panel/`)
284
+
285
+ A new module (1,761 LOC across 10 files) that replaces the modal-only agent
286
+ surface with an in-document path. Design rationale: `docs/design/2026-08-20-inline-agent-panel.md`.
287
+ Attribution: `NOTICE.md` §"Inline agent panel" — adapted from `pi-subtask`
288
+ v0.7.4 (Victor Mustar, MIT); no code copied verbatim; steering rides
289
+ pi-crew's existing `team steer` channel rather than pi-subtask's stdin pipe.
290
+
291
+ - **`↓` from the empty prompt opens the dock** (commits `cfcad621`, `cf4895e8`,
292
+ `bff74c4f`). Static-icon flat rows, footer usage meter, `belowEditor`
293
+ placement. Enter on a row drops you into the worker's transcript.
294
+ - **Worker view is an in-document pane, never a session switch** (commits
295
+ `11c6649a`, `21ff211d`, `87497bd5`, `de3d44a0`, `50f41f30`, `5526c279`,
296
+ `402bb2a5`, `3dd68cc8`, `2b3e899d`, `9ee89866`, `ec8efd0a`, `e1708b20`,
297
+ `27c5c402`, `56279b00`, `c16cb332`). A sequence of fixes that landed
298
+ together: a) the `/crew-view` dispatch was routed through pi's immediate
299
+ command path (not a custom overlay), b) the agent view is a *byte-copy*
300
+ of the worker's own session log via a derived sessions ROOT, c) live
301
+ refresh polls the worker transcript and re-renders, d) `Enter` always
302
+ opens a real Pi session (no broken overlay), e) the worker-143 kill on
303
+ switches is root-caused (stale `ctx` was being passed around) and the
304
+ `AbortError` post-exit crash is fixed (`9db66cda`).
305
+ - **Dock survives until the run is done** (commit `67fa202a`) — rows no
306
+ longer disappear at "completed", the 3-row scroll window keeps the
307
+ in-progress task visible, and each row remembers its model.
308
+ - **Full-screen overlay still works for end-of-run review** (commit `c16cb332`)
309
+ — transcripts are complete; `Escape` returns to the dock.
310
+
311
+ ### Workflow: default is now adaptive (BREAKING for templates)
312
+
313
+ `workflows/default.workflow.md` was rewritten (commit `fff4b98d`) — old
314
+ sequential `explore → plan → execute → verify` was too rigid for the
315
+ common case of "small goal, fast turnaround". The new default is a
316
+ single-`assess` adaptive plan:
317
+
318
+ - Topology: `complex-dag` (was `sequential`).
319
+ - Frontmatter: `adaptive: true`.
320
+ - The `assess` step (planner role) inspects the repo and emits an
321
+ `ADAPTIVE_PLAN_JSON` block with the concrete phases + tasks. Independent
322
+ tasks go into the SAME phase so they run in parallel; the verifier still
323
+ closes the loop at the end of any implementation plan.
324
+ - Hard cap: 12 tasks per phase. A simple goal may produce 1-2 phases with
325
+ 1-2 tasks; broader goals fan out.
326
+ - Workflow file is **runtime data** (no rebuild needed) — the change is live
327
+ the next time a worker loads it.
328
+ - Migration: anyone pinning the old `explore/plan/execute/verify` chain
329
+ should switch to `workflow='plan-execute'` (still ships the fixed DAG).
330
+
331
+ ### Misc
332
+
333
+ - **Model-routing transparency**: `console.warn` per-model passthrough
334
+ muted (`273c4f83`) + test pins the muted behaviour (`b019e645`).
335
+ - **Biome 2.5.3 lint + format sync** (commit `69a0460e`, no logic changes).
336
+ - 5 `docs/real-test/reports/real-test-2026-08-2{0..4}-*.md` reports landed
337
+ alongside the B5 real-test battery (the subagent-v2 release was
338
+ end-to-end verified before this UI batch).
339
+ - Real-test re-run on the released bundle (`b0cf3a3a` onward): test:critical
340
+ 102/102, typecheck clean, 9a 10/10, 9b 5/5, chain 306.8s observation;
341
+ opportunistic finding #5 (SPEC-EVIDENCE marker format mismatch `===` vs
342
+ `:`) filed separately.
343
+
344
+ ### See also
345
+ - `NOTICE.md` §"Inline agent panel" — pi-subtask attribution.
346
+ - `NOTICE.md` §"Source inspiration" — pi-tasks attribution for task list rendering.
347
+ - `docs/design/2026-08-20-inline-agent-panel.md` — inline panel design rationale.
348
+ - `workflows/default.workflow.md` — adaptive default workflow (runtime data).
349
+ - `docs/real-test/reports/real-test-2026-08-11-full-battery.md` — full 9-tier
350
+ battery on the post-v0.10.1 HEAD (`54e638ef`).
351
+
5
352
  ## [0.10.1] — subagent v2: governed delegation, plan objects, spec system, transparency (2026-08-20)
6
353
 
7
354
  The full subagent-v2 effort (design `docs/design/subagent-v2-design.md`, plan
package/NOTICE.md CHANGED
@@ -6,6 +6,7 @@
6
6
 
7
7
  - Primary design and Pi-extension implementation inspiration: `pi-subagents` by Nico Bailon, MIT license.
8
8
  - Team orchestration, state, and worktree contract inspiration: `oh-my-claudecode` by Yeachan Heo, MIT license.
9
+ - Task-list-above-the-editor rendering (numbered plan rows, dependency hints, one-line-per-task) draws on `pi-tasks` (tintinweb, MIT) and Claude Code's plan header convention; no code copied — the pi-crew implementation lives in `src/ui/widget/task-list.ts` and is original work informed by those surfaces.
9
10
  - Conceptual inspiration only: `oh-my-openagent` / `oh-my-opencode`, SUL-1.0. No source code from this project should be copied into `pi-crew` unless explicitly reviewed for license compatibility and documented here.
10
11
  - Built-in skill topics are original pi-crew guidance informed by common agent-skill patterns in `Source/awesome-agent-skills`, `Source/oh-my-claudecode`, and related local references; no verbatim skill text was copied.
11
12
 
@@ -13,6 +14,26 @@
13
14
 
14
15
  When code is copied or substantially adapted from an MIT source, add the source path and license note here.
15
16
 
17
+ ### Inline agent panel (2026-08-20)
18
+
19
+ The inline agent panel (`src/ui/inline-panel/`) adapts the display architecture
20
+ of `pi-subtask` v0.7.4 by Victor Mustar (MIT,
21
+ https://github.com/gary149/pi-subtask):
22
+
23
+ - width-budgeted single-line agent rows (compact widget row style),
24
+ - identity-tracked panel cursor (`panel-selection.ts` matches its
25
+ `panelSelId` state machine),
26
+ - in-document `aboveEditor` transcript pane reusing pi's native transcript
27
+ components instead of a viewport overlay,
28
+ - `CustomEditor` wrapper with `↓`/`↑`/`enter`/`x`/`escape` panel navigation
29
+ and the `@agent` editor-border label, and the
30
+ `!ctx.ui.getEditorComponent()` yield rule for editor ownership.
31
+
32
+ No code was copied verbatim; the pi-crew implementation is a fresh port onto
33
+ pi-crew's own widget/store/event architecture (steering rides pi-crew's
34
+ existing `team steer` steering-file channel rather than pi-subtask's stdin
35
+ pipe).
36
+
16
37
  Current scaffold status: no substantial source files have been copied verbatim; implementation is a fresh scaffold based on documented design lessons.
17
38
 
18
39
  ## crew-vibes font assets
package/README.md CHANGED
@@ -53,7 +53,9 @@ repo: https://github.com/baphuongna/pi-crew
53
53
  - **Durable state** — manifest, tasks, events, artifacts all persisted to disk
54
54
  - **Async/background runs** — detached runs survive session switches with completion notifications
55
55
  - **Worktree isolation** — opt-in git worktrees per task for safe parallel edits
56
- - **Rich UI** — live widget, dashboard, progress tracking, model/token display
56
+ - **Rich UI** — task list above the editor (pi-tasks style: numbered plan rows, dependency hints, `… and N more` overflow), dock at the very bottom (static icons, per-row model, footer usage), and an inline agent panel (open a worker's transcript with `↓` from the empty prompt — never a session switch). Live widget, dashboard, and progress tracking unchanged.
57
+ - **Inline agent panel** (`src/ui/inline-panel/`) — status rows at the bottom, transcript in-document with pi's native components, `CustomEditor` overlay for steering (rides the existing `team steer` channel). Adapted from `pi-subtask` v0.7.4 (MIT) — attribution `NOTICE.md` §"Inline agent panel"; no code copied verbatim.
58
+ - **Adaptive default team** (`workflows/default.workflow.md`) — the built-in default is now a single `assess` → adaptive-DAG step instead of a fixed `explore → plan → execute → verify` chain. The planner inspects the repo and emits a JSON plan; independent tasks run in parallel; the verifier closes the loop. Workflow files are runtime data — the change is live without a rebuild. Pin to `workflow='plan-execute'` if you need the old fixed DAG.
57
59
  - **Observability** — metrics registry, Prometheus/OTLP exporters, heartbeat watching, deadletter queue
58
60
  - **Resource management** — create/update/delete agents, teams, workflows with validation
59
61
  - **Import/export** — portable run bundles for sharing and archiving
@@ -212,7 +214,7 @@ When unsure which team/workflow fits:
212
214
 
213
215
  | Team | Workflow | Purpose |
214
216
  |------|----------|----------|
215
- | `default` | explore → plan → execute → verify | Balanced, general-purpose |
217
+ | `default` | adaptive: planner derives concrete tasks from the goal, parallel phases, verify | Balanced, general-purpose |
216
218
  | `fast-fix` | explore → execute → verify | Quick bug fixes |
217
219
  | `implementation` | Adaptive planner decides fanout | Multi-file implementation |
218
220
  | `review` | explore → code-review → security-review → verify | Code review + security audit |
@@ -289,6 +291,46 @@ The advisory is **informational only** — there is no `force:true` flag needed
289
291
 
290
292
  ## Recent changes
291
293
 
294
+ ### v0.10.2: UI rewrite + adaptive default team (2026-08-24)
295
+
296
+ 40 commits after `v0.10.1` (≈3,500 LOC, 54 files). Headline: the UI surface
297
+ goes from "two modal overlays + status widget" to a proper in-document
298
+ panel — task list above the editor, dock at the very bottom, and an inline
299
+ agent transcript that opens with `↓` from the empty prompt. The default
300
+ team also moves from a fixed 4-step chain to a single adaptive `assess` →
301
+ parallel-execute → verify DAG.
302
+
303
+ - **Task list above the editor** — pi-tasks style numbered plan rows
304
+ (`#1`, `#2`, …) instead of `01_explore` ids; completed rows dim and
305
+ strike through; running row shows spinner + elapsed time + token
306
+ counts; queued rows name dependencies (`› blocked by #2`). Header
307
+ is Claude-Code style (`● 4 tasks (1 done, 1 in progress, 2 open)`).
308
+ Role/agent/model identity moved to the dock — the list is the *plan*,
309
+ not a worker report. 10-row cap with `… and N more` overflow.
310
+ - **Inline agent panel** (`src/ui/inline-panel/`, ~1,761 LOC, 10 files) —
311
+ `↓` from the empty prompt opens the dock; Enter drops into the worker's
312
+ full transcript rendered in-document with pi's native components;
313
+ steering rides the existing `team steer` channel (no stdin pipe).
314
+ Worker view is a *byte-copy* of the worker's own session log, polled
315
+ for live refresh, and Enter on the dock row always opens a real Pi
316
+ session (the worker-143 kill on switches and the `AbortError`
317
+ post-exit crash are both fixed). Full-screen overlay preserved for
318
+ end-of-run review.
319
+ - **Dock survives until the run is done** — rows no longer disappear at
320
+ "completed"; 3-row scroll window keeps the in-progress task visible;
321
+ per-row model display.
322
+ - **Adaptive default team** (`workflows/default.workflow.md`, runtime
323
+ data — no rebuild needed) — old fixed `explore → plan → execute →
324
+ verify` replaced by a single `assess` step (planner role) that emits
325
+ an `ADAPTIVE_PLAN_JSON` block. Independent tasks go into the SAME
326
+ phase so they run in parallel; verifier still closes the loop.
327
+ **Pin to `workflow='plan-execute'` if you need the old fixed DAG.**
328
+ - **Model-routing passthrough muted** + Biome 2.5.3 lint/format sync.
329
+ - Real-test re-run on the released v0.10.1 bundle: test:critical 102/102,
330
+ typecheck clean, 9a 10/10, 9b 5/5, chain 306.8s observation.
331
+ See `CHANGELOG.md` §Unreleased for full notes and `NOTICE.md` for
332
+ pi-subtask / pi-tasks attributions.
333
+
292
334
  ### v0.9.65: team-tool schema empty-string guard + effectiveness empty-result guard (2026-08-10)
293
335
 
294
336
  - **`budgetTotal` empty-string unset marker accepted**: `budgetTotal` was the only numeric `TeamToolParams` field missing the `Literal("")` union branch its siblings had. Calling models that emit every schema key with defaults were rejected by pi-ai's pre-handler validation → `Validation failed for tool "team"` on every action. The `MISCONFIGURATION GUARD` (rejects 1-999) is preserved. Caught by the Tier 9 feature battery — Tiers 1-8 stayed green while the team tool was broken for emitting models.
@@ -5,7 +5,7 @@ model: false
5
5
  systemPromptMode: replace
6
6
  inheritProjectContext: true
7
7
  inheritSkills: false
8
- tools: read, grep, find, ls, bash, edit, write, scratchpad, ask
8
+ tools: read, grep, find, ls, glob, bash, edit, write, scratchpad, ask, delegate
9
9
  ---
10
10
 
11
11
  You are an implementation specialist. Follow the provided plan, make targeted changes, keep edits minimal, and report changed files plus validation status. Do not broaden scope without explaining why.
@@ -5,7 +5,7 @@ model: false
5
5
  systemPromptMode: replace
6
6
  inheritProjectContext: true
7
7
  inheritSkills: false
8
- tools: read, edit, write, bash, ls, scratchpad, ask
8
+ tools: read, edit, write, bash, ls, glob, grep, find, scratchpad, ask, delegate
9
9
  ---
10
10
 
11
11
  You are a test engineer. Identify the right test level, add or adjust tests when asked, detect flaky assumptions, and report exact validation commands and results.