pi-crew 0.9.16 → 0.9.18

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 (435) hide show
  1. package/CHANGELOG.md +130 -0
  2. package/README.md +19 -0
  3. package/dist/build-meta.json +21784 -0
  4. package/dist/index.mjs +83169 -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/migration/atomic-write-v2-migration.md +297 -0
  14. package/docs/patterns/command-agent-skill.md +1 -1
  15. package/docs/perf/performance-review-2026-07.md +287 -0
  16. package/docs/skills/REFERENCE.md +0 -17
  17. package/docs//303/242mmaAAA/303/242 +357 -0
  18. package/index.bundle.ts +25 -0
  19. package/index.ts +95 -4
  20. package/package.json +15 -4
  21. package/skills/iterative-audit/SKILL.md +0 -1
  22. package/skills/widget-rendering/SKILL.md +17 -0
  23. package/src/adapters/claude-adapter.ts +1 -3
  24. package/src/adapters/export-util.ts +16 -16
  25. package/src/adapters/index.ts +5 -5
  26. package/src/agents/agent-config.ts +20 -14
  27. package/src/agents/agent-serializer.ts +1 -1
  28. package/src/agents/discover-agents.ts +83 -39
  29. package/src/benchmark/benchmark-runner.ts +51 -51
  30. package/src/benchmark/feedback-loop.ts +1 -1
  31. package/src/config/config.ts +303 -591
  32. package/src/config/defaults.ts +28 -2
  33. package/src/config/drift-detector.ts +11 -14
  34. package/src/config/markers.ts +201 -203
  35. package/src/config/resilient-parser.ts +14 -6
  36. package/src/config/role-tools.ts +3 -3
  37. package/src/config/suggestions.ts +5 -12
  38. package/src/config/types.ts +9 -25
  39. package/src/errors.ts +151 -157
  40. package/src/extension/action-suggestions.ts +54 -9
  41. package/src/extension/async-notifier.ts +43 -13
  42. package/src/extension/autonomous-policy.ts +77 -37
  43. package/src/extension/command-completions.ts +9 -8
  44. package/src/extension/context-status-injection.ts +14 -12
  45. package/src/extension/crew-autocomplete.ts +8 -16
  46. package/src/extension/crew-cleanup.ts +2 -1
  47. package/src/extension/crew-shortcuts.ts +9 -6
  48. package/src/extension/cross-extension-rpc.ts +136 -42
  49. package/src/extension/help.ts +1 -1
  50. package/src/extension/import-index.ts +10 -5
  51. package/src/extension/knowledge-injection.ts +88 -15
  52. package/src/extension/management.ts +89 -349
  53. package/src/extension/message-renderers.ts +3 -4
  54. package/src/extension/notification-router.ts +22 -5
  55. package/src/extension/notification-sink.ts +6 -3
  56. package/src/extension/pi-api.ts +17 -8
  57. package/src/extension/plan-orchestrate.ts +8 -27
  58. package/src/extension/project-init.ts +21 -6
  59. package/src/extension/register.ts +329 -975
  60. package/src/extension/registration/artifact-cleanup.ts +9 -4
  61. package/src/extension/registration/command-utils.ts +5 -1
  62. package/src/extension/registration/commands.ts +806 -314
  63. package/src/extension/registration/compaction-guard.ts +15 -15
  64. package/src/extension/registration/lifecycle.ts +259 -0
  65. package/src/extension/registration/observability.ts +293 -0
  66. package/src/extension/registration/subagent-helpers.ts +29 -7
  67. package/src/extension/registration/subagent-tools.ts +253 -44
  68. package/src/extension/registration/team-tool.ts +19 -84
  69. package/src/extension/registration/ui.ts +168 -0
  70. package/src/extension/registration/viewers.ts +64 -24
  71. package/src/extension/result-watcher.ts +18 -7
  72. package/src/extension/run-bundle-schema.ts +21 -6
  73. package/src/extension/run-export.ts +15 -6
  74. package/src/extension/run-import.ts +64 -29
  75. package/src/extension/run-index.ts +28 -9
  76. package/src/extension/run-maintenance.ts +32 -12
  77. package/src/extension/session-summary.ts +1 -1
  78. package/src/extension/team-manager-command.ts +64 -7
  79. package/src/extension/team-onboard.ts +149 -150
  80. package/src/extension/team-recommendation.ts +121 -21
  81. package/src/extension/team-tool/anchor.ts +31 -64
  82. package/src/extension/team-tool/api.ts +929 -141
  83. package/src/extension/team-tool/auto-summarize.ts +14 -26
  84. package/src/extension/team-tool/cache-control.ts +1 -5
  85. package/src/extension/team-tool/cancel.ts +138 -38
  86. package/src/extension/team-tool/chain-dispatch.ts +5 -13
  87. package/src/extension/team-tool/chain-executor.ts +29 -51
  88. package/src/extension/team-tool/config-patch.ts +1 -1
  89. package/src/extension/team-tool/context.ts +40 -20
  90. package/src/extension/team-tool/destructive-gate.ts +10 -5
  91. package/src/extension/team-tool/doctor.ts +170 -51
  92. package/src/extension/team-tool/explain.ts +228 -214
  93. package/src/extension/team-tool/failure-patterns.ts +3 -9
  94. package/src/extension/team-tool/goal-wrap.ts +71 -29
  95. package/src/extension/team-tool/goal.ts +185 -35
  96. package/src/extension/team-tool/handle-schedule.ts +34 -15
  97. package/src/extension/team-tool/handle-settings.ts +94 -56
  98. package/src/extension/team-tool/health-monitor.ts +27 -108
  99. package/src/extension/team-tool/inspect.ts +42 -9
  100. package/src/extension/team-tool/intent-policy.ts +4 -1
  101. package/src/extension/team-tool/lifecycle-actions.ts +244 -48
  102. package/src/extension/team-tool/orchestrate.ts +7 -18
  103. package/src/extension/team-tool/parallel-dispatch.ts +51 -29
  104. package/src/extension/team-tool/plan.ts +29 -5
  105. package/src/extension/team-tool/respond.ts +49 -16
  106. package/src/extension/team-tool/run-not-found.ts +3 -8
  107. package/src/extension/team-tool/run.ts +80 -317
  108. package/src/extension/team-tool/status.ts +135 -43
  109. package/src/extension/team-tool/workflow-manage.ts +92 -25
  110. package/src/extension/team-tool-types.ts +8 -1
  111. package/src/extension/team-tool.ts +142 -551
  112. package/src/extension/validate-resources.ts +39 -8
  113. package/src/hooks/registry.ts +66 -17
  114. package/src/hooks/types.ts +1 -1
  115. package/src/i18n.ts +25 -11
  116. package/src/observability/correlation.ts +17 -3
  117. package/src/observability/event-bus.ts +51 -56
  118. package/src/observability/event-to-metric.ts +117 -15
  119. package/src/observability/exporters/otlp-exporter.ts +56 -17
  120. package/src/observability/exporters/prometheus-exporter.ts +1 -1
  121. package/src/observability/metric-registry.ts +16 -4
  122. package/src/observability/metric-retention.ts +8 -2
  123. package/src/observability/metric-sink.ts +11 -3
  124. package/src/observability/metrics-primitives.ts +42 -9
  125. package/src/plugins/plugin-define.ts +2 -2
  126. package/src/plugins/plugin-registry.ts +25 -25
  127. package/src/plugins/plugins/index.ts +1 -1
  128. package/src/plugins/plugins/nextjs.ts +16 -16
  129. package/src/plugins/plugins/vite.ts +7 -11
  130. package/src/plugins/plugins/vitest.ts +6 -11
  131. package/src/runtime/adaptive-plan.ts +225 -40
  132. package/src/runtime/agent-control.ts +58 -15
  133. package/src/runtime/agent-memory.ts +15 -9
  134. package/src/runtime/agent-observability.ts +10 -2
  135. package/src/runtime/anchor-manager.ts +27 -25
  136. package/src/runtime/async-marker.ts +7 -1
  137. package/src/runtime/async-runner.ts +39 -24
  138. package/src/runtime/auto-summarize.ts +7 -13
  139. package/src/runtime/background-runner.ts +189 -251
  140. package/src/runtime/batch-barrier.ts +18 -16
  141. package/src/runtime/cancellation-token.ts +16 -6
  142. package/src/runtime/cancellation.ts +46 -8
  143. package/src/runtime/capability-inventory.ts +6 -4
  144. package/src/runtime/chain-parser.ts +44 -11
  145. package/src/runtime/chain-runner.ts +63 -69
  146. package/src/runtime/checkpoint.ts +12 -56
  147. package/src/runtime/child-pi.ts +344 -79
  148. package/src/runtime/coalesce-tasks.ts +268 -0
  149. package/src/runtime/code-summary.ts +71 -26
  150. package/src/runtime/compact-stages/index.ts +15 -5
  151. package/src/runtime/compact-stages/tail-capture-stage.ts +7 -2
  152. package/src/runtime/compact-stages/truncation-stage.ts +4 -1
  153. package/src/runtime/compaction-summary.ts +17 -10
  154. package/src/runtime/completion-guard.ts +33 -16
  155. package/src/runtime/crash-classification.ts +28 -7
  156. package/src/runtime/crash-recovery.ts +177 -37
  157. package/src/runtime/crew-agent-records.ts +145 -47
  158. package/src/runtime/crew-hooks.ts +9 -24
  159. package/src/runtime/cross-extension-rpc.ts +25 -23
  160. package/src/runtime/custom-tools/irc-tool.ts +43 -15
  161. package/src/runtime/custom-tools/submit-result-tool.ts +16 -5
  162. package/src/runtime/delivery-coordinator.ts +34 -7
  163. package/src/runtime/delta-conflict.ts +9 -21
  164. package/src/runtime/deterministic-ast.ts +1 -1
  165. package/src/runtime/diagnostic-export.ts +53 -20
  166. package/src/runtime/direct-run.ts +12 -2
  167. package/src/runtime/dwf-state-store.ts +1 -1
  168. package/src/runtime/dynamic-workflow-context.ts +187 -59
  169. package/src/runtime/dynamic-workflow-runner.ts +42 -20
  170. package/src/runtime/effectiveness.ts +16 -8
  171. package/src/runtime/errors/crew-errors.ts +7 -11
  172. package/src/runtime/event-stream-bridge.ts +9 -3
  173. package/src/runtime/foreground-control.ts +54 -14
  174. package/src/runtime/foreground-watchdog.ts +9 -6
  175. package/src/runtime/goal-achievement.ts +27 -10
  176. package/src/runtime/goal-evaluator.ts +54 -19
  177. package/src/runtime/goal-loop-runner.ts +280 -99
  178. package/src/runtime/goal-state-store.ts +27 -17
  179. package/src/runtime/green-contract.ts +11 -2
  180. package/src/runtime/group-join.ts +64 -31
  181. package/src/runtime/handoff-manager.ts +37 -42
  182. package/src/runtime/heartbeat-gradient.ts +10 -2
  183. package/src/runtime/heartbeat-watcher.ts +32 -6
  184. package/src/runtime/hidden-handoff.ts +13 -31
  185. package/src/runtime/important-line-classifier.ts +12 -2
  186. package/src/runtime/iteration-hooks.ts +25 -15
  187. package/src/runtime/live-agent-control.ts +55 -7
  188. package/src/runtime/live-agent-manager.ts +130 -27
  189. package/src/runtime/live-control-realtime.ts +23 -3
  190. package/src/runtime/live-irc.ts +4 -1
  191. package/src/runtime/live-session-health.ts +12 -4
  192. package/src/runtime/live-session-runtime.ts +379 -117
  193. package/src/runtime/manifest-cache.ts +28 -12
  194. package/src/runtime/mcp-proxy.ts +10 -18
  195. package/src/runtime/metric-parser.ts +1 -5
  196. package/src/runtime/model-fallback.ts +55 -18
  197. package/src/runtime/model-resolver.ts +2 -6
  198. package/src/runtime/model-scope.ts +19 -3
  199. package/src/runtime/notebook-helpers.ts +60 -62
  200. package/src/runtime/orphan-worker-registry.ts +37 -26
  201. package/src/runtime/output-validator.ts +18 -3
  202. package/src/runtime/overflow-recovery.ts +5 -4
  203. package/src/runtime/parallel-research.ts +29 -5
  204. package/src/runtime/parallel-utils.ts +9 -11
  205. package/src/runtime/path-overlap.ts +150 -0
  206. package/src/runtime/peer-dep.ts +12 -17
  207. package/src/runtime/per-write-validator.ts +1 -3
  208. package/src/runtime/phase-tracker.ts +342 -330
  209. package/src/runtime/pi-args.ts +26 -8
  210. package/src/runtime/pi-json-output.ts +1 -1
  211. package/src/runtime/pi-spawn.ts +30 -19
  212. package/src/runtime/pipeline-runner.ts +56 -55
  213. package/src/runtime/plan-templates.ts +5 -6
  214. package/src/runtime/policy-engine.ts +43 -7
  215. package/src/runtime/post-checks.ts +12 -4
  216. package/src/runtime/post-exit-stdio-guard.ts +2 -2
  217. package/src/runtime/process-lifecycle.ts +20 -10
  218. package/src/runtime/process-status.ts +16 -5
  219. package/src/runtime/progress-event-coalescer.ts +2 -1
  220. package/src/runtime/progress-tracker.ts +103 -103
  221. package/src/runtime/prose-compressor.ts +9 -11
  222. package/src/runtime/recovery-recipes.ts +118 -24
  223. package/src/runtime/replace.ts +25 -10
  224. package/src/runtime/resilient-edit.ts +10 -25
  225. package/src/runtime/result-extractor.ts +2 -6
  226. package/src/runtime/retry-executor.ts +20 -4
  227. package/src/runtime/retry-runner.ts +27 -51
  228. package/src/runtime/role-permission.ts +6 -1
  229. package/src/runtime/run-coalesced-task-group.ts +256 -0
  230. package/src/runtime/run-drift.ts +14 -15
  231. package/src/runtime/run-tracker.ts +6 -28
  232. package/src/runtime/runtime-policy.ts +1 -6
  233. package/src/runtime/runtime-resolver.ts +80 -15
  234. package/src/runtime/scheduler.ts +47 -18
  235. package/src/runtime/semaphore.ts +5 -7
  236. package/src/runtime/sensitive-paths.ts +2 -1
  237. package/src/runtime/session-usage.ts +1 -1
  238. package/src/runtime/settings-store.ts +16 -12
  239. package/src/runtime/sidechain-output.ts +6 -2
  240. package/src/runtime/single-agent-compose.ts +1 -4
  241. package/src/runtime/skill-effectiveness.ts +29 -97
  242. package/src/runtime/skill-instructions.ts +40 -83
  243. package/src/runtime/stale-reconciler.ts +73 -197
  244. package/src/runtime/stream-preview.ts +1 -1
  245. package/src/runtime/streaming-output.ts +1 -1
  246. package/src/runtime/subagent-manager.ts +44 -169
  247. package/src/runtime/subprocess-tool-registry.ts +4 -1
  248. package/src/runtime/supervisor-contact.ts +10 -5
  249. package/src/runtime/task-display.ts +19 -5
  250. package/src/runtime/task-graph-scheduler.ts +95 -21
  251. package/src/runtime/task-graph.ts +5 -11
  252. package/src/runtime/task-health.ts +54 -47
  253. package/src/runtime/task-id.ts +12 -19
  254. package/src/runtime/task-output-context.ts +265 -81
  255. package/src/runtime/task-packet.ts +12 -20
  256. package/src/runtime/task-quality.ts +6 -14
  257. package/src/runtime/task-runner/context-retrieval.ts +4 -13
  258. package/src/runtime/task-runner/live-executor.ts +114 -36
  259. package/src/runtime/task-runner/output-splitter.ts +152 -0
  260. package/src/runtime/task-runner/progress.ts +50 -12
  261. package/src/runtime/task-runner/prompt-builder.ts +31 -7
  262. package/src/runtime/task-runner/prompt-pipeline.ts +31 -7
  263. package/src/runtime/task-runner/result-utils.ts +3 -1
  264. package/src/runtime/task-runner/retrieval-orchestrator.ts +310 -0
  265. package/src/runtime/task-runner/run-projection.ts +27 -8
  266. package/src/runtime/task-runner/state-helpers.ts +50 -14
  267. package/src/runtime/task-runner/tail-read.ts +2 -6
  268. package/src/runtime/task-runner.ts +180 -326
  269. package/src/runtime/team-runner-artifacts.ts +13 -0
  270. package/src/runtime/team-runner.ts +456 -974
  271. package/src/runtime/tool-output-pruner.ts +6 -9
  272. package/src/runtime/tool-progress.ts +11 -21
  273. package/src/runtime/verification-gates.ts +33 -24
  274. package/src/runtime/verification-integrity.ts +2 -7
  275. package/src/runtime/verification-worktree.ts +62 -12
  276. package/src/runtime/worker-heartbeat.ts +5 -1
  277. package/src/runtime/worker-startup.ts +29 -5
  278. package/src/runtime/workflow-state.ts +17 -9
  279. package/src/runtime/workspace-lock.ts +30 -35
  280. package/src/runtime/workspace-tree.ts +20 -32
  281. package/src/runtime/yield-handler.ts +43 -9
  282. package/src/runtime/zombie-scanner.ts +5 -4
  283. package/src/schema/config-schema.ts +266 -172
  284. package/src/schema/team-tool-schema.ts +29 -74
  285. package/src/schema/validation-types.ts +25 -17
  286. package/src/skills/discover-skills.ts +35 -10
  287. package/src/skills/skill-templates.ts +109 -27
  288. package/src/skills/validate.ts +26 -8
  289. package/src/state/active-run-registry.ts +87 -28
  290. package/src/state/artifact-store.ts +9 -5
  291. package/src/state/atomic-write-v2.ts +85 -63
  292. package/src/state/atomic-write.ts +106 -27
  293. package/src/state/blob-store.ts +47 -20
  294. package/src/state/contracts.ts +20 -5
  295. package/src/state/crew-init.ts +5 -22
  296. package/src/state/decision-ledger.ts +19 -73
  297. package/src/state/event-log-rotation.ts +41 -15
  298. package/src/state/event-log.ts +168 -53
  299. package/src/state/event-reconstructor.ts +11 -1
  300. package/src/state/gitignore-manager.ts +2 -8
  301. package/src/state/health-store.ts +57 -57
  302. package/src/state/hook-instinct-bridge.ts +1 -1
  303. package/src/state/hook-integrations.ts +1 -1
  304. package/src/state/instinct-store.ts +17 -5
  305. package/src/state/jsonl-writer.ts +1 -1
  306. package/src/state/locks.ts +23 -9
  307. package/src/state/mailbox.ts +151 -28
  308. package/src/state/observation-store.ts +20 -14
  309. package/src/state/run-cache.ts +142 -135
  310. package/src/state/run-graph.ts +6 -15
  311. package/src/state/run-metrics.ts +5 -18
  312. package/src/state/schedule.ts +15 -9
  313. package/src/state/state-store.ts +137 -47
  314. package/src/state/task-claims.ts +12 -2
  315. package/src/state/tiered-eval.ts +52 -43
  316. package/src/state/types-eval.ts +2 -2
  317. package/src/state/types.ts +24 -20
  318. package/src/state/usage.ts +20 -4
  319. package/src/state/worker-atomic-writer.ts +6 -3
  320. package/src/subagents/index.ts +2 -2
  321. package/src/teams/discover-teams.ts +21 -6
  322. package/src/tools/safe-bash-extension.ts +5 -6
  323. package/src/tools/safe-bash.ts +10 -11
  324. package/src/types/new-api-types.ts +6 -10
  325. package/src/ui/agent-management-overlay.ts +52 -40
  326. package/src/ui/card-colors.ts +13 -4
  327. package/src/ui/crew-footer.ts +8 -7
  328. package/src/ui/crew-select-list.ts +1 -1
  329. package/src/ui/dashboard-panes/agents-pane.ts +41 -25
  330. package/src/ui/dashboard-panes/cancellation-pane.ts +1 -1
  331. package/src/ui/dashboard-panes/capability-pane.ts +32 -15
  332. package/src/ui/dashboard-panes/health-pane.ts +2 -1
  333. package/src/ui/dashboard-panes/metrics-pane.ts +4 -1
  334. package/src/ui/dashboard-panes/progress-pane.ts +12 -9
  335. package/src/ui/heartbeat-aggregator.ts +15 -4
  336. package/src/ui/keybinding-map.ts +40 -7
  337. package/src/ui/live-conversation-overlay.ts +36 -20
  338. package/src/ui/live-duration.ts +1 -4
  339. package/src/ui/live-run-sidebar.ts +88 -25
  340. package/src/ui/loaders.ts +2 -8
  341. package/src/ui/mascot.ts +20 -36
  342. package/src/ui/overlays/agent-picker-overlay.ts +11 -3
  343. package/src/ui/overlays/confirm-overlay.ts +4 -2
  344. package/src/ui/overlays/help-overlay.ts +25 -14
  345. package/src/ui/overlays/mailbox-compose-overlay.ts +48 -11
  346. package/src/ui/overlays/mailbox-compose-preview.ts +20 -5
  347. package/src/ui/overlays/mailbox-detail-overlay.ts +27 -6
  348. package/src/ui/pi-ui-compat.ts +7 -7
  349. package/src/ui/powerbar-publisher.ts +120 -42
  350. package/src/ui/render-diff.ts +10 -3
  351. package/src/ui/render-scheduler.ts +12 -4
  352. package/src/ui/run-action-dispatcher.ts +81 -18
  353. package/src/ui/run-dashboard.ts +172 -76
  354. package/src/ui/run-event-bus.ts +59 -37
  355. package/src/ui/run-snapshot-cache.ts +276 -86
  356. package/src/ui/settings-overlay.ts +361 -74
  357. package/src/ui/status-colors.ts +12 -1
  358. package/src/ui/syntax-highlight.ts +1 -1
  359. package/src/ui/terminal-status.ts +1 -3
  360. package/src/ui/theme-adapter.ts +16 -14
  361. package/src/ui/theme-discovery.ts +13 -2
  362. package/src/ui/tool-progress-formatter.ts +7 -7
  363. package/src/ui/tool-render.ts +128 -56
  364. package/src/ui/tool-renderers/brief-mode.ts +45 -27
  365. package/src/ui/tool-renderers/index.ts +109 -43
  366. package/src/ui/transcript-cache.ts +32 -6
  367. package/src/ui/transcript-entries.ts +25 -23
  368. package/src/ui/transcript-viewer.ts +78 -29
  369. package/src/ui/widget/index.ts +99 -40
  370. package/src/ui/widget/widget-formatters.ts +13 -6
  371. package/src/ui/widget/widget-model.ts +19 -8
  372. package/src/ui/widget/widget-renderer.ts +23 -13
  373. package/src/ui/widget/widget-types.ts +1 -1
  374. package/src/utils/bm25-search.ts +199 -199
  375. package/src/utils/conflict-detect.ts +22 -21
  376. package/src/utils/env-filter.ts +14 -7
  377. package/src/utils/file-coalescer.ts +5 -1
  378. package/src/utils/fingerprint.ts +3 -6
  379. package/src/utils/frontmatter.ts +3 -1
  380. package/src/utils/fs-watch.ts +2 -6
  381. package/src/utils/gh-protocol.ts +119 -44
  382. package/src/utils/git.ts +13 -15
  383. package/src/utils/guards.ts +2 -5
  384. package/src/utils/ids.ts +9 -2
  385. package/src/utils/incremental-reader.ts +14 -3
  386. package/src/utils/internal-error.ts +2 -1
  387. package/src/utils/names.ts +12 -3
  388. package/src/utils/paths.ts +49 -5
  389. package/src/utils/project-detector.ts +2 -2
  390. package/src/utils/redaction.ts +29 -19
  391. package/src/utils/resolve-shell.ts +9 -7
  392. package/src/utils/run-watcher-registry.ts +19 -31
  393. package/src/utils/safe-paths.ts +46 -29
  394. package/src/utils/scan-cache.ts +9 -2
  395. package/src/utils/session-utils.ts +2 -4
  396. package/src/utils/sleep.ts +12 -5
  397. package/src/utils/sse-parser.ts +5 -17
  398. package/src/utils/visual.ts +52 -32
  399. package/src/workflows/discover-workflows.ts +41 -109
  400. package/src/workflows/intermediate-store.ts +5 -21
  401. package/src/workflows/preflight-validator.ts +6 -33
  402. package/src/workflows/topology-analyzer.ts +5 -21
  403. package/src/workflows/workflow-config.ts +7 -6
  404. package/src/worktree/branch-freshness.ts +66 -8
  405. package/src/worktree/cleanup.ts +130 -20
  406. package/src/worktree/worktree-manager.ts +212 -69
  407. package/skills/artifact-analysis-loop/SKILL.md +0 -303
  408. package/skills/detection-pipeline-design/SKILL.md +0 -286
  409. package/skills/hunting-investigation-loop/SKILL.md +0 -402
  410. package/skills/incident-playbook-construction/SKILL.md +0 -384
  411. package/skills/security-review/SKILL.md +0 -561
  412. package/skills/threat-hypothesis-framework/SKILL.md +0 -176
  413. package/skills/ui-render-performance/SKILL.md +0 -58
  414. /package/docs/{followup-review-round3-2026-05-12.md → archive/followup-review-round3-2026-05-12.md} +0 -0
  415. /package/docs/{followup-review-round4-2026-05-13.md → archive/followup-review-round4-2026-05-13.md} +0 -0
  416. /package/docs/{pi-crew-bugs.md → archive/pi-crew-bugs.md} +0 -0
  417. /package/docs/{pi-crew-test-final.md → archive/pi-crew-test-final.md} +0 -0
  418. /package/docs/{pi-crew-test-results.md → archive/pi-crew-test-results.md} +0 -0
  419. /package/docs/{pi-crew-test-round2.md → archive/pi-crew-test-round2.md} +0 -0
  420. /package/docs/{pi-crew-test-round4.md → archive/pi-crew-test-round4.md} +0 -0
  421. /package/docs/{pi-crew-test-round5.md → archive/pi-crew-test-round5.md} +0 -0
  422. /package/docs/{pi-crew-test-round6.md → archive/pi-crew-test-round6.md} +0 -0
  423. /package/docs/{pi-crew-v0.5.10-audit-fix-plan.md → archive/pi-crew-v0.5.10-audit-fix-plan.md} +0 -0
  424. /package/docs/{pi-crew-v0.5.11-audit-fix-plan.md → archive/pi-crew-v0.5.11-audit-fix-plan.md} +0 -0
  425. /package/docs/{pi-crew-v0.5.12-audit-fix-plan.md → archive/pi-crew-v0.5.12-audit-fix-plan.md} +0 -0
  426. /package/docs/{pi-crew-v0.5.13-audit-fix-plan.md → archive/pi-crew-v0.5.13-audit-fix-plan.md} +0 -0
  427. /package/docs/{pi-crew-v0.5.14-audit-fix-plan.md → archive/pi-crew-v0.5.14-audit-fix-plan.md} +0 -0
  428. /package/docs/{pi-crew-v0.5.16-audit-fix-plan.md → archive/pi-crew-v0.5.16-audit-fix-plan.md} +0 -0
  429. /package/docs/{pi-crew-v0.5.17-audit-fix-plan.md → archive/pi-crew-v0.5.17-audit-fix-plan.md} +0 -0
  430. /package/docs/{pi-crew-v0.5.5-audit-fix-plan.md → archive/pi-crew-v0.5.5-audit-fix-plan.md} +0 -0
  431. /package/docs/{pi-crew-v0.5.9-audit-fix-plan.md → archive/pi-crew-v0.5.9-audit-fix-plan.md} +0 -0
  432. /package/docs/{pi-mono-opportunities.md → archive/pi-mono-opportunities.md} +0 -0
  433. /package/docs/{pi-mono-review.md → archive/pi-mono-review.md} +0 -0
  434. /package/docs/{pi-subagent4-comparison.md → archive/pi-subagent4-comparison.md} +0 -0
  435. /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`));