pi-crew 0.1.49 → 0.2.0

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 (249) hide show
  1. package/CHANGELOG.md +74 -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 +14 -1
  48. package/src/config/defaults.ts +5 -5
  49. package/src/config/drift-detector.ts +211 -0
  50. package/src/config/markers.ts +327 -0
  51. package/src/config/resilient-parser.ts +108 -0
  52. package/src/config/suggestions.ts +74 -0
  53. package/src/extension/cross-extension-rpc.ts +103 -82
  54. package/src/extension/project-init.ts +36 -4
  55. package/src/extension/register.ts +67 -22
  56. package/src/extension/registration/commands.ts +77 -8
  57. package/src/extension/registration/subagent-tools.ts +10 -1
  58. package/src/extension/registration/team-tool.ts +10 -1
  59. package/src/extension/registration/viewers.ts +48 -34
  60. package/src/extension/run-bundle-schema.ts +89 -89
  61. package/src/extension/run-export.ts +26 -12
  62. package/src/extension/run-import.ts +25 -1
  63. package/src/extension/run-index.ts +5 -1
  64. package/src/extension/run-maintenance.ts +142 -68
  65. package/src/extension/team-manager-command.ts +10 -1
  66. package/src/extension/team-tool/context.ts +1 -1
  67. package/src/extension/team-tool/doctor.ts +28 -3
  68. package/src/extension/team-tool/handle-settings.ts +195 -188
  69. package/src/extension/team-tool/inspect.ts +41 -41
  70. package/src/extension/team-tool/intent-policy.ts +42 -42
  71. package/src/extension/team-tool/lifecycle-actions.ts +27 -8
  72. package/src/extension/team-tool/plan.ts +19 -19
  73. package/src/extension/team-tool/run.ts +12 -1
  74. package/src/extension/team-tool.ts +14 -3
  75. package/src/i18n.ts +184 -184
  76. package/src/observability/exporters/otlp-exporter.ts +92 -77
  77. package/src/prompt/prompt-runtime.ts +72 -72
  78. package/src/runtime/agent-memory.ts +72 -72
  79. package/src/runtime/agent-observability.ts +114 -114
  80. package/src/runtime/async-marker.ts +26 -26
  81. package/src/runtime/attention-events.ts +28 -28
  82. package/src/runtime/auto-resume.ts +100 -0
  83. package/src/runtime/background-runner.ts +11 -1
  84. package/src/runtime/cancellation-token.ts +89 -89
  85. package/src/runtime/cancellation.ts +61 -61
  86. package/src/runtime/capability-inventory.ts +116 -116
  87. package/src/runtime/child-pi.ts +7 -2
  88. package/src/runtime/compaction-summary.ts +271 -0
  89. package/src/runtime/completion-guard.ts +190 -190
  90. package/src/runtime/concurrency.ts +3 -1
  91. package/src/runtime/crash-recovery.ts +33 -0
  92. package/src/runtime/delta-conflict.ts +360 -0
  93. package/src/runtime/diagnostic-export.ts +3 -1
  94. package/src/runtime/direct-run.ts +35 -35
  95. package/src/runtime/event-stream-bridge.ts +3 -1
  96. package/src/runtime/foreground-control.ts +82 -82
  97. package/src/runtime/green-contract.ts +46 -46
  98. package/src/runtime/group-join.ts +106 -106
  99. package/src/runtime/heartbeat-gradient.ts +28 -28
  100. package/src/runtime/heartbeat-watcher.ts +124 -124
  101. package/src/runtime/iteration-hooks.ts +262 -0
  102. package/src/runtime/live-agent-control.ts +88 -88
  103. package/src/runtime/live-control-realtime.ts +36 -36
  104. package/src/runtime/live-extension-bridge.ts +150 -150
  105. package/src/runtime/live-irc.ts +92 -92
  106. package/src/runtime/live-session-health.ts +100 -100
  107. package/src/runtime/loop-gates.ts +129 -0
  108. package/src/runtime/metric-parser.ts +40 -0
  109. package/src/runtime/notebook-helpers.ts +90 -90
  110. package/src/runtime/orphan-sentinel.ts +7 -7
  111. package/src/runtime/parallel-research.ts +44 -44
  112. package/src/runtime/phase-progress.ts +217 -0
  113. package/src/runtime/pi-args.ts +38 -2
  114. package/src/runtime/pi-json-output.ts +111 -111
  115. package/src/runtime/pi-spawn.ts +74 -6
  116. package/src/runtime/policy-engine.ts +79 -79
  117. package/src/runtime/post-checks.ts +122 -0
  118. package/src/runtime/process-status.ts +14 -1
  119. package/src/runtime/progress-event-coalescer.ts +43 -43
  120. package/src/runtime/prose-compressor.ts +164 -164
  121. package/src/runtime/recovery-recipes.ts +74 -74
  122. package/src/runtime/result-extractor.ts +121 -121
  123. package/src/runtime/role-permission.ts +39 -39
  124. package/src/runtime/sensitive-paths.ts +3 -3
  125. package/src/runtime/session-resources.ts +25 -25
  126. package/src/runtime/session-snapshot.ts +59 -59
  127. package/src/runtime/session-usage.ts +79 -79
  128. package/src/runtime/sidechain-output.ts +29 -29
  129. package/src/runtime/stream-preview.ts +177 -177
  130. package/src/runtime/supervisor-contact.ts +59 -59
  131. package/src/runtime/task-display.ts +38 -38
  132. package/src/runtime/task-graph.ts +207 -0
  133. package/src/runtime/task-quality.ts +207 -0
  134. package/src/runtime/task-runner/capabilities.ts +78 -78
  135. package/src/runtime/task-runner/live-executor.ts +7 -1
  136. package/src/runtime/task-runner/progress.ts +119 -119
  137. package/src/runtime/task-runner/prompt-builder.ts +1 -1
  138. package/src/runtime/task-runner/prompt-pipeline.ts +64 -64
  139. package/src/runtime/task-runner/result-utils.ts +14 -14
  140. package/src/runtime/task-runner/run-projection.ts +103 -103
  141. package/src/runtime/task-runner/state-helpers.ts +22 -22
  142. package/src/runtime/team-runner.ts +126 -7
  143. package/src/runtime/worker-heartbeat.ts +21 -21
  144. package/src/runtime/worker-startup.ts +57 -57
  145. package/src/runtime/workflow-state.ts +187 -0
  146. package/src/runtime/workspace-tree.ts +298 -298
  147. package/src/schema/config-schema.ts +12 -0
  148. package/src/schema/validation-types.ts +148 -0
  149. package/src/skills/skill-templates.ts +374 -0
  150. package/src/state/active-run-registry.ts +35 -11
  151. package/src/state/atomic-write.ts +33 -26
  152. package/src/state/contracts.ts +1 -0
  153. package/src/state/event-reconstructor.ts +217 -0
  154. package/src/state/locks.ts +2 -11
  155. package/src/state/mailbox.ts +4 -3
  156. package/src/state/state-store.ts +32 -14
  157. package/src/state/task-claims.ts +44 -44
  158. package/src/state/types.ts +9 -0
  159. package/src/state/usage.ts +29 -29
  160. package/src/subagents/async-entry.ts +1 -1
  161. package/src/subagents/index.ts +3 -3
  162. package/src/subagents/live/control.ts +1 -1
  163. package/src/subagents/live/manager.ts +1 -1
  164. package/src/subagents/live/realtime.ts +1 -1
  165. package/src/subagents/live/session-runtime.ts +1 -1
  166. package/src/subagents/manager.ts +1 -1
  167. package/src/subagents/spawn.ts +1 -1
  168. package/src/teams/team-serializer.ts +38 -38
  169. package/src/types/diff.d.ts +18 -18
  170. package/src/ui/crew-footer.ts +101 -101
  171. package/src/ui/crew-select-list.ts +111 -111
  172. package/src/ui/crew-widget.ts +9 -4
  173. package/src/ui/dashboard-panes/cancellation-pane.ts +42 -42
  174. package/src/ui/dashboard-panes/capability-pane.ts +59 -59
  175. package/src/ui/dashboard-panes/mailbox-pane.ts +35 -35
  176. package/src/ui/dashboard-panes/metrics-pane.ts +34 -34
  177. package/src/ui/dashboard-panes/progress-pane.ts +11 -0
  178. package/src/ui/dynamic-border.ts +25 -25
  179. package/src/ui/layout-primitives.ts +106 -106
  180. package/src/ui/loaders.ts +158 -158
  181. package/src/ui/powerbar-publisher.ts +6 -0
  182. package/src/ui/render-coalescer.ts +51 -51
  183. package/src/ui/render-diff.ts +119 -119
  184. package/src/ui/render-scheduler.ts +143 -143
  185. package/src/ui/run-action-dispatcher.ts +10 -1
  186. package/src/ui/spinner.ts +17 -17
  187. package/src/ui/status-colors.ts +58 -58
  188. package/src/ui/syntax-highlight.ts +116 -116
  189. package/src/ui/transcript-entries.ts +258 -258
  190. package/src/utils/completion-dedupe.ts +63 -63
  191. package/src/utils/frontmatter.ts +68 -68
  192. package/src/utils/git.ts +262 -262
  193. package/src/utils/ids.ts +17 -17
  194. package/src/utils/incremental-reader.ts +104 -104
  195. package/src/utils/names.ts +27 -27
  196. package/src/utils/redaction.ts +44 -44
  197. package/src/utils/safe-paths.ts +47 -47
  198. package/src/utils/scan-cache.ts +136 -136
  199. package/src/utils/sleep.ts +40 -26
  200. package/src/utils/task-name-generator.ts +337 -337
  201. package/src/workflows/validate-workflow.ts +40 -40
  202. package/src/worktree/branch-freshness.ts +45 -45
  203. package/src/worktree/worktree-manager.ts +11 -3
  204. package/teams/default.team.md +12 -12
  205. package/teams/fast-fix.team.md +11 -11
  206. package/teams/implementation.team.md +18 -18
  207. package/teams/parallel-research.team.md +14 -14
  208. package/teams/research.team.md +11 -11
  209. package/teams/review.team.md +12 -12
  210. package/workflows/default.workflow.md +30 -29
  211. package/workflows/fast-fix.workflow.md +23 -22
  212. package/workflows/implementation.workflow.md +43 -38
  213. package/workflows/parallel-research.workflow.md +46 -46
  214. package/workflows/research.workflow.md +22 -22
  215. package/workflows/review.workflow.md +30 -30
  216. package/docs/refactor-tasks-phase3.md +0 -394
  217. package/docs/refactor-tasks-phase4.md +0 -564
  218. package/docs/refactor-tasks-phase5.md +0 -402
  219. package/docs/refactor-tasks-phase6.md +0 -662
  220. package/docs/refactor-tasks.md +0 -1484
  221. package/docs/research/AGENT-EXECUTION-ARCHITECTURE.md +0 -261
  222. package/docs/research/AGENT-LIFECYCLE-COMPARISON.md +0 -111
  223. package/docs/research/AUDIT_OH_MY_PI.md +0 -261
  224. package/docs/research/AUDIT_PI_CREW.md +0 -457
  225. package/docs/research/CAVEMAN-DEEP-RESEARCH.md +0 -281
  226. package/docs/research/COMPARISON_OH_MY_PI_VS_PI_CREW.md +0 -264
  227. package/docs/research/DEEP-RESEARCH-PI-POWERBAR.md +0 -343
  228. package/docs/research/DEEP_RESEARCH_SUBAGENT_ARCHITECTURE.md +0 -480
  229. package/docs/research/GAP_CLOSURE_IMPLEMENTATION_PLAN.md +0 -354
  230. package/docs/research/IMPLEMENTATION_PLAN.md +0 -385
  231. package/docs/research/LIVE-SESSION-PRODUCTION-READY-PLAN.md +0 -502
  232. package/docs/research/OH-MY-PI-DEEP-RESEARCH-v14.7.6.md +0 -266
  233. package/docs/research/REMAINING-GAPS-PLAN.md +0 -363
  234. package/docs/research/SESSION-SUMMARY-2026-05-08.md +0 -146
  235. package/docs/research/UI-RESPONSIVENESS-AUDIT.md +0 -173
  236. package/docs/research-awesome-agent-skills-distillation.md +0 -100
  237. package/docs/research-extension-examples.md +0 -297
  238. package/docs/research-extension-system.md +0 -324
  239. package/docs/research-oh-my-pi-distillation.md +0 -369
  240. package/docs/research-optimization-plan.md +0 -548
  241. package/docs/research-phase10-distillation.md +0 -199
  242. package/docs/research-phase11-distillation.md +0 -201
  243. package/docs/research-phase8-operator-experience-plan.md +0 -819
  244. package/docs/research-phase9-observability-reliability-plan.md +0 -1190
  245. package/docs/research-pi-coding-agent.md +0 -357
  246. package/docs/research-source-pi-crew-reference.md +0 -174
  247. package/docs/research-ui-optimization-plan.md +0 -480
  248. package/docs/source-runtime-refactor-map.md +0 -107
  249. 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
- }