pi-crew 0.1.51 → 0.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (240) hide show
  1. package/CHANGELOG.md +56 -1
  2. package/README.md +176 -781
  3. package/agents/analyst.md +11 -11
  4. package/agents/critic.md +11 -11
  5. package/agents/executor.md +11 -11
  6. package/agents/explorer.md +11 -11
  7. package/agents/planner.md +11 -11
  8. package/agents/reviewer.md +11 -11
  9. package/agents/security-reviewer.md +11 -11
  10. package/agents/test-engineer.md +11 -11
  11. package/agents/verifier.md +70 -11
  12. package/agents/writer.md +11 -11
  13. package/docs/actions-reference.md +595 -0
  14. package/docs/commands-reference.md +347 -0
  15. package/docs/runtime-flow.md +148 -148
  16. package/index.ts +6 -6
  17. package/package.json +99 -99
  18. package/skills/async-worker-recovery/SKILL.md +42 -42
  19. package/skills/context-artifact-hygiene/SKILL.md +52 -52
  20. package/skills/delegation-patterns/SKILL.md +54 -54
  21. package/skills/mailbox-interactive/SKILL.md +40 -40
  22. package/skills/model-routing-context/SKILL.md +39 -39
  23. package/skills/multi-perspective-review/SKILL.md +58 -58
  24. package/skills/observability-reliability/SKILL.md +41 -41
  25. package/skills/orchestration/SKILL.md +157 -157
  26. package/skills/ownership-session-security/SKILL.md +41 -41
  27. package/skills/pi-extension-lifecycle/SKILL.md +39 -39
  28. package/skills/requirements-to-task-packet/SKILL.md +63 -63
  29. package/skills/resource-discovery-config/SKILL.md +41 -41
  30. package/skills/runtime-state-reader/SKILL.md +44 -44
  31. package/skills/secure-agent-orchestration-review/SKILL.md +45 -45
  32. package/skills/state-mutation-locking/SKILL.md +42 -42
  33. package/skills/systematic-debugging/SKILL.md +67 -67
  34. package/skills/ui-render-performance/SKILL.md +39 -39
  35. package/skills/verification-before-done/SKILL.md +57 -57
  36. package/skills/worktree-isolation/SKILL.md +39 -39
  37. package/src/adapters/claude-adapter.ts +25 -0
  38. package/src/adapters/codex-adapter.ts +21 -0
  39. package/src/adapters/cursor-adapter.ts +17 -0
  40. package/src/adapters/export-util.ts +137 -0
  41. package/src/adapters/index.ts +15 -0
  42. package/src/adapters/registry.ts +18 -0
  43. package/src/adapters/types.ts +23 -0
  44. package/src/agents/agent-config.ts +2 -0
  45. package/src/agents/agent-search.ts +98 -98
  46. package/src/agents/discover-agents.ts +2 -1
  47. package/src/config/config.ts +13 -1
  48. package/src/config/drift-detector.ts +211 -0
  49. package/src/config/markers.ts +327 -0
  50. package/src/config/resilient-parser.ts +108 -0
  51. package/src/config/suggestions.ts +74 -0
  52. package/src/extension/cross-extension-rpc.ts +103 -94
  53. package/src/extension/project-init.ts +21 -1
  54. package/src/extension/register.ts +45 -14
  55. package/src/extension/registration/commands.ts +77 -8
  56. package/src/extension/registration/subagent-tools.ts +10 -1
  57. package/src/extension/registration/team-tool.ts +10 -1
  58. package/src/extension/registration/viewers.ts +48 -34
  59. package/src/extension/run-bundle-schema.ts +89 -89
  60. package/src/extension/run-import.ts +25 -1
  61. package/src/extension/run-index.ts +5 -1
  62. package/src/extension/run-maintenance.ts +142 -68
  63. package/src/extension/team-manager-command.ts +10 -1
  64. package/src/extension/team-tool/api.ts +441 -441
  65. package/src/extension/team-tool/doctor.ts +28 -3
  66. package/src/extension/team-tool/handle-settings.ts +195 -188
  67. package/src/extension/team-tool/inspect.ts +41 -41
  68. package/src/extension/team-tool/intent-policy.ts +42 -42
  69. package/src/extension/team-tool/lifecycle-actions.ts +27 -8
  70. package/src/extension/team-tool/plan.ts +19 -19
  71. package/src/extension/team-tool/run.ts +12 -1
  72. package/src/extension/team-tool.ts +332 -322
  73. package/src/i18n.ts +184 -184
  74. package/src/observability/exporters/otlp-exporter.ts +92 -77
  75. package/src/prompt/prompt-runtime.ts +72 -72
  76. package/src/runtime/agent-memory.ts +72 -72
  77. package/src/runtime/agent-observability.ts +114 -114
  78. package/src/runtime/async-marker.ts +26 -26
  79. package/src/runtime/attention-events.ts +28 -28
  80. package/src/runtime/auto-resume.ts +100 -0
  81. package/src/runtime/background-runner.ts +11 -1
  82. package/src/runtime/cancellation-token.ts +89 -89
  83. package/src/runtime/cancellation.ts +61 -61
  84. package/src/runtime/capability-inventory.ts +116 -116
  85. package/src/runtime/child-pi.ts +7 -2
  86. package/src/runtime/compaction-summary.ts +271 -0
  87. package/src/runtime/completion-guard.ts +190 -190
  88. package/src/runtime/crash-recovery.ts +33 -1
  89. package/src/runtime/delta-conflict.ts +360 -0
  90. package/src/runtime/direct-run.ts +35 -35
  91. package/src/runtime/foreground-control.ts +82 -82
  92. package/src/runtime/green-contract.ts +46 -46
  93. package/src/runtime/group-join.ts +106 -106
  94. package/src/runtime/heartbeat-gradient.ts +28 -28
  95. package/src/runtime/heartbeat-watcher.ts +124 -124
  96. package/src/runtime/iteration-hooks.ts +264 -0
  97. package/src/runtime/live-agent-control.ts +88 -88
  98. package/src/runtime/live-control-realtime.ts +36 -36
  99. package/src/runtime/live-extension-bridge.ts +150 -150
  100. package/src/runtime/live-irc.ts +92 -92
  101. package/src/runtime/live-session-health.ts +100 -100
  102. package/src/runtime/loop-gates.ts +129 -0
  103. package/src/runtime/metric-parser.ts +40 -0
  104. package/src/runtime/notebook-helpers.ts +90 -90
  105. package/src/runtime/orphan-sentinel.ts +7 -7
  106. package/src/runtime/parallel-research.ts +44 -44
  107. package/src/runtime/phase-progress.ts +217 -0
  108. package/src/runtime/pi-args.ts +38 -11
  109. package/src/runtime/pi-json-output.ts +111 -111
  110. package/src/runtime/pi-spawn.ts +57 -7
  111. package/src/runtime/policy-engine.ts +79 -79
  112. package/src/runtime/post-checks.ts +122 -0
  113. package/src/runtime/progress-event-coalescer.ts +43 -43
  114. package/src/runtime/prose-compressor.ts +164 -164
  115. package/src/runtime/recovery-recipes.ts +74 -74
  116. package/src/runtime/result-extractor.ts +121 -121
  117. package/src/runtime/role-permission.ts +39 -39
  118. package/src/runtime/sensitive-paths.ts +2 -2
  119. package/src/runtime/session-resources.ts +25 -25
  120. package/src/runtime/session-snapshot.ts +59 -59
  121. package/src/runtime/session-usage.ts +79 -79
  122. package/src/runtime/sidechain-output.ts +29 -29
  123. package/src/runtime/stream-preview.ts +177 -177
  124. package/src/runtime/supervisor-contact.ts +59 -59
  125. package/src/runtime/task-display.ts +38 -38
  126. package/src/runtime/task-graph.ts +207 -0
  127. package/src/runtime/task-quality.ts +207 -0
  128. package/src/runtime/task-runner/capabilities.ts +78 -78
  129. package/src/runtime/task-runner/live-executor.ts +7 -1
  130. package/src/runtime/task-runner/progress.ts +119 -119
  131. package/src/runtime/task-runner/prompt-pipeline.ts +64 -64
  132. package/src/runtime/task-runner/result-utils.ts +14 -14
  133. package/src/runtime/task-runner/run-projection.ts +103 -103
  134. package/src/runtime/task-runner/state-helpers.ts +22 -22
  135. package/src/runtime/team-runner.ts +117 -7
  136. package/src/runtime/worker-heartbeat.ts +21 -21
  137. package/src/runtime/worker-startup.ts +57 -57
  138. package/src/runtime/workflow-state.ts +187 -0
  139. package/src/runtime/workspace-tree.ts +298 -298
  140. package/src/schema/config-schema.ts +11 -0
  141. package/src/schema/validation-types.ts +148 -0
  142. package/src/skills/skill-templates.ts +374 -0
  143. package/src/state/active-run-registry.ts +35 -11
  144. package/src/state/atomic-write.ts +33 -26
  145. package/src/state/contracts.ts +1 -0
  146. package/src/state/event-reconstructor.ts +217 -0
  147. package/src/state/locks.ts +2 -13
  148. package/src/state/mailbox.ts +4 -3
  149. package/src/state/state-store.ts +16 -6
  150. package/src/state/task-claims.ts +44 -44
  151. package/src/state/types.ts +9 -0
  152. package/src/state/usage.ts +29 -29
  153. package/src/subagents/async-entry.ts +1 -1
  154. package/src/subagents/index.ts +3 -3
  155. package/src/subagents/live/control.ts +1 -1
  156. package/src/subagents/live/manager.ts +1 -1
  157. package/src/subagents/live/realtime.ts +1 -1
  158. package/src/subagents/live/session-runtime.ts +1 -1
  159. package/src/subagents/manager.ts +1 -1
  160. package/src/subagents/spawn.ts +1 -1
  161. package/src/teams/team-serializer.ts +38 -38
  162. package/src/types/diff.d.ts +18 -18
  163. package/src/ui/crew-footer.ts +101 -101
  164. package/src/ui/crew-select-list.ts +111 -111
  165. package/src/ui/crew-widget.ts +5 -2
  166. package/src/ui/dashboard-panes/cancellation-pane.ts +42 -42
  167. package/src/ui/dashboard-panes/capability-pane.ts +59 -59
  168. package/src/ui/dashboard-panes/mailbox-pane.ts +35 -35
  169. package/src/ui/dashboard-panes/metrics-pane.ts +34 -34
  170. package/src/ui/dashboard-panes/progress-pane.ts +11 -0
  171. package/src/ui/dynamic-border.ts +25 -25
  172. package/src/ui/layout-primitives.ts +106 -106
  173. package/src/ui/loaders.ts +158 -158
  174. package/src/ui/render-coalescer.ts +51 -51
  175. package/src/ui/render-diff.ts +119 -119
  176. package/src/ui/render-scheduler.ts +143 -143
  177. package/src/ui/run-action-dispatcher.ts +10 -1
  178. package/src/ui/spinner.ts +17 -17
  179. package/src/ui/status-colors.ts +58 -58
  180. package/src/ui/syntax-highlight.ts +116 -116
  181. package/src/ui/transcript-entries.ts +258 -258
  182. package/src/utils/completion-dedupe.ts +63 -63
  183. package/src/utils/frontmatter.ts +68 -68
  184. package/src/utils/git.ts +262 -262
  185. package/src/utils/ids.ts +17 -17
  186. package/src/utils/incremental-reader.ts +104 -104
  187. package/src/utils/names.ts +27 -27
  188. package/src/utils/redaction.ts +44 -44
  189. package/src/utils/safe-paths.ts +47 -47
  190. package/src/utils/scan-cache.ts +136 -136
  191. package/src/utils/sleep.ts +40 -26
  192. package/src/utils/task-name-generator.ts +337 -337
  193. package/src/workflows/validate-workflow.ts +40 -40
  194. package/src/worktree/branch-freshness.ts +45 -45
  195. package/teams/default.team.md +12 -12
  196. package/teams/fast-fix.team.md +11 -11
  197. package/teams/implementation.team.md +18 -18
  198. package/teams/parallel-research.team.md +14 -14
  199. package/teams/research.team.md +11 -11
  200. package/teams/review.team.md +12 -12
  201. package/workflows/default.workflow.md +30 -29
  202. package/workflows/fast-fix.workflow.md +23 -22
  203. package/workflows/implementation.workflow.md +43 -43
  204. package/workflows/parallel-research.workflow.md +46 -46
  205. package/workflows/research.workflow.md +22 -22
  206. package/workflows/review.workflow.md +30 -30
  207. package/docs/refactor-tasks-phase3.md +0 -394
  208. package/docs/refactor-tasks-phase4.md +0 -564
  209. package/docs/refactor-tasks-phase5.md +0 -402
  210. package/docs/refactor-tasks-phase6.md +0 -662
  211. package/docs/refactor-tasks.md +0 -1484
  212. package/docs/research/AGENT-EXECUTION-ARCHITECTURE.md +0 -261
  213. package/docs/research/AGENT-LIFECYCLE-COMPARISON.md +0 -111
  214. package/docs/research/AUDIT_OH_MY_PI.md +0 -261
  215. package/docs/research/AUDIT_PI_CREW.md +0 -457
  216. package/docs/research/CAVEMAN-DEEP-RESEARCH.md +0 -281
  217. package/docs/research/COMPARISON_OH_MY_PI_VS_PI_CREW.md +0 -264
  218. package/docs/research/DEEP-RESEARCH-PI-POWERBAR.md +0 -343
  219. package/docs/research/DEEP_RESEARCH_SUBAGENT_ARCHITECTURE.md +0 -480
  220. package/docs/research/GAP_CLOSURE_IMPLEMENTATION_PLAN.md +0 -354
  221. package/docs/research/IMPLEMENTATION_PLAN.md +0 -385
  222. package/docs/research/LIVE-SESSION-PRODUCTION-READY-PLAN.md +0 -502
  223. package/docs/research/OH-MY-PI-DEEP-RESEARCH-v14.7.6.md +0 -266
  224. package/docs/research/REMAINING-GAPS-PLAN.md +0 -363
  225. package/docs/research/SESSION-SUMMARY-2026-05-08.md +0 -146
  226. package/docs/research/UI-RESPONSIVENESS-AUDIT.md +0 -173
  227. package/docs/research-awesome-agent-skills-distillation.md +0 -100
  228. package/docs/research-extension-examples.md +0 -297
  229. package/docs/research-extension-system.md +0 -324
  230. package/docs/research-oh-my-pi-distillation.md +0 -369
  231. package/docs/research-optimization-plan.md +0 -548
  232. package/docs/research-phase10-distillation.md +0 -199
  233. package/docs/research-phase11-distillation.md +0 -201
  234. package/docs/research-phase8-operator-experience-plan.md +0 -819
  235. package/docs/research-phase9-observability-reliability-plan.md +0 -1190
  236. package/docs/research-pi-coding-agent.md +0 -357
  237. package/docs/research-source-pi-crew-reference.md +0 -174
  238. package/docs/research-ui-optimization-plan.md +0 -480
  239. package/docs/source-runtime-refactor-map.md +0 -107
  240. package/src/utils/atomic-write.ts +0 -33
