pi-crew 0.6.3 → 0.7.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 (56) hide show
  1. package/CHANGELOG.md +84 -0
  2. package/README.md +80 -1
  3. package/docs/ui-optimization-plan.md +447 -0
  4. package/package.json +2 -1
  5. package/src/extension/knowledge-injection.ts +71 -0
  6. package/src/extension/pi-api.ts +47 -0
  7. package/src/extension/register.ts +32 -1
  8. package/src/extension/registration/commands.ts +65 -1
  9. package/src/extension/registration/compaction-guard.ts +154 -14
  10. package/src/extension/registration/subagent-tools.ts +8 -3
  11. package/src/extension/registration/team-tool.ts +18 -11
  12. package/src/extension/team-tool/handle-settings.ts +57 -0
  13. package/src/extension/team-tool/inspect.ts +4 -1
  14. package/src/extension/team-tool/plan.ts +8 -1
  15. package/src/extension/team-tool/run.ts +4 -3
  16. package/src/extension/team-tool-types.ts +2 -0
  17. package/src/runtime/intercom-bridge.ts +5 -1
  18. package/src/runtime/replace.ts +555 -0
  19. package/src/runtime/resilient-edit.ts +166 -0
  20. package/src/runtime/single-agent-compose.ts +87 -0
  21. package/src/runtime/team-runner.ts +23 -6
  22. package/src/schema/team-tool-schema.ts +6 -0
  23. package/src/state/session-state-map.ts +51 -0
  24. package/src/state/usage.ts +73 -0
  25. package/src/ui/card-colors.ts +126 -0
  26. package/src/ui/deploy-bundled-themes.ts +71 -0
  27. package/src/ui/powerbar-publisher.ts +1 -1
  28. package/src/ui/render-diff.ts +37 -3
  29. package/src/ui/settings-overlay.ts +70 -7
  30. package/src/ui/status-colors.ts +5 -1
  31. package/src/ui/syntax-highlight.ts +42 -23
  32. package/src/ui/theme-adapter.ts +80 -1
  33. package/src/ui/theme-discovery.ts +188 -0
  34. package/src/ui/tool-progress-formatter.ts +9 -5
  35. package/src/ui/tool-render.ts +4 -0
  36. package/src/ui/tool-renderers/brief-mode.ts +207 -0
  37. package/src/ui/tool-renderers/index.ts +640 -0
  38. package/src/ui/widget/index.ts +224 -0
  39. package/src/ui/widget/widget-formatters.ts +148 -0
  40. package/src/ui/widget/widget-model.ts +90 -0
  41. package/src/ui/widget/widget-renderer.ts +130 -0
  42. package/src/ui/widget/widget-types.ts +37 -0
  43. package/src/utils/guards.ts +110 -0
  44. package/themes/crew-catppuccin-latte.json +96 -0
  45. package/themes/crew-catppuccin-mocha.json +93 -0
  46. package/themes/crew-dark.json +90 -0
  47. package/themes/crew-dracula.json +83 -0
  48. package/themes/crew-gruvbox-dark.json +83 -0
  49. package/themes/crew-gruvbox-light.json +90 -0
  50. package/themes/crew-nord.json +85 -0
  51. package/themes/crew-one-dark.json +89 -0
  52. package/themes/crew-solarized-dark.json +90 -0
  53. package/themes/crew-solarized-light.json +92 -0
  54. package/themes/crew-tokyo-night.json +85 -0
  55. package/src/runtime/budget-tracker.ts +0 -354
  56. package/src/state/memory-store.ts +0 -244
package/CHANGELOG.md CHANGED
@@ -1,5 +1,89 @@
1
1
  # Changelog
2
2
 
