pi-crew 0.6.3 → 0.6.4

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 CHANGED
@@ -1,5 +1,39 @@
1
1
  # Changelog
2
2
 
3
+ ## [0.6.4] — Visually Rich Tool Rendering: Merged Frames, Live Progress Bars (2026-06-14)
4
+
5
+ ### Highlights
6
+ - **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
7
+ - **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
8
+ - **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
9
+ - **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`)
10
+ - **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(...)`
11
+
12
+ ### Bug Fixes
13
+ - **`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)`.
14
+ - **`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`.
15
+ - **`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.
16
+ - **`7d01ebb`** — Typecheck fix: `agentToolRenderer.renderCall` had parameter named `_ctx` (unused convention) but `borderFromContext(ctx)` referenced `ctx` (`error TS2552`).
17
+
18
+ ### Reverts
19
+ - **`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`.
20
+
21
+ ### Test Fixes
22
+ - **`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.
23
+
24
+ ### Features (UI)
25
+ - **`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.
26
+ - **`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".
27
+ - **`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).
28
+ - **`22d8132`** — `extractContentText` returns only the LAST text block (was `.join("\n")` on all blocks, causing stacked progress frames during streaming).
29
+ - **`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).
30
+ - **`9fa5153`** — Cost display in collapsed cards (`computeTotalCost()`), `⌘E` expand hint, agent briefs with duration/tokens, `shortenPath()` (`$HOME` → `~`), OSC 8 clickable paths (`linkPath()`).
31
+ - **`f9c9803`** — Frame width auto-adjusts to terminal via `process.stdout.columns`.
32
+
33
+ ### Stats
34
+ - 9 commits since v0.6.3
35
+ - CI green on Ubuntu, macOS, and Windows
36
+
3
37
  ## [0.6.3] — Cross-Platform CI, 87 Test Fixes, Worktree Validation, Heartbeat & Crash Fixes (2026-06-12)
4
38
 
5
39
  ### Highlights
package/README.md CHANGED
@@ -9,7 +9,18 @@ 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.3 → v0.6.4)
15
+
16
+ - **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
17
+ - **Merged call+result into ONE connected frame** — the call header and result body now form a single seamless frame instead of two disconnected boxes
18
+ - **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
19
+ - **Compact completion summary** — collapsed cards show `✓ crew run 3/3 done · 1m2s · 26k tok · $0.068` with expand hint and per-agent briefs
20
+ - **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
21
+ - **Disabled brief tool overrides** — reverted the experimental brief mode that replaced Pi's superior native renderers (syntax highlighting, diff views, full content)
22
+ - **Flaky test fix** — `AnimatedMascot` timing tests made CI-load-robust via polling loops
23
+ - **CI green** — 0 failures on Ubuntu, macOS, and Windows
13
24
 
14
25
  ### Highlights (v0.6.2 → v0.6.3)
15
26
 
@@ -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.6.4",
4
4
  "description": "Pi extension for coordinated AI teams, workflows, worktrees, and async task orchestration",
5
5
  "author": "baphuongna",
6
6
  "license": "MIT",
@@ -61,7 +61,7 @@ import {
61
61
  type CrewWidgetState,
62
62
  stopCrewWidget,
63
63
  updateCrewWidget,
64
- } from "../ui/crew-widget.ts";
64
+ } from "../ui/widget/index.ts";
65
65
  import { summarizeHeartbeats } from "../ui/heartbeat-aggregator.ts";
66
66
  import {
67
67
  requestRender,
@@ -100,6 +100,7 @@ import {
100
100
  import { createJsonlSink, type NotificationSink } from "./notification-sink.ts";
101
101
  import { runArtifactCleanup } from "./registration/artifact-cleanup.ts";
102
102
  import { registerTeamCommands } from "./registration/commands.ts";
103
+ import { registerBriefToolOverrides } from "./registration/brief-tool-overrides.ts";
103
104
  import { registerCompactionGuard } from "./registration/compaction-guard.ts";
104
105
  import {
105
106
  __test__subagentSpawnParams,
@@ -1194,6 +1195,17 @@ export function registerPiTeams(pi: ExtensionAPI): void {
1194
1195
 
1195
1196
  pi.on("session_start", (_event, ctx) => {
1196
1197
  runArtifactCleanup(ctx.cwd);
1198
+
1199
+ // Restore brief mode state from session entries
1200
+ try {
1201
+ const entries = ctx.sessionManager?.getEntries?.();
1202
+ if (entries) {
1203
+ import("../ui/tool-renderers/brief-mode.ts").then(({ restoreBriefState }) => {
1204
+ restoreBriefState(entries);
1205
+ }).catch(() => {/* non-critical */});
1206
+ }
1207
+ } catch { /* non-critical */ }
1208
+
1197
1209
  time("register.session-start");
1198
1210
  cleanedUp = false;
1199
1211
  sessionGeneration++;
@@ -1974,6 +1986,12 @@ export function registerPiTeams(pi: ExtensionAPI): void {
1974
1986
 
1975
1987
  registerCleanupHandler(pi);
1976
1988
 
1989
+ // Brief tool overrides DISABLED: re-registering built-in tools replaced Pi's
1990
+ // superior native renderers (syntax highlighting, diff views, full file
1991
+ // content) with inferior custom ones, and caused renderCall/renderResult
1992
+ // to duplicate path/command info. Pi's native rendering is better.
1993
+ // To re-enable, uncomment: registerBriefToolOverrides(pi, process.cwd());
1994
+
1977
1995
  registerTeamCommands(pi, {
1978
1996
  startForegroundRun,
1979
1997
  abortForegroundRun,