pi-crew 0.9.15 → 0.9.17

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 (432) hide show
  1. package/CHANGELOG.md +145 -0
  2. package/README.md +19 -0
  3. package/dist/build-meta.json +21790 -0
  4. package/dist/index.mjs +83070 -0
  5. package/dist/index.mjs.map +7 -0
  6. package/docs/A +358 -0
  7. package/docs/M-A +357 -0
  8. package/docs/REVIEW-FINDINGS-2026-06 +357 -0
  9. package/docs/Y +357 -0
  10. package/docs/a +357 -0
  11. package/docs/aA +358 -0
  12. package/docs/archive/README.md +91 -0
  13. package/docs/patterns/command-agent-skill.md +1 -1
  14. package/docs/skills/REFERENCE.md +0 -17
  15. package/docs//303/242mmaAAA/303/242 +357 -0
  16. package/index.bundle.ts +25 -0
  17. package/index.ts +95 -4
  18. package/package.json +15 -4
  19. package/skills/iterative-audit/SKILL.md +0 -1
  20. package/skills/widget-rendering/SKILL.md +17 -0
  21. package/src/adapters/claude-adapter.ts +1 -3
  22. package/src/adapters/export-util.ts +16 -16
  23. package/src/adapters/index.ts +5 -5
  24. package/src/agents/agent-config.ts +20 -14
  25. package/src/agents/agent-serializer.ts +1 -1
  26. package/src/agents/discover-agents.ts +83 -39
  27. package/src/benchmark/benchmark-runner.ts +51 -51
  28. package/src/benchmark/feedback-loop.ts +1 -1
  29. package/src/config/config.ts +166 -590
  30. package/src/config/defaults.ts +28 -2
  31. package/src/config/drift-detector.ts +11 -14
  32. package/src/config/markers.ts +201 -203
  33. package/src/config/resilient-parser.ts +14 -6
  34. package/src/config/role-tools.ts +3 -3
  35. package/src/config/suggestions.ts +5 -12
  36. package/src/config/types.ts +9 -25
  37. package/src/errors.ts +151 -157
  38. package/src/extension/action-suggestions.ts +54 -9
  39. package/src/extension/async-notifier.ts +43 -13
  40. package/src/extension/autonomous-policy.ts +77 -37
  41. package/src/extension/command-completions.ts +9 -8
  42. package/src/extension/context-status-injection.ts +14 -12
  43. package/src/extension/crew-autocomplete.ts +8 -16
  44. package/src/extension/crew-cleanup.ts +2 -1
  45. package/src/extension/crew-shortcuts.ts +9 -6
  46. package/src/extension/cross-extension-rpc.ts +136 -42
  47. package/src/extension/help.ts +1 -1
  48. package/src/extension/import-index.ts +10 -5
  49. package/src/extension/knowledge-injection.ts +88 -15
  50. package/src/extension/management.ts +89 -349
  51. package/src/extension/message-renderers.ts +3 -4
  52. package/src/extension/notification-router.ts +22 -5
  53. package/src/extension/notification-sink.ts +6 -3
  54. package/src/extension/pi-api.ts +17 -8
  55. package/src/extension/plan-orchestrate.ts +8 -27
  56. package/src/extension/project-init.ts +21 -6
  57. package/src/extension/register.ts +329 -975
  58. package/src/extension/registration/artifact-cleanup.ts +9 -4
  59. package/src/extension/registration/command-utils.ts +5 -1
  60. package/src/extension/registration/commands.ts +806 -314
  61. package/src/extension/registration/compaction-guard.ts +15 -15
  62. package/src/extension/registration/lifecycle.ts +259 -0
  63. package/src/extension/registration/observability.ts +293 -0
  64. package/src/extension/registration/subagent-helpers.ts +29 -7
  65. package/src/extension/registration/subagent-tools.ts +253 -44
  66. package/src/extension/registration/team-tool.ts +19 -84
  67. package/src/extension/registration/ui.ts +168 -0
  68. package/src/extension/registration/viewers.ts +64 -24
  69. package/src/extension/result-watcher.ts +18 -7
  70. package/src/extension/run-bundle-schema.ts +21 -6
  71. package/src/extension/run-export.ts +15 -6
  72. package/src/extension/run-import.ts +64 -29
  73. package/src/extension/run-index.ts +28 -9
  74. package/src/extension/run-maintenance.ts +32 -12
  75. package/src/extension/session-summary.ts +1 -1
  76. package/src/extension/team-manager-command.ts +64 -7
  77. package/src/extension/team-onboard.ts +151 -150
  78. package/src/extension/team-recommendation.ts +121 -21
  79. package/src/extension/team-tool/anchor.ts +31 -64
  80. package/src/extension/team-tool/api.ts +929 -141
  81. package/src/extension/team-tool/auto-summarize.ts +14 -26
  82. package/src/extension/team-tool/cache-control.ts +1 -5
  83. package/src/extension/team-tool/cancel.ts +138 -38
  84. package/src/extension/team-tool/chain-dispatch.ts +5 -13
  85. package/src/extension/team-tool/chain-executor.ts +29 -51
  86. package/src/extension/team-tool/config-patch.ts +1 -1
  87. package/src/extension/team-tool/context.ts +40 -20
  88. package/src/extension/team-tool/destructive-gate.ts +10 -5
  89. package/src/extension/team-tool/doctor.ts +170 -51
  90. package/src/extension/team-tool/explain.ts +228 -214
  91. package/src/extension/team-tool/failure-patterns.ts +3 -9
  92. package/src/extension/team-tool/goal-wrap.ts +71 -29
  93. package/src/extension/team-tool/goal.ts +185 -35
  94. package/src/extension/team-tool/handle-schedule.ts +34 -15
  95. package/src/extension/team-tool/handle-settings.ts +94 -56
  96. package/src/extension/team-tool/health-monitor.ts +27 -108
  97. package/src/extension/team-tool/inspect.ts +42 -9
  98. package/src/extension/team-tool/intent-policy.ts +4 -1
  99. package/src/extension/team-tool/lifecycle-actions.ts +244 -48
  100. package/src/extension/team-tool/orchestrate.ts +7 -18
  101. package/src/extension/team-tool/parallel-dispatch.ts +51 -29
  102. package/src/extension/team-tool/plan.ts +29 -5
  103. package/src/extension/team-tool/respond.ts +49 -16
  104. package/src/extension/team-tool/run-not-found.ts +3 -8
  105. package/src/extension/team-tool/run.ts +80 -317
  106. package/src/extension/team-tool/status.ts +135 -43
  107. package/src/extension/team-tool/workflow-manage.ts +92 -25
  108. package/src/extension/team-tool-types.ts +8 -1
  109. package/src/extension/team-tool.ts +142 -551
  110. package/src/extension/validate-resources.ts +39 -8
  111. package/src/hooks/registry.ts +66 -17
  112. package/src/hooks/types.ts +1 -1
  113. package/src/i18n.ts +25 -11
  114. package/src/observability/correlation.ts +17 -3
  115. package/src/observability/event-bus.ts +51 -56
  116. package/src/observability/event-to-metric.ts +117 -15
  117. package/src/observability/exporters/otlp-exporter.ts +56 -17
  118. package/src/observability/exporters/prometheus-exporter.ts +1 -1
  119. package/src/observability/metric-registry.ts +16 -4
  120. package/src/observability/metric-retention.ts +8 -2
  121. package/src/observability/metric-sink.ts +11 -3
  122. package/src/observability/metrics-primitives.ts +42 -9
  123. package/src/plugins/plugin-define.ts +2 -2
  124. package/src/plugins/plugin-registry.ts +25 -25
  125. package/src/plugins/plugins/index.ts +1 -1
  126. package/src/plugins/plugins/nextjs.ts +16 -16
  127. package/src/plugins/plugins/vite.ts +7 -11
  128. package/src/plugins/plugins/vitest.ts +6 -11
  129. package/src/runtime/adaptive-plan.ts +225 -40
  130. package/src/runtime/agent-control.ts +58 -15
  131. package/src/runtime/agent-memory.ts +15 -9
  132. package/src/runtime/agent-observability.ts +10 -2
  133. package/src/runtime/anchor-manager.ts +27 -25
  134. package/src/runtime/async-marker.ts +7 -1
  135. package/src/runtime/async-runner.ts +27 -23
  136. package/src/runtime/auto-summarize.ts +7 -13
  137. package/src/runtime/background-runner.ts +189 -251
  138. package/src/runtime/batch-barrier.ts +18 -16
  139. package/src/runtime/cancellation-token.ts +16 -6
  140. package/src/runtime/cancellation.ts +46 -8
  141. package/src/runtime/capability-inventory.ts +6 -4
  142. package/src/runtime/chain-parser.ts +44 -11
  143. package/src/runtime/chain-runner.ts +63 -69
  144. package/src/runtime/checkpoint.ts +12 -56
  145. package/src/runtime/child-pi.ts +343 -78
  146. package/src/runtime/coalesce-tasks.ts +268 -0
  147. package/src/runtime/code-summary.ts +71 -26
  148. package/src/runtime/compact-stages/index.ts +15 -5
  149. package/src/runtime/compact-stages/tail-capture-stage.ts +7 -2
  150. package/src/runtime/compact-stages/truncation-stage.ts +4 -1
  151. package/src/runtime/compaction-summary.ts +17 -10
  152. package/src/runtime/completion-guard.ts +33 -16
  153. package/src/runtime/crash-classification.ts +28 -7
  154. package/src/runtime/crash-recovery.ts +177 -37
  155. package/src/runtime/crew-agent-records.ts +193 -40
  156. package/src/runtime/crew-hooks.ts +9 -24
  157. package/src/runtime/cross-extension-rpc.ts +25 -23
  158. package/src/runtime/custom-tools/irc-tool.ts +43 -15
  159. package/src/runtime/custom-tools/submit-result-tool.ts +16 -5
  160. package/src/runtime/delivery-coordinator.ts +34 -7
  161. package/src/runtime/delta-conflict.ts +9 -21
  162. package/src/runtime/deterministic-ast.ts +1 -1
  163. package/src/runtime/diagnostic-export.ts +53 -20
  164. package/src/runtime/direct-run.ts +12 -2
  165. package/src/runtime/dwf-state-store.ts +1 -1
  166. package/src/runtime/dynamic-workflow-context.ts +186 -58
  167. package/src/runtime/dynamic-workflow-runner.ts +42 -20
  168. package/src/runtime/effectiveness.ts +16 -8
  169. package/src/runtime/errors/crew-errors.ts +7 -11
  170. package/src/runtime/event-stream-bridge.ts +9 -3
  171. package/src/runtime/foreground-control.ts +54 -14
  172. package/src/runtime/foreground-watchdog.ts +9 -6
  173. package/src/runtime/goal-achievement.ts +27 -10
  174. package/src/runtime/goal-evaluator.ts +54 -19
  175. package/src/runtime/goal-loop-runner.ts +280 -99
  176. package/src/runtime/goal-state-store.ts +27 -17
  177. package/src/runtime/green-contract.ts +11 -2
  178. package/src/runtime/group-join.ts +64 -31
  179. package/src/runtime/handoff-manager.ts +37 -42
  180. package/src/runtime/heartbeat-gradient.ts +10 -2
  181. package/src/runtime/heartbeat-watcher.ts +32 -6
  182. package/src/runtime/hidden-handoff.ts +12 -30
  183. package/src/runtime/important-line-classifier.ts +12 -2
  184. package/src/runtime/iteration-hooks.ts +25 -15
  185. package/src/runtime/live-agent-control.ts +55 -7
  186. package/src/runtime/live-agent-manager.ts +130 -27
  187. package/src/runtime/live-control-realtime.ts +23 -3
  188. package/src/runtime/live-irc.ts +4 -1
  189. package/src/runtime/live-session-health.ts +12 -4
  190. package/src/runtime/live-session-runtime.ts +379 -117
  191. package/src/runtime/manifest-cache.ts +28 -12
  192. package/src/runtime/mcp-proxy.ts +8 -16
  193. package/src/runtime/metric-parser.ts +1 -5
  194. package/src/runtime/model-fallback.ts +55 -18
  195. package/src/runtime/model-resolver.ts +2 -6
  196. package/src/runtime/model-scope.ts +19 -3
  197. package/src/runtime/notebook-helpers.ts +60 -62
  198. package/src/runtime/orphan-worker-registry.ts +37 -26
  199. package/src/runtime/output-validator.ts +18 -3
  200. package/src/runtime/overflow-recovery.ts +5 -4
  201. package/src/runtime/parallel-research.ts +29 -5
  202. package/src/runtime/parallel-utils.ts +9 -11
  203. package/src/runtime/path-overlap.ts +150 -0
  204. package/src/runtime/peer-dep.ts +12 -17
  205. package/src/runtime/per-write-validator.ts +1 -3
  206. package/src/runtime/phase-tracker.ts +342 -330
  207. package/src/runtime/pi-args.ts +26 -8
  208. package/src/runtime/pi-json-output.ts +1 -1
  209. package/src/runtime/pi-spawn.ts +30 -19
  210. package/src/runtime/pipeline-runner.ts +56 -55
  211. package/src/runtime/plan-templates.ts +5 -6
  212. package/src/runtime/policy-engine.ts +43 -7
  213. package/src/runtime/post-checks.ts +12 -4
  214. package/src/runtime/post-exit-stdio-guard.ts +2 -2
  215. package/src/runtime/process-lifecycle.ts +20 -10
  216. package/src/runtime/process-status.ts +16 -5
  217. package/src/runtime/progress-event-coalescer.ts +2 -1
  218. package/src/runtime/progress-tracker.ts +103 -103
  219. package/src/runtime/prose-compressor.ts +9 -11
  220. package/src/runtime/recovery-recipes.ts +118 -24
  221. package/src/runtime/replace.ts +25 -10
  222. package/src/runtime/resilient-edit.ts +10 -25
  223. package/src/runtime/result-extractor.ts +1 -2
  224. package/src/runtime/retry-executor.ts +20 -4
  225. package/src/runtime/retry-runner.ts +26 -50
  226. package/src/runtime/role-permission.ts +6 -1
  227. package/src/runtime/run-coalesced-task-group.ts +256 -0
  228. package/src/runtime/run-drift.ts +14 -15
  229. package/src/runtime/run-tracker.ts +6 -28
  230. package/src/runtime/runtime-policy.ts +1 -6
  231. package/src/runtime/runtime-resolver.ts +80 -15
  232. package/src/runtime/scheduler.ts +47 -18
  233. package/src/runtime/semaphore.ts +5 -7
  234. package/src/runtime/sensitive-paths.ts +2 -1
  235. package/src/runtime/session-usage.ts +1 -1
  236. package/src/runtime/settings-store.ts +16 -12
  237. package/src/runtime/sidechain-output.ts +6 -2
  238. package/src/runtime/single-agent-compose.ts +1 -4
  239. package/src/runtime/skill-effectiveness.ts +29 -97
  240. package/src/runtime/skill-instructions.ts +40 -83
  241. package/src/runtime/stale-reconciler.ts +73 -197
  242. package/src/runtime/stream-preview.ts +1 -1
  243. package/src/runtime/streaming-output.ts +1 -1
  244. package/src/runtime/subagent-manager.ts +86 -169
  245. package/src/runtime/subprocess-tool-registry.ts +4 -1
  246. package/src/runtime/supervisor-contact.ts +10 -5
  247. package/src/runtime/task-display.ts +19 -5
  248. package/src/runtime/task-graph-scheduler.ts +95 -21
  249. package/src/runtime/task-graph.ts +5 -11
  250. package/src/runtime/task-health.ts +54 -47
  251. package/src/runtime/task-id.ts +11 -18
  252. package/src/runtime/task-output-context.ts +265 -81
  253. package/src/runtime/task-packet.ts +12 -20
  254. package/src/runtime/task-quality.ts +6 -14
  255. package/src/runtime/task-runner/context-retrieval.ts +4 -13
  256. package/src/runtime/task-runner/live-executor.ts +114 -36
  257. package/src/runtime/task-runner/output-splitter.ts +152 -0
  258. package/src/runtime/task-runner/progress.ts +50 -12
  259. package/src/runtime/task-runner/prompt-builder.ts +31 -7
  260. package/src/runtime/task-runner/prompt-pipeline.ts +31 -7
  261. package/src/runtime/task-runner/result-utils.ts +3 -1
  262. package/src/runtime/task-runner/retrieval-orchestrator.ts +310 -0
  263. package/src/runtime/task-runner/run-projection.ts +27 -8
  264. package/src/runtime/task-runner/state-helpers.ts +29 -8
  265. package/src/runtime/task-runner/tail-read.ts +2 -6
  266. package/src/runtime/task-runner.ts +180 -326
  267. package/src/runtime/team-runner-artifacts.ts +13 -0
  268. package/src/runtime/team-runner.ts +456 -974
  269. package/src/runtime/tool-output-pruner.ts +6 -9
  270. package/src/runtime/tool-progress.ts +11 -21
  271. package/src/runtime/verification-gates.ts +33 -24
  272. package/src/runtime/verification-integrity.ts +1 -4
  273. package/src/runtime/verification-worktree.ts +62 -12
  274. package/src/runtime/worker-heartbeat.ts +5 -1
  275. package/src/runtime/worker-startup.ts +29 -5
  276. package/src/runtime/workflow-state.ts +17 -9
  277. package/src/runtime/workspace-lock.ts +30 -35
  278. package/src/runtime/workspace-tree.ts +20 -32
  279. package/src/runtime/yield-handler.ts +43 -9
  280. package/src/runtime/zombie-scanner.ts +5 -4
  281. package/src/schema/config-schema.ts +266 -172
  282. package/src/schema/team-tool-schema.ts +29 -74
  283. package/src/schema/validation-types.ts +25 -17
  284. package/src/skills/discover-skills.ts +35 -10
  285. package/src/skills/skill-templates.ts +109 -27
  286. package/src/skills/validate.ts +26 -8
  287. package/src/state/active-run-registry.ts +87 -28
  288. package/src/state/artifact-store.ts +9 -5
  289. package/src/state/atomic-write-v2.ts +85 -63
  290. package/src/state/atomic-write.ts +105 -26
  291. package/src/state/blob-store.ts +47 -20
  292. package/src/state/contracts.ts +20 -5
  293. package/src/state/crew-init.ts +5 -22
  294. package/src/state/decision-ledger.ts +19 -73
  295. package/src/state/event-log-rotation.ts +41 -15
  296. package/src/state/event-log.ts +168 -53
  297. package/src/state/event-reconstructor.ts +11 -1
  298. package/src/state/gitignore-manager.ts +2 -8
  299. package/src/state/health-store.ts +57 -57
  300. package/src/state/hook-instinct-bridge.ts +1 -1
  301. package/src/state/hook-integrations.ts +1 -1
  302. package/src/state/instinct-store.ts +17 -5
  303. package/src/state/jsonl-writer.ts +1 -1
  304. package/src/state/locks.ts +23 -9
  305. package/src/state/mailbox.ts +151 -28
  306. package/src/state/observation-store.ts +20 -14
  307. package/src/state/run-cache.ts +142 -135
  308. package/src/state/run-graph.ts +6 -15
  309. package/src/state/run-metrics.ts +5 -18
  310. package/src/state/schedule.ts +15 -9
  311. package/src/state/state-store.ts +129 -45
  312. package/src/state/task-claims.ts +12 -2
  313. package/src/state/tiered-eval.ts +52 -43
  314. package/src/state/types-eval.ts +2 -2
  315. package/src/state/types.ts +24 -20
  316. package/src/state/usage.ts +20 -4
  317. package/src/state/worker-atomic-writer.ts +6 -3
  318. package/src/subagents/index.ts +2 -2
  319. package/src/teams/discover-teams.ts +21 -6
  320. package/src/tools/safe-bash-extension.ts +5 -6
  321. package/src/tools/safe-bash.ts +10 -11
  322. package/src/types/new-api-types.ts +6 -10
  323. package/src/ui/agent-management-overlay.ts +52 -40
  324. package/src/ui/card-colors.ts +13 -4
  325. package/src/ui/crew-footer.ts +8 -7
  326. package/src/ui/crew-select-list.ts +1 -1
  327. package/src/ui/dashboard-panes/agents-pane.ts +41 -25
  328. package/src/ui/dashboard-panes/cancellation-pane.ts +1 -1
  329. package/src/ui/dashboard-panes/capability-pane.ts +32 -15
  330. package/src/ui/dashboard-panes/health-pane.ts +2 -1
  331. package/src/ui/dashboard-panes/metrics-pane.ts +4 -1
  332. package/src/ui/dashboard-panes/progress-pane.ts +12 -9
  333. package/src/ui/heartbeat-aggregator.ts +15 -4
  334. package/src/ui/keybinding-map.ts +40 -7
  335. package/src/ui/live-conversation-overlay.ts +36 -20
  336. package/src/ui/live-duration.ts +1 -4
  337. package/src/ui/live-run-sidebar.ts +88 -25
  338. package/src/ui/loaders.ts +2 -8
  339. package/src/ui/mascot.ts +20 -36
  340. package/src/ui/overlays/agent-picker-overlay.ts +11 -3
  341. package/src/ui/overlays/confirm-overlay.ts +4 -2
  342. package/src/ui/overlays/help-overlay.ts +25 -14
  343. package/src/ui/overlays/mailbox-compose-overlay.ts +48 -11
  344. package/src/ui/overlays/mailbox-compose-preview.ts +20 -5
  345. package/src/ui/overlays/mailbox-detail-overlay.ts +27 -6
  346. package/src/ui/pi-ui-compat.ts +7 -7
  347. package/src/ui/powerbar-publisher.ts +120 -42
  348. package/src/ui/render-diff.ts +10 -3
  349. package/src/ui/render-scheduler.ts +12 -4
  350. package/src/ui/run-action-dispatcher.ts +81 -18
  351. package/src/ui/run-dashboard.ts +172 -76
  352. package/src/ui/run-event-bus.ts +59 -37
  353. package/src/ui/run-snapshot-cache.ts +276 -86
  354. package/src/ui/settings-overlay.ts +361 -74
  355. package/src/ui/status-colors.ts +12 -1
  356. package/src/ui/syntax-highlight.ts +1 -1
  357. package/src/ui/theme-adapter.ts +16 -14
  358. package/src/ui/theme-discovery.ts +13 -2
  359. package/src/ui/tool-progress-formatter.ts +7 -7
  360. package/src/ui/tool-render.ts +128 -56
  361. package/src/ui/tool-renderers/brief-mode.ts +45 -27
  362. package/src/ui/tool-renderers/index.ts +109 -43
  363. package/src/ui/transcript-cache.ts +32 -6
  364. package/src/ui/transcript-entries.ts +25 -23
  365. package/src/ui/transcript-viewer.ts +78 -29
  366. package/src/ui/widget/index.ts +99 -40
  367. package/src/ui/widget/widget-formatters.ts +13 -6
  368. package/src/ui/widget/widget-model.ts +19 -8
  369. package/src/ui/widget/widget-renderer.ts +23 -13
  370. package/src/ui/widget/widget-types.ts +1 -1
  371. package/src/utils/bm25-search.ts +199 -199
  372. package/src/utils/conflict-detect.ts +22 -21
  373. package/src/utils/env-filter.ts +14 -7
  374. package/src/utils/file-coalescer.ts +5 -1
  375. package/src/utils/fingerprint.ts +3 -6
  376. package/src/utils/frontmatter.ts +3 -1
  377. package/src/utils/fs-watch.ts +2 -6
  378. package/src/utils/gh-protocol.ts +119 -44
  379. package/src/utils/git.ts +13 -15
  380. package/src/utils/guards.ts +2 -5
  381. package/src/utils/ids.ts +9 -2
  382. package/src/utils/incremental-reader.ts +14 -3
  383. package/src/utils/internal-error.ts +2 -1
  384. package/src/utils/names.ts +12 -3
  385. package/src/utils/paths.ts +49 -5
  386. package/src/utils/project-detector.ts +2 -2
  387. package/src/utils/redaction.ts +29 -19
  388. package/src/utils/resolve-shell.ts +9 -7
  389. package/src/utils/run-watcher-registry.ts +19 -31
  390. package/src/utils/safe-paths.ts +45 -24
  391. package/src/utils/scan-cache.ts +9 -2
  392. package/src/utils/session-utils.ts +2 -4
  393. package/src/utils/sleep.ts +12 -5
  394. package/src/utils/sse-parser.ts +5 -17
  395. package/src/utils/visual.ts +52 -32
  396. package/src/workflows/discover-workflows.ts +41 -109
  397. package/src/workflows/intermediate-store.ts +5 -21
  398. package/src/workflows/preflight-validator.ts +6 -33
  399. package/src/workflows/topology-analyzer.ts +5 -21
  400. package/src/workflows/workflow-config.ts +7 -6
  401. package/src/worktree/branch-freshness.ts +66 -8
  402. package/src/worktree/cleanup.ts +130 -20
  403. package/src/worktree/worktree-manager.ts +212 -69
  404. package/skills/artifact-analysis-loop/SKILL.md +0 -303
  405. package/skills/detection-pipeline-design/SKILL.md +0 -286
  406. package/skills/hunting-investigation-loop/SKILL.md +0 -402
  407. package/skills/incident-playbook-construction/SKILL.md +0 -384
  408. package/skills/security-review/SKILL.md +0 -561
  409. package/skills/threat-hypothesis-framework/SKILL.md +0 -176
  410. package/skills/ui-render-performance/SKILL.md +0 -58
  411. /package/docs/{followup-review-round3-2026-05-12.md → archive/followup-review-round3-2026-05-12.md} +0 -0
  412. /package/docs/{followup-review-round4-2026-05-13.md → archive/followup-review-round4-2026-05-13.md} +0 -0
  413. /package/docs/{pi-crew-bugs.md → archive/pi-crew-bugs.md} +0 -0
  414. /package/docs/{pi-crew-test-final.md → archive/pi-crew-test-final.md} +0 -0
  415. /package/docs/{pi-crew-test-results.md → archive/pi-crew-test-results.md} +0 -0
  416. /package/docs/{pi-crew-test-round2.md → archive/pi-crew-test-round2.md} +0 -0
  417. /package/docs/{pi-crew-test-round4.md → archive/pi-crew-test-round4.md} +0 -0
  418. /package/docs/{pi-crew-test-round5.md → archive/pi-crew-test-round5.md} +0 -0
  419. /package/docs/{pi-crew-test-round6.md → archive/pi-crew-test-round6.md} +0 -0
  420. /package/docs/{pi-crew-v0.5.10-audit-fix-plan.md → archive/pi-crew-v0.5.10-audit-fix-plan.md} +0 -0
  421. /package/docs/{pi-crew-v0.5.11-audit-fix-plan.md → archive/pi-crew-v0.5.11-audit-fix-plan.md} +0 -0
  422. /package/docs/{pi-crew-v0.5.12-audit-fix-plan.md → archive/pi-crew-v0.5.12-audit-fix-plan.md} +0 -0
  423. /package/docs/{pi-crew-v0.5.13-audit-fix-plan.md → archive/pi-crew-v0.5.13-audit-fix-plan.md} +0 -0
  424. /package/docs/{pi-crew-v0.5.14-audit-fix-plan.md → archive/pi-crew-v0.5.14-audit-fix-plan.md} +0 -0
  425. /package/docs/{pi-crew-v0.5.16-audit-fix-plan.md → archive/pi-crew-v0.5.16-audit-fix-plan.md} +0 -0
  426. /package/docs/{pi-crew-v0.5.17-audit-fix-plan.md → archive/pi-crew-v0.5.17-audit-fix-plan.md} +0 -0
  427. /package/docs/{pi-crew-v0.5.5-audit-fix-plan.md → archive/pi-crew-v0.5.5-audit-fix-plan.md} +0 -0
  428. /package/docs/{pi-crew-v0.5.9-audit-fix-plan.md → archive/pi-crew-v0.5.9-audit-fix-plan.md} +0 -0
  429. /package/docs/{pi-mono-opportunities.md → archive/pi-mono-opportunities.md} +0 -0
  430. /package/docs/{pi-mono-review.md → archive/pi-mono-review.md} +0 -0
  431. /package/docs/{pi-subagent4-comparison.md → archive/pi-subagent4-comparison.md} +0 -0
  432. /package/docs/{pi-subagents3-deep-analysis.md → archive/pi-subagents3-deep-analysis.md} +0 -0
@@ -47,13 +47,7 @@ export type CrewThemeColor =
47
47
  // Special
48
48
  | "bashMode";
49
49
 
50
- export type CrewThemeBg =
51
- | "selectedBg"
52
- | "userMessageBg"
53
- | "customMessageBg"
54
- | "toolPendingBg"
55
- | "toolSuccessBg"
56
- | "toolErrorBg";
50
+ export type CrewThemeBg = "selectedBg" | "userMessageBg" | "customMessageBg" | "toolPendingBg" | "toolSuccessBg" | "toolErrorBg";
57
51
 
58
52
  /** ANSI fallback values for theme color slots when the active theme doesn't define them. */
59
53
  export const THEME_COLOR_FALLBACKS: Record<CrewThemeColor, string> = {
@@ -102,10 +96,7 @@ export const THEME_COLOR_FALLBACKS: Record<CrewThemeColor, string> = {
102
96
 
103
97
  /** Map a thinking intensity level (0–5) to a theme color slot. */
104
98
  export function thinkingColorForLevel(level: number): CrewThemeColor {
105
- const slots: CrewThemeColor[] = [
106
- "thinkingOff", "thinkingMinimal", "thinkingLow",
107
- "thinkingMedium", "thinkingHigh", "thinkingXhigh",
108
- ];
99
+ const slots: CrewThemeColor[] = ["thinkingOff", "thinkingMinimal", "thinkingLow", "thinkingMedium", "thinkingHigh", "thinkingXhigh"];
109
100
  return slots[Math.min(Math.max(level, 0), 5)] ?? "thinkingOff";
110
101
  }
111
102
 
@@ -177,7 +168,14 @@ function callMaybeString(fn: unknown): string | undefined {
177
168
  function themeSignature(theme: object): string {
178
169
  const record = theme as Record<string, unknown>;
179
170
  const primitiveEntries = Object.entries(record)
180
- .filter(([_key, value]) => value === undefined || value === null || typeof value === "string" || typeof value === "number" || typeof value === "boolean")
171
+ .filter(
172
+ ([_key, value]) =>
173
+ value === undefined ||
174
+ value === null ||
175
+ typeof value === "string" ||
176
+ typeof value === "number" ||
177
+ typeof value === "boolean",
178
+ )
181
179
  .map(([key, value]) => `${key}:${String(value)}`)
182
180
  .sort();
183
181
  const colorMode = callMaybeString(record.getColorMode);
@@ -217,7 +215,8 @@ function startThemeSourceSubscription(theme: object, subscription: ThemeSourceSu
217
215
  if (typeof record.addEventListener === "function") {
218
216
  (record.addEventListener as (type: string, callback: () => void) => void)("change", emit);
219
217
  if (typeof record.removeEventListener === "function") {
220
- subscription.unsubscribeSource = () => (record.removeEventListener as (type: string, callback: () => void) => void)("change", emit);
218
+ subscription.unsubscribeSource = () =>
219
+ (record.removeEventListener as (type: string, callback: () => void) => void)("change", emit);
221
220
  }
222
221
  return;
223
222
  }
@@ -235,7 +234,10 @@ export function subscribeThemeChange(theme: unknown, callback: () => void): () =
235
234
  const key = theme;
236
235
  let subscription = themeSubscriptions.get(key);
237
236
  if (!subscription) {
238
- subscription = { callbacks: new Set(), lastSignature: themeSignature(key) };
237
+ subscription = {
238
+ callbacks: new Set(),
239
+ lastSignature: themeSignature(key),
240
+ };
239
241
  themeSubscriptions.set(key, subscription);
240
242
  startThemeSourceSubscription(key, subscription);
241
243
  }
@@ -61,7 +61,12 @@ export function discoverPiThemes(): PiThemeInfo[] {
61
61
  for (const name of BUILTIN_PI_THEMES) {
62
62
  if (seen.has(name)) continue;
63
63
  seen.add(name);
64
- out.push({ name, source: "builtin", displayName: name, mode: name === "light" ? "light" : "dark" });
64
+ out.push({
65
+ name,
66
+ source: "builtin",
67
+ displayName: name,
68
+ mode: name === "light" ? "light" : "dark",
69
+ });
65
70
  }
66
71
 
67
72
  // Custom themes from ~/.pi/agent/themes/
@@ -85,7 +90,13 @@ export function discoverPiThemes(): PiThemeInfo[] {
85
90
  // keep undefined
86
91
  }
87
92
  seen.add(name);
88
- out.push({ name, source: "custom", path: fullPath, displayName, mode });
93
+ out.push({
94
+ name,
95
+ source: "custom",
96
+ path: fullPath,
97
+ displayName,
98
+ mode,
99
+ });
89
100
  }
90
101
  }
91
102
  } catch {
@@ -24,10 +24,12 @@ const MAX_OUTPUT_LINE = 80;
24
24
 
25
25
  function pickActiveAgent(agents: CrewAgentRecord[] | undefined): CrewAgentRecord | undefined {
26
26
  if (!agents || agents.length === 0) return undefined;
27
- return agents.find((agent) => agent.status === "running")
28
- ?? agents.find((agent) => agent.status === "waiting")
29
- ?? agents.find((agent) => agent.status === "queued")
30
- ?? agents[agents.length - 1];
27
+ return (
28
+ agents.find((agent) => agent.status === "running") ??
29
+ agents.find((agent) => agent.status === "waiting") ??
30
+ agents.find((agent) => agent.status === "queued") ??
31
+ agents[agents.length - 1]
32
+ );
31
33
  }
32
34
 
33
35
  function totalTokens(agent: CrewAgentRecord): number {
@@ -52,9 +54,7 @@ function taskCounts(tasks: TeamTaskState[] | undefined): string | undefined {
52
54
  const completed = tasks.filter((t) => t.status === "completed").length;
53
55
  const buckets = new Map<string, number>();
54
56
  for (const task of tasks) buckets.set(task.status, (buckets.get(task.status) ?? 0) + 1);
55
- const summary = [...buckets.entries()]
56
- .map(([status, count]) => `${status}=${count}`)
57
- .join(" ");
57
+ const summary = [...buckets.entries()].map(([status, count]) => `${status}=${count}`).join(" ");
58
58
  return `tasks ${completed}/${total} done ${summary}`;
59
59
  }
60
60
 
@@ -9,8 +9,8 @@
9
9
  */
10
10
  import { Container, Spacer, Text, visibleWidth } from "@earendil-works/pi-tui";
11
11
  import type { CrewAgentRecord } from "../runtime/crew-agent-runtime.ts";
12
- import { replaceTabs } from "./render-diff.ts";
13
12
  import { truncateToWidth } from "../utils/visual.ts";
13
+ import { replaceTabs } from "./render-diff.ts";
14
14
 
15
15
  // ── Types ──────────────────────────────────────────────────────────────
16
16
  export interface Theme {
@@ -18,12 +18,20 @@ export interface Theme {
18
18
  bold(text: string): string;
19
19
  }
20
20
  export type ThemeColor = "success" | "error" | "warning" | "dim" | "toolTitle" | "accent" | "muted" | "text";
21
- export interface ToolRenderContext { expanded: boolean; lastComponent?: Container }
21
+ export interface ToolRenderContext {
22
+ expanded: boolean;
23
+ lastComponent?: Container;
24
+ }
22
25
  export type Component = Container | Text;
23
26
 
24
27
  export interface TeamToolResultDetails {
25
- action?: string; status?: string; runId?: string; goal?: string;
26
- team?: string; workflow?: string; error?: string;
28
+ action?: string;
29
+ status?: string;
30
+ runId?: string;
31
+ goal?: string;
32
+ team?: string;
33
+ workflow?: string;
34
+ error?: string;
27
35
  agentRecords?: CrewAgentRecord[];
28
36
  // FIX (Round 14): `results` is the legacy key used by some subagent
29
37
  // responses. Add it here so renderers can read either field without
@@ -31,7 +39,12 @@ export interface TeamToolResultDetails {
31
39
  results?: CrewAgentRecord[];
32
40
  }
33
41
  export interface AgentToolResultDetails {
34
- results?: Array<{ agentId?: string; status?: string; output?: string; error?: string }>;
42
+ results?: Array<{
43
+ agentId?: string;
44
+ status?: string;
45
+ output?: string;
46
+ error?: string;
47
+ }>;
35
48
  }
36
49
 
37
50
  /** Combined type for renderAgentToolResult — handles both nested details and flat result shapes */
@@ -55,7 +68,8 @@ export function formatTokens(n: number): string {
55
68
  export function formatDuration(ms: number): string {
56
69
  if (ms < 1000) return `${ms}ms`;
57
70
  if (ms < 60_000) return `${(ms / 1000).toFixed(1)}s`;
58
- const m = Math.floor(ms / 60_000), s = Math.floor((ms % 60_000) / 1000);
71
+ const m = Math.floor(ms / 60_000),
72
+ s = Math.floor((ms % 60_000) / 1000);
59
73
  return s > 0 ? `${m}m${s}s` : `${m}m`;
60
74
  }
61
75
 
@@ -79,17 +93,34 @@ export function truncLine(text: string, maxWidth: number): string {
79
93
 
80
94
  export function formatToolPreview(name: string, args: Record<string, unknown>): string {
81
95
  switch (name) {
82
- case "bash": case "safe_bash": return `$ ${((args.command as string) || "").slice(0, 80)}`;
83
- case "read": return `read ${(args.path as string) || ""}`;
84
- case "write": return `write ${(args.path as string) || ""}`;
85
- case "edit": return `edit ${(args.path as string) || ""}`;
86
- case "grep": case "find": return `${name} ${((args.pattern || args.path) as string) || ""}`;
87
- case "ls": return `ls ${(args.path as string) || "."}`;
88
- case "web_search": case "search": return `search "${((args.query as string) || "").slice(0, 60)}"`;
89
- case "web_fetch": case "fetch": return `fetch ${(args.url as string) || ""}`;
90
- case "team": return `team action=${(args.action as string) || ""}`;
91
- case "agent": return `agent ${(args.agent as string) || ""}`;
92
- default: { const s = JSON.stringify(args); return `${name} ${s.slice(0, 60)}`; }
96
+ case "bash":
97
+ case "safe_bash":
98
+ return `$ ${((args.command as string) || "").slice(0, 80)}`;
99
+ case "read":
100
+ return `read ${(args.path as string) || ""}`;
101
+ case "write":
102
+ return `write ${(args.path as string) || ""}`;
103
+ case "edit":
104
+ return `edit ${(args.path as string) || ""}`;
105
+ case "grep":
106
+ case "find":
107
+ return `${name} ${((args.pattern || args.path) as string) || ""}`;
108
+ case "ls":
109
+ return `ls ${(args.path as string) || "."}`;
110
+ case "web_search":
111
+ case "search":
112
+ return `search "${((args.query as string) || "").slice(0, 60)}"`;
113
+ case "web_fetch":
114
+ case "fetch":
115
+ return `fetch ${(args.url as string) || ""}`;
116
+ case "team":
117
+ return `team action=${(args.action as string) || ""}`;
118
+ case "agent":
119
+ return `agent ${(args.agent as string) || ""}`;
120
+ default: {
121
+ const s = JSON.stringify(args);
122
+ return `${name} ${s.slice(0, 60)}`;
123
+ }
93
124
  }
94
125
  }
95
126
 
@@ -98,42 +129,54 @@ export function formatToolPreview(name: string, args: Record<string, unknown>):
98
129
  /** team tool call: collapsed "team action='run' impl..." / expanded: header + goal */
99
130
  export function renderTeamToolCall(
100
131
  args: { action?: string; goal?: string; team?: string; workflow?: string },
101
- theme: Theme, context: ToolRenderContext,
132
+ theme: Theme,
133
+ context: ToolRenderContext,
102
134
  ): Component {
103
- const action = args.action || "", goal = args.goal || "";
135
+ const action = args.action || "",
136
+ goal = args.goal || "";
104
137
  const team = args.team ? ` ${theme.fg("dim", `(${args.team})`)}` : "";
105
138
 
106
139
  if (!context.expanded) {
107
140
  const preview = goal.length > 60 ? goal.slice(0, 60) + "…" : goal;
108
141
  return new Text(
109
142
  `${theme.fg("toolTitle", theme.bold("team"))} action=${theme.fg("accent", `'${action}'`)}${team}${theme.fg("dim", preview ? ` "${preview.replace(/\n/g, " ")}"` : "")}`,
110
- 0, 0,
143
+ 0,
144
+ 0,
111
145
  );
112
146
  }
113
147
  const c = context.lastComponent instanceof Container ? (context.lastComponent.clear(), context.lastComponent) : new Container();
114
148
  c.addChild(new Text(`${theme.fg("toolTitle", theme.bold("team"))} action=${theme.fg("accent", `'${action}'`)}${team}`, 0, 0));
115
- if (goal) { c.addChild(new Spacer(1)); c.addChild(new Text(theme.fg("text", goal), 0, 0)); }
149
+ if (goal) {
150
+ c.addChild(new Spacer(1));
151
+ c.addChild(new Text(theme.fg("text", goal), 0, 0));
152
+ }
116
153
  return c;
117
154
  }
118
155
 
119
156
  /** agent tool call: collapsed "Agent explorer..." / expanded: header + prompt */
120
157
  export function renderAgentToolCall(
121
158
  args: { agent?: string; prompt?: string; task?: string; cwd?: string },
122
- theme: Theme, context: ToolRenderContext,
159
+ theme: Theme,
160
+ context: ToolRenderContext,
123
161
  ): Component {
124
- const agentName = args.agent || "", prompt = args.prompt || args.task || "";
162
+ const agentName = args.agent || "",
163
+ prompt = args.prompt || args.task || "";
125
164
 
126
165
  if (!context.expanded) {
127
166
  const preview = prompt.length > 60 ? prompt.slice(0, 60) + "…" : prompt;
128
167
  return new Text(
129
168
  `${theme.fg("toolTitle", theme.bold("agent"))} ${theme.fg("accent", agentName)}${theme.fg("dim", preview ? ` "${preview.replace(/\n/g, " ")}"` : "")}`,
130
- 0, 0,
169
+ 0,
170
+ 0,
131
171
  );
132
172
  }
133
173
  const c = context.lastComponent instanceof Container ? (context.lastComponent.clear(), context.lastComponent) : new Container();
134
174
  const cwdLabel = args.cwd ? theme.fg("dim", ` (cwd: ${args.cwd})`) : "";
135
175
  c.addChild(new Text(`${theme.fg("toolTitle", theme.bold("agent"))} ${theme.fg("accent", agentName)}${cwdLabel}`, 0, 0));
136
- if (prompt) { c.addChild(new Spacer(1)); c.addChild(new Text(theme.fg("text", prompt), 0, 0)); }
176
+ if (prompt) {
177
+ c.addChild(new Spacer(1));
178
+ c.addChild(new Text(theme.fg("text", prompt), 0, 0));
179
+ }
137
180
  return c;
138
181
  }
139
182
 
@@ -146,23 +189,23 @@ export function renderAgentToolCall(
146
189
  * Tool log: "▸ bash: $ npm test" / " read: src/index.ts"
147
190
  * Usage: "↑12k ↓3k R45k W0 $0.023"
148
191
  */
149
- export function renderAgentProgress(
150
- record: CrewAgentRecord, theme: Theme, expanded: boolean, w: number,
151
- ): Container {
192
+ export function renderAgentProgress(record: CrewAgentRecord, theme: Theme, expanded: boolean, w: number): Container {
152
193
  const c = new Container();
153
194
  const prog = record.progress;
154
195
  const isRunning = record.status === "running";
155
196
  const isPending = record.status === "queued" || record.status === "waiting";
156
197
  const innerW = Math.max(20, w);
157
198
 
158
- const addLine = (content: string) =>
159
- c.addChild(new Text(expanded ? content : truncLine(content, innerW), 0, 0));
199
+ const addLine = (content: string) => c.addChild(new Text(expanded ? content : truncLine(content, innerW), 0, 0));
160
200
 
161
201
  // Status icon
162
- const icon = isRunning ? theme.fg("warning", "⟳")
163
- : isPending ? theme.fg("dim", "")
164
- : record.status === "completed" ? theme.fg("success", "✓")
165
- : theme.fg("error", "");
202
+ const icon = isRunning
203
+ ? theme.fg("warning", "")
204
+ : isPending
205
+ ? theme.fg("dim", "")
206
+ : record.status === "completed"
207
+ ? theme.fg("success", "✓")
208
+ : theme.fg("error", "✗");
166
209
 
167
210
  // Duration
168
211
  const durationMs = prog?.durationMs ?? computeDurationMs(record.startedAt, record.completedAt);
@@ -181,9 +224,7 @@ export function renderAgentProgress(
181
224
  if (prog?.recentTools?.length) {
182
225
  for (const tool of prog.recentTools) {
183
226
  const detail = tool.args ? `: ${tool.args}` : "";
184
- const line = tool.endedAt
185
- ? theme.fg("muted", ` ${tool.tool}${detail}`)
186
- : theme.fg("warning", `▸ ${tool.tool}${detail}`);
227
+ const line = tool.endedAt ? theme.fg("muted", ` ${tool.tool}${detail}`) : theme.fg("warning", `▸ ${tool.tool}${detail}`);
187
228
  addLine(line);
188
229
  }
189
230
  }
@@ -216,7 +257,10 @@ export function renderAgentProgress(
216
257
  if (usage?.cost) parts.push(theme.fg("dim", `$${usage.cost.toFixed(3)}`));
217
258
  const tokens = prog?.tokens ?? 0;
218
259
  if (tokens > 0) parts.push(theme.fg("dim", `${formatTokens(tokens)} ctx`));
219
- if (parts.length) { c.addChild(new Spacer(1)); addLine(parts.join(" ")); }
260
+ if (parts.length) {
261
+ c.addChild(new Spacer(1));
262
+ addLine(parts.join(" "));
263
+ }
220
264
 
221
265
  return c;
222
266
  }
@@ -243,7 +287,9 @@ interface TeamToolFlattenedDetails {
243
287
  /** team tool result: 'run' shows agent progress rows, else compact summary */
244
288
  export function renderTeamToolResult(
245
289
  result: { details?: TeamToolResultDetails; content?: unknown[] } & Record<string, unknown>,
246
- _options: unknown, theme: Theme, _context: unknown,
290
+ _options: unknown,
291
+ theme: Theme,
292
+ _context: unknown,
247
293
  ): Component {
248
294
  // Handle both nested details (result.details) and flattened result shape (details at root level)
249
295
  const d = (result as { details?: TeamToolResultDetails }).details;
@@ -264,7 +310,12 @@ export function renderTeamToolResult(
264
310
  // For 'run' action without records: show goal prominently with status badge
265
311
  if (flat.action === "run") {
266
312
  const goalText = flat.goal || "";
267
- const statusBadge = flat.status ? theme.fg(flat.status === "completed" ? "success" : flat.status === "failed" ? "error" : "warning", `[${flat.status}]`) + " " : "";
313
+ const statusBadge = flat.status
314
+ ? theme.fg(
315
+ flat.status === "completed" ? "success" : flat.status === "failed" ? "error" : "warning",
316
+ `[${flat.status}]`,
317
+ ) + " "
318
+ : "";
268
319
  return new Text(statusBadge + theme.fg("text", truncLine(goalText, 116)), 0, 0);
269
320
  }
270
321
  // For other actions: compact info line
@@ -301,7 +352,9 @@ export function renderTeamToolResult(
301
352
  /** agent tool result: shows agent output rows with status icons */
302
353
  export function renderAgentToolResult(
303
354
  result: { details?: AgentToolResultDetails; content?: unknown[] } & Record<string, unknown>,
304
- _options: unknown, theme: Theme, _context: unknown,
355
+ _options: unknown,
356
+ theme: Theme,
357
+ _context: unknown,
305
358
  ): Component {
306
359
  // Handle both nested details and flattened result shape
307
360
  const d = (result.details ?? result) as AgentResultData;
@@ -312,10 +365,14 @@ export function renderAgentToolResult(
312
365
  const results = d?.results;
313
366
  if (results?.length) {
314
367
  for (const item of results) {
315
- const icon = item.status === "completed" ? theme.fg("success", "✓")
316
- : item.status === "failed" ? theme.fg("error", "✗")
317
- : item.status === "running" ? theme.fg("warning", "")
318
- : theme.fg("dim", "");
368
+ const icon =
369
+ item.status === "completed"
370
+ ? theme.fg("success", "")
371
+ : item.status === "failed"
372
+ ? theme.fg("error", "✗")
373
+ : item.status === "running"
374
+ ? theme.fg("warning", "⟳")
375
+ : theme.fg("dim", "○");
319
376
  const label = item.agentId || "agent";
320
377
  c.addChild(new Text(`${icon} ${theme.fg("toolTitle", theme.bold(label))}`, 0, 0));
321
378
  if (item.error) {
@@ -335,10 +392,14 @@ export function renderAgentToolResult(
335
392
 
336
393
  // Handle single agent result shape: { agentId, runId, status, output }
337
394
  if (d?.agentId) {
338
- const icon = d.status === "completed" ? theme.fg("success", "✓")
339
- : d.status === "failed" ? theme.fg("error", "✗")
340
- : d.status === "running" ? theme.fg("warning", "")
341
- : theme.fg("dim", "");
395
+ const icon =
396
+ d.status === "completed"
397
+ ? theme.fg("success", "")
398
+ : d.status === "failed"
399
+ ? theme.fg("error", "✗")
400
+ : d.status === "running"
401
+ ? theme.fg("warning", "⟳")
402
+ : theme.fg("dim", "○");
342
403
  const label = d.agentId;
343
404
  c.addChild(new Text(`${icon} ${theme.fg("toolTitle", theme.bold(label))}`, 0, 0));
344
405
  if (d.error) {
@@ -347,8 +408,7 @@ export function renderAgentToolResult(
347
408
  const clean = truncLine(replaceTabs(String(d.error)), w - 2);
348
409
  c.addChild(new Text(theme.fg("error", ` Error: ${clean}`), 0, 0));
349
410
  } else if (d.output) {
350
- for (const line of d.output.split("\n").slice(0, 5))
351
- c.addChild(new Text(theme.fg("dim", ` ${truncLine(line, w - 2)}`), 0, 0));
411
+ for (const line of d.output.split("\n").slice(0, 5)) c.addChild(new Text(theme.fg("dim", ` ${truncLine(line, w - 2)}`), 0, 0));
352
412
  }
353
413
  return c;
354
414
  }
@@ -361,21 +421,33 @@ export function renderAgentToolResult(
361
421
  function extractText(content: unknown[] | undefined): string {
362
422
  if (!content) return "(no output)";
363
423
  if (!Array.isArray(content)) return String(content);
364
- return content.filter((c): c is Record<string, unknown> => typeof c === "object" && c !== null && (c as Record<string, unknown>).type === "text").map((c) => String((c as Record<string, unknown>).text ?? "")).join("\n") || "(no output)";
424
+ return (
425
+ content
426
+ .filter(
427
+ (c): c is Record<string, unknown> => typeof c === "object" && c !== null && (c as Record<string, unknown>).type === "text",
428
+ )
429
+ .map((c) => String((c as Record<string, unknown>).text ?? ""))
430
+ .join("\n") || "(no output)"
431
+ );
365
432
  }
366
433
 
367
434
  function parseArgs(argsStr: string | undefined): Record<string, unknown> {
368
435
  if (!argsStr) return {};
369
436
  try {
370
437
  const p = JSON.parse(argsStr);
371
- return typeof p === "object" && p !== null ? p as Record<string, unknown> : {};
372
- } catch { return {}; }
438
+ return typeof p === "object" && p !== null ? (p as Record<string, unknown>) : {};
439
+ } catch {
440
+ return {};
441
+ }
373
442
  }
374
443
 
375
444
  function computeDurationMs(startedAt: string, completedAt?: string): number {
376
445
  if (!startedAt) return 0;
377
446
  const start = new Date(startedAt).getTime();
378
447
  if (isNaN(start)) return 0;
379
- if (completedAt) { const end = new Date(completedAt).getTime(); return isNaN(end) ? 0 : Math.max(0, end - start); }
448
+ if (completedAt) {
449
+ const end = new Date(completedAt).getTime();
450
+ return isNaN(end) ? 0 : Math.max(0, end - start);
451
+ }
380
452
  return Math.max(0, Date.now() - start);
381
- }
453
+ }
@@ -6,9 +6,9 @@
6
6
  * session reloads via pi.appendEntry().
7
7
  */
8
8
 
9
- import type { CrewTheme } from "../theme-adapter.ts";
10
- import { formatTokens, formatDuration, truncLine } from "../tool-render.ts";
11
9
  import type { CrewAgentRecord } from "../../runtime/crew-agent-runtime.ts";
10
+ import type { CrewTheme } from "../theme-adapter.ts";
11
+ import { formatDuration, formatTokens, truncLine } from "../tool-render.ts";
12
12
 
13
13
  // ── State ──────────────────────────────────────────────────────────────
14
14
 
@@ -37,9 +37,12 @@ export function makeBriefEntry(enabled: boolean): BriefStateEntry {
37
37
  export function restoreBriefState(entries: Iterable<unknown>): void {
38
38
  for (const entry of entries) {
39
39
  if (
40
- typeof entry === "object" && entry !== null &&
41
- "type" in entry && (entry as Record<string, unknown>).type === "custom" &&
42
- "customType" in entry && (entry as Record<string, unknown>).customType === BRIEF_ENTRY_TYPE &&
40
+ typeof entry === "object" &&
41
+ entry !== null &&
42
+ "type" in entry &&
43
+ (entry as Record<string, unknown>).type === "custom" &&
44
+ "customType" in entry &&
45
+ (entry as Record<string, unknown>).customType === BRIEF_ENTRY_TYPE &&
43
46
  "data" in entry
44
47
  ) {
45
48
  const data = (entry as Record<string, unknown>).data;
@@ -58,16 +61,26 @@ export { BRIEF_ENTRY_TYPE };
58
61
  export function briefToolResult(toolName: string, result: { content?: unknown[] }, theme: CrewTheme): string {
59
62
  const text = extractText(result?.content);
60
63
  switch (toolName) {
61
- case "read": return briefRead(text, theme);
62
- case "bash": return briefBash(text, theme);
63
- case "edit": return briefEdit(text, theme);
64
- case "write": return briefWrite(text, theme);
65
- case "find": return briefFind(text, theme);
66
- case "grep": return briefGrep(text, theme);
67
- case "ls": return briefLs(text, theme);
68
- case "team": return briefTeam(result, theme);
69
- case "agent": return briefAgent(result, theme);
70
- default: return briefDefault(text, theme);
64
+ case "read":
65
+ return briefRead(text, theme);
66
+ case "bash":
67
+ return briefBash(text, theme);
68
+ case "edit":
69
+ return briefEdit(text, theme);
70
+ case "write":
71
+ return briefWrite(text, theme);
72
+ case "find":
73
+ return briefFind(text, theme);
74
+ case "grep":
75
+ return briefGrep(text, theme);
76
+ case "ls":
77
+ return briefLs(text, theme);
78
+ case "team":
79
+ return briefTeam(result, theme);
80
+ case "agent":
81
+ return briefAgent(result, theme);
82
+ default:
83
+ return briefDefault(text, theme);
71
84
  }
72
85
  }
73
86
 
@@ -96,9 +109,7 @@ function briefEdit(text: string, theme: CrewTheme): string {
96
109
  if (added === 0 && removed === 0) {
97
110
  return theme.fg("success", "→ edited");
98
111
  }
99
- return theme.fg("success", "→ edited ") +
100
- theme.fg("toolDiffAdded", `+${added} `) +
101
- theme.fg("toolDiffRemoved", `-${removed}`);
112
+ return theme.fg("success", "→ edited ") + theme.fg("toolDiffAdded", `+${added} `) + theme.fg("toolDiffRemoved", `-${removed}`);
102
113
  }
103
114
 
104
115
  function briefWrite(text: string, theme: CrewTheme): string {
@@ -127,13 +138,17 @@ function briefLs(text: string, theme: CrewTheme): string {
127
138
  function briefTeam(result: { content?: unknown[] }, theme: CrewTheme): string {
128
139
  // Try to extract structured details
129
140
  const details = (result as Record<string, unknown>).details ?? result;
130
- const d = typeof details === "object" && details !== null ? details as Record<string, unknown> : {};
141
+ const d = typeof details === "object" && details !== null ? (details as Record<string, unknown>) : {};
131
142
  const status = typeof d.status === "string" ? d.status : "";
132
143
  const runId = typeof d.runId === "string" ? d.runId : "";
133
- const icon = status === "completed" ? theme.fg("success", "✓")
134
- : status === "failed" ? theme.fg("error", "✗")
135
- : status === "running" ? theme.fg("warning", "")
136
- : theme.fg("dim", "");
144
+ const icon =
145
+ status === "completed"
146
+ ? theme.fg("success", "")
147
+ : status === "failed"
148
+ ? theme.fg("error", "✗")
149
+ : status === "running"
150
+ ? theme.fg("warning", "⟳")
151
+ : theme.fg("dim", "○");
137
152
 
138
153
  // Agent records summary
139
154
  const records = (d.agentRecords ?? d.results) as CrewAgentRecord[] | undefined;
@@ -154,12 +169,15 @@ function briefTeam(result: { content?: unknown[] }, theme: CrewTheme): string {
154
169
 
155
170
  function briefAgent(result: { content?: unknown[] }, theme: CrewTheme): string {
156
171
  const d = (result as Record<string, unknown>).details ?? result;
157
- const data = typeof d === "object" && d !== null ? d as Record<string, unknown> : {};
172
+ const data = typeof d === "object" && d !== null ? (d as Record<string, unknown>) : {};
158
173
  const status = typeof data.status === "string" ? data.status : "";
159
174
  const agentId = typeof data.agentId === "string" ? data.agentId : "agent";
160
- const icon = status === "completed" ? theme.fg("success", "\u2713")
161
- : status === "failed" ? theme.fg("error", "\u2717")
162
- : theme.fg("dim", "\u25CB");
175
+ const icon =
176
+ status === "completed"
177
+ ? theme.fg("success", "\u2713")
178
+ : status === "failed"
179
+ ? theme.fg("error", "\u2717")
180
+ : theme.fg("dim", "\u25CB");
163
181
  // P3: Show duration and tokens when available
164
182
  const parts: string[] = [agentId];
165
183
  if (data.durationMs) parts.push(formatDuration(data.durationMs as number));