pi-crew 0.9.16 → 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 +81 -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 +145 -47
  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 +44 -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
@@ -3,8 +3,12 @@ import type { TeamToolParamsValue } from "../schema/team-tool-schema.ts";
3
3
  import { resolveContainedPath } from "../utils/safe-paths.ts";
4
4
  // Lazy-loaded to avoid pulling team-tool.ts (and its entire runtime chain) into module load.
5
5
  import type { handleTeamTool as HandleTeamToolFn } from "./team-tool.ts";
6
+
6
7
  let _cachedHandleTeamTool: typeof HandleTeamToolFn | undefined;
7
- async function handleTeamTool(params: Parameters<typeof HandleTeamToolFn>[0], ctx: Parameters<typeof HandleTeamToolFn>[1]): Promise<Awaited<ReturnType<typeof HandleTeamToolFn>>> {
8
+ async function handleTeamTool(
9
+ params: Parameters<typeof HandleTeamToolFn>[0],
10
+ ctx: Parameters<typeof HandleTeamToolFn>[1],
11
+ ): Promise<Awaited<ReturnType<typeof HandleTeamToolFn>>> {
8
12
  if (!_cachedHandleTeamTool) {
9
13
  // LAZY: avoid pulling team-tool.ts (and its entire runtime chain) into module load.
10
14
  const mod = await import("./team-tool.ts");
@@ -12,6 +16,7 @@ async function handleTeamTool(params: Parameters<typeof HandleTeamToolFn>[0], ct
12
16
  }
13
17
  return _cachedHandleTeamTool(params, ctx);
14
18
  }
19
+
15
20
  import { parseLiveControlRealtimeMessage, publishLiveControlRealtime } from "../runtime/live-control-realtime.ts";
16
21
 
17
22
  export interface EventBusLike {
@@ -27,7 +32,9 @@ export interface PiCrewRpcHandle {
27
32
  }
28
33
 
29
34
  function requestId(raw: unknown): string | undefined {
30
- return raw && typeof raw === "object" && !Array.isArray(raw) && typeof (raw as { requestId?: unknown }).requestId === "string" ? (raw as { requestId: string }).requestId : undefined;
35
+ return raw && typeof raw === "object" && !Array.isArray(raw) && typeof (raw as { requestId?: unknown }).requestId === "string"
36
+ ? (raw as { requestId: string }).requestId
37
+ : undefined;
31
38
  }
32
39
 
33
40
  function reply(events: EventBusLike, channel: string, id: string | undefined, payload: RpcReply): void {
@@ -38,7 +45,7 @@ function reply(events: EventBusLike, channel: string, id: string | undefined, pa
38
45
  }
39
46
 
40
47
  function textOf(result: Awaited<ReturnType<typeof handleTeamTool>>): string {
41
- return result.content?.map((item) => item.type === "text" ? item.text : "").join("\n") ?? "";
48
+ return result.content?.map((item) => (item.type === "text" ? item.text : "")).join("\n") ?? "";
42
49
  }
43
50
 
44
51
  // SECURITY: Strictly enumerate allowed operations per RPC channel.
@@ -46,13 +53,23 @@ function textOf(result: Awaited<ReturnType<typeof handleTeamTool>>): string {
46
53
  // from mutating run state without user consent.
47
54
  const RPC_ALLOWED_OPERATIONS = new Set([
48
55
  // Read-only manifest/plan ops
49
- "metrics-snapshot", "inventory", "read-manifest",
50
- "list-tasks", "read-task", "read-events",
56
+ "metrics-snapshot",
57
+ "inventory",
58
+ "read-manifest",
59
+ "list-tasks",
60
+ "read-task",
61
+ "read-events",
51
62
  // Read-only agent ops
52
- "list-agents", "read-agent-status", "read-agent-events",
53
- "read-agent-transcript", "read-agent-output", "agent-dashboard",
63
+ "list-agents",
64
+ "read-agent-status",
65
+ "read-agent-events",
66
+ "read-agent-transcript",
67
+ "read-agent-output",
68
+ "agent-dashboard",
54
69
  // Mailbox read ops
55
- "read-mailbox", "read-delivery", "read-heartbeat",
70
+ "read-mailbox",
71
+ "read-delivery",
72
+ "read-heartbeat",
56
73
  // No mutating ops (approve-plan, cancel-plan, steer-agent, stop-agent, etc.)
57
74
  // — these require explicit intent confirmation and are NOT allowed via RPC.
58
75
  ]);
@@ -91,20 +108,29 @@ export function resetRpcRateLimit(): void {
91
108
  rpcRunTimestamps.length = 0;
92
109
  }
93
110
 
94
- function isAllowedRpcRunParams(params: TeamToolParamsValue): { ok: boolean; error?: string } {
111
+ function isAllowedRpcRunParams(params: TeamToolParamsValue): {
112
+ ok: boolean;
113
+ error?: string;
114
+ } {
95
115
  // SECURITY: Require explicit intent for any RPC-initiated run creation.
96
116
  // This prevents malicious extensions from spawning child Pi processes silently.
97
117
  const cfg = params.config as Record<string, unknown> | undefined;
98
118
  const intent = cfg?.intent as string | undefined;
99
119
  if (!intent || typeof intent !== "string" || intent.trim().length === 0) {
100
- return { ok: false, error: "RPC run requires config.intent (a non-empty intent string)" };
120
+ return {
121
+ ok: false,
122
+ error: "RPC run requires config.intent (a non-empty intent string)",
123
+ };
101
124
  }
102
125
  // SECURITY: Validate cwd is within the project directory if provided.
103
126
  if (params.cwd && typeof params.cwd === "string") {
104
127
  try {
105
128
  resolveContainedPath(params.cwd, ".");
106
129
  } catch {
107
- return { ok: false, error: "RPC run config.cwd must be within the project directory" };
130
+ return {
131
+ ok: false,
132
+ error: "RPC run config.cwd must be within the project directory",
133
+ };
108
134
  }
109
135
  }
110
136
  return { ok: true };
@@ -121,10 +147,18 @@ function on(events: EventBusLike, channel: string, handler: (raw: unknown) => vo
121
147
  // requirement for runs, operation allowlist for live-control reads, and cwd
122
148
  // containment validation. A full fix requires event-bus-level origin signing.
123
149
 
124
- export function registerPiCrewRpc(events: EventBusLike | undefined, getCtx: () => ExtensionContext | undefined): PiCrewRpcHandle | undefined {
150
+ export function registerPiCrewRpc(
151
+ events: EventBusLike | undefined,
152
+ getCtx: () => ExtensionContext | undefined,
153
+ ): PiCrewRpcHandle | undefined {
125
154
  if (!events) return undefined;
126
155
  const unsubs = [
127
- on(events, "pi-crew:rpc:ping", (raw) => reply(events, "pi-crew:rpc:ping", requestId(raw), { success: true, data: { version: PI_CREW_RPC_VERSION } })),
156
+ on(events, "pi-crew:rpc:ping", (raw) =>
157
+ reply(events, "pi-crew:rpc:ping", requestId(raw), {
158
+ success: true,
159
+ data: { version: PI_CREW_RPC_VERSION },
160
+ }),
161
+ ),
128
162
  on(events, "pi-crew:rpc:run", async (raw) => {
129
163
  const id = requestId(raw);
130
164
  try {
@@ -144,24 +178,40 @@ export function registerPiCrewRpc(events: EventBusLike | undefined, getCtx: () =
144
178
  const ALLOWED_RPC_RUN_KEYS = new Set(["goal", "team", "workflow", "async", "cwd", "config", "skill", "model"]);
145
179
  let params: TeamToolParamsValue;
146
180
  if (raw && typeof raw === "object" && !Array.isArray(raw)) {
147
- const filtered: Record<string, unknown> = { ...(raw as object) };
181
+ const filtered: Record<string, unknown> = {
182
+ ...(raw as object),
183
+ };
148
184
  // Strip any keys not in the allowlist to prevent injection of unexpected fields
149
185
  for (const key of Object.keys(filtered)) {
150
186
  if (!ALLOWED_RPC_RUN_KEYS.has(key)) delete filtered[key];
151
187
  }
152
- params = { ...filtered, action: "run" } as TeamToolParamsValue;
188
+ params = {
189
+ ...filtered,
190
+ action: "run",
191
+ } as TeamToolParamsValue;
153
192
  } else {
154
193
  params = { action: "run" };
155
194
  }
156
195
  const permission = isAllowedRpcRunParams(params);
157
196
  if (!permission.ok) {
158
- reply(events, "pi-crew:rpc:run", id, { success: false, error: permission.error ?? "permission denied" });
197
+ reply(events, "pi-crew:rpc:run", id, {
198
+ success: false,
199
+ error: permission.error ?? "permission denied",
200
+ });
159
201
  return;
160
202
  }
161
203
  const result = await handleTeamTool(params, ctx);
162
- reply(events, "pi-crew:rpc:run", id, result.isError ? { success: false, error: textOf(result) } : { success: true, data: result.details });
204
+ reply(
205
+ events,
206
+ "pi-crew:rpc:run",
207
+ id,
208
+ result.isError ? { success: false, error: textOf(result) } : { success: true, data: result.details },
209
+ );
163
210
  } catch (error) {
164
- reply(events, "pi-crew:rpc:run", id, { success: false, error: error instanceof Error ? error.message : String(error) });
211
+ reply(events, "pi-crew:rpc:run", id, {
212
+ success: false,
213
+ error: error instanceof Error ? error.message : String(error),
214
+ });
165
215
  }
166
216
  }),
167
217
  on(events, "pi-crew:rpc:status", async (raw) => {
@@ -171,38 +221,82 @@ export function registerPiCrewRpc(events: EventBusLike | undefined, getCtx: () =
171
221
  if (!ctx) throw new Error("No active pi-crew session context.");
172
222
  const runId = raw && typeof raw === "object" && !Array.isArray(raw) ? (raw as { runId?: string }).runId : undefined;
173
223
  const result = await handleTeamTool({ action: "status", runId }, ctx);
174
- reply(events, "pi-crew:rpc:status", id, result.isError ? { success: false, error: textOf(result) } : { success: true, data: { text: textOf(result), details: result.details } });
224
+ reply(
225
+ events,
226
+ "pi-crew:rpc:status",
227
+ id,
228
+ result.isError
229
+ ? { success: false, error: textOf(result) }
230
+ : {
231
+ success: true,
232
+ data: {
233
+ text: textOf(result),
234
+ details: result.details,
235
+ },
236
+ },
237
+ );
175
238
  } catch (error) {
176
- reply(events, "pi-crew:rpc:status", id, { success: false, error: error instanceof Error ? error.message : String(error) });
239
+ reply(events, "pi-crew:rpc:status", id, {
240
+ success: false,
241
+ error: error instanceof Error ? error.message : String(error),
242
+ });
177
243
  }
178
244
  }),
179
245
  on(events, "pi-crew:live-control", (raw) => {
180
246
  const request = parseLiveControlRealtimeMessage(raw);
181
247
  if (request) publishLiveControlRealtime(request);
182
248
  }),
183
- on(events, "pi-crew:rpc:live-control", async (raw) => {
184
- const id = requestId(raw);
185
- try {
186
- const ctx = getCtx();
187
- if (!ctx) throw new Error("No active pi-crew session context.");
188
- const obj = raw && typeof raw === "object" && !Array.isArray(raw) ? raw as Record<string, unknown> : {};
189
- const rawOp = typeof obj.operation === "string" ? obj.operation : "steer-agent";
190
- // SECURITY: Reject any operation not in the explicit allowlist.
191
- // Mutating ops (approve-plan, cancel-plan, steer-agent, stop-agent, etc.)
192
- // require user consent and are blocked here.
193
- if (!isAllowedRpcOperation(rawOp)) {
194
- reply(events, "pi-crew:rpc:live-control", id, {
195
- success: false,
196
- error: `RPC operation '${rawOp}' is not allowed. Allowed: ${[...RPC_ALLOWED_OPERATIONS].join(", ")}`,
197
- });
198
- return;
199
- }
200
- const result = await handleTeamTool({ action: "api", runId: typeof obj.runId === "string" ? obj.runId : undefined, config: { operation: rawOp, agentId: obj.agentId, message: obj.message, prompt: obj.prompt } }, ctx);
201
- reply(events, "pi-crew:rpc:live-control", id, result.isError ? { success: false, error: textOf(result) } : { success: true, data: { text: textOf(result), details: result.details } });
202
- } catch (error) {
203
- reply(events, "pi-crew:rpc:live-control", id, { success: false, error: error instanceof Error ? error.message : String(error) });
249
+ on(events, "pi-crew:rpc:live-control", async (raw) => {
250
+ const id = requestId(raw);
251
+ try {
252
+ const ctx = getCtx();
253
+ if (!ctx) throw new Error("No active pi-crew session context.");
254
+ const obj = raw && typeof raw === "object" && !Array.isArray(raw) ? (raw as Record<string, unknown>) : {};
255
+ const rawOp = typeof obj.operation === "string" ? obj.operation : "steer-agent";
256
+ // SECURITY: Reject any operation not in the explicit allowlist.
257
+ // Mutating ops (approve-plan, cancel-plan, steer-agent, stop-agent, etc.)
258
+ // require user consent and are blocked here.
259
+ if (!isAllowedRpcOperation(rawOp)) {
260
+ reply(events, "pi-crew:rpc:live-control", id, {
261
+ success: false,
262
+ error: `RPC operation '${rawOp}' is not allowed. Allowed: ${[...RPC_ALLOWED_OPERATIONS].join(", ")}`,
263
+ });
264
+ return;
204
265
  }
205
- }),
266
+ const result = await handleTeamTool(
267
+ {
268
+ action: "api",
269
+ runId: typeof obj.runId === "string" ? obj.runId : undefined,
270
+ config: {
271
+ operation: rawOp,
272
+ agentId: obj.agentId,
273
+ message: obj.message,
274
+ prompt: obj.prompt,
275
+ },
276
+ },
277
+ ctx,
278
+ );
279
+ reply(
280
+ events,
281
+ "pi-crew:rpc:live-control",
282
+ id,
283
+ result.isError
284
+ ? { success: false, error: textOf(result) }
285
+ : {
286
+ success: true,
287
+ data: {
288
+ text: textOf(result),
289
+ details: result.details,
290
+ },
291
+ },
292
+ );
293
+ } catch (error) {
294
+ reply(events, "pi-crew:rpc:live-control", id, {
295
+ success: false,
296
+ error: error instanceof Error ? error.message : String(error),
297
+ });
298
+ }
299
+ }),
206
300
  ];
207
301
  return { unsubscribe: () => unsubs.forEach((unsub) => unsub()) };
208
302
  }
@@ -11,7 +11,7 @@ export function piTeamsHelp(): string {
11
11
  "- /team-summary <runId>",
12
12
  "- /team-resume <runId>",
13
13
  "- /team-cancel <runId>",
14
- "- /team-retry <runId> [taskId]",
14
+ "- /team-retry <runId> [taskId]",
15
15
  "",
16
16
  "Inspection:",
17
17
  "- /team-events <runId>",
@@ -1,7 +1,7 @@
1
1
  import * as fs from "node:fs";
2
2
  import * as path from "node:path";
3
- import { projectCrewRoot, userCrewRoot } from "../utils/paths.ts";
4
3
  import { DEFAULT_PATHS } from "../config/defaults.ts";
4
+ import { projectCrewRoot, userCrewRoot } from "../utils/paths.ts";
5
5
  import { isSafePathId, resolveRealContainedPath } from "../utils/safe-paths.ts";
6
6
 
7
7
  export interface ImportedRunIndexEntry {
@@ -30,7 +30,10 @@ function readEntry(root: string, scope: "project" | "user", runId: string): Impo
30
30
  if (!fs.existsSync(bundlePath)) return undefined;
31
31
  try {
32
32
  const raw = JSON.parse(fs.readFileSync(bundlePath, "utf-8")) as Record<string, unknown>;
33
- const manifest = raw.manifest && typeof raw.manifest === "object" && !Array.isArray(raw.manifest) ? raw.manifest as Record<string, unknown> : {};
33
+ const manifest =
34
+ raw.manifest && typeof raw.manifest === "object" && !Array.isArray(raw.manifest)
35
+ ? (raw.manifest as Record<string, unknown>)
36
+ : {};
34
37
  return {
35
38
  runId,
36
39
  scope,
@@ -55,7 +58,8 @@ function collect(root: string, scope: "project" | "user"): ImportedRunIndexEntry
55
58
  } catch {
56
59
  return [];
57
60
  }
58
- return fs.readdirSync(root)
61
+ return fs
62
+ .readdirSync(root)
59
63
  .filter((entry) => isSafePathId(entry))
60
64
  .map((entry) => readEntry(root, scope, entry))
61
65
  .filter((entry): entry is ImportedRunIndexEntry => entry !== undefined);
@@ -64,6 +68,7 @@ function collect(root: string, scope: "project" | "user"): ImportedRunIndexEntry
64
68
  export function listImportedRuns(cwd: string): ImportedRunIndexEntry[] {
65
69
  const projectRoot = path.join(projectCrewRoot(cwd), DEFAULT_PATHS.state.importsSubdir);
66
70
  const userRoot = path.join(userCrewRoot(), DEFAULT_PATHS.state.importsSubdir);
67
- return [...collect(userRoot, "user"), ...collect(projectRoot, "project")]
68
- .sort((a, b) => (b.importedAt ?? "").localeCompare(a.importedAt ?? ""));
71
+ return [...collect(userRoot, "user"), ...collect(projectRoot, "project")].sort((a, b) =>
72
+ (b.importedAt ?? "").localeCompare(a.importedAt ?? ""),
73
+ );
69
74
  }
@@ -22,8 +22,8 @@
22
22
  */
23
23
  import * as fs from "node:fs";
24
24
  import * as path from "node:path";
25
- import type { BeforeAgentStartEvent, ExtensionAPI } from "./pi-api.ts";
26
25
  import { projectCrewRoot } from "../utils/paths.ts";
26
+ import type { BeforeAgentStartEvent, ExtensionAPI } from "./pi-api.ts";
27
27
 
28
28
  /** The knowledge file, relative to the project crew root. */
29
29
  export const KNOWLEDGE_FILENAME = "knowledge.md";
@@ -73,10 +73,45 @@ interface KnowledgeSection {
73
73
  }
74
74
 
75
75
  const STOPWORDS = new Set([
76
- "the", "a", "an", "is", "are", "of", "to", "in", "for", "and", "or", "not",
77
- "with", "this", "that", "it", "be", "on", "at", "by", "do", "does", "how",
78
- "what", "when", "from", "fix", "fixes", "fixed", "v0", "v1", "released",
79
- "progress", "uncommitted", "not", "pushed", "published", "session", "post",
76
+ "the",
77
+ "a",
78
+ "an",
79
+ "is",
80
+ "are",
81
+ "of",
82
+ "to",
83
+ "in",
84
+ "for",
85
+ "and",
86
+ "or",
87
+ "not",
88
+ "with",
89
+ "this",
90
+ "that",
91
+ "it",
92
+ "be",
93
+ "on",
94
+ "at",
95
+ "by",
96
+ "do",
97
+ "does",
98
+ "how",
99
+ "what",
100
+ "when",
101
+ "from",
102
+ "fix",
103
+ "fixes",
104
+ "fixed",
105
+ "v0",
106
+ "v1",
107
+ "released",
108
+ "progress",
109
+ "uncommitted",
110
+ "not",
111
+ "pushed",
112
+ "published",
113
+ "session",
114
+ "post",
80
115
  ]);
81
116
 
82
117
  /** Tokenize header text into a Set of lowercased non-stopword tokens. */
@@ -91,20 +126,33 @@ function tokenizeHeader(header: string): Set<string> {
91
126
  }
92
127
 
93
128
  /** Parse knowledge.md into (conventions, sessionLog) sections by H2 header. */
94
- function parseKnowledgeSections(content: string): { conventions: KnowledgeSection[]; sessionLog: KnowledgeSection[] } {
129
+ function parseKnowledgeSections(content: string): {
130
+ conventions: KnowledgeSection[];
131
+ sessionLog: KnowledgeSection[];
132
+ } {
95
133
  const lines = content.split(/\r?\n/);
96
134
  const sections: KnowledgeSection[] = [];
97
135
  let current: { header: string; lines: string[] } | null = null;
98
136
  for (const line of lines) {
99
137
  const m = /^##\s+(.+?)\s*$/.exec(line);
100
138
  if (m) {
101
- if (current) sections.push({ header: current.header, body: current.lines.join("\n"), headerTokens: tokenizeHeader(current.header) });
139
+ if (current)
140
+ sections.push({
141
+ header: current.header,
142
+ body: current.lines.join("\n"),
143
+ headerTokens: tokenizeHeader(current.header),
144
+ });
102
145
  current = { header: m[1]!, lines: [line] };
103
146
  } else if (current) {
104
147
  current.lines.push(line);
105
148
  }
106
149
  }
107
- if (current) sections.push({ header: current.header, body: current.lines.join("\n"), headerTokens: tokenizeHeader(current.header) });
150
+ if (current)
151
+ sections.push({
152
+ header: current.header,
153
+ body: current.lines.join("\n"),
154
+ headerTokens: tokenizeHeader(current.header),
155
+ });
108
156
 
109
157
  // Classify: a section is a CONVENTION if its header starts-with one of the
110
158
  // known convention titles. Once we leave the convention run (first non-
@@ -168,7 +216,12 @@ function selectSessionLog(query: string, sessionLog: KnowledgeSection[], budgetB
168
216
  const scored = sessionLog
169
217
  .map((sec, idx) => {
170
218
  const overlap = [...queryTokens].filter((t) => sec.headerTokens.has(t));
171
- return { sec, score: overlap.reduce((sum, t) => sum + (idf.get(t) ?? 0), 0), idx, hasOverlap: overlap.length > 0 };
219
+ return {
220
+ sec,
221
+ score: overlap.reduce((sum, t) => sum + (idf.get(t) ?? 0), 0),
222
+ idx,
223
+ hasOverlap: overlap.length > 0,
224
+ };
172
225
  })
173
226
  .filter((x) => x.hasOverlap);
174
227
  if (scored.length === 0) return [];
@@ -188,7 +241,10 @@ function selectSessionLog(query: string, sessionLog: KnowledgeSection[], budgetB
188
241
  // a head-sliced copy of the single best match so the query isn't empty.
189
242
  if (selected.length === 0 && bestMatch) {
190
243
  const sliced = bestMatch.sec.body.slice(0, Math.max(0, budgetBytes));
191
- selected.push({ ...bestMatch.sec, body: `${sliced}\n\n<!-- section truncated (session-log budget ${budgetBytes} bytes). Full file: use \`read\`. -->` });
244
+ selected.push({
245
+ ...bestMatch.sec,
246
+ body: `${sliced}\n\n<!-- section truncated (session-log budget ${budgetBytes} bytes). Full file: use \`read\`. -->`,
247
+ });
192
248
  }
193
249
  return selected;
194
250
  }
@@ -225,13 +281,23 @@ export function readKnowledge(cwd: string, query?: KnowledgeQuery): string {
225
281
 
226
282
  // Section-aware path: cache parsed sections, select per-query.
227
283
  const cachedSections = sectionCache.get(p);
228
- let parsed: { conventions: KnowledgeSection[]; sessionLog: KnowledgeSection[] };
284
+ let parsed: {
285
+ conventions: KnowledgeSection[];
286
+ sessionLog: KnowledgeSection[];
287
+ };
229
288
  if (cachedSections && cachedSections.key === cacheKey) {
230
- parsed = { conventions: cachedSections.conventions, sessionLog: cachedSections.sessionLog };
289
+ parsed = {
290
+ conventions: cachedSections.conventions,
291
+ sessionLog: cachedSections.sessionLog,
292
+ };
231
293
  } else {
232
294
  const content = fs.readFileSync(p, "utf8").trim();
233
295
  parsed = parseKnowledgeSections(content);
234
- sectionCache.set(p, { key: cacheKey, conventions: parsed.conventions, sessionLog: parsed.sessionLog });
296
+ sectionCache.set(p, {
297
+ key: cacheKey,
298
+ conventions: parsed.conventions,
299
+ sessionLog: parsed.sessionLog,
300
+ });
235
301
  }
236
302
 
237
303
  const queryText = [query.goal, query.taskText].filter(Boolean).join(" \n ");
@@ -245,7 +311,9 @@ export function readKnowledge(cwd: string, query?: KnowledgeQuery): string {
245
311
  // Always: section-index of ALL session-log headers (recovery safety net).
246
312
  if (parsed.sessionLog.length > 0) {
247
313
  const indexLines = parsed.sessionLog.map((s) => ` - ${s.header}`);
248
- parts.push(`<!-- Session-log sections in knowledge.md (not injected unless matched above — use \`read\` for detail):\n${indexLines.join("\n")}\nFull file: ${p} -->`);
314
+ parts.push(
315
+ `<!-- Session-log sections in knowledge.md (not injected unless matched above — use \`read\` for detail):\n${indexLines.join("\n")}\nFull file: ${p} -->`,
316
+ );
249
317
  }
250
318
  return parts.join("\n").trim();
251
319
  } catch {
@@ -311,7 +379,12 @@ export function buildKnowledgeFragment(cwd: string, query?: KnowledgeQuery): str
311
379
  */
312
380
  export function registerKnowledgeInjection(pi: ExtensionAPI): void {
313
381
  pi.on("before_agent_start", (event: BeforeAgentStartEvent) => {
314
- const options = (event as BeforeAgentStartEvent & { systemPromptOptions?: { cwd?: unknown } }).systemPromptOptions ?? {};
382
+ const options =
383
+ (
384
+ event as BeforeAgentStartEvent & {
385
+ systemPromptOptions?: { cwd?: unknown };
386
+ }
387
+ ).systemPromptOptions ?? {};
315
388
  const cwd = typeof options.cwd === "string" ? options.cwd : process.cwd();
316
389
  const fragment = buildKnowledgeFragment(cwd);
317
390
  if (!fragment) return undefined;