3
+ ## [0.7.1] — Fix: Auto-Continue After Compaction (2026-06-15)
4
+
5
+ ### Bug Fix
6
+
7
+ - **`a??`** — **Compaction resilience actually works now.** The v0.7.0 fix (O10) only *appended a resume-directive entry* after compaction, but appending an entry does **not trigger an agent turn** — the session still waited for user input, so the user still had to type "continue". The real root cause: Pi's threshold auto-compaction (`_runAutoCompaction` reason=`threshold` willRetry=`false`) returns `this.agent.hasQueuedMessages()`, which is `false` when nothing is queued → the agent loop ends → Pi waits for input (documented: "NO auto-retry, user continues manually").
8
+
9
+ **Fix**: after `session_compact` fires, call `pi.sendUserMessage(continuationPrompt)`. Per Pi's API, `sendUserMessage` *always triggers a turn*. The agent automatically runs a new turn, sees the resume directive, calls `team status`, and continues the in-flight crew task — **zero manual intervention**.
10
+
11
+ - `buildContinuationPrompt()`: action-oriented prompt ("Context was compacted while crew tasks were in-flight. Continue the work — do not wait for me.")
12
+ - `triggerContinuation(pi, ctx, runs)`: fire-and-forget `sendUserMessage`, best-effort error handling
13
+ - Wired in both the reactive path (`session_compact` handler) and proactive path (`startCompact.onComplete`)
14
+ - Only fires when in-flight crew runs exist; non-crew compaction unaffected
15
+ - 6 new unit tests
16
+
17
+ ## [0.7.0] — Long-Term Roadmap: Compaction Resilience, Cost Visibility, Trust Trinity (2026-06-15)
18
+
19
+ This release implements Phase 0 + Phase 1 of the pi-crew long-term roadmap (a 10-round research synthesis), plus the single-agent cliff hedge. The organizing principle: **build trust and cliff-resilience, stay lean, delete before adding.**
20
+
21
+ ### Highlights
22
+
23
+ - **🛡️ Compaction resilience (O10)** — the #1 user pain ("after auto-compact, the task stops midway") is fixed. pi-crew now detects in-flight runs, injects an explicit resume directive into the compaction summary, and re-attaches after compaction. Tasks survive context compaction.
24
+ - **💰 Cost visibility (O1)** — `team summary <runId>` now shows a full cost report with per-role attribution and token breakdown. Multi-agent's #1 barrier is cost; now it's visible.
25
+ - **✋ Plan-level HITL for any workflow (O5)** — plan approval was locked to the `implementation` workflow; now any workflow honors `config.runtime.requirePlanApproval`, gating at the read-only→mutating (plan→execute) boundary.
26
+ - **🧠 Cross-run memory (O4)** — `.crew/knowledge.md` is auto-read and injected into every agent's system prompt. pi-crew "gets better the longer you use it." Radically downsized (~80 LOC) replacement for the deleted MemoryStore.
27
+ - **🎯 Single-agent cliff hedge (T0.5/T2.2)** — any workflow can be composed into a single sequential prompt (`team plan singleAgent=true`). Proves pi-crew's mission survives even if multi-agent is obsoleted by 1M+ token models.
28
+ - **🧹 2,335 LOC of dead code removed** — grep-verified unused BudgetTracker, MemoryStore, `.bak` files, disabled brief-mode.
29
+ - **🔌 Pi-api seam** — centralizes the 8-symbol Pi coupling surface in one file, hedging against Pi API churn.
30
+
31
+ ### Features (Phase 0 — Stabilize & Clean)
32
+
33
+ - **`dbb4b6c`** — Deleted `budget-tracker.ts` (353 LOC), `memory-store.ts` (244 LOC), `brief-tool-overrides.ts` (400 LOC, disabled since 0.6.4), 3× `.bak` files (1,338 LOC), and their tests. Net −2,918 LOC including tests.
34
+ - **`42c1442`** — **Compaction resilience (O10)**: `compaction-guard.ts` gained `collectInFlightRuns()`, `formatResumeDirective()`, and a new `session_compact` handler that re-injects a `crew:resume-directive` entry into the fresh post-compaction context + notifies the user. Covers both the proactive path and Pi's reactive auto-compact path.
35
+ - **`40caf9e`** — `src/extension/pi-api.ts`: a type-level seam re-exporting the 8 public-API symbols pi-crew uses (ExtensionAPI, ExtensionContext, ExtensionCommandContext, ToolDefinition, defineTool, createBashTool, AgentSessionEvent, BeforeAgentStartEvent) + `BUILT_AGAINST_PI_VERSION` constant for version-drift diagnostics.
36
+ - **`8f40b07`** — **Single-agent cliff hedge v0**: `single-agent-compose.ts` (~95 LOC). `orderSteps()` topologically sorts by dependsOn; `composeSingleAgentPrompt()` turns a workflow into one sequential execution prompt.
37
+
38
+ ### Features (Phase 1 — Trust Trinity)
39
+
40
+ - **`3184303`** — **Cost visibility (O1)**: `state/usage.ts` gained `formatTokens()`, `formatCost()`, `aggregateUsageByRole()`, and `formatCostReport()`. The `summary` action now includes a multi-line report with token split + per-role % breakdown.
41
+ - **`198994e`** — **Plan-level HITL (O5)**: `team-runner.ts` `requiresPlanApproval()` dropped the `workflow.name === "implementation"` constraint; `hasPendingMutatingTaskAtBoundary()` (new) gates at the plan→execute boundary for any workflow; `ensurePlanApprovalRequested()` is robust to a missing `assess` step and gives clearer approval guidance.
42
+ - **`0272d77`** — **Cross-run memory (O4)**: `knowledge-injection.ts` (~80 LOC) registers a `before_agent_start` hook that appends `.crew/knowledge.md` (truncated to 16KB) to every agent's system prompt — main session + each crew worker.
43
+
44
+ ### Features (Phase 2 — Lean Power)
45
+
46
+ - **`eeefe0a`** — **Single-agent runtime mode (T2.2)**: `singleAgent` boolean param on the `team plan` action. A Pi agent calling `team plan singleAgent=true` receives the full composed sequential prompt for any workflow. MCP tool consumption (T2.1) already existed for live-session workers (`mcp-proxy.ts`); verified and left in place rather than duplicated.
47
+
48
+ ### Upgrade Notes
49
+ - New config: `runtime.requirePlanApproval = true` enables plan-level approval gates on any workflow.
50
+ - New file: `.crew/knowledge.md` (optional) — write durable project knowledge; it's injected into every run.
51
+ - Cost report appears automatically in `team summary`. Budget *enforcement* (auto-stop) is intentionally deferred until cost-data accuracy is validated.
52
+
53
+ ## [0.6.4] — Visually Rich Tool Rendering: Merged Frames, Live Progress Bars (2026-06-14)
54
+
55
+ ### Highlights
56
+ - **Visually rich team & agent tool rendering** — framed cards with box-drawing borders, colored status badges, and structured layouts for `team` and `Agent` tool calls in the Pi TUI
57
+ - **Merged call+result into ONE connected frame** — previously `renderCall` and `renderResult` each drew a complete box, producing two disconnected frames. Now they split a single frame (top border + header from `renderCall`, content + bottom border from `renderResult`) that merge seamlessly in Pi's `Box(1,1)` container
58
+ - **Animated live progress bar during runs** — real-time task progress (`tasks completed=N/M`) parsed from streaming updates and rendered as a `████░░░░ N/M` bar with elapsed time, DURING the run (not after completion). Indeterminate "starting" phase uses an animated scanning bar
59
+ - **Compact summary after completion** — collapsed cards show `✓ crew run 3/3 done · 1m2s · 26k tok · $0.068` with expand hint (`⌘E`) and agent briefs (`✓ explorer · 45.0s · 8.0k tok`)
60
+ - **Crash fix on session resume** — `renderCall` was returning a `string` (from `buildFrame`), causing `TypeError: child.render is not a function` when Pi re-rendered stored tool calls on resume. Now wraps in `new Text(...)`
61
+
62
+ ### Bug Fixes
63
+ - **`5613ecc`** — **Critical crash fix**: `teamToolRenderer.renderCall` and `agentToolRenderer.renderCall` returned `buildFrame(...)` (a string), not a Component. Pi's `addChild(string)` stored the string in `children[]`, then `Box.render()` called `child.render(width)` on the string → crash. Only surfaced on resume because fast-completing tools got their `Text` result frame painted before the string call frame was rendered. Fixed by wrapping both renderers in `new Text(..., 0, 0)`.
64
+ - **`58ba6e5`** — Elapsed time miscalculation: Pi's `ctx.executionStarted` is a **boolean** flag (not a timestamp), so `Date.now() - true` produced ~56-year durations. Now timing is tracked via `ctx.state.briefStartedAt`.
65
+ - **`1c2cf71`** — Reverted `lastComponent` reuse: returning `ctx.lastComponent` and mutating its private `.text` field crashed on session resume (deserialized components lose prototype methods). Pi already calls `renderContainer.clear()` before each `updateDisplay()`, so single-frame streaming is guaranteed without reuse.
66
+ - **`7d01ebb`** — Typecheck fix: `agentToolRenderer.renderCall` had parameter named `_ctx` (unused convention) but `borderFromContext(ctx)` referenced `ctx` (`error TS2552`).
67
+
68
+ ### Reverts
69
+ - **`0763e67`** — **Disabled brief tool overrides**. Re-registering built-in tools (read/bash/edit/write/find/grep/ls) replaced Pi's superior native renderers (syntax highlighting, diff views, full file content) with inferior custom `fullRender()` output, and caused `renderCall`/`renderResult` to duplicate path/command info. The file is retained for reference; re-enable by uncommenting one line in `register.ts`.
70
+
71
+ ### Test Fixes
72
+ - **`39d1dc7`** — `AnimatedMascot` timing tests were flaky under CI load. The animation advances via `setInterval(20ms)` which is `unref()`'d; under `--test-concurrency=4` the unref'd timers get delayed, so a fixed 70ms wait wasn't always enough for one tick. Replaced fixed waits with polling loops (retry until the frame advances, up to 600ms). Applied to both cat and armin animation tests. Robust: finishes fast normally (~40ms), tolerates heavy load.
73
+
74
+ ### Features (UI)
75
+ - **`a7b703b`** — `parseStreamingProgress()` parses `tasks completed=N running=M` and `N/M done` formats from streaming progress text; `renderScanBar()` renders an animated bouncing bar for the indeterminate "starting" phase.
76
+ - **`9b1de38`** — `onRunStarted` now called in the async path of `run.ts` (was only in foreground path), so background runs attach the progress binder and show real-time progress instead of stuck "starting".
77
+ - **`5741d73`** — `formatCompactToolProgress` always includes the `tasks N/M done status=X` line even when an active agent is present (was skipped via `else if` bug).
78
+ - **`22d8132`** — `extractContentText` returns only the LAST text block (was `.join("\n")` on all blocks, causing stacked progress frames during streaming).
79
+ - **`3777fbc`** — `buildFrameTop()` / `buildFrameBottom()` split rendering so `renderCall` + `renderResult` merge into one connected frame; `borderFromContext(ctx)` keeps top and bottom border colors consistent (accent while running, green on success, red on error).
80
+ - **`9fa5153`** — Cost display in collapsed cards (`computeTotalCost()`), `⌘E` expand hint, agent briefs with duration/tokens, `shortenPath()` (`$HOME` → `~`), OSC 8 clickable paths (`linkPath()`).
81
+ - **`f9c9803`** — Frame width auto-adjusts to terminal via `process.stdout.columns`.
82
+
83
+ ### Stats
84
+ - 9 commits since v0.6.3
85
+ - CI green on Ubuntu, macOS, and Windows
86
+
3
87
  ## [0.6.3] — Cross-Platform CI, 87 Test Fixes, Worktree Validation, Heartbeat & Crash Fixes (2026-06-12)
4
88
 
5
89
  ### Highlights
package/README.md CHANGED
@@ -9,7 +9,29 @@ npm: pi-crew
9
9
  repo: https://github.com/baphuongna/pi-crew
10
10
  ```
11
11
 
12
- **v0.6.3**: See [CHANGELOG.md](CHANGELOG.md).
12
+ **v0.6.4**: See [CHANGELOG.md](CHANGELOG.md).
13
+
14
+ ### Highlights (v0.6.4 → v0.7.0)
15
+
16
+ This release implements **Phase 0 + Phase 1** of the long-term roadmap (synthesized from a 10-round research process), plus the **single-agent cliff hedge**. Principle: *build trust and cliff-resilience, stay lean, delete before adding.*
17
+
18
+ - **🛡️ Compaction resilience (O10)** — the #1 user pain ("after auto-compact, the task stops midway") is fixed. In-flight crew runs are detected, a resume directive is injected into the compaction summary, and tasks re-attach after compaction.
19
+ - **💰 Cost visibility (O1)** — `team summary <runId>` now shows a full cost report with per-role attribution and token breakdown (`$0.77 — executor 79%, reviewer 14%...`).
20
+ - **✋ Plan-level HITL for any workflow (O5)** — set `runtime.requirePlanApproval = true` to gate any workflow at the plan→execute boundary; approve via `team api op=approve-plan`.
21
+ - **🧠 Cross-run memory (O4)** — `.crew/knowledge.md` is auto-injected into every run's system prompt. pi-crew remembers project context across runs.
22
+ - **🎯 Single-agent cliff hedge** — `team plan singleAgent=true` composes any workflow into one sequential prompt, so pi-crew's mission survives even if multi-agent is obsoleted by large-context models.
23
+ - **🧹 2,335 LOC of dead code removed** + **Pi-api seam** centralizing the coupling surface.
24
+
25
+ ### Highlights (v0.6.3 → v0.6.4)
26
+
27
+ - **Visually rich tool rendering** — `team` and `Agent` tool calls now render as framed cards in the Pi TUI with box-drawing borders, colored status badges, and structured layouts
28
+ - **Merged call+result into ONE connected frame** — the call header and result body now form a single seamless frame instead of two disconnected boxes
29
+ - **Animated live progress bar during runs** — real-time `████░░░░ N/M` task progress with elapsed time, rendered DURING the run; indeterminate "starting" phase uses an animated scanning bar
30
+ - **Compact completion summary** — collapsed cards show `✓ crew run 3/3 done · 1m2s · 26k tok · $0.068` with expand hint and per-agent briefs
31
+ - **Critical crash fix on session resume** — `renderCall` was returning a `string` instead of a `Text` component, causing `TypeError: child.render is not a function` when Pi re-rendered stored tool calls
32
+ - **Disabled brief tool overrides** — reverted the experimental brief mode that replaced Pi's superior native renderers (syntax highlighting, diff views, full content)
33
+ - **Flaky test fix** — `AnimatedMascot` timing tests made CI-load-robust via polling loops
34
+ - **CI green** — 0 failures on Ubuntu, macOS, and Windows
13
35
 
14
36
  ### Highlights (v0.6.2 → v0.6.3)
15
37
 
@@ -249,6 +271,63 @@ If preconditions are not met, a friendly error message is returned instead of cr
249
271
 
250
272
  ---
251
273
 
274
+ ## Reliability & Trust
275
+
276
+ ### Compaction resilience
277
+
278
+ pi-crew survives Pi's context compaction. When the context is compacted (auto or manual), in-flight crew runs are detected and a **resume directive** is injected into the post-compaction context, so tasks continue instead of stalling. You'll see a notification like:
279
+
280
+ ```
281
+ Context compacted. 1 pi-crew run(s) still in-flight — use team status to continue.
282
+ ```
283
+
284
+ ### Plan-level human-in-the-loop (HITL)
285
+
286
+ Set `runtime.requirePlanApproval = true` to gate **any workflow** at the plan→execute boundary. After the read-only (planning) phases complete, the run pauses for explicit approval before mutating tasks run:
287
+
288
+ ```
289
+ team api op=approve-plan runId=<runId> # approve → execute
290
+ team api op=cancel-plan runId=<runId> # cancel
291
+ ```
292
+
293
+ This is plan-level (not per-step) — per-step gates would kill the parallelism that's pi-crew's point.
294
+
295
+ ### Cross-run memory (`.crew/knowledge.md`)
296
+
297
+ Create `.crew/knowledge.md` in your project root with durable learnings (code style, test commands, common pitfalls, past refactors). It's auto-read (up to 16KB) and injected into **every** agent's system prompt — the main session and each crew worker. pi-crew gets better the longer you use it.
298
+
299
+ ```markdown
300
+ # Project Knowledge
301
+ - Tests: run with `npm test` (not jest directly)
302
+ - Style: tabs, not spaces
303
+ - Auth refactor (2026-06): split auth.ts into session.ts + api.ts
304
+ ```
305
+
306
+ ### Cost visibility
307
+
308
+ Every `team summary <runId>` includes a per-role cost report:
309
+
310
+ ```
311
+ ═══ Cost Report ═══
312
+ Tokens: 134k (in 112k, out 5.7k, cache-write 16k)
313
+ Cost: $0.7700 across 18 turn(s)
314
+ By role:
315
+ executor (2 tasks): $0.6100 — 79%, 98k tok, 13 turns
316
+ reviewer (1 task): $0.1100 — 14%, 23k tok, 3 turns
317
+ ```
318
+
319
+ ### Single-agent mode (cliff hedge)
320
+
321
+ Any workflow can run single-agent instead of multi-agent — composing all phases into one sequential prompt:
322
+
323
+ ```
324
+ team plan team=default workflow=default goal="..." singleAgent=true
325
+ ```
326
+
327
+ This is pi-crew's cliff-resilient mode: the workflow definitions, phase structure, and artifact contracts survive even if a single large-context model outperforms multi-agent teams.
328
+
329
+ ---
330
+
252
331
  ## Tool Actions
253
332
 
254
333
  ```json
@@ -0,0 +1,447 @@
1
+ # pi-crew UI Optimization & Beautification Plan
2
+
3
+ > Based on deep analysis of oh-my-pi patterns + pi-crew current UI state.
4
+ > Date: 2026-06-12
5
+ > Status: Draft — awaiting approval
6
+
7
+ ## Current State
8
+
9
+ ### pi-crew UI (~7,800 lines across 45 files)
10
+
11
+ | Component | Lines | Status |
12
+ |---|---|---|
13
+ | `run-snapshot-cache.ts` | 827 | Complex, over-engineered |
14
+ | `settings-overlay.ts` | 723 | Functional |
15
+ | `crew-widget.ts` | 544 | **High complexity, hard to read** |
16
+ | `run-dashboard.ts` | 536 | Dense, many responsibilities |
17
+ | `mascot.ts` | 444 | Cute but bloated |
18
+ | `tool-render.ts` | 380 | **Needs pattern overhaul** |
19
+ | `theme-adapter.ts` | 190 | Defensive but verbose |
20
+
21
+ ### Key Problems
22
+
23
+ 1. **No theme color consistency** — `CrewThemeColor` has ~22 slots vs oh-my-pi's 40+
24
+ 2. **Tool rendering reimplements logic** — pi-brief's delegate-execute pattern is cleaner
25
+ 3. **Widget is monolithic** — 544 lines doing state management, rendering, caching, and formatting
26
+ 4. **No structured interaction** — `respond` action is free-text only; no `ask_user`-style schema
27
+ 5. **Raw ANSI codes in places** — mixing `theme.fg()` with `\x1b[38;5;2m`
28
+ 6. **No brief/compact mode** — all output is verbose, no toggle for condensed display
29
+ 7. **Checkpoint display is text-heavy** — run history shows full text vs compact stats
30
+
31
+ ---
32
+
33
+ ## Phase 1: Theme System Upgrade
34
+
35
+ **Priority**: HIGH — foundation for all other UI work
36
+ **Effort**: 2-3 days
37
+ **Risk**: LOW (additive changes, no breaking API)
38
+
39
+ ### 1.1 Expand Theme Color Slots
40
+
41
+ **Current** (`src/ui/theme-adapter.ts`):
42
+ ```typescript
43
+ export type CrewThemeColor =
44
+ | "accent" | "border" | "borderAccent" | "borderMuted"
45
+ | "success" | "error" | "warning" | "muted" | "dim" | "text"
46
+ | "toolDiffAdded" | "toolDiffRemoved" | "toolDiffContext"
47
+ | "syntaxKeyword" | "syntaxString" | "syntaxNumber"
48
+ | "syntaxComment" | "syntaxFunction" | "syntaxVariable"
49
+ | "syntaxType" | "syntaxOperator" | "syntaxPunctuation"
50
+ | "mdCodeBlock";
51
+ ```
52
+
53
+ **Target** — add from oh-my-pi's 40+ slots:
54
+ ```typescript
55
+ export type CrewThemeColor =
56
+ // Existing (keep)
57
+ | "accent" | "border" | "borderAccent" | "borderMuted"
58
+ | "success" | "error" | "warning" | "muted" | "dim" | "text"
59
+ | "toolDiffAdded" | "toolDiffRemoved" | "toolDiffContext"
60
+ | "syntaxKeyword" | "syntaxString" | "syntaxNumber"
61
+ | "syntaxComment" | "syntaxFunction" | "syntaxVariable"
62
+ | "syntaxType" | "syntaxOperator" | "syntaxPunctuation"
63
+ | "mdCodeBlock"
64
+ // NEW — message display
65
+ | "userMessageText" | "customMessageLabel"
66
+ // NEW — tool rendering
67
+ | "toolTitle" // already used in tool-render.ts but missing from type
68
+ | "toolOutput"
69
+ | "toolPending" | "toolSuccess" | "toolError"
70
+ // NEW — markdown
71
+ | "mdHeading" | "mdLink" | "mdCode" | "mdQuote" | "mdHr" | "mdListBullet"
72
+ // NEW — thinking gradient (6 levels)
73
+ | "thinkingOff" | "thinkingMinimal" | "thinkingLow"
74
+ | "thinkingMedium" | "thinkingHigh" | "thinkingXhigh"
75
+ // NEW — special
76
+ | "bashMode" | "thinkingText";
77
+
78
+ export type CrewThemeBg =
79
+ // Existing
80
+ | "selectedBg" | "userMessageBg" | "toolPendingBg" | "toolSuccessBg" | "toolErrorBg"
81
+ // NEW
82
+ | "customMessageBg";
83
+ ```
84
+
85
+ **Files to change**: `src/ui/theme-adapter.ts`
86
+
87
+ ### 1.2 Theme Color Fallback Map
88
+
89
+ Add default ANSI values for all new slots so widgets work even with minimal themes:
90
+
91
+ ```typescript
92
+ const THEME_FALLBACKS: Record<CrewThemeColor, string> = {
93
+ toolTitle: "\x1b[36m", // cyan
94
+ toolOutput: "\x1b[38;5;245m", // gray
95
+ toolPending: "\x1b[38;5;240m",
96
+ toolSuccess: "\x1b[32m",
97
+ toolError: "\x1b[31m",
98
+ mdHeading: "\x1b[33m", // yellow
99
+ mdLink: "\x1b[35m", // indigo
100
+ mdCode: "\x1b[32m", // green
101
+ // ... all new slots
102
+ };
103
+ ```
104
+
105
+ ### 1.3 Remove Raw ANSI from Business Logic
106
+
107
+ Find and replace all raw `\x1b[38;5;XXXm` in non-UI files with `theme.fg("slot", text)` calls.
108
+
109
+ **Files to audit**:
110
+ - `src/ui/tool-render.ts` — check for raw ANSI
111
+ - `src/extension/registration/commands.ts` — status line rendering
112
+ - `src/runtime/task-display.ts` — display formatting
113
+
114
+ ---
115
+
116
+ ## Phase 2: Tool Rendering Overhaul
117
+
118
+ **Priority**: HIGH — visible improvement to every tool call display
119
+ **Effort**: 2-3 days
120
+ **Risk**: MEDIUM (changes how tool calls look)
121
+
122
+ ### 2.1 Adopt Rendering-Only Override Pattern
123
+
124
+ **From oh-my-pi's pi-brief**: Register tool rendering that delegates execution to original.
125
+
126
+ **Current pi-crew approach** (`src/ui/tool-render.ts`):
127
+ - 380 lines of monolithic rendering functions
128
+ - Separate `renderTeamToolCall`, `renderAgentToolCall`, `renderTeamToolResult`, `renderAgentToolResult`
129
+ - Each function handles both collapsed and expanded mode internally
130
+
131
+ **Target**: Split into focused renderers using a registry pattern:
132
+
133
+ ```typescript
134
+ // src/ui/tool-renderers/index.ts
135
+ export interface ToolRenderer {
136
+ renderCall(args: unknown, theme: CrewTheme, expanded: boolean): Component;
137
+ renderResult(result: unknown, theme: CrewTheme, expanded: boolean): Component;
138
+ }
139
+
140
+ // src/ui/tool-renderers/team-renderer.ts
141
+ export const teamToolRenderer: ToolRenderer = {
142
+ renderCall(args, theme, expanded) { ... },
143
+ renderResult(result, theme, expanded) { ... },
144
+ };
145
+
146
+ // src/ui/tool-renderers/agent-renderer.ts
147
+ export const agentToolRenderer: ToolRenderer = { ... };
148
+ ```
149
+
150
+ ### 2.2 Compact Brief Mode for Tool Output
151
+
152
+ **From pi-brief**: Add a configurable "brief" toggle that shows one-line summaries.
153
+
154
+ ```typescript
155
+ // New: src/ui/tool-renderers/brief-mode.ts
156
+ export function briefResult(result: ToolResult, theme: CrewTheme): string {
157
+ // read → "→ 142 lines"
158
+ // bash → "→ done" or "→ 12 lines"
159
+ // edit → "→ edited +3 -1"
160
+ // write → "→ written"
161
+ // team → "→ 3/3 tasks · 1.2m · 45k tok"
162
+ // agent → "✓ explorer · 8 tools · 23.4s"
163
+ }
164
+ ```
165
+
166
+ Add `/crew-brief on|off` command and persist state via `pi.appendEntry()`.
167
+
168
+ ### 2.3 Team Tool Result — Compact Stats Display
169
+
170
+ **From pi-rewind's checkpoint display**: Show goal + task stats in one line.
171
+
172
+ **Current**:
173
+ ```
174
+ team action='run' (implementation) · status=completed · runId=team_2026... · goal="Investigate failing..."
175
+ ```
176
+
177
+ **Target** (compact):
178
+ ```
179
+ ✓ team/implementation · 3/3 tasks · 1.2m · ↑45k ↓12k · $0.042
180
+ ```
181
+
182
+ With expanded (Ctrl+O):
183
+ ```
184
+ ✓ team/implementation · 3/3 tasks · 1.2m · ↑45k ↓12k · $0.042
185
+ ├─ ✓ explorer · 8 tools · 23.4s · ↑12k ↓4k
186
+ ├─ ✓ executor · 15 tools · 41.2s · ↑22k ↓6k
187
+ └─ ✓ verifier · 5 tools · 12.1s · ↑11k ↓2k
188
+ ```
189
+
190
+ ---
191
+
192
+ ## Phase 3: Widget Refactor
193
+
194
+ **Priority**: MEDIUM — internal cleanup, same visual output
195
+ **Effort**: 3-4 days
196
+ **Risk**: MEDIUM (core display component)
197
+
198
+ ### 3.1 Split crew-widget.ts into Modules
199
+
200
+ **Current**: 544 lines monolith doing everything.
201
+
202
+ **Target structure**:
203
+ ```
204
+ src/ui/widget/
205
+ ├── index.ts # Public API: updateCrewWidget, stopCrewWidget
206
+ ├── widget-component.ts # CrewWidgetComponent class (~100 lines)
207
+ ├── widget-model.ts # Data fetching + caching (~100 lines)
208
+ ├── widget-renderer.ts # Line building + colorizing (~150 lines)
209
+ ├── widget-formatters.ts # formatTokens, formatDuration, agentStats (~100 lines)
210
+ └── widget-types.ts # Shared types
211
+ ```
212
+
213
+ ### 3.2 Adopt SessionStateMap Pattern
214
+
215
+ **From oh-my-pi**: Generic session-scoped state container instead of scattered maps.
216
+
217
+ ```typescript
218
+ // src/state/session-state-map.ts (new)
219
+ export class SessionStateMap<T> {
220
+ private map = new Map<string, T>();
221
+ getOrUndefined(sessionId: string): T | undefined { ... }
222
+ set(sessionId: string, value: T): void { ... }
223
+ delete(sessionId: string): void { ... }
224
+ }
225
+ ```
226
+
227
+ Use this in widget, dashboard, and live-agent-manager instead of separate `Map<string, ...>` instances.
228
+
229
+ ### 3.3 Render Coalescing Optimization
230
+
231
+ The widget currently rebuilds signature strings on every render call. Optimize:
232
+ - Pre-compute signatures when data changes, not on render
233
+ - Use a simple counter-based invalidation instead of string concatenation
234
+ - Eliminate `this.cacheSignature` string comparison in hot path
235
+
236
+ ---
237
+
238
+ ## Phase 4: Dashboard Polish
239
+
240
+ **Priority**: MEDIUM
241
+ **Effort**: 3-4 days
242
+ **Risk**: LOW
243
+
244
+ ### 4.1 Run History — Compact Checkpoint Style
245
+
246
+ **From pi-rewind**: Show runs with file-change statistics.
247
+
248
+ **Current** (status command output):
249
+ ```
250
+ Run: team_20260612100313...
251
+ Status: completed
252
+ Team: implementation
253
+ Goal: Fix failing tests
254
+ Tasks: 3/3
255
+ Duration: 5m23s
256
+ Tokens: 45.2k
257
+ ```
258
+
259
+ **Target** (compact):
260
+ ```
261
+ ✓ team_...3d7f implementation · Fix failing tests
262
+ 3/3 tasks · 5m23s · ↑45k ↓12k
263
+ 14 files +342 -87
264
+ ```
265
+
266
+ ### 4.2 Agent Progress — Thinking Level Visualization
267
+
268
+ **From oh-my-pi's thinking gradient**: Show thinking intensity with color gradient.
269
+
270
+ ```typescript
271
+ function thinkingColor(level: number, theme: CrewTheme): CrewThemeColor {
272
+ // level 0-5 → off, minimal, low, medium, high, xhigh
273
+ return ["thinkingOff", "thinkingMinimal", "thinkingLow",
274
+ "thinkingMedium", "thinkingHigh", "thinkingXhigh"][level];
275
+ }
276
+ ```
277
+
278
+ Apply to agent activity line when agent is "thinking..." (no tool call, just LLM processing).
279
+
280
+ ### 4.3 Dashboard Pane Improvements
281
+
282
+ **Agents pane**: Add compact/expanded toggle per agent
283
+ **Progress pane**: Use brief mode rendering from Phase 2
284
+ **Mailbox pane**: Add structured response schema option
285
+ **Health pane**: Color-code issues by severity
286
+
287
+ ---
288
+
289
+ ## Phase 5: Structured Interaction
290
+
291
+ **Priority**: MEDIUM
292
+ **Effort**: 4-5 days
293
+ **Risk**: MEDIUM (new feature)
294
+
295
+ ### 5.1 Structured Respond Action
296
+
297
+ **From pi-clarify**: Add schema validation to `respond` action.
298
+
299
+ ```typescript
300
+ // In team-tool/respond.ts
301
+ interface RespondOptions {
302
+ message: string;
303
+ // NEW: structured answer option
304
+ answer?: {
305
+ type: "select" | "text" | "confirm";
306
+ value: string | boolean;
307
+ label?: string;
308
+ };
309
+ }
310
+ ```
311
+
312
+ ### 5.2 Secret Rejection in Tool Inputs
313
+
314
+ **From pi-clarify's SECRET_WORDS**: Add to all tool inputs that accept user text.
315
+
316
+ ```typescript
317
+ const SECRET_PATTERNS = [
318
+ "api key", "apikey", "auth token", "cookie", "credential",
319
+ "password", "private key", "secret", "token",
320
+ ];
321
+ ```
322
+
323
+ Already partially done in `env-filter.ts`, but should extend to `goal`, `message`, `task` parameters.
324
+
325
+ ---
326
+
327
+ ## Phase 6: Code Quality from oh-my-pi
328
+
329
+ **Priority**: LOW-MEDIUM (foundation for long-term)
330
+ **Effort**: 2-3 days
331
+ **Risk**: LOW
332
+
333
+ ### 6.1 Type Guard Library
334
+
335
+ **From runtime-core**: Create `src/utils/guards.ts` with systematic type guards.
336
+
337
+ ```typescript
338
+ // src/utils/guards.ts
339
+ export function isRecord(value: unknown): value is Record<string, unknown> { ... }
340
+ export function isString(value: unknown): value is string { ... }
341
+ export function isNumber(value: unknown): value is number { ... }
342
+ export function isNonEmptyString(value: unknown): value is string { ... }
343
+ export function isArrayOf<T>(guard: (v: unknown) => v is T): (v: unknown) => v is readonly T[] { ... }
344
+ export function getStringField(value: unknown, key: string): string | undefined { ... }
345
+ export function getNumberField(value: unknown, key: number): number | undefined { ... }
346
+ export function errorMessage(err: unknown): string { ... }
347
+ ```
348
+
349
+ Replace scattered `typeof x === "string"` checks across codebase.
350
+
351
+ ### 6.2 No-Any Lint Rule
352
+
353
+ Add ESLint rule to enforce `unknown` over `any`:
354
+
355
+ ```javascript
356
+ // .eslintrc
357
+ {
358
+ "rules": {
359
+ "@typescript-eslint/no-explicit-any": "error",
360
+ "@typescript-eslint/no-unsafe-assignment": "error",
361
+ "@typescript-eslint/no-unsafe-call": "error"
362
+ }
363
+ }
364
+ ```
365
+
366
+ ### 6.3 mkdir-Based Locking (Optional)
367
+
368
+ **From pi-checkpoint**: Replace JSON token-based locks with `mkdir` atomic locks.
369
+
370
+ This is a bigger change — could be Phase 7 if needed.
371
+
372
+ ---
373
+
374
+ ## Implementation Order & Timeline
375
+
376
+ | Phase | Duration | Depends On | Impact |
377
+ |---|---|---|---|
378
+ | **Phase 1**: Theme System | 2-3 days | Nothing | Foundation for all UI |
379
+ | **Phase 2**: Tool Rendering | 2-3 days | Phase 1 | Every tool call looks better |
380
+ | **Phase 3**: Widget Refactor | 3-4 days | Phase 1 | Internal cleanup |
381
+ | **Phase 4**: Dashboard Polish | 3-4 days | Phase 1, 2 | Visible improvement |
382
+ | **Phase 5**: Structured Interaction | 4-5 days | Phase 2 | New feature |
383
+ | **Phase 6**: Code Quality | 2-3 days | Nothing | Long-term maintainability |
384
+
385
+ **Total estimated**: 16-22 days (can parallelize Phase 1+6, Phase 2+3)
386
+
387
+ ### Recommended Execution
388
+
389
+ ```
390
+ Week 1: Phase 1 (Theme) + Phase 6 (Code Quality) [parallel]
391
+ Week 2: Phase 2 (Tool Rendering)
392
+ Week 3: Phase 3 (Widget) + Phase 4 (Dashboard) [sequential]
393
+ Week 4: Phase 5 (Structured Interaction) + polish
394
+ ```
395
+
396
+ ---
397
+
398
+ ## Success Metrics
399
+
400
+ | Metric | Current | Target |
401
+ |---|---|---|
402
+ | Theme color slots | 22 | 40+ |
403
+ | Raw ANSI in business logic | ~15 instances | 0 |
404
+ | Widget lines of code | 544 | ~150 (per module) |
405
+ | Tool result compact display | N/A | All 7 tool types |
406
+ | Structured respond | Free text only | Schema-validated |
407
+ | `any` in production code | ~40 instances | 0 |
408
+ | Type guard reuse | Scattered | Centralized in guards.ts |
409
+
410
+ ---
411
+
412
+ ## Risks & Mitigations
413
+
414
+ | Risk | Mitigation |
415
+ |---|---|
416
+ | Theme slot additions break existing themes | All new slots have fallback ANSI values |
417
+ | Widget refactor breaks live updates | Keep same public API, refactor internals only |
418
+ | Brief mode confuses users | Default OFF, toggle via `/crew-brief on` |
419
+ | Structured respond breaks existing workflows | `message` field still accepts free text; `answer` is optional |
420
+ | No-any lint produces too many errors | Incremental: start with new files, then expand |
421
+
422
+ ---
423
+
424
+ ## Files to Create/Modify
425
+
426
+ ### New Files
427
+ - `src/ui/tool-renderers/index.ts`
428
+ - `src/ui/tool-renderers/team-renderer.ts`
429
+ - `src/ui/tool-renderers/agent-renderer.ts`
430
+ - `src/ui/tool-renderers/brief-mode.ts`
431
+ - `src/ui/widget/index.ts`
432
+ - `src/ui/widget/widget-component.ts`
433
+ - `src/ui/widget/widget-model.ts`
434
+ - `src/ui/widget/widget-renderer.ts`
435
+ - `src/ui/widget/widget-formatters.ts`
436
+ - `src/ui/widget/widget-types.ts`
437
+ - `src/state/session-state-map.ts`
438
+ - `src/utils/guards.ts`
439
+
440
+ ### Modified Files
441
+ - `src/ui/theme-adapter.ts` — expand color types + fallbacks
442
+ - `src/ui/tool-render.ts` — slim down, delegate to renderers
443
+ - `src/ui/crew-widget.ts` — split into widget/ modules
444
+ - `src/ui/run-dashboard.ts` — compact display + thinking gradient
445
+ - `src/ui/status-colors.ts` — add new status colors
446
+ - `src/extension/team-tool/respond.ts` — structured response option
447
+ - `src/extension/registration/commands.ts` — add `/crew-brief` command
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pi-crew",
3
- "version": "0.6.3",
3
+ "version": "0.7.1",
4
4
  "description": "Pi extension for coordinated AI teams, workflows, worktrees, and async task orchestration",
5
5
  "author": "baphuongna",
6
6
  "license": "MIT",
@@ -33,6 +33,7 @@
33
33
  "teams/",
34
34
  "workflows/",
35
35
  "skills/**/SKILL.md",
36
+ "themes/",
36
37
  "README.md",
37
38
  "AGENTS.md",
38
39
  "docs/",