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
@@ -113,10 +113,7 @@ export interface WeightedSkill {
113
113
  * for `.pi`-based projects (see issue #29).
114
114
  */
115
115
  function getSkillMetricsPath(cwd: string, runId: string): string {
116
- return join(
117
- projectCrewRoot(cwd),
118
- `state/runs/${runId}/skill-metrics.jsonl`,
119
- );
116
+ return join(projectCrewRoot(cwd), `state/runs/${runId}/skill-metrics.jsonl`);
120
117
  }
121
118
 
122
119
  /**
@@ -125,10 +122,7 @@ function getSkillMetricsPath(cwd: string, runId: string): string {
125
122
  * for `.pi`-based projects (see issue #29).
126
123
  */
127
124
  function getSkillActivationsPath(cwd: string, runId: string): string {
128
- return join(
129
- projectCrewRoot(cwd),
130
- `state/runs/${runId}/skill-activations.jsonl`,
131
- );
125
+ return join(projectCrewRoot(cwd), `state/runs/${runId}/skill-activations.jsonl`);
132
126
  }
133
127
 
134
128
  /**
@@ -156,9 +150,7 @@ export function computeInitialConfidence(observationCount: number): number {
156
150
  * Per ECC instinct system: +0.05 for success, -0.1 for failure.
157
151
  */
158
152
  export function adjustConfidence(current: number, passed: boolean): number {
159
- const delta = passed
160
- ? CONFIDENCE_ADJUSTMENTS.CONFIRMING
161
- : CONFIDENCE_ADJUSTMENTS.CONTRADICTING;
153
+ const delta = passed ? CONFIDENCE_ADJUSTMENTS.CONFIRMING : CONFIDENCE_ADJUSTMENTS.CONTRADICTING;
162
154
  return Math.max(0.1, Math.min(0.95, current + delta)); // Clamp to [0.1, 0.95]
163
155
  }
164
156
 
@@ -179,11 +171,7 @@ export function adjustConfidence(current: number, passed: boolean): number {
179
171
  * preserves the existing `adjustConfidence` clamp range [0.1, 0.95] and the
180
172
  * existing tests (which assert on the stored numeric values).
181
173
  */
182
- export function computeNextActivationConfidence(
183
- skillId: string,
184
- activations: SkillActivation[],
185
- passed: boolean,
186
- ): number {
174
+ export function computeNextActivationConfidence(skillId: string, activations: SkillActivation[], passed: boolean): number {
187
175
  const prior = activations.filter((a) => a.skillId === skillId);
188
176
  if (prior.length === 0) {
189
177
  // First activation of this skill in the run: seed by observation count.
@@ -191,8 +179,7 @@ export function computeNextActivationConfidence(
191
179
  return computeInitialConfidence(1);
192
180
  }
193
181
  // Rolling confidence = last recorded confidence for this skill, adjusted.
194
- const lastConfidence = prior[prior.length - 1]?.confidence
195
- ?? computeInitialConfidence(prior.length);
182
+ const lastConfidence = prior[prior.length - 1]?.confidence ?? computeInitialConfidence(prior.length);
196
183
  return adjustConfidence(lastConfidence, passed);
197
184
  }
198
185
 
@@ -202,9 +189,7 @@ export function computeNextActivationConfidence(
202
189
  export function applyDecay(current: number, lastActivation?: string): number {
203
190
  if (!lastActivation) return current;
204
191
 
205
- const daysSince =
206
- (Date.now() - new Date(lastActivation).getTime()) /
207
- (1000 * 60 * 60 * 24);
192
+ const daysSince = (Date.now() - new Date(lastActivation).getTime()) / (1000 * 60 * 60 * 24);
208
193
  const decayWeeks = Math.floor(daysSince / 7);
209
194
  const decay = decayWeeks * CONFIDENCE_ADJUSTMENTS.DECAY_PER_WEEK;
210
195
 
@@ -214,11 +199,8 @@ export function applyDecay(current: number, lastActivation?: string): number {
214
199
  /**
215
200
  * Determine behavior based on confidence threshold.
216
201
  */
217
- export function confidenceToBehavior(
218
- confidence: number,
219
- ): WeightedSkill["behavior"] {
220
- if (confidence >= CONFIDENCE_THRESHOLDS.NEAR_CERTAIN)
221
- return "act_autonomous";
202
+ export function confidenceToBehavior(confidence: number): WeightedSkill["behavior"] {
203
+ if (confidence >= CONFIDENCE_THRESHOLDS.NEAR_CERTAIN) return "act_autonomous";
222
204
  if (confidence >= CONFIDENCE_THRESHOLDS.STRONG) return "apply_auto";
223
205
  if (confidence >= CONFIDENCE_THRESHOLDS.MODERATE) return "apply_if_asked";
224
206
  return "suggest";
@@ -227,9 +209,7 @@ export function confidenceToBehavior(
227
209
  /**
228
210
  * Determine threshold name from confidence.
229
211
  */
230
- export function confidenceToThreshold(
231
- confidence: number,
232
- ): keyof typeof CONFIDENCE_THRESHOLDS {
212
+ export function confidenceToThreshold(confidence: number): keyof typeof CONFIDENCE_THRESHOLDS {
233
213
  if (confidence >= CONFIDENCE_THRESHOLDS.NEAR_CERTAIN) return "NEAR_CERTAIN";
234
214
  if (confidence >= CONFIDENCE_THRESHOLDS.STRONG) return "STRONG";
235
215
  if (confidence >= CONFIDENCE_THRESHOLDS.TENTATIVE) return "MODERATE";
@@ -240,10 +220,7 @@ export function confidenceToThreshold(
240
220
  * Record a skill activation.
241
221
  * Appends to the run's skill-activations.jsonl for learning.
242
222
  */
243
- export function recordSkillActivation(
244
- cwd: string,
245
- activation: SkillActivation,
246
- ): SkillActivation {
223
+ export function recordSkillActivation(cwd: string, activation: SkillActivation): SkillActivation {
247
224
  ensureSkillMetricsDir(cwd, activation.runId);
248
225
 
249
226
  const path = getSkillActivationsPath(cwd, activation.runId);
@@ -256,10 +233,7 @@ export function recordSkillActivation(
256
233
  /**
257
234
  * Get all skill activations for a run.
258
235
  */
259
- export function getSkillActivations(
260
- cwd: string,
261
- runId: string,
262
- ): SkillActivation[] {
236
+ export function getSkillActivations(cwd: string, runId: string): SkillActivation[] {
263
237
  const path = getSkillActivationsPath(cwd, runId);
264
238
 
265
239
  if (!existsSync(path)) {
@@ -280,10 +254,7 @@ export function getSkillActivations(
280
254
  /**
281
255
  * Compute metrics for a skill across all activations.
282
256
  */
283
- export function computeSkillMetrics(
284
- skillId: string,
285
- activations: SkillActivation[],
286
- ): SkillMetrics {
257
+ export function computeSkillMetrics(skillId: string, activations: SkillActivation[]): SkillMetrics {
287
258
  const skillActivations = activations.filter((a) => a.skillId === skillId);
288
259
 
289
260
  if (skillActivations.length === 0) {
@@ -302,22 +273,14 @@ export function computeSkillMetrics(
302
273
 
303
274
  const passed = skillActivations.filter((a) => a.passed).length;
304
275
  const failed = skillActivations.filter((a) => !a.passed).length;
305
- const avgConfidence =
306
- skillActivations.reduce((sum, a) => sum + a.confidence, 0) /
307
- skillActivations.length;
308
- const currentConfidence =
309
- skillActivations[skillActivations.length - 1]?.confidence ??
310
- avgConfidence;
276
+ const avgConfidence = skillActivations.reduce((sum, a) => sum + a.confidence, 0) / skillActivations.length;
277
+ const currentConfidence = skillActivations[skillActivations.length - 1]?.confidence ?? avgConfidence;
311
278
 
312
279
  // Compute trend from last 5 activations
313
280
  const recent = skillActivations.slice(-5);
314
- const recentPassRate =
315
- recent.filter((a) => a.passed).length / recent.length;
281
+ const recentPassRate = recent.filter((a) => a.passed).length / recent.length;
316
282
  const earlier = skillActivations.slice(0, -5);
317
- const earlierPassRate =
318
- earlier.length > 0
319
- ? earlier.filter((a) => a.passed).length / earlier.length
320
- : recentPassRate;
283
+ const earlierPassRate = earlier.length > 0 ? earlier.filter((a) => a.passed).length / earlier.length : recentPassRate;
321
284
 
322
285
  let trend: SkillMetrics["trend"] = "stable";
323
286
  if (recentPassRate > earlierPassRate + 0.1) {
@@ -329,13 +292,11 @@ export function computeSkillMetrics(
329
292
  // Role breakdown
330
293
  const roleBreakdown: Record<string, number> = {};
331
294
  for (const activation of skillActivations) {
332
- roleBreakdown[activation.role] =
333
- (roleBreakdown[activation.role] ?? 0) + 1;
295
+ roleBreakdown[activation.role] = (roleBreakdown[activation.role] ?? 0) + 1;
334
296
  }
335
297
 
336
298
  // Apply decay if not observed recently
337
- const lastActivation =
338
- skillActivations[skillActivations.length - 1]?.timestamp;
299
+ const lastActivation = skillActivations[skillActivations.length - 1]?.timestamp;
339
300
  const decayedConfidence = applyDecay(currentConfidence, lastActivation);
340
301
 
341
302
  return {
@@ -368,13 +329,10 @@ export function evaluatePromotionGate(metrics: SkillMetrics): {
368
329
  reason: string;
369
330
  } {
370
331
  const criteria = {
371
- correctness:
372
- metrics.passRate >= PROMOTION_GATE_CRITERIA.MIN_CORRECTNESS,
373
- evidence:
374
- metrics.totalActivations >= PROMOTION_GATE_CRITERIA.MIN_ACTIVATIONS,
332
+ correctness: metrics.passRate >= PROMOTION_GATE_CRITERIA.MIN_CORRECTNESS,
333
+ evidence: metrics.totalActivations >= PROMOTION_GATE_CRITERIA.MIN_ACTIVATIONS,
375
334
  rollback: metrics.trend !== "declining",
376
- encoding:
377
- metrics.avgConfidence >= PROMOTION_GATE_CRITERIA.MIN_AVG_CONFIDENCE,
335
+ encoding: metrics.avgConfidence >= PROMOTION_GATE_CRITERIA.MIN_AVG_CONFIDENCE,
378
336
  };
379
337
 
380
338
  const allPassed = Object.values(criteria).every(Boolean);
@@ -439,13 +397,7 @@ function filterSkillsByConfidence(
439
397
  threshold: keyof typeof CONFIDENCE_THRESHOLDS = "MODERATE",
440
398
  ): WeightedSkill[] {
441
399
  const minConfidence = CONFIDENCE_THRESHOLDS[threshold];
442
- return getWeightedSkillsForRole(
443
- cwd,
444
- "global",
445
- skillIds,
446
- runId,
447
- minConfidence,
448
- );
400
+ return getWeightedSkillsForRole(cwd, "global", skillIds, runId, minConfidence);
449
401
  }
450
402
 
451
403
  /**
@@ -481,11 +433,7 @@ export function registerSkillEffectivenessHooks(): void {
481
433
 
482
434
  // Record each skill activation with its rolling confidence
483
435
  for (const skillId of skillNames) {
484
- const confidence = computeNextActivationConfidence(
485
- skillId,
486
- existingActivations,
487
- success,
488
- );
436
+ const confidence = computeNextActivationConfidence(skillId, existingActivations, success);
489
437
  const activation: SkillActivation = {
490
438
  id: `act-${Date.now()}-${Math.random().toString(36).slice(2)}`,
491
439
  skillId,
@@ -517,11 +465,7 @@ export function registerSkillEffectivenessHooks(): void {
517
465
  const existingActivations = getSkillActivations(eventCwd, runId);
518
466
 
519
467
  for (const skillId of skillNames) {
520
- const confidence = computeNextActivationConfidence(
521
- skillId,
522
- existingActivations,
523
- false,
524
- );
468
+ const confidence = computeNextActivationConfidence(skillId, existingActivations, false);
525
469
  const activation: SkillActivation = {
526
470
  id: `act-${Date.now()}-${Math.random().toString(36).slice(2)}`,
527
471
  skillId,
@@ -541,11 +485,7 @@ export function registerSkillEffectivenessHooks(): void {
541
485
  * Generate a skill effectiveness report for a run.
542
486
  */
543
487
  /** @internal */
544
- function generateSkillEffectivenessReport(
545
- cwd: string,
546
- runId: string,
547
- skillIds: string[],
548
- ): string {
488
+ function generateSkillEffectivenessReport(cwd: string, runId: string, skillIds: string[]): string {
549
489
  const activations = getSkillActivations(cwd, runId);
550
490
  const lines: string[] = [
551
491
  `# Skill Effectiveness Report: ${runId}`,
@@ -568,21 +508,13 @@ function generateSkillEffectivenessReport(
568
508
  const gate = evaluatePromotionGate(metrics);
569
509
 
570
510
  lines.push(`### ${skillId}`);
571
- lines.push(
572
- `- **Confidence**: ${metrics.currentConfidence.toFixed(2)} (${metrics.trend})`,
573
- );
574
- lines.push(
575
- `- **Pass Rate**: ${(metrics.passRate * 100).toFixed(1)}% (${metrics.passedActivations}/${metrics.totalActivations})`,
576
- );
511
+ lines.push(`- **Confidence**: ${metrics.currentConfidence.toFixed(2)} (${metrics.trend})`);
512
+ lines.push(`- **Pass Rate**: ${(metrics.passRate * 100).toFixed(1)}% (${metrics.passedActivations}/${metrics.totalActivations})`);
577
513
  lines.push(`- **Avg Confidence**: ${metrics.avgConfidence.toFixed(2)}`);
578
- lines.push(
579
- `- **Promotion Gate**: ${gate.passed ? "PASSED ✅" : "NOT MET"}`,
580
- );
514
+ lines.push(`- **Promotion Gate**: ${gate.passed ? "PASSED ✅" : "NOT MET"}`);
581
515
 
582
516
  if (Object.keys(metrics.roleBreakdown).length > 0) {
583
- lines.push(
584
- `- **By Role**: ${JSON.stringify(metrics.roleBreakdown)}`,
585
- );
517
+ lines.push(`- **By Role**: ${JSON.stringify(metrics.roleBreakdown)}`);
586
518
  }
587
519
 
588
520
  lines.push("");
@@ -3,30 +3,19 @@ import * as path from "node:path";
3
3
  import { fileURLToPath } from "node:url";
4
4
  import type { AgentConfig } from "../agents/agent-config.ts";
5
5
  import type { TeamRole } from "../teams/team-config.ts";
6
- import {
7
- isSafePathId,
8
- resolveContainedPath,
9
- resolveRealContainedPath,
10
- } from "../utils/safe-paths.ts";
6
+ import { isSafePathId, resolveContainedPath, resolveRealContainedPath } from "../utils/safe-paths.ts";
11
7
  import type { WorkflowStep } from "../workflows/workflow-config.ts";
12
- import {
13
- CONFIDENCE_THRESHOLDS,
14
- getWeightedSkillsForRole,
15
- registerSkillEffectivenessHooks,
16
- } from "./skill-effectiveness.ts";
8
+ import { CONFIDENCE_THRESHOLDS, getWeightedSkillsForRole, registerSkillEffectivenessHooks } from "./skill-effectiveness.ts";
9
+
10
+ const PACKAGE_SKILLS_DIR = path.resolve(path.dirname(fileURLToPath(import.meta.url)), "..", "..", "skills");
17
11
 
18
- const PACKAGE_SKILLS_DIR = path.resolve(
19
- path.dirname(fileURLToPath(import.meta.url)),
20
- "..",
21
- "..",
22
- "skills",
23
- );
24
12
  import * as os from "node:os";
25
13
  // peer-dep.ts resolves @earendil-works/pi-coding-agent robustly across install
26
14
  // layouts (extension-under-~/.pi + pi-under-global). A static `import { getAgentDir }`
27
15
  // here crashes detached child processes when pi-crew and pi live in separate
28
16
  // node_modules trees. See src/runtime/peer-dep.ts.
29
17
  import { getAgentDir } from "../runtime/peer-dep.ts";
18
+
30
19
  const MAX_SKILL_CHARS = 1500;
31
20
  const MAX_TOTAL_CHARS = 6000;
32
21
  const MAX_SKILL_NAME_CHARS = 80;
@@ -38,11 +27,7 @@ const DEFAULT_ROLE_SKILLS: Record<string, string[]> = {
38
27
  analyst: ["read-only-explorer", "requirements-to-task-packet"],
39
28
  planner: ["delegation-patterns", "requirements-to-task-packet"],
40
29
  critic: ["read-only-explorer", "multi-perspective-review"],
41
- executor: [
42
- "state-mutation-locking",
43
- "safe-bash",
44
- "verification-before-done",
45
- ],
30
+ executor: ["state-mutation-locking", "safe-bash", "verification-before-done"],
46
31
  reviewer: ["read-only-explorer", "multi-perspective-review"],
47
32
  // SECURITY NOTE: The following skill names are trusted package-level skills.
48
33
  // If a project has a skills/ directory containing subdirectories with these names,
@@ -50,13 +35,10 @@ const DEFAULT_ROLE_SKILLS: Record<string, string[]> = {
50
35
  // project dir before package dir) and their content injected verbatim into prompts.
51
36
  // The "Applicable Skills" block will add an untrusted-content warning for project skills,
52
37
  // but be aware this is a potential supply-chain risk in multi-contributor projects.
53
- "security-reviewer": [
54
- "secure-agent-orchestration-review",
55
- "ownership-session-security",
56
- ],
38
+ "security-reviewer": ["secure-agent-orchestration-review", "ownership-session-security"],
57
39
  "test-engineer": ["verification-before-done", "safe-bash"],
58
40
  verifier: ["verification-before-done", "runtime-state-reader"],
59
- writer: ["context-artifact-hygiene", "verify-evidence"],
41
+ writer: ["context-artifact-hygiene", "verification-before-done"],
60
42
  };
61
43
 
62
44
  export interface ResolveTaskSkillsInput {
@@ -72,18 +54,11 @@ export interface RenderSkillInstructionsInput extends ResolveTaskSkillsInput {
72
54
  }
73
55
 
74
56
  function isValidSkillName(name: string): boolean {
75
- return (
76
- name.length > 0 &&
77
- name.length <= MAX_SKILL_NAME_CHARS &&
78
- isSafePathId(name)
79
- );
57
+ return name.length > 0 && name.length <= MAX_SKILL_NAME_CHARS && isSafePathId(name);
80
58
  }
81
59
 
82
60
  function sanitizeSkillName(name: string): string {
83
- return (
84
- name.replace(/[^A-Za-z0-9_-]/g, "_").slice(0, MAX_SKILL_NAME_CHARS) ||
85
- "invalid"
86
- );
61
+ return name.replace(/[^A-Za-z0-9_-]/g, "_").slice(0, MAX_SKILL_NAME_CHARS) || "invalid";
87
62
  }
88
63
 
89
64
  function unique(items: string[]): string[] {
@@ -98,9 +73,7 @@ function unique(items: string[]): string[] {
98
73
  return result;
99
74
  }
100
75
 
101
- export function normalizeSkillOverride(
102
- value: string | string[] | boolean | undefined,
103
- ): string[] | false | undefined {
76
+ export function normalizeSkillOverride(value: string | string[] | boolean | undefined): string[] | false | undefined {
104
77
  if (value === false) return false;
105
78
  if (typeof value === "string")
106
79
  return value
@@ -108,8 +81,7 @@ export function normalizeSkillOverride(
108
81
  .map((entry) => entry.trim())
109
82
  .filter(Boolean);
110
83
  if (value === true) return undefined;
111
- if (Array.isArray(value))
112
- return value.map((entry) => entry.trim()).filter(Boolean);
84
+ if (Array.isArray(value)) return value.map((entry) => entry.trim()).filter(Boolean);
113
85
  return undefined;
114
86
  }
115
87
 
@@ -117,17 +89,13 @@ export function defaultSkillsForRole(role: string): string[] {
117
89
  return DEFAULT_ROLE_SKILLS[role] ?? [];
118
90
  }
119
91
 
120
- function collectTaskSkillNames(
121
- input: ResolveTaskSkillsInput | undefined,
122
- ): string[] {
92
+ function collectTaskSkillNames(input: ResolveTaskSkillsInput | undefined): string[] {
123
93
  if (!input) return [];
124
94
  if (input.override === false) return [];
125
- const roleDefaultsDisabled =
126
- input.teamRole?.skills === false || input.step?.skills === false;
95
+ const roleDefaultsDisabled = input.teamRole?.skills === false || input.step?.skills === false;
127
96
  const names = roleDefaultsDisabled ? [] : defaultSkillsForRole(input.role);
128
97
  if (input.agent?.skills?.length) names.push(...input.agent.skills);
129
- if (Array.isArray(input.teamRole?.skills))
130
- names.push(...input.teamRole.skills);
98
+ if (Array.isArray(input.teamRole?.skills)) names.push(...input.teamRole.skills);
131
99
  if (Array.isArray(input.step?.skills)) names.push(...input.step.skills);
132
100
  if (Array.isArray(input.override)) names.push(...input.override);
133
101
  return unique(names);
@@ -143,19 +111,26 @@ export function resolveTaskSkillNames(input: ResolveTaskSkillsInput): string[] {
143
111
  // See: SECURITY-ISSUES.md SEC-003
144
112
  // ═══════════════════════════════════════════════════════════════════════════
145
113
 
146
- function candidateSkillDirs(
147
- cwd: string,
148
- ): Array<{ root: string; source: "project" | "package" | "project-pi" | "user-pi" | "project-agents" | "user-agents" }> {
114
+ function candidateSkillDirs(cwd: string): Array<{
115
+ root: string;
116
+ source: "project" | "package" | "project-pi" | "user-pi" | "project-agents" | "user-agents";
117
+ }> {
149
118
  return [
150
119
  { root: PACKAGE_SKILLS_DIR, source: "package" }, // ✓ Trusted first
151
120
  // F6 (v0.7.9): same five roots as discover-skills, in the same precedence
152
121
  // order. The first hit wins, so a project `.pi/skills/foo/SKILL.md`
153
122
  // overrides both the bundled `foo` and any legacy `<cwd>/skills/foo`.
154
123
  { root: path.resolve(cwd, ".pi", "skills"), source: "project-pi" },
155
- { root: path.resolve(cwd, ".agents", "skills"), source: "project-agents" },
124
+ {
125
+ root: path.resolve(cwd, ".agents", "skills"),
126
+ source: "project-agents",
127
+ },
156
128
  { root: path.resolve(cwd, "skills"), source: "project" },
157
129
  { root: path.join(getAgentDir(), "skills"), source: "user-pi" },
158
- { root: path.join(os.homedir(), ".agents", "skills"), source: "user-agents" },
130
+ {
131
+ root: path.join(os.homedir(), ".agents", "skills"),
132
+ source: "user-agents",
133
+ },
159
134
  { root: path.join(os.homedir(), ".pi", "skills"), source: "user-pi" },
160
135
  ];
161
136
  }
@@ -170,10 +145,7 @@ interface CachedSkillMarkdown {
170
145
 
171
146
  const skillReadCache = new Map<string, CachedSkillMarkdown>();
172
147
 
173
- function rememberSkill(
174
- key: string,
175
- value: CachedSkillMarkdown,
176
- ): CachedSkillMarkdown {
148
+ function rememberSkill(key: string, value: CachedSkillMarkdown): CachedSkillMarkdown {
177
149
  if (skillReadCache.has(key)) skillReadCache.delete(key);
178
150
  skillReadCache.set(key, value);
179
151
  while (skillReadCache.size > SKILL_CACHE_MAX_ENTRIES) {
@@ -201,7 +173,11 @@ function readSkillMarkdown(
201
173
  cwd: string,
202
174
  name: string,
203
175
  ):
204
- | { path: string; source: "project" | "package" | "project-pi" | "user-pi" | "project-agents" | "user-agents"; content: string }
176
+ | {
177
+ path: string;
178
+ source: "project" | "package" | "project-pi" | "user-pi" | "project-agents" | "user-agents";
179
+ content: string;
180
+ }
205
181
  | undefined {
206
182
  if (!isValidSkillName(name)) return undefined;
207
183
  const cacheKey = `${path.resolve(cwd)}:${name}`;
@@ -231,9 +207,7 @@ function readSkillMarkdown(
231
207
  function frontmatterDescription(content: string): string | undefined {
232
208
  const match = /^---\r?\n([\s\S]*?)\r?\n---/.exec(content);
233
209
  if (!match) return undefined;
234
- const line = match[1]
235
- .split(/\r?\n/)
236
- .find((entry) => entry.startsWith("description:"));
210
+ const line = match[1].split(/\r?\n/).find((entry) => entry.startsWith("description:"));
237
211
  return line?.slice("description:".length).trim();
238
212
  }
239
213
 
@@ -244,12 +218,8 @@ function stripFrontmatter(content: string): string {
244
218
  function compactSkillContent(content: string): string {
245
219
  const body = stripFrontmatter(content);
246
220
  if (body.length <= MAX_SKILL_CHARS) return body;
247
- const preferred =
248
- body.split(/\r?\n## Verification\r?\n/)[0]?.trim() ?? body;
249
- const truncated =
250
- preferred.length > MAX_SKILL_CHARS
251
- ? preferred.slice(0, MAX_SKILL_CHARS - 40).trimEnd()
252
- : preferred;
221
+ const preferred = body.split(/\r?\n## Verification\r?\n/)[0]?.trim() ?? body;
222
+ const truncated = preferred.length > MAX_SKILL_CHARS ? preferred.slice(0, MAX_SKILL_CHARS - 40).trimEnd() : preferred;
253
223
  return `${truncated}\n\n[skill instructions truncated]`;
254
224
  }
255
225
 
@@ -285,13 +255,7 @@ export function renderSkillInstructions(
285
255
  if (input.runId) {
286
256
  // Register effectiveness hooks once per process
287
257
  registerSkillEffectivenessHooks();
288
- const weighted = getWeightedSkillsForRole(
289
- input.cwd,
290
- input.role,
291
- names,
292
- input.runId,
293
- CONFIDENCE_THRESHOLDS.TENTATIVE,
294
- );
258
+ const weighted = getWeightedSkillsForRole(input.cwd, input.role, names, input.runId, CONFIDENCE_THRESHOLDS.TENTATIVE);
295
259
  weightedSkills = weighted.map((w) => ({
296
260
  skillId: w.skillId,
297
261
  confidence: w.confidence,
@@ -316,22 +280,15 @@ export function renderSkillInstructions(
316
280
  }
317
281
  skillPaths.push(path.dirname(loaded.path));
318
282
  const description = frontmatterDescription(loaded.content);
319
- const source =
320
- loaded.source === "project"
321
- ? `project:skills/${safeName}`
322
- : `package:skills/${safeName}`;
283
+ const source = loaded.source === "project" ? `project:skills/${safeName}` : `package:skills/${safeName}`;
323
284
 
324
285
  // ECC INSTINCT: Add confidence annotation from weighted skills
325
286
  const weighted = weightedSkills?.find((w) => w.skillId === name);
326
- const confidenceNote = weighted
327
- ? ` [Confidence: ${(weighted.confidence * 100).toFixed(0)}% — ${weighted.threshold}]`
328
- : "";
287
+ const confidenceNote = weighted ? ` [Confidence: ${(weighted.confidence * 100).toFixed(0)}% — ${weighted.threshold}]` : "";
329
288
 
330
289
  const header = [
331
290
  `## ${safeName}`,
332
- description
333
- ? `Description: ${description}${confidenceNote}`
334
- : undefined,
291
+ description ? `Description: ${description}${confidenceNote}` : undefined,
335
292
  `Source: ${source}`,
336
293
  // Path: pointer to the skill directory so the agent can deterministically
337
294
  // `ls <Path>/references/` and `read` a co-located reference corpus.