@@ -1,480 +0,0 @@
1
- # Research: UI Optimization Plan
2
-
3
- > Phase 7 plan derived from `parallel-research` run `team_20260429053958_6497405a`.
4
- > Source artifacts:
5
- > - `.crew/artifacts/team_20260429053958_6497405a/shared/research-summary.md`
6
- > - `.crew/artifacts/team_20260429053958_6497405a/shared/04_synthesize.md`
7
- > - `.crew/artifacts/team_20260429053958_6497405a/shared/01_discover.md`
8
- > - `.crew/artifacts/team_20260429053958_6497405a/shared/02_explore-shard-1.md`
9
- > - `.crew/artifacts/team_20260429053958_6497405a/shared/03_explore-shard-2.md`
10
-
11
- ## Overview
12
-
13
- pi-crew already exposes the runtime data needed for a strong TUI: manifests, `tasks.json`, `agents.json`, per-agent `status.json`, `events.jsonl`, `output.log`, transcripts, and durable mailbox state. The gaps are in the UI layer:
14
-
15
- 1. Widget recreated on every timer tick (`crew-widget.ts:267-272`).
16
- 2. Live signatures miss `progress / toolUses / usage / recent output` so cached lines stay stale.
17
- 3. Multiple UI surfaces re-read the same files independently (no shared snapshot).
18
- 4. `/team-dashboard` is static — only reload via key `r`.
19
- 5. `transcript-viewer.ts` calls `readFileSync` inside `render()` on every paint.
20
- 6. Mailbox API/runtime exists but no first-class panel/badges.
21
- 7. Pi UI integration uses untyped private-like casts (`requestRender`, `setWorkingIndicator`).
22
-
23
- The plan below sequences fixes for highest ROI and lowest risk first, lockdown the snapshot contract before refactoring surfaces, and defers anything depending on uncertain pi-mono compatibility.
24
-
25
- ## Implementation Status
26
-
27
- > Track status here. Use `[x]` for done, `[ ]` for pending, `[-]` for won't-do/deferred.
28
-
29
- - [x] Phase 0 — Pi UI compatibility shim
30
- - [x] Phase 1.A — Persistent widget instance
31
- - [x] Phase 1.B — `RunUiSnapshot` + `RunSnapshotCache`
32
- - [x] Phase 1.C — Freshness signatures (progress / tool / usage / mtimes)
33
- - [x] Phase 2 — Refactor widget / sidebar / dashboard / powerbar onto snapshot
34
- - [x] Phase 3.A — `/team-dashboard` live component
35
- - [x] Phase 3.B — Dashboard panes (agents, progress, mailbox, transcript)
36
- - [x] Phase 4.A — Transcript viewer cache (mtime/size keyed)
37
- - [x] Phase 4.B — Transcript bounded-tail mode
38
- - [x] Phase 5.A — Adaptive/coalesced render scheduler
39
- - [x] Phase 5.B — Powerbar fallback strategy + docs
40
- - [x] Phase 5.C — Performance tests (large runs / large transcripts)
41
-
42
- ## Roadmap-Level Decisions
43
-
44
- | Decision | Choice | Rationale |
45
- |---|---|---|
46
- | Snapshot contract before refactor | Lock `RunUiSnapshot` interface in Phase 1.B before any consumer refactor | Avoid concurrent rename/conflict in widget/sidebar/dashboard |
47
- | Persistent widget independent of snapshot | Phase 1.A done before 1.B | Quick win, doesn't block snapshot work, removes biggest CPU/flicker churn |
48
- | Compatibility shim placed first (Phase 0) | Centralize `requestRender / setStatus / custom / setWidget` casts in `src/ui/pi-ui-compat.ts` | Every later phase consumes it; avoids re-casting in each module |
49
- | Transcript fix split (4.A then 4.B) | Cache + invalidate first, tail-mode second | Cache by `mtime+size` is S effort and removes blocking `readFileSync` per-render; tail mode is M-L and can land later |
50
- | Event-driven refresh deferred to Phase 5.A | Subscribe `crew.run.* / crew.subagent.* / crew.mailbox.*` only after snapshot is stable | Avoids listener leak risk during rapid refactor |
51
- | RPC mode | Best-effort, not first-class | RPC drops function widgets; we emit string fallback via shim |
52
- | Powerbar | Always-fallback to `setStatus`/widget; document event contract | No confirmed pi-mono consumer found in research |
53
- | Memory safety | LRU cap 8 active + 16 recent runs in snapshot cache | Prevent leak when user browses many runs |
54
-
55
- ## Phase 0 — Pi UI Compatibility Shim
56
-
57
- **Goal:** Eliminate ad-hoc `(ctx.ui as { requestRender?: ... })` casts; provide one typed entry-point per UI capability.
58
-
59
- **Deliverables:**
60
- - New file `src/ui/pi-ui-compat.ts` exporting:
61
- - `requestRender(ctx)` — feature-detected.
62
- - `setWorkingIndicator(ctx, opts?)` — feature-detected, no-op fallback.
63
- - `setExtensionWidget(ctx, key, factory, options)` — wraps `setWidget`, accepts `{ persist?: boolean }` flag.
64
- - `showCustom(ctx, ...)` — wraps `ctx.ui.custom` with overlay options.
65
- - `setStatusFallback(ctx, key, lines, segment?)` — used when powerbar consumer is absent.
66
- - Replace existing inline casts in `crew-widget.ts`, `register.ts`, `live-run-sidebar.ts`, `powerbar-publisher.ts`.
67
-
68
- **Files affected:**
69
- - `src/ui/pi-ui-compat.ts` (new)
70
- - `src/ui/crew-widget.ts`
71
- - `src/ui/live-run-sidebar.ts`
72
- - `src/ui/powerbar-publisher.ts`
73
- - `src/extension/register.ts`
74
-
75
- **Tests:**
76
- - Unit test asserting fallback when host lacks `requestRender` / `setWorkingIndicator`.
77
- - Snapshot of cast removal via grep test (no `as { requestRender` left in `src/`).
78
-
79
- **Effort:** S (0.5–1 day) · **Risk:** Low
80
-
81
- ## Phase 1.A — Persistent Widget Instance
82
-
83
- **Goal:** Stop calling `setWidget` every timer tick; only call when placement/visibility/key changes.
84
-
85
- **Approach:**
86
- - Extend `CrewWidgetState` with `lastPlacement: string`, `lastVisibility: "hidden" | "visible"`, `lastKey: string`.
87
- - `updateCrewWidget` decides: if state matches and component instance exists → only invalidate via shim's `requestRender()`; do NOT call `setWidget`.
88
- - Component reads `runs` lazily inside `render(width)` using existing `activeWidgetRuns` (later replaced by snapshot in Phase 2).
89
-
90
- **Files affected:**
91
- - `src/ui/crew-widget.ts`
92
- - `src/extension/register.ts` (timer interval handler)
93
-
94
- **Tests (unit):**
95
- - `updateCrewWidget` called N times with unchanged placement → `setWidget` invoked exactly once (count via mock).
96
- - Switching placement triggers exactly 1 additional `setWidget`.
97
- - Hide/clear path still calls `setWidget(WIDGET_KEY, undefined, ...)`.
98
-
99
- **Effort:** S–M (1 day) · **Risk:** Low
100
-
101
- ## Phase 1.B — `RunUiSnapshot` + `RunSnapshotCache`
102
-
103
- **Status:** Done in Wave 2 via `src/ui/snapshot-types.ts` and `src/ui/run-snapshot-cache.ts`.
104
-
105
- **Goal:** Single read pass per run; share results across widget/sidebar/dashboard/powerbar.
106
-
107
- **Locked interface (do not change without bumping plan):**
108
-
109
- ```ts
110
- export interface RunUiProgress {
111
- total: number;
112
- completed: number;
113
- running: number;
114
- failed: number;
115
- queued: number;
116
- }
117
-
118
- export interface RunUiUsage {
119
- tokensIn: number;
120
- tokensOut: number;
121
- toolUses: number;
122
- }
123
-
124
- export interface RunUiMailbox {
125
- inboxUnread: number;
126
- outboxPending: number;
127
- needsAttention: number;
128
- }
129
-
130
- export interface RunUiSnapshot {
131
- runId: string;
132
- cwd: string;
133
- fetchedAt: number;
134
- signature: string; // stable hash; differs only when content changed
135
- manifest: TeamRunManifest;
136
- tasks: TeamTaskState[];
137
- agents: CrewAgentRecord[];
138
- progress: RunUiProgress;
139
- usage: RunUiUsage;
140
- mailbox: RunUiMailbox;
141
- recentEvents: TeamEvent[]; // last N (config N=20)
142
- recentOutputLines: string[]; // last N lines, capped at MAX_TAIL_BYTES
143
- }
144
-
145
- export interface RunSnapshotCache {
146
- get(runId: string): RunUiSnapshot | undefined;
147
- refresh(runId: string): RunUiSnapshot; // forces re-read
148
- refreshIfStale(runId: string): RunUiSnapshot; // re-read only if mtime/size changed or TTL exceeded
149
- invalidate(runId?: string): void; // invalidate one or all
150
- snapshotsByKey(): Map<string, RunUiSnapshot>; // for dashboard list rendering
151
- }
152
- ```
153
-
154
- **Cache rules:**
155
- - Key by `runId`.
156
- - Stored entry includes `tasksMtime`, `tasksSize`, `agentsMtime`, `agentsSize`, `manifestMtime`, `mailboxMtime`, `outputMtime`.
157
- - TTL = 250ms (matches existing `crew-agent-records` reader cache).
158
- - LRU: max 8 active + 16 recent entries; evict on insert beyond limit.
159
- - All `JSON.parse` wrapped in `try/catch`; on parse fail return previous valid entry (never crash render).
160
-
161
- **Files affected:**
162
- - `src/ui/run-snapshot.ts` (new)
163
- - `src/ui/run-snapshot-cache.ts` (new)
164
- - `src/ui/snapshot-types.ts` (new — exported types)
165
-
166
- **Tests (unit):**
167
- - `refreshIfStale` returns same entry when mtimes unchanged.
168
- - File rewrite changes `signature`.
169
- - Parse error returns last valid snapshot, no throw.
170
- - LRU eviction at boundary.
171
-
172
- **Effort:** M–L (2–3 days) · **Risk:** Medium
173
-
174
- ## Phase 1.C — Freshness Signatures
175
-
176
- **Goal:** Make widget/sidebar invalidate when progress/tool/tokens/output change, not just status.
177
-
178
- **Changes:**
179
- - `CrewWidgetComponent.buildSignature` includes per-agent `progress.completed`, `progress.total`, `currentTool`, `usage.tokensOut`, `lastOutputMtime`.
180
- - `LiveRunSidebar.buildSignature` similarly includes progress/tool/usage; add `mailbox.inboxUnread`.
181
- - Signatures derived from `RunUiSnapshot.signature` once Phase 1.B is in.
182
-
183
- **Files affected:**
184
- - `src/ui/crew-widget.ts`
185
- - `src/ui/live-run-sidebar.ts`
186
-
187
- **Tests (unit):**
188
- - Two snapshots with same status but different progress → different signatures.
189
- - Mock progress event → render output line count/contents change.
190
-
191
- **Effort:** S (0.5 day) · **Risk:** Low
192
-
193
- ## Phase 2 — Refactor Surfaces onto Snapshot
194
-
195
- **Status:** Done in Wave 2 for widget/sidebar/dashboard/powerbar, with fallback direct reads preserved when no cache is supplied.
196
-
197
- **Goal:** Replace independent FS reads in widget / sidebar / dashboard / powerbar with `RunSnapshotCache`.
198
-
199
- **Deliverables:**
200
- - `crew-widget.ts` reads via `cache.refreshIfStale(runId)`.
201
- - `live-run-sidebar.ts` same.
202
- - `run-dashboard.ts` calls `cache.snapshotsByKey()` once per render.
203
- - `powerbar-publisher.ts` derives segment text from snapshot.
204
- - Remove direct `agentsFor`/`readTasks`/`readManifest` reads from UI modules.
205
-
206
- **Files affected:**
207
- - `src/ui/crew-widget.ts`
208
- - `src/ui/live-run-sidebar.ts`
209
- - `src/ui/run-dashboard.ts`
210
- - `src/ui/powerbar-publisher.ts`
211
-
212
- **Tests (unit):**
213
- - One render of all four surfaces with N=10 runs triggers ≤ N cache reads (use spy).
214
- - Snapshot reuse across surfaces in same tick (counter assert).
215
-
216
- **Effort:** M (2 days) · **Risk:** Medium
217
-
218
- ## Phase 3.A — Live `/team-dashboard`
219
-
220
- **Goal:** Dashboard auto-refreshes while open, preserves selection, separates active vs recent runs.
221
-
222
- **Changes:**
223
- - Convert `RunDashboard` from one-shot render to TUI overlay component owning its own timer (250–1000ms adaptive).
224
- - Internal state: `selectedRunId`, `activeTab`, `cachedSnapshots` (via `RunSnapshotCache`).
225
- - Hotkey `r` no longer needed but kept as manual force-refresh.
226
-
227
- **Files affected:**
228
- - `src/ui/run-dashboard.ts`
229
- - `src/extension/registration/commands.ts` (dashboard handler now overlay-based)
230
-
231
- **Tests (unit + integration):**
232
- - Component receives mocked snapshot updates → re-renders without losing `selectedRunId`.
233
- - Active runs list updates when manifest status flips.
234
-
235
- **Effort:** M (2 days) · **Risk:** Medium
236
-
237
- ## Phase 3.B — Dashboard Panes (agents · progress · mailbox · transcript)
238
-
239
- **Goal:** First-class panel/tabs surfacing data already in snapshot.
240
-
241
- **Tabs:**
242
- 1. **Agents** — table (agent · status · current tool · tokens · last activity).
243
- 2. **Progress / Events** — last N events with role badge and timestamps.
244
- 3. **Mailbox** — inbox unread, outbox pending, needs-attention; row actions: nudge/ack via existing `team-tool/api.ts` (`send-message`, `ack-message`).
245
- 4. **Transcript / Output** — opens existing `DurableTranscriptViewer` (post Phase 4.A).
246
-
247
- **Files affected:**
248
- - `src/ui/run-dashboard.ts`
249
- - `src/ui/dashboard-panes/` (new directory: agents-pane, progress-pane, mailbox-pane, transcript-pane)
250
- - `src/extension/team-tool/api.ts` (no API change; UI calls existing `read-mailbox`, `send-message`, `ack-message`)
251
-
252
- **Tests (unit):**
253
- - Mailbox pane shows badge counts from snapshot.
254
- - Pane switching preserves selection within pane.
255
- - Action `ack` triggers API call once and refreshes snapshot.
256
-
257
- **Effort:** M–L (3 days) · **Risk:** Medium
258
-
259
- ## Phase 4.A — Transcript Viewer Cache
260
-
261
- **Goal:** Stop blocking `readFileSync` inside `render()`; eliminate full-parse per paint.
262
-
263
- **Changes:**
264
- - New `TranscriptCacheEntry { path, mtime, size, lines, parsedAt }` keyed by `(runId, taskId)`.
265
- - `readRunTranscript` consults cache; only re-reads if `mtime` or `size` changed.
266
- - `DurableTranscriptViewer.render` reads `cache.lines`, never the disk directly.
267
- - TTL 500ms safety net.
268
-
269
- **Files affected:**
270
- - `src/ui/transcript-viewer.ts`
271
- - `src/ui/transcript-cache.ts` (new)
272
-
273
- **Tests (unit):**
274
- - Two consecutive renders with unchanged file → 1 disk read.
275
- - File grow → new cached lines, signature changes.
276
- - Parse failure preserves last good cache.
277
-
278
- **Effort:** S (0.5 day) · **Risk:** Low
279
-
280
- ## Phase 4.B — Bounded-Tail Mode
281
-
282
- **Goal:** Default to last N bytes/events to keep latency bounded for large transcripts.
283
-
284
- **Approach:**
285
- - Default `maxTailBytes = 256 KB`.
286
- - Tail strategy: `fs.statSync` → `fs.openSync` → read last N bytes → discard partial first line if file exceeds N.
287
- - Add hotkey `f` to "load full transcript on demand"; show byte counter.
288
- - Auto-scroll toggle (`a`) preserved.
289
-
290
- **Files affected:**
291
- - `src/ui/transcript-viewer.ts`
292
- - `src/ui/transcript-cache.ts` (extend)
293
-
294
- **Config:**
295
- - `config.ui.transcriptTailBytes` (optional, default 262144).
296
-
297
- **Tests (unit):**
298
- - 1MB file → only ~256KB worth of lines parsed.
299
- - Force-full mode loads everything.
300
- - Tail re-aligns when first newline straddles boundary.
301
-
302
- **Effort:** M (2 days) · **Risk:** Medium
303
-
304
- ## Phase 5.A — Adaptive Render Scheduler
305
-
306
- **Goal:** Replace fixed 1000ms timers with event-driven refresh + low-frequency fallback.
307
-
308
- **Approach:**
309
- - Single `RenderScheduler` listening on `pi.events` for `crew.run.*`, `crew.subagent.*`, `crew.mailbox.*`.
310
- - On event → invalidate snapshot + `requestRender` (debounced 50–100ms via animation-frame analog).
311
- - Fallback timer 750ms (reduced from 1000ms) only triggers if no event in window.
312
- - All listeners disposed on extension unload + run completion.
313
-
314
- **Files affected:**
315
- - `src/ui/render-scheduler.ts` (new)
316
- - `src/extension/register.ts` (replace `setInterval` block)
317
-
318
- **Tests (unit):**
319
- - Event burst coalesces to single `requestRender` within debounce window.
320
- - Listeners removed after `dispose()` (counter on event emitter).
321
- - Fallback timer fires only when no events in interval.
322
-
323
- **Effort:** M (1.5 days) · **Risk:** Low–Medium
324
-
325
- ## Phase 5.B — Powerbar Fallback Strategy
326
-
327
- **Goal:** Don't depend on an external `powerbar:*` consumer.
328
-
329
- **Changes:**
330
- - Detect listener via `pi.events.listenerCount?.("powerbar:register-segment")`.
331
- - If 0 listeners: emit AND mirror to `ctx.ui.setStatus("pi-crew", text)`.
332
- - Document event contract in `docs/architecture.md`.
333
-
334
- **Files affected:**
335
- - `src/ui/powerbar-publisher.ts`
336
- - `docs/architecture.md`
337
-
338
- **Tests (unit):**
339
- - No consumer → `setStatus` called.
340
- - Consumer registered → only event emitted, no `setStatus`.
341
-
342
- **Effort:** S–M (0.5–1 day) · **Risk:** Medium (depends on listener-count API availability)
343
-
344
- ## Phase 5.C — Performance Tests
345
-
346
- **Goal:** Catch regressions on large runs / transcripts.
347
-
348
- **Suite:**
349
- - 50 simulated runs, 200 events each → render dashboard, assert ≤ 50 disk reads / render cycle.
350
- - 5MB transcript → tail mode reads ≤ 1MB, full mode allowed.
351
- - 100 widget update calls without state change → ≤ 1 `setWidget` invocation.
352
-
353
- **Files affected:**
354
- - `test/integration/ui-performance.test.ts` (new)
355
-
356
- **Effort:** M (1.5 days) · **Risk:** Low
357
-
358
- ## Implementation Order
359
-
360
- > Recommended: do quick wins (Phase 0, 1.A, 1.C, 4.A) in parallel as 4 small PRs before starting Phase 1.B (snapshot foundation).
361
-
362
- ```
363
- Wave 1 (parallel, all S effort):
364
- [x] Phase 0 — Pi UI compat shim
365
- [x] Phase 1.A — Persistent widget
366
- [x] Phase 1.C — Freshness signatures (use ad-hoc fields until snapshot lands)
367
- [x] Phase 4.A — Transcript cache
368
-
369
- Wave 2 (sequential):
370
- [x] Phase 1.B — RunUiSnapshot foundation
371
- [x] Phase 2 — Refactor surfaces onto snapshot
372
- [x] Phase 5.A — Adaptive render scheduler
373
-
374
- Wave 3 (parallel after Wave 2):
375
- [x] Phase 3.A — Live dashboard
376
- [x] Phase 3.B — Dashboard panes
377
- [x] Phase 4.B — Transcript tail mode
378
-
379
- Wave 4 (cleanup):
380
- [x] Phase 5.B — Powerbar fallback
381
- [x] Phase 5.C — Perf tests
382
- ```
383
-
384
- ## Files Affected (grouped)
385
-
386
- **New files:**
387
- - `src/ui/pi-ui-compat.ts`
388
- - `src/ui/run-snapshot.ts`
389
- - `src/ui/run-snapshot-cache.ts`
390
- - `src/ui/snapshot-types.ts`
391
- - `src/ui/transcript-cache.ts`
392
- - `src/ui/render-scheduler.ts`
393
- - `src/ui/dashboard-panes/agents-pane.ts`
394
- - `src/ui/dashboard-panes/progress-pane.ts`
395
- - `src/ui/dashboard-panes/mailbox-pane.ts`
396
- - `src/ui/dashboard-panes/transcript-pane.ts`
397
- - `test/integration/ui-performance.test.ts`
398
-
399
- **Modified files:**
400
- - `src/ui/crew-widget.ts`
401
- - `src/ui/live-run-sidebar.ts`
402
- - `src/ui/run-dashboard.ts`
403
- - `src/ui/powerbar-publisher.ts`
404
- - `src/ui/transcript-viewer.ts`
405
- - `src/extension/register.ts`
406
- - `src/extension/registration/commands.ts`
407
- - `docs/architecture.md`
408
-
409
- **Read-only references:**
410
- - `src/runtime/crew-agent-records.ts`
411
- - `src/state/mailbox.ts`
412
- - `src/extension/team-tool/api.ts`
413
-
414
- ## Risk Assessment
415
-
416
- | Risk | Phase | Likelihood | Impact | Mitigation |
417
- |---|---|---|---|---|
418
- | Snapshot cache memory leak with many runs | 1.B | Medium | High | LRU cap (8 active + 16 recent), eviction unit test |
419
- | Race between `agents.json` rewrite and UI read | 1.B | Medium | Medium | `try/catch JSON.parse` + return last valid snapshot |
420
- | Listener leak from event-driven refresh | 5.A | Medium | Medium | Centralize in `RenderScheduler.dispose()`, integration test counts listeners post-shutdown |
421
- | Persistent widget breaks on placement change edge cases | 1.A | Low | Medium | Diff against `lastPlacement/lastKey/lastVisibility` triple |
422
- | Transcript tail-mode misaligns at chunk boundary | 4.B | Medium | Low | Discard partial-first-line; unit test with files at `n*chunkSize ± 1` |
423
- | Pi RPC mode silently drops widgets | 0/2 | High | Low | Shim falls back to `setStatus` string lines |
424
- | Powerbar consumer never appears | 5.B | High | Low | Always emit + always set status fallback |
425
- | `requestRender` removed in future pi-mono | 0 | Low | Medium | Compat shim already feature-detects |
426
- | Snapshot signature collision (different state, same hash) | 1.B | Low | Medium | Include mtimes + sizes + counts in hash input |
427
- | Test suite runtime grows from perf tests | 5.C | Medium | Low | Run perf separately via dedicated script when needed |
428
- | Concurrent refactor of widget/sidebar/dashboard while contract evolves | 1.B → 2 | Medium | High | Lock interface in 1.B PR before opening Phase 2 PR |
429
- | Mailbox pane spams renders on incoming messages | 3.B / 5.A | Medium | Low | Debounce via `RenderScheduler`, batch mailbox events |
430
-
431
- ## Testing Strategy
432
-
433
- **Unit (Wave 1):**
434
- - Compat shim feature-detect fallback (Phase 0).
435
- - `setWidget` called once per state change (Phase 1.A).
436
- - Signature includes progress/tool/usage diff (Phase 1.C).
437
- - Transcript cache reuses entry when mtime unchanged (Phase 4.A).
438
-
439
- **Unit (Wave 2):**
440
- - Snapshot cache: TTL, LRU, parse-error fallback, signature stability.
441
- - Surface refactor: 4 surfaces share ≤ 1 read per run per tick.
442
- - Scheduler: event coalesce, dispose, fallback timer.
443
-
444
- **Unit (Wave 3):**
445
- - Dashboard live refresh preserves selection.
446
- - Pane switching state, mailbox badge counts, ack action.
447
- - Tail-mode boundary alignment, force-full toggle.
448
-
449
- **Integration:**
450
- - 50-run dashboard render ≤ 50 disk reads (Phase 5.C).
451
- - 5MB transcript tail ≤ 1MB read.
452
- - Long-lived run (10 min simulated) without listener growth.
453
-
454
- **Manual smoke:**
455
- - Open `/team-dashboard`, switch panes, send mailbox message, ack from UI.
456
- - Resize terminal, switch placement above/below editor.
457
- - Reload extension; ensure all timers/listeners cleared.
458
-
459
- **Regression baseline:**
460
- - Existing 286 unit + 26 integration tests must remain green at every wave.
461
- - Run `npm run typecheck && npm run test:unit && npm run test:integration` before each PR merge.
462
-
463
- ## Open Questions
464
-
465
- 1. **Powerbar consumer status** — is any pi-mono extension/host expected to consume `powerbar:*` events? (Decides Phase 5.B aggressiveness; default plan: always-fallback.)
466
- 2. **Target scale** — how many concurrent runs / what max transcript size should we optimize for? Plan assumes 8 active runs and 256KB tail by default.
467
- 3. **RPC mode priority** — must function widgets work in RPC, or is graceful string fallback acceptable? Plan assumes best-effort string fallback.
468
- 4. **Phase 1.B contract freeze** — once the interface ships, downstream phases depend on it. Should we publish it as `RunUiSnapshotV1` and treat changes as breaking?
469
-
470
- ## Effort Summary
471
-
472
- | Wave | Phases | Effort | Dependency |
473
- |---|---|---|---|
474
- | 1 (parallel) | 0, 1.A, 1.C, 4.A | ~2.5 days total | None |
475
- | 2 (sequential) | 1.B → 2 → 5.A | ~5.5 days | Wave 1 done |
476
- | 3 (parallel) | 3.A, 3.B, 4.B | ~7 days | Wave 2 done |
477
- | 4 (parallel) | 5.B, 5.C | ~3 days | Wave 3 done |
478
- | **Total** | 12 phases | **~18 dev-days** | — |
479
-
480
- > Quick-win path (Wave 1 only) delivers ~70% of perceived UI improvement (no flicker, fresh signatures, no transcript blocking) at <15% of total effort.
@@ -1,107 +0,0 @@
1
- # pi-crew runtime refactor source map
2
-
3
- This document records the source projects used as the baseline for the pi-crew subagent/runtime refactor. The goal is to avoid ad-hoc fixes in critical process orchestration paths and instead align pi-crew with proven Pi extension patterns.
4
-
5
- ## Source/pi-subagents
6
-
7
- Primary source for child-process worker execution.
8
-
9
- - `pi-spawn.ts`: robust Pi CLI resolution on Windows and package installs.
10
- - `async-execution.ts`: detached async runner with `windowsHide: true` to avoid blank console windows.
11
- - `subagent-runner.ts`: streaming child Pi process runner, output capture, result extraction.
12
- - `post-exit-stdio-guard.ts`: guards for child processes that exit before stdio fully closes.
13
- - `result-watcher.ts` and `async-job-tracker.ts`: durable async job/result observation patterns.
14
- - `model-fallback.ts`: model fallback policy independent of hardcoded provider assumptions.
15
- - `subagent-control.ts`, `run-status.ts`: status and control semantics.
16
-
17
- pi-crew alignment:
18
-
19
- - Background runner and child worker spawn options now explicitly set `windowsHide: true`.
20
- - Parallel research no longer gates all shard workers behind a single discover worker.
21
- - Further work should consolidate `child-pi.ts`, `async-runner.ts`, and `subagent-manager.ts` into a durable-first subagent runtime module.
22
-
23
- ## Source/pi-subagents2
24
-
25
- Primary source for higher-level agent management and UI patterns.
26
-
27
- - `src/agent-manager.ts`: agent lifecycle registry boundaries.
28
- - `src/agent-runner.ts`: invocation/run abstraction separate from UI registration.
29
- - `src/model-resolver.ts`: cleaner model resolution responsibility.
30
- - `src/output-file.ts`: output file abstraction.
31
- - `src/ui/agent-widget.ts`, `src/ui/conversation-viewer.ts`: compact live status and transcript viewing.
32
-
33
- pi-crew alignment:
34
-
35
- - Keep `Agent`/`crew_agent` tools as thin adapters over a durable manager.
36
- - Avoid storing essential run mapping in memory only.
37
- - Keep UI active-only and file-backed.
38
-
39
- ## Source/pi-mono
40
-
41
- Primary source for Pi extension API/lifecycle constraints.
42
-
43
- - `packages/coding-agent/src/core/extensions/types.ts`: extension context/tool contracts.
44
- - `packages/coding-agent/src/core/extensions/runner.ts`: extension execution boundaries.
45
- - `packages/coding-agent/src/core/model-registry.ts`: available model discovery.
46
- - `packages/coding-agent/src/modes/interactive/interactive-mode.ts`: session lifecycle/UI behavior.
47
-
48
- pi-crew alignment:
49
-
50
- - Treat session-bound foreground workers differently from explicit async background workers.
51
- - Do not assume hardcoded providers/models.
52
- - Use Pi-native UI calls without modal auto-open by default.
53
-
54
- ## Source/pi-powerbar, pi-plan, pi-diff-review, pi-extensions*
55
-
56
- Sources for UI and small-extension patterns.
57
-
58
- - `pi-powerbar/src/powerbar/*`: low-noise status segment publishing.
59
- - `pi-plan/src/plan-action-ui.ts`: action-oriented UI without persistent heavy overlays.
60
- - `pi-diff-review/src/*`: command/tool registration and review UX patterns.
61
- - `pi-extensions2/files-widget/*`: file-backed UI composition and navigation.
62
-
63
- pi-crew alignment:
64
-
65
- - Keep persistent widget active-only.
66
- - Prefer manual dashboard/transcript commands for history.
67
- - Avoid expensive render scans and auto-opening focus-capturing overlays.
68
-
69
- ## Source/oh-my-pi
70
-
71
- Primary source for broader agent runtime, UI, extension, hook, skill, native process, and release patterns.
72
-
73
- Detailed distillation: `docs/research-oh-my-pi-distillation.md`.
74
- Next implementation roadmap: `docs/next-upgrade-roadmap.md`.
75
-
76
- Key patterns to apply:
77
-
78
- - Separate durable run history from worker/provider prompt context.
79
- - Distinguish steering (interrupt active work) from follow-up (continue after idle).
80
- - Preserve cancellation invariants with structured cancel reasons and synthetic terminal events.
81
- - Use shared/exclusive execution semantics and intent tracing for risky actions.
82
- - Keep TUI components small, width-safe, event-driven, coalesced, and lifecycle-clean.
83
- - Split extension/plugin lifecycle into register vs initialized side-effect phases.
84
- - Normalize teams/workflows/agents/skills/hooks/tools into a capability inventory with disabled/shadowed states.
85
- - Add typed lifecycle hooks for crew operations.
86
- - Move toward append-only run history with attempt/branch provenance.
87
- - Use cooperative cancellation tokens and two-phase process teardown for workers.
88
- - Cache raw scan entries, not final semantic query results.
89
- - Consider content-addressed blob artifacts for large worker outputs/log chunks.
90
-
91
- ## Current refactor checkpoints
92
-
93
- - [x] Hide Windows console windows for background runner and child Pi workers.
94
- - [x] Make parallel research shard workers start in parallel instead of depending on a single discover worker.
95
- - [x] Keep direct-agent reconstruction gated by `workflow === "direct-agent"` only.
96
- - [x] Persist subagent records and recover terminal results after restart.
97
- - [x] Fail fast for unrecoverable persisted records without `runId` instead of hanging.
98
- - [x] Persist direct-agent model override into task state for background/resume reconstruction.
99
-
100
- For the current prioritized upgrade backlog, see `docs/next-upgrade-roadmap.md`.
101
-
102
- ## Remaining larger subsystem work
103
-
104
- - Consolidate subagent runtime into `src/subagents/*` or equivalent durable-first module.
105
- - Move model routing transparency into persisted task/subagent records: requested model, selected model, fallback chain, fallback reason.
106
- - Add real integration smoke scripts for Windows process visibility, async restart recovery, and multi-shard fanout.
107
- - Add adaptive planner repair/retry for invalid JSON instead of immediate block when safe.
@@ -1,33 +0,0 @@
1
- import * as fs from "node:fs";
2
- import * as path from "node:path";
3
-
4
- /**
5
- * Write JSON data to a file atomically.
6
- * Uses write-to-temp + rename to avoid torn writes on crash.
7
- */
8
- export function writeAtomicJson(filePath: string, data: unknown, pretty = false): void {
9
- const dir = path.dirname(filePath);
10
- const content = pretty ? JSON.stringify(data, null, 2) : JSON.stringify(data);
11
- const tmpPath = filePath + ".tmp";
12
- fs.writeFileSync(tmpPath, content, "utf-8");
13
- fs.renameSync(tmpPath, filePath);
14
- }
15
-
16
- /**
17
- * Read and parse JSON from a file. Returns undefined on any error.
18
- */
19
- export function readJsonFile<T = unknown>(filePath: string): T | undefined {
20
- try {
21
- return JSON.parse(fs.readFileSync(filePath, "utf-8")) as T;
22
- } catch {
23
- return undefined;
24
- }
25
- }
26
-
27
- /**
28
- * Append a JSON line to a JSONL file atomically per line.
29
- */
30
- export function appendJsonlLine(filePath: string, data: unknown): void {
31
- const line = JSON.stringify(data) + "\n";
32
- fs.appendFileSync(filePath, line, "utf-8");
33
- }