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
@@ -1,13 +1,12 @@
1
+ import type { CrashClass } from "../runtime/crash-classification.ts";
2
+ import type { CrewAgentProgress } from "../runtime/crew-agent-runtime.ts";
3
+ import type { WorkerHeartbeatState } from "../runtime/worker-heartbeat.ts";
1
4
  import type { TeamRunStatus, TeamTaskStatus } from "./contracts.ts";
5
+ import type { CoherenceMark, RolloutEntry } from "./decision-ledger.ts";
2
6
  import type { TaskClaimState } from "./task-claims.ts";
3
- import type { WorkerHeartbeatState } from "../runtime/worker-heartbeat.ts";
4
- import type { CrewAgentProgress } from "../runtime/crew-agent-runtime.ts";
5
- import type { RolloutEntry, CoherenceMark } from "./decision-ledger.ts";
6
- import type { CrashClass } from "../runtime/crash-classification.ts";
7
- export type { RolloutEntry, CoherenceMark };
8
- export type { CrewAgentProgress };
9
7
 
10
8
  export type { TeamRunStatus, TeamTaskStatus } from "./contracts.ts";
9
+ export type { CoherenceMark, CrewAgentProgress, RolloutEntry };
11
10
 
12
11
  export interface ArtifactDescriptor {
13
12
  kind: "plan" | "prompt" | "result" | "summary" | "log" | "diff" | "patch" | "progress" | "notepad" | "metadata";
@@ -74,7 +73,17 @@ export interface TaskPacket {
74
73
  }
75
74
 
76
75
  export type PolicyDecisionAction = "retry" | "reassign" | "escalate" | "block" | "notify" | "cleanup" | "closeout" | "fail";
77
- export type PolicyDecisionReason = "task_failed" | "worker_stale" | "green_unsatisfied" | "limit_exceeded" | "run_complete" | "mailbox_timeout" | "review_rejected" | "branch_stale" | "scope_mismatch" | "ineffective_worker";
76
+ export type PolicyDecisionReason =
77
+ | "task_failed"
78
+ | "worker_stale"
79
+ | "green_unsatisfied"
80
+ | "limit_exceeded"
81
+ | "run_complete"
82
+ | "mailbox_timeout"
83
+ | "review_rejected"
84
+ | "branch_stale"
85
+ | "scope_mismatch"
86
+ | "ineffective_worker";
78
87
 
79
88
  export interface PolicyDecision {
80
89
  action: PolicyDecisionAction;
@@ -228,15 +237,7 @@ export interface UsageState {
228
237
  * stuck → running (only by `goal resume`, atomically via GoalStore.compareAndSetStatus)
229
238
  * stuck → cancelled (by the idle-timeout sweeper OR `goal stop`)
230
239
  */
231
- export type GoalLoopStatus =
232
- | "running"
233
- | "paused"
234
- | "stuck"
235
- | "achieved"
236
- | "max_turns"
237
- | "budget_exceeded"
238
- | "blocked"
239
- | "cancelled";
240
+ export type GoalLoopStatus = "running" | "paused" | "stuck" | "achieved" | "max_turns" | "budget_exceeded" | "blocked" | "cancelled";
240
241
 
241
242
  /** One evaluation by the goal-judge model after a turn. */
242
243
  export interface GoalVerdict {
@@ -274,9 +275,7 @@ export interface GoalLoopState {
274
275
  * `"none-text-only"` marks goals started in text-only verification mode
275
276
  * (no objective oracle → no snapshot taken).
276
277
  */
277
- verificationIntegrity?:
278
- | { snapshot: Record<string, string>; takenAt: string }
279
- | "none-text-only";
278
+ verificationIntegrity?: { snapshot: Record<string, string>; takenAt: string } | "none-text-only";
280
279
  evaluatorModel: string;
281
280
  workerModel?: string;
282
281
  /** subagent_type / agent name for worker turns (default "executor"). */
@@ -288,7 +287,12 @@ export interface GoalLoopState {
288
287
  /** The team-run of the current in-flight turn (for cancel/steer). */
289
288
  currentRunId?: string;
290
289
  verdicts: GoalVerdict[];
291
- history: { runId: string; outcome: string; learnedAt: string; turn: number }[];
290
+ history: {
291
+ runId: string;
292
+ outcome: string;
293
+ learnedAt: string;
294
+ turn: number;
295
+ }[];
292
296
  createdAt: string;
293
297
  updatedAt: string;
294
298
  /** Mirror of manifest.async for PID-liveness checks (cf. AsyncRunState). */
@@ -6,7 +6,11 @@ import type { TeamTaskState, UsageState } from "./types.ts";
6
6
  * prefix re-read on that one call — summing across turns would count it N times.
7
7
  * See: https://github.com/nichekate/pi-subagents3/issues/38
8
8
  */
9
- export type LifetimeUsage = { input: number; output: number; cacheWrite: number };
9
+ export type LifetimeUsage = {
10
+ input: number;
11
+ output: number;
12
+ cacheWrite: number;
13
+ };
10
14
 
11
15
  /** Sum of lifetime usage components, or 0 if undefined. */
12
16
  export function getLifetimeTotal(u?: LifetimeUsage): number {
@@ -80,7 +84,15 @@ export function aggregateUsageByRole(tasks: TeamTaskState[]): RoleUsage[] {
80
84
  const role = task.role || "unknown";
81
85
  let bucket = byRole.get(role);
82
86
  if (!bucket) {
83
- bucket = { role, input: 0, output: 0, cacheWrite: 0, cost: 0, turns: 0, taskCount: 0 };
87
+ bucket = {
88
+ role,
89
+ input: 0,
90
+ output: 0,
91
+ cacheWrite: 0,
92
+ cost: 0,
93
+ turns: 0,
94
+ taskCount: 0,
95
+ };
84
96
  byRole.set(role, bucket);
85
97
  }
86
98
  bucket.taskCount++;
@@ -105,7 +117,9 @@ export function formatCostReport(tasks: TeamTaskState[]): string {
105
117
  const totalTokens = (usage.input ?? 0) + (usage.output ?? 0) + (usage.cacheWrite ?? 0);
106
118
  const lines: string[] = [];
107
119
  lines.push("═══ Cost Report ═══");
108
- lines.push(`Tokens: ${formatTokens(totalTokens)} (in ${formatTokens(usage.input ?? 0)}, out ${formatTokens(usage.output ?? 0)}, cache-write ${formatTokens(usage.cacheWrite ?? 0)})`);
120
+ lines.push(
121
+ `Tokens: ${formatTokens(totalTokens)} (in ${formatTokens(usage.input ?? 0)}, out ${formatTokens(usage.output ?? 0)}, cache-write ${formatTokens(usage.cacheWrite ?? 0)})`,
122
+ );
109
123
  lines.push(`Cost: ${formatCost(usage.cost)}${usage.turns ? ` across ${usage.turns} turn(s)` : ""}`);
110
124
  if (byRole.length > 1) {
111
125
  lines.push("");
@@ -113,7 +127,9 @@ export function formatCostReport(tasks: TeamTaskState[]): string {
113
127
  for (const r of byRole) {
114
128
  const pct = usage.cost && usage.cost > 0 ? Math.round((r.cost / usage.cost) * 100) : 0;
115
129
  const tok = r.input + r.output + r.cacheWrite;
116
- lines.push(` ${r.role} (${r.taskCount} task${r.taskCount === 1 ? "" : "s"}): ${formatCost(r.cost)}${pct ? ` — ${pct}%` : ""}, ${formatTokens(tok)} tok, ${r.turns} turns`);
130
+ lines.push(
131
+ ` ${r.role} (${r.taskCount} task${r.taskCount === 1 ? "" : "s"}): ${formatCost(r.cost)}${pct ? ` — ${pct}%` : ""}, ${formatTokens(tok)} tok, ${r.turns} turns`,
132
+ );
117
133
  }
118
134
  }
119
135
  lines.push("");
@@ -20,10 +20,11 @@
20
20
  * { kind: "done", id }
21
21
  * { kind: "error", id, message }
22
22
  */
23
- import { Worker } from "node:worker_threads";
24
- import * as path from "node:path";
23
+
25
24
  import * as fs from "node:fs";
26
25
  import { createRequire } from "node:module";
26
+ import * as path from "node:path";
27
+ import { Worker } from "node:worker_threads";
27
28
 
28
29
  const require = createRequire(import.meta.url);
29
30
 
@@ -175,7 +176,9 @@ export function terminateWorkerAtomicWriter(): void {
175
176
  if (worker) {
176
177
  const w = worker;
177
178
  worker = undefined;
178
- w.terminate().catch(() => { /* ignore */ });
179
+ w.terminate().catch(() => {
180
+ /* ignore */
181
+ });
179
182
  }
180
183
  for (const [, entry] of pending) entry.reject(new Error("worker terminated"));
181
184
  pending.clear();
@@ -1,3 +1,3 @@
1
- export * from "./spawn.ts";
2
- export * from "./manager.ts";
3
1
  export * from "./async-entry.ts";
2
+ export * from "./manager.ts";
3
+ export * from "./spawn.ts";
@@ -1,10 +1,10 @@
1
1
  import * as fs from "node:fs";
2
2
  import * as path from "node:path";
3
3
  import type { ResourceSource } from "../agents/agent-config.ts";
4
- import type { TeamConfig, TeamRole } from "./team-config.ts";
5
4
  import { parseCsv, parseFrontmatter } from "../utils/frontmatter.ts";
6
5
  import { parseGitUrl } from "../utils/git.ts";
7
6
  import { packageRoot, projectCrewRoot, userPiRoot } from "../utils/paths.ts";
7
+ import type { TeamConfig, TeamRole } from "./team-config.ts";
8
8
 
9
9
  export interface TeamDiscoveryResult {
10
10
  builtin: TeamConfig[];
@@ -15,7 +15,10 @@ export interface TeamDiscoveryResult {
15
15
  function parseRoleSkills(value: string | undefined): string[] | false | undefined {
16
16
  if (!value) return undefined;
17
17
  if (value === "false") return false;
18
- const skills = value.split(",").map((entry) => entry.trim()).filter(Boolean);
18
+ const skills = value
19
+ .split(",")
20
+ .map((entry) => entry.trim())
21
+ .filter(Boolean);
19
22
  return skills.length ? skills : undefined;
20
23
  }
21
24
 
@@ -39,7 +42,12 @@ function parseRoleLine(line: string): TeamRole | undefined {
39
42
  return "";
40
43
  });
41
44
  const description = descriptionSource.replace(/\s+/g, " ").trim() || undefined;
42
- const maxConcurrency = metadata.maxConcurrency ? (() => { const p = Number.parseInt(metadata.maxConcurrency, 10); return p > 0 ? p : undefined; })() : undefined;
45
+ const maxConcurrency = metadata.maxConcurrency
46
+ ? (() => {
47
+ const p = Number.parseInt(metadata.maxConcurrency, 10);
48
+ return p > 0 ? p : undefined;
49
+ })()
50
+ : undefined;
43
51
  return {
44
52
  name,
45
53
  agent: metadata.agent ?? name,
@@ -54,7 +62,10 @@ function parseCost(value: string | undefined): "free" | "cheap" | "expensive" |
54
62
  return value === "free" || value === "cheap" || value === "expensive" ? value : undefined;
55
63
  }
56
64
 
57
- function parseTeamSource(rawSource: string | undefined, fallback: ResourceSource): { source: ResourceSource; sourceUrl: string | undefined } {
65
+ function parseTeamSource(
66
+ rawSource: string | undefined,
67
+ fallback: ResourceSource,
68
+ ): { source: ResourceSource; sourceUrl: string | undefined } {
58
69
  if (!rawSource) return { source: fallback, sourceUrl: undefined };
59
70
  const parsed = parseGitUrl(rawSource);
60
71
  if (!parsed) return { source: fallback, sourceUrl: undefined };
@@ -66,7 +77,10 @@ function parseTeamFile(filePath: string, source: ResourceSource): TeamConfig | u
66
77
  const content = fs.readFileSync(filePath, "utf-8");
67
78
  const { frontmatter, body } = parseFrontmatter(content);
68
79
  const name = frontmatter.name?.trim() || path.basename(filePath, ".team.md");
69
- const roles = body.split("\n").map(parseRoleLine).filter((role): role is TeamRole => role !== undefined);
80
+ const roles = body
81
+ .split("\n")
82
+ .map(parseRoleLine)
83
+ .filter((role): role is TeamRole => role !== undefined);
70
84
  const triggers = parseCsv(frontmatter.triggers ?? frontmatter.trigger);
71
85
  const useWhen = parseCsv(frontmatter.useWhen);
72
86
  const avoidWhen = parseCsv(frontmatter.avoidWhen);
@@ -92,7 +106,8 @@ function parseTeamFile(filePath: string, source: ResourceSource): TeamConfig | u
92
106
 
93
107
  function readTeamDir(dir: string, source: ResourceSource): TeamConfig[] {
94
108
  if (!fs.existsSync(dir)) return [];
95
- return fs.readdirSync(dir)
109
+ return fs
110
+ .readdirSync(dir)
96
111
  .filter((entry) => entry.endsWith(".team.md"))
97
112
  .map((entry) => parseTeamFile(path.join(dir, entry), source))
98
113
  .filter((team): team is TeamConfig => team !== undefined)
@@ -23,16 +23,15 @@ export default function safeBashExtension(pi: ExtensionAPI): void {
23
23
  pi.registerTool({
24
24
  name: "safe_bash",
25
25
  label: "Safe Bash",
26
- description:
27
- "Execute a bash command safely. Blocks dangerous commands like `rm -rf /`, `sudo`, `curl | sh`, etc.",
26
+ description: "Execute a bash command safely. Blocks dangerous commands like `rm -rf /`, `sudo`, `curl | sh`, etc.",
28
27
  parameters: Type.Object({
29
28
  command: Type.String({ description: "Bash command to execute" }),
30
29
  /** Timeout in seconds (optional). Default: no timeout. If exceeded, the command is killed. */
31
- timeout: Type.Optional(
32
- Type.Number({ description: "Timeout in seconds (optional)" }),
33
- ),
30
+ timeout: Type.Optional(Type.Number({ description: "Timeout in seconds (optional)" })),
34
31
  description: Type.Optional(
35
- Type.String({ description: "Description of what this command does (optional)" }),
32
+ Type.String({
33
+ description: "Description of what this command does (optional)",
34
+ }),
36
35
  ),
37
36
  }),
38
37
  async execute(toolCallId, params, signal, onUpdate, ctx) {
@@ -6,7 +6,6 @@
6
6
 
7
7
  import { logInternalError } from "../utils/internal-error.ts";
8
8
 
9
-
10
9
  // Backward-compatible pattern array (kept for getPatterns API)
11
10
  // IMPORTANT: Line 8 (rm pattern with nested quantifiers) has been replaced
12
11
  // with linear-time checking in isDangerous() to prevent ReDoS attacks.
@@ -112,7 +111,7 @@ function matchesDangerousRm(command: string): boolean {
112
111
  // Block dangerous system paths
113
112
  const rest = command.slice(p);
114
113
  if (/^\/etc[\/\s;]/.test(rest) || rest === "/etc") return true;
115
- if ((/^\/var\/(?!tmp)/.test(rest)) || rest === "/var") return true;
114
+ if (/^\/var\/(?!tmp)/.test(rest) || rest === "/var") return true;
116
115
  if (/^\/usr[\/\s;]/.test(rest) || rest === "/usr") return true;
117
116
  if (/^\/boot[\/\s;]/.test(rest) || rest === "/boot") return true;
118
117
  if (/^\/sys[\/\s;]/.test(rest) || rest === "/sys") return true;
@@ -231,8 +230,8 @@ export function isDangerous(command: string, options: SafeBashOptions = {}): str
231
230
 
232
231
  // Normalize: strip ANSI escapes and control chars, remove line continuations, collapse whitespace
233
232
  const normalized = command
234
- .replace(/\x1b\[[0-9;]*[a-zA-Z]/g, '') // strip ANSI escapes
235
- .replace(/[\x00-\x08\x0b\x0c\x0e-\x1f]/g, '') // strip control chars
233
+ .replace(/\x1b\[[0-9;]*[a-zA-Z]/g, "") // strip ANSI escapes
234
+ .replace(/[\x00-\x08\x0b\x0c\x0e-\x1f]/g, "") // strip control chars
236
235
  .replace(/\\\n/g, " ")
237
236
  .replace(/\s+/g, " ")
238
237
  .trim();
@@ -335,7 +334,11 @@ export function createSafeBash(options: SafeBashOptions = {}) {
335
334
  /**
336
335
  * Get all active patterns (for debugging/config display)
337
336
  */
338
- getPatterns(): { dangerous: RegExp[]; additional: RegExp[]; allow: RegExp[] } {
337
+ getPatterns(): {
338
+ dangerous: RegExp[];
339
+ additional: RegExp[];
340
+ allow: RegExp[];
341
+ } {
339
342
  return {
340
343
  dangerous: [...DANGEROUS_PATTERNS],
341
344
  additional: options.additionalPatterns || [],
@@ -391,11 +394,7 @@ export const SAFE_BASH_PRESETS = {
391
394
  permissive: {
392
395
  enabled: true,
393
396
  additionalPatterns: [],
394
- allowPatterns: [
395
- COMMON_SAFE_PATTERNS.safeRm,
396
- COMMON_SAFE_PATTERNS.safeGit,
397
- COMMON_SAFE_PATTERNS.safePackage,
398
- ],
397
+ allowPatterns: [COMMON_SAFE_PATTERNS.safeRm, COMMON_SAFE_PATTERNS.safeGit, COMMON_SAFE_PATTERNS.safePackage],
399
398
  },
400
399
  /** No safety checks */
401
400
  disabled: {
@@ -403,4 +402,4 @@ export const SAFE_BASH_PRESETS = {
403
402
  additionalPatterns: [],
404
403
  allowPatterns: [],
405
404
  },
406
- };
405
+ };
@@ -3,9 +3,7 @@
3
3
  */
4
4
  import type { AgentSessionEvent } from "@earendil-works/pi-coding-agent";
5
5
 
6
- export type {
7
- AgentSessionEvent,
8
- } from "@earendil-works/pi-coding-agent";
6
+ export type { AgentSessionEvent } from "@earendil-works/pi-coding-agent";
9
7
 
10
8
  // Note: AgentEvent is not exported by pi-coding-agent v0.77.0
11
9
  // Using AgentEndEvent and AgentStartEvent instead
@@ -13,27 +11,25 @@ export type {
13
11
  // Type guards for pi-crew usage
14
12
  /** @internal */
15
13
  function isToolEvent(event: AgentSessionEvent): boolean {
16
- return event.type === "tool_execution_start" ||
17
- event.type === "tool_execution_update" ||
18
- event.type === "tool_execution_end";
14
+ return event.type === "tool_execution_start" || event.type === "tool_execution_update" || event.type === "tool_execution_end";
19
15
  }
20
16
 
21
17
  /** @internal */
22
18
  function isAgentLifecycleEvent(event: AgentSessionEvent): boolean {
23
- return event.type === "agent_start" || event.type === "agent_end";
19
+ return event.type === "agent_start" || event.type === "agent_end";
24
20
  }
25
21
 
26
22
  /** @internal */
27
23
  function isCompactionEvent(event: AgentSessionEvent): boolean {
28
- return event.type === "compaction_start" || event.type === "compaction_end";
24
+ return event.type === "compaction_start" || event.type === "compaction_end";
29
25
  }
30
26
 
31
27
  /** @internal */
32
28
  function isRetryEvent(event: AgentSessionEvent): boolean {
33
- return event.type === "auto_retry_start" || event.type === "auto_retry_end";
29
+ return event.type === "auto_retry_start" || event.type === "auto_retry_end";
34
30
  }
35
31
 
36
32
  /** @internal */
37
33
  function isQueueEvent(event: AgentSessionEvent): boolean {
38
- return event.type === "queue_update";
34
+ return event.type === "queue_update";
39
35
  }
@@ -34,23 +34,35 @@ export function agentToEntry(agent: AgentConfig): AgentEntry {
34
34
 
35
35
  function sourceIcon(source: ResourceSource): string {
36
36
  switch (source) {
37
- case "builtin": return "📦";
38
- case "user": return "👤";
39
- case "project": return "📂";
40
- case "git": return "🔗";
41
- case "dynamic": return "⚡";
42
- default: return "";
37
+ case "builtin":
38
+ return "📦";
39
+ case "user":
40
+ return "👤";
41
+ case "project":
42
+ return "📂";
43
+ case "git":
44
+ return "🔗";
45
+ case "dynamic":
46
+ return "⚡";
47
+ default:
48
+ return "❓";
43
49
  }
44
50
  }
45
51
 
46
52
  function sourceLabel(source: ResourceSource): string {
47
53
  switch (source) {
48
- case "builtin": return "builtin";
49
- case "user": return "user";
50
- case "project": return "project";
51
- case "git": return "git";
52
- case "dynamic": return "dynamic";
53
- default: return "unknown";
54
+ case "builtin":
55
+ return "builtin";
56
+ case "user":
57
+ return "user";
58
+ case "project":
59
+ return "project";
60
+ case "git":
61
+ return "git";
62
+ case "dynamic":
63
+ return "dynamic";
64
+ default:
65
+ return "unknown";
54
66
  }
55
67
  }
56
68
 
@@ -65,7 +77,14 @@ export interface AgentOverlayState {
65
77
  export function createAgentOverlayState(entries: AgentEntry[], maxVisible = 20): AgentOverlayState {
66
78
  return {
67
79
  entries: entries.sort((a, b) => {
68
- const order: Record<ResourceSource, number> = { project: 0, "project-pi": 1, user: 2, git: 3, builtin: 4, dynamic: 5 };
80
+ const order: Record<ResourceSource, number> = {
81
+ project: 0,
82
+ "project-pi": 1,
83
+ user: 2,
84
+ git: 3,
85
+ builtin: 4,
86
+ dynamic: 5,
87
+ };
69
88
  const diff = (order[a.source] ?? 4) - (order[b.source] ?? 4);
70
89
  return diff !== 0 ? diff : a.name.localeCompare(b.name);
71
90
  }),
@@ -80,11 +99,7 @@ export function moveSelection(state: AgentOverlayState, direction: -1 | 1): Agen
80
99
  const next = Math.max(0, Math.min(state.entries.length - 1, state.selectedIndex + direction));
81
100
  const visibleStart = state.scrollOffset;
82
101
  const visibleEnd = state.scrollOffset + state.maxVisible;
83
- const newScroll = next < visibleStart
84
- ? next
85
- : next >= visibleEnd
86
- ? Math.max(0, next - state.maxVisible + 1)
87
- : state.scrollOffset;
102
+ const newScroll = next < visibleStart ? next : next >= visibleEnd ? Math.max(0, next - state.maxVisible + 1) : state.scrollOffset;
88
103
  return { ...state, selectedIndex: next, scrollOffset: newScroll };
89
104
  }
90
105
 
@@ -109,34 +124,31 @@ export function renderAgentOverlay(state: AgentOverlayState, width: number): str
109
124
  return lines;
110
125
  }
111
126
 
112
- const visible = state.entries.slice(
113
- state.scrollOffset,
114
- state.scrollOffset + state.maxVisible,
115
- );
127
+ const visible = state.entries.slice(state.scrollOffset, state.scrollOffset + state.maxVisible);
116
128
 
117
129
  for (const [i, entry] of visible.entries()) {
118
130
  const globalIndex = state.scrollOffset + i;
119
131
  const isSelected = globalIndex === state.selectedIndex;
120
132
  const isExpanded = state.expanded.has(globalIndex);
121
133
  const cursor = isSelected ? "▸" : " ";
122
- const disabled = entry.disabled ? " [disabled]" : "";
123
- const model = entry.model ? ` (${entry.model})` : "";
124
-
125
- const summary = `${cursor} ${sourceIcon(entry.source)} ${entry.name}${model}${disabled}`;
126
- lines.push(truncate(summary, width));
127
-
128
- if (isExpanded) {
129
- const desc = ` ${entry.description}`;
130
- lines.push(truncate(desc, width));
131
- const meta: string[] = [` source: ${sourceLabel(entry.source)}`];
132
- if (entry.model) meta.push(`model: ${entry.model}`);
133
- if (entry.thinking) meta.push(`thinking: ${entry.thinking}`);
134
- if (entry.loadMode) meta.push(`loadMode: ${entry.loadMode}`);
135
- if (entry.contextMode) meta.push(`context: ${entry.contextMode}`);
136
- meta.push(`file: ${entry.filePath}`);
137
- lines.push(truncate(meta.join(" · "), width));
138
- lines.push(truncate("─".repeat(Math.min(width - 4, 50)), width));
139
- }
134
+ const disabled = entry.disabled ? " [disabled]" : "";
135
+ const model = entry.model ? ` (${entry.model})` : "";
136
+
137
+ const summary = `${cursor} ${sourceIcon(entry.source)} ${entry.name}${model}${disabled}`;
138
+ lines.push(truncate(summary, width));
139
+
140
+ if (isExpanded) {
141
+ const desc = ` ${entry.description}`;
142
+ lines.push(truncate(desc, width));
143
+ const meta: string[] = [` source: ${sourceLabel(entry.source)}`];
144
+ if (entry.model) meta.push(`model: ${entry.model}`);
145
+ if (entry.thinking) meta.push(`thinking: ${entry.thinking}`);
146
+ if (entry.loadMode) meta.push(`loadMode: ${entry.loadMode}`);
147
+ if (entry.contextMode) meta.push(`context: ${entry.contextMode}`);
148
+ meta.push(`file: ${entry.filePath}`);
149
+ lines.push(truncate(meta.join(" · "), width));
150
+ lines.push(truncate("─".repeat(Math.min(width - 4, 50)), width));
151
+ }
140
152
  }
141
153
 
142
154
  if (state.scrollOffset + state.maxVisible < state.entries.length) {
@@ -13,12 +13,17 @@
13
13
  * 15-18% — line background (visible but not loud)
14
14
  * 30-35% — word-level emphasis (prominent)
15
15
  */
16
- import type { CrewTheme } from "./theme-adapter.ts";
16
+
17
17
  import { visibleWidth as visualWidth } from "../utils/visual.ts";
18
+ import type { CrewTheme } from "./theme-adapter.ts";
18
19
 
19
20
  // ── ANSI parsing ────────────────────────────────────────────────────────
20
21
 
21
- interface Rgb { r: number; g: number; b: number; }
22
+ interface Rgb {
23
+ r: number;
24
+ g: number;
25
+ b: number;
26
+ }
22
27
 
23
28
  const ANSI_RGB_FG_RE = /^\x1b?\[?38;2;(\d+);(\d+);(\d+)m?$/;
24
29
  const ANSI_RGB_BG_RE = /^\x1b?\[?48;2;(\d+);(\d+);(\d+)m?$/;
@@ -80,7 +85,9 @@ export function deriveCardBackground(
80
85
  const bg = themeAny.getBgAnsi("background");
81
86
  const parsed = parseAnsiRgb(bg);
82
87
  if (parsed) base = parsed;
83
- } catch { /* fall back to black */ }
88
+ } catch {
89
+ /* fall back to black */
90
+ }
84
91
  }
85
92
 
86
93
  // Get the accent from the theme's fg for the requested slot.
@@ -88,7 +95,9 @@ export function deriveCardBackground(
88
95
  if (themeAny.getFgAnsi) {
89
96
  try {
90
97
  accentRgb = parseAnsiRgb(themeAny.getFgAnsi(statusSlot));
91
- } catch { /* accent stays null */ }
98
+ } catch {
99
+ /* accent stays null */
100
+ }
92
101
  }
93
102
  if (!accentRgb) return ""; // can't derive — render without bg tint
94
103
 
@@ -72,13 +72,14 @@ export class CrewFooter {
72
72
  const usage = this.data.usage;
73
73
  const context = contextText(this.data);
74
74
  const contextPercent = this.data.contextPercent;
75
- const contextColor = contextPercent !== undefined && Number.isFinite(contextPercent)
76
- ? contextPercent > 90
77
- ? "error"
78
- : contextPercent > 70
79
- ? "warning"
80
- : undefined
81
- : undefined;
75
+ const contextColor =
76
+ contextPercent !== undefined && Number.isFinite(contextPercent)
77
+ ? contextPercent > 90
78
+ ? "error"
79
+ : contextPercent > 70
80
+ ? "warning"
81
+ : undefined
82
+ : undefined;
82
83
  const contextRendered = contextColor ? this.theme.fg(contextColor, context) : context;
83
84
  const usageLine = [
84
85
  `↑${formatCount(usage?.input)}`,
@@ -85,7 +85,7 @@ export class CrewSelectList<T = string> {
85
85
  const prefix = index === this.selectedIndex ? " → " : " ";
86
86
  const suffix = item.description ? this.theme.fg("dim", ` — ${item.description}`) : "";
87
87
  const raw = `${prefix}${item.label}${suffix}`;
88
- const line = index === this.selectedIndex ? this.theme.inverse?.(raw) ?? raw : raw;
88
+ const line = index === this.selectedIndex ? (this.theme.inverse?.(raw) ?? raw) : raw;
89
89
  lines.push(pad(truncate(line, width), Math.max(1, width)));
90
90
  }
91
91
  if (hasBottom) lines.push(this.theme.fg("muted", `↓ ${this.items.length - (this.scrollOffset + slots)} more`));