pi-crew 0.1.51 → 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.
- package/CHANGELOG.md +56 -1
- package/README.md +176 -781
- package/agents/analyst.md +11 -11
- package/agents/critic.md +11 -11
- package/agents/executor.md +11 -11
- package/agents/explorer.md +11 -11
- package/agents/planner.md +11 -11
- package/agents/reviewer.md +11 -11
- package/agents/security-reviewer.md +11 -11
- package/agents/test-engineer.md +11 -11
- package/agents/verifier.md +70 -11
- package/agents/writer.md +11 -11
- package/docs/actions-reference.md +595 -0
- package/docs/commands-reference.md +347 -0
- package/docs/runtime-flow.md +148 -148
- package/index.ts +6 -6
- package/package.json +99 -99
- package/skills/async-worker-recovery/SKILL.md +42 -42
- package/skills/context-artifact-hygiene/SKILL.md +52 -52
- package/skills/delegation-patterns/SKILL.md +54 -54
- package/skills/mailbox-interactive/SKILL.md +40 -40
- package/skills/model-routing-context/SKILL.md +39 -39
- package/skills/multi-perspective-review/SKILL.md +58 -58
- package/skills/observability-reliability/SKILL.md +41 -41
- package/skills/orchestration/SKILL.md +157 -157
- package/skills/ownership-session-security/SKILL.md +41 -41
- package/skills/pi-extension-lifecycle/SKILL.md +39 -39
- package/skills/requirements-to-task-packet/SKILL.md +63 -63
- package/skills/resource-discovery-config/SKILL.md +41 -41
- package/skills/runtime-state-reader/SKILL.md +44 -44
- package/skills/secure-agent-orchestration-review/SKILL.md +45 -45
- package/skills/state-mutation-locking/SKILL.md +42 -42
- package/skills/systematic-debugging/SKILL.md +67 -67
- package/skills/ui-render-performance/SKILL.md +39 -39
- package/skills/verification-before-done/SKILL.md +57 -57
- package/skills/worktree-isolation/SKILL.md +39 -39
- package/src/adapters/claude-adapter.ts +25 -0
- package/src/adapters/codex-adapter.ts +21 -0
- package/src/adapters/cursor-adapter.ts +17 -0
- package/src/adapters/export-util.ts +137 -0
- package/src/adapters/index.ts +15 -0
- package/src/adapters/registry.ts +18 -0
- package/src/adapters/types.ts +23 -0
- package/src/agents/agent-config.ts +2 -0
- package/src/agents/agent-search.ts +98 -98
- package/src/agents/discover-agents.ts +2 -1
- package/src/config/config.ts +13 -1
- package/src/config/drift-detector.ts +211 -0
- package/src/config/markers.ts +327 -0
- package/src/config/resilient-parser.ts +108 -0
- package/src/config/suggestions.ts +74 -0
- package/src/extension/cross-extension-rpc.ts +103 -94
- package/src/extension/project-init.ts +21 -1
- package/src/extension/register.ts +45 -14
- package/src/extension/registration/commands.ts +77 -8
- package/src/extension/registration/subagent-tools.ts +10 -1
- package/src/extension/registration/team-tool.ts +10 -1
- package/src/extension/registration/viewers.ts +48 -34
- package/src/extension/run-bundle-schema.ts +89 -89
- package/src/extension/run-import.ts +25 -1
- package/src/extension/run-index.ts +5 -1
- package/src/extension/run-maintenance.ts +142 -68
- package/src/extension/team-manager-command.ts +10 -1
- package/src/extension/team-tool/doctor.ts +28 -3
- package/src/extension/team-tool/handle-settings.ts +195 -188
- package/src/extension/team-tool/inspect.ts +41 -41
- package/src/extension/team-tool/intent-policy.ts +42 -42
- package/src/extension/team-tool/lifecycle-actions.ts +27 -8
- package/src/extension/team-tool/plan.ts +19 -19
- package/src/extension/team-tool/run.ts +12 -1
- package/src/extension/team-tool.ts +11 -1
- package/src/i18n.ts +184 -184
- package/src/observability/exporters/otlp-exporter.ts +92 -77
- package/src/prompt/prompt-runtime.ts +72 -72
- package/src/runtime/agent-memory.ts +72 -72
- package/src/runtime/agent-observability.ts +114 -114
- package/src/runtime/async-marker.ts +26 -26
- package/src/runtime/attention-events.ts +28 -28
- package/src/runtime/auto-resume.ts +100 -0
- package/src/runtime/background-runner.ts +11 -1
- package/src/runtime/cancellation-token.ts +89 -89
- package/src/runtime/cancellation.ts +61 -61
- package/src/runtime/capability-inventory.ts +116 -116
- package/src/runtime/child-pi.ts +7 -2
- package/src/runtime/compaction-summary.ts +271 -0
- package/src/runtime/completion-guard.ts +190 -190
- package/src/runtime/crash-recovery.ts +33 -0
- package/src/runtime/delta-conflict.ts +360 -0
- package/src/runtime/direct-run.ts +35 -35
- package/src/runtime/foreground-control.ts +82 -82
- package/src/runtime/green-contract.ts +46 -46
- package/src/runtime/group-join.ts +106 -106
- package/src/runtime/heartbeat-gradient.ts +28 -28
- package/src/runtime/heartbeat-watcher.ts +124 -124
- package/src/runtime/iteration-hooks.ts +262 -0
- package/src/runtime/live-agent-control.ts +88 -88
- package/src/runtime/live-control-realtime.ts +36 -36
- package/src/runtime/live-extension-bridge.ts +150 -150
- package/src/runtime/live-irc.ts +92 -92
- package/src/runtime/live-session-health.ts +100 -100
- package/src/runtime/loop-gates.ts +129 -0
- package/src/runtime/metric-parser.ts +40 -0
- package/src/runtime/notebook-helpers.ts +90 -90
- package/src/runtime/orphan-sentinel.ts +7 -7
- package/src/runtime/parallel-research.ts +44 -44
- package/src/runtime/phase-progress.ts +217 -0
- package/src/runtime/pi-args.ts +38 -11
- package/src/runtime/pi-json-output.ts +111 -111
- package/src/runtime/pi-spawn.ts +57 -7
- package/src/runtime/policy-engine.ts +79 -79
- package/src/runtime/post-checks.ts +122 -0
- package/src/runtime/progress-event-coalescer.ts +43 -43
- package/src/runtime/prose-compressor.ts +164 -164
- package/src/runtime/recovery-recipes.ts +74 -74
- package/src/runtime/result-extractor.ts +121 -121
- package/src/runtime/role-permission.ts +39 -39
- package/src/runtime/sensitive-paths.ts +2 -2
- package/src/runtime/session-resources.ts +25 -25
- package/src/runtime/session-snapshot.ts +59 -59
- package/src/runtime/session-usage.ts +79 -79
- package/src/runtime/sidechain-output.ts +29 -29
- package/src/runtime/stream-preview.ts +177 -177
- package/src/runtime/supervisor-contact.ts +59 -59
- package/src/runtime/task-display.ts +38 -38
- package/src/runtime/task-graph.ts +207 -0
- package/src/runtime/task-quality.ts +207 -0
- package/src/runtime/task-runner/capabilities.ts +78 -78
- package/src/runtime/task-runner/live-executor.ts +7 -1
- package/src/runtime/task-runner/progress.ts +119 -119
- package/src/runtime/task-runner/prompt-pipeline.ts +64 -64
- package/src/runtime/task-runner/result-utils.ts +14 -14
- package/src/runtime/task-runner/run-projection.ts +103 -103
- package/src/runtime/task-runner/state-helpers.ts +22 -22
- package/src/runtime/team-runner.ts +117 -7
- package/src/runtime/worker-heartbeat.ts +21 -21
- package/src/runtime/worker-startup.ts +57 -57
- package/src/runtime/workflow-state.ts +187 -0
- package/src/runtime/workspace-tree.ts +298 -298
- package/src/schema/config-schema.ts +11 -0
- package/src/schema/validation-types.ts +148 -0
- package/src/skills/skill-templates.ts +374 -0
- package/src/state/active-run-registry.ts +35 -11
- package/src/state/atomic-write.ts +33 -26
- package/src/state/contracts.ts +1 -0
- package/src/state/event-reconstructor.ts +217 -0
- package/src/state/locks.ts +2 -13
- package/src/state/mailbox.ts +4 -3
- package/src/state/state-store.ts +32 -14
- package/src/state/task-claims.ts +44 -44
- package/src/state/types.ts +9 -0
- package/src/state/usage.ts +29 -29
- package/src/subagents/async-entry.ts +1 -1
- package/src/subagents/index.ts +3 -3
- package/src/subagents/live/control.ts +1 -1
- package/src/subagents/live/manager.ts +1 -1
- package/src/subagents/live/realtime.ts +1 -1
- package/src/subagents/live/session-runtime.ts +1 -1
- package/src/subagents/manager.ts +1 -1
- package/src/subagents/spawn.ts +1 -1
- package/src/teams/team-serializer.ts +38 -38
- package/src/types/diff.d.ts +18 -18
- package/src/ui/crew-footer.ts +101 -101
- package/src/ui/crew-select-list.ts +111 -111
- package/src/ui/crew-widget.ts +5 -2
- package/src/ui/dashboard-panes/cancellation-pane.ts +42 -42
- package/src/ui/dashboard-panes/capability-pane.ts +59 -59
- package/src/ui/dashboard-panes/mailbox-pane.ts +35 -35
- package/src/ui/dashboard-panes/metrics-pane.ts +34 -34
- package/src/ui/dashboard-panes/progress-pane.ts +11 -0
- package/src/ui/dynamic-border.ts +25 -25
- package/src/ui/layout-primitives.ts +106 -106
- package/src/ui/loaders.ts +158 -158
- package/src/ui/render-coalescer.ts +51 -51
- package/src/ui/render-diff.ts +119 -119
- package/src/ui/render-scheduler.ts +143 -143
- package/src/ui/run-action-dispatcher.ts +10 -1
- package/src/ui/spinner.ts +17 -17
- package/src/ui/status-colors.ts +58 -58
- package/src/ui/syntax-highlight.ts +116 -116
- package/src/ui/transcript-entries.ts +258 -258
- package/src/utils/completion-dedupe.ts +63 -63
- package/src/utils/frontmatter.ts +68 -68
- package/src/utils/git.ts +262 -262
- package/src/utils/ids.ts +17 -17
- package/src/utils/incremental-reader.ts +104 -104
- package/src/utils/names.ts +27 -27
- package/src/utils/redaction.ts +44 -44
- package/src/utils/safe-paths.ts +47 -47
- package/src/utils/scan-cache.ts +136 -136
- package/src/utils/sleep.ts +40 -26
- package/src/utils/task-name-generator.ts +337 -337
- package/src/workflows/validate-workflow.ts +40 -40
- package/src/worktree/branch-freshness.ts +45 -45
- package/teams/default.team.md +12 -12
- package/teams/fast-fix.team.md +11 -11
- package/teams/implementation.team.md +18 -18
- package/teams/parallel-research.team.md +14 -14
- package/teams/research.team.md +11 -11
- package/teams/review.team.md +12 -12
- package/workflows/default.workflow.md +30 -29
- package/workflows/fast-fix.workflow.md +23 -22
- package/workflows/implementation.workflow.md +43 -43
- package/workflows/parallel-research.workflow.md +46 -46
- package/workflows/research.workflow.md +22 -22
- package/workflows/review.workflow.md +30 -30
- package/docs/refactor-tasks-phase3.md +0 -394
- package/docs/refactor-tasks-phase4.md +0 -564
- package/docs/refactor-tasks-phase5.md +0 -402
- package/docs/refactor-tasks-phase6.md +0 -662
- package/docs/refactor-tasks.md +0 -1484
- package/docs/research/AGENT-EXECUTION-ARCHITECTURE.md +0 -261
- package/docs/research/AGENT-LIFECYCLE-COMPARISON.md +0 -111
- package/docs/research/AUDIT_OH_MY_PI.md +0 -261
- package/docs/research/AUDIT_PI_CREW.md +0 -457
- package/docs/research/CAVEMAN-DEEP-RESEARCH.md +0 -281
- package/docs/research/COMPARISON_OH_MY_PI_VS_PI_CREW.md +0 -264
- package/docs/research/DEEP-RESEARCH-PI-POWERBAR.md +0 -343
- package/docs/research/DEEP_RESEARCH_SUBAGENT_ARCHITECTURE.md +0 -480
- package/docs/research/GAP_CLOSURE_IMPLEMENTATION_PLAN.md +0 -354
- package/docs/research/IMPLEMENTATION_PLAN.md +0 -385
- package/docs/research/LIVE-SESSION-PRODUCTION-READY-PLAN.md +0 -502
- package/docs/research/OH-MY-PI-DEEP-RESEARCH-v14.7.6.md +0 -266
- package/docs/research/REMAINING-GAPS-PLAN.md +0 -363
- package/docs/research/SESSION-SUMMARY-2026-05-08.md +0 -146
- package/docs/research/UI-RESPONSIVENESS-AUDIT.md +0 -173
- package/docs/research-awesome-agent-skills-distillation.md +0 -100
- package/docs/research-extension-examples.md +0 -297
- package/docs/research-extension-system.md +0 -324
- package/docs/research-oh-my-pi-distillation.md +0 -369
- package/docs/research-optimization-plan.md +0 -548
- package/docs/research-phase10-distillation.md +0 -199
- package/docs/research-phase11-distillation.md +0 -201
- package/docs/research-phase8-operator-experience-plan.md +0 -819
- package/docs/research-phase9-observability-reliability-plan.md +0 -1190
- package/docs/research-pi-coding-agent.md +0 -357
- package/docs/research-source-pi-crew-reference.md +0 -174
- package/docs/research-ui-optimization-plan.md +0 -480
- package/docs/source-runtime-refactor-map.md +0 -107
- 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
|
-
}
|