pi-crew 0.9.16 → 0.9.18

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (435) hide show
  1. package/CHANGELOG.md +130 -0
  2. package/README.md +19 -0
  3. package/dist/build-meta.json +21784 -0
  4. package/dist/index.mjs +83169 -0
  5. package/dist/index.mjs.map +7 -0
  6. package/docs/A +358 -0
  7. package/docs/M-A +357 -0
  8. package/docs/REVIEW-FINDINGS-2026-06 +357 -0
  9. package/docs/Y +357 -0
  10. package/docs/a +357 -0
  11. package/docs/aA +358 -0
  12. package/docs/archive/README.md +91 -0
  13. package/docs/migration/atomic-write-v2-migration.md +297 -0
  14. package/docs/patterns/command-agent-skill.md +1 -1
  15. package/docs/perf/performance-review-2026-07.md +287 -0
  16. package/docs/skills/REFERENCE.md +0 -17
  17. package/docs//303/242mmaAAA/303/242 +357 -0
  18. package/index.bundle.ts +25 -0
  19. package/index.ts +95 -4
  20. package/package.json +15 -4
  21. package/skills/iterative-audit/SKILL.md +0 -1
  22. package/skills/widget-rendering/SKILL.md +17 -0
  23. package/src/adapters/claude-adapter.ts +1 -3
  24. package/src/adapters/export-util.ts +16 -16
  25. package/src/adapters/index.ts +5 -5
  26. package/src/agents/agent-config.ts +20 -14
  27. package/src/agents/agent-serializer.ts +1 -1
  28. package/src/agents/discover-agents.ts +83 -39
  29. package/src/benchmark/benchmark-runner.ts +51 -51
  30. package/src/benchmark/feedback-loop.ts +1 -1
  31. package/src/config/config.ts +303 -591
  32. package/src/config/defaults.ts +28 -2
  33. package/src/config/drift-detector.ts +11 -14
  34. package/src/config/markers.ts +201 -203
  35. package/src/config/resilient-parser.ts +14 -6
  36. package/src/config/role-tools.ts +3 -3
  37. package/src/config/suggestions.ts +5 -12
  38. package/src/config/types.ts +9 -25
  39. package/src/errors.ts +151 -157
  40. package/src/extension/action-suggestions.ts +54 -9
  41. package/src/extension/async-notifier.ts +43 -13
  42. package/src/extension/autonomous-policy.ts +77 -37
  43. package/src/extension/command-completions.ts +9 -8
  44. package/src/extension/context-status-injection.ts +14 -12
  45. package/src/extension/crew-autocomplete.ts +8 -16
  46. package/src/extension/crew-cleanup.ts +2 -1
  47. package/src/extension/crew-shortcuts.ts +9 -6
  48. package/src/extension/cross-extension-rpc.ts +136 -42
  49. package/src/extension/help.ts +1 -1
  50. package/src/extension/import-index.ts +10 -5
  51. package/src/extension/knowledge-injection.ts +88 -15
  52. package/src/extension/management.ts +89 -349
  53. package/src/extension/message-renderers.ts +3 -4
  54. package/src/extension/notification-router.ts +22 -5
  55. package/src/extension/notification-sink.ts +6 -3
  56. package/src/extension/pi-api.ts +17 -8
  57. package/src/extension/plan-orchestrate.ts +8 -27
  58. package/src/extension/project-init.ts +21 -6
  59. package/src/extension/register.ts +329 -975
  60. package/src/extension/registration/artifact-cleanup.ts +9 -4
  61. package/src/extension/registration/command-utils.ts +5 -1
  62. package/src/extension/registration/commands.ts +806 -314
  63. package/src/extension/registration/compaction-guard.ts +15 -15
  64. package/src/extension/registration/lifecycle.ts +259 -0
  65. package/src/extension/registration/observability.ts +293 -0
  66. package/src/extension/registration/subagent-helpers.ts +29 -7
  67. package/src/extension/registration/subagent-tools.ts +253 -44
  68. package/src/extension/registration/team-tool.ts +19 -84
  69. package/src/extension/registration/ui.ts +168 -0
  70. package/src/extension/registration/viewers.ts +64 -24
  71. package/src/extension/result-watcher.ts +18 -7
  72. package/src/extension/run-bundle-schema.ts +21 -6
  73. package/src/extension/run-export.ts +15 -6
  74. package/src/extension/run-import.ts +64 -29
  75. package/src/extension/run-index.ts +28 -9
  76. package/src/extension/run-maintenance.ts +32 -12
  77. package/src/extension/session-summary.ts +1 -1
  78. package/src/extension/team-manager-command.ts +64 -7
  79. package/src/extension/team-onboard.ts +149 -150
  80. package/src/extension/team-recommendation.ts +121 -21
  81. package/src/extension/team-tool/anchor.ts +31 -64
  82. package/src/extension/team-tool/api.ts +929 -141
  83. package/src/extension/team-tool/auto-summarize.ts +14 -26
  84. package/src/extension/team-tool/cache-control.ts +1 -5
  85. package/src/extension/team-tool/cancel.ts +138 -38
  86. package/src/extension/team-tool/chain-dispatch.ts +5 -13
  87. package/src/extension/team-tool/chain-executor.ts +29 -51
  88. package/src/extension/team-tool/config-patch.ts +1 -1
  89. package/src/extension/team-tool/context.ts +40 -20
  90. package/src/extension/team-tool/destructive-gate.ts +10 -5
  91. package/src/extension/team-tool/doctor.ts +170 -51
  92. package/src/extension/team-tool/explain.ts +228 -214
  93. package/src/extension/team-tool/failure-patterns.ts +3 -9
  94. package/src/extension/team-tool/goal-wrap.ts +71 -29
  95. package/src/extension/team-tool/goal.ts +185 -35
  96. package/src/extension/team-tool/handle-schedule.ts +34 -15
  97. package/src/extension/team-tool/handle-settings.ts +94 -56
  98. package/src/extension/team-tool/health-monitor.ts +27 -108
  99. package/src/extension/team-tool/inspect.ts +42 -9
  100. package/src/extension/team-tool/intent-policy.ts +4 -1
  101. package/src/extension/team-tool/lifecycle-actions.ts +244 -48
  102. package/src/extension/team-tool/orchestrate.ts +7 -18
  103. package/src/extension/team-tool/parallel-dispatch.ts +51 -29
  104. package/src/extension/team-tool/plan.ts +29 -5
  105. package/src/extension/team-tool/respond.ts +49 -16
  106. package/src/extension/team-tool/run-not-found.ts +3 -8
  107. package/src/extension/team-tool/run.ts +80 -317
  108. package/src/extension/team-tool/status.ts +135 -43
  109. package/src/extension/team-tool/workflow-manage.ts +92 -25
  110. package/src/extension/team-tool-types.ts +8 -1
  111. package/src/extension/team-tool.ts +142 -551
  112. package/src/extension/validate-resources.ts +39 -8
  113. package/src/hooks/registry.ts +66 -17
  114. package/src/hooks/types.ts +1 -1
  115. package/src/i18n.ts +25 -11
  116. package/src/observability/correlation.ts +17 -3
  117. package/src/observability/event-bus.ts +51 -56
  118. package/src/observability/event-to-metric.ts +117 -15
  119. package/src/observability/exporters/otlp-exporter.ts +56 -17
  120. package/src/observability/exporters/prometheus-exporter.ts +1 -1
  121. package/src/observability/metric-registry.ts +16 -4
  122. package/src/observability/metric-retention.ts +8 -2
  123. package/src/observability/metric-sink.ts +11 -3
  124. package/src/observability/metrics-primitives.ts +42 -9
  125. package/src/plugins/plugin-define.ts +2 -2
  126. package/src/plugins/plugin-registry.ts +25 -25
  127. package/src/plugins/plugins/index.ts +1 -1
  128. package/src/plugins/plugins/nextjs.ts +16 -16
  129. package/src/plugins/plugins/vite.ts +7 -11
  130. package/src/plugins/plugins/vitest.ts +6 -11
  131. package/src/runtime/adaptive-plan.ts +225 -40
  132. package/src/runtime/agent-control.ts +58 -15
  133. package/src/runtime/agent-memory.ts +15 -9
  134. package/src/runtime/agent-observability.ts +10 -2
  135. package/src/runtime/anchor-manager.ts +27 -25
  136. package/src/runtime/async-marker.ts +7 -1
  137. package/src/runtime/async-runner.ts +39 -24
  138. package/src/runtime/auto-summarize.ts +7 -13
  139. package/src/runtime/background-runner.ts +189 -251
  140. package/src/runtime/batch-barrier.ts +18 -16
  141. package/src/runtime/cancellation-token.ts +16 -6
  142. package/src/runtime/cancellation.ts +46 -8
  143. package/src/runtime/capability-inventory.ts +6 -4
  144. package/src/runtime/chain-parser.ts +44 -11
  145. package/src/runtime/chain-runner.ts +63 -69
  146. package/src/runtime/checkpoint.ts +12 -56
  147. package/src/runtime/child-pi.ts +344 -79
  148. package/src/runtime/coalesce-tasks.ts +268 -0
  149. package/src/runtime/code-summary.ts +71 -26
  150. package/src/runtime/compact-stages/index.ts +15 -5
  151. package/src/runtime/compact-stages/tail-capture-stage.ts +7 -2
  152. package/src/runtime/compact-stages/truncation-stage.ts +4 -1
  153. package/src/runtime/compaction-summary.ts +17 -10
  154. package/src/runtime/completion-guard.ts +33 -16
  155. package/src/runtime/crash-classification.ts +28 -7
  156. package/src/runtime/crash-recovery.ts +177 -37
  157. package/src/runtime/crew-agent-records.ts +145 -47
  158. package/src/runtime/crew-hooks.ts +9 -24
  159. package/src/runtime/cross-extension-rpc.ts +25 -23
  160. package/src/runtime/custom-tools/irc-tool.ts +43 -15
  161. package/src/runtime/custom-tools/submit-result-tool.ts +16 -5
  162. package/src/runtime/delivery-coordinator.ts +34 -7
  163. package/src/runtime/delta-conflict.ts +9 -21
  164. package/src/runtime/deterministic-ast.ts +1 -1
  165. package/src/runtime/diagnostic-export.ts +53 -20
  166. package/src/runtime/direct-run.ts +12 -2
  167. package/src/runtime/dwf-state-store.ts +1 -1
  168. package/src/runtime/dynamic-workflow-context.ts +187 -59
  169. package/src/runtime/dynamic-workflow-runner.ts +42 -20
  170. package/src/runtime/effectiveness.ts +16 -8
  171. package/src/runtime/errors/crew-errors.ts +7 -11
  172. package/src/runtime/event-stream-bridge.ts +9 -3
  173. package/src/runtime/foreground-control.ts +54 -14
  174. package/src/runtime/foreground-watchdog.ts +9 -6
  175. package/src/runtime/goal-achievement.ts +27 -10
  176. package/src/runtime/goal-evaluator.ts +54 -19
  177. package/src/runtime/goal-loop-runner.ts +280 -99
  178. package/src/runtime/goal-state-store.ts +27 -17
  179. package/src/runtime/green-contract.ts +11 -2
  180. package/src/runtime/group-join.ts +64 -31
  181. package/src/runtime/handoff-manager.ts +37 -42
  182. package/src/runtime/heartbeat-gradient.ts +10 -2
  183. package/src/runtime/heartbeat-watcher.ts +32 -6
  184. package/src/runtime/hidden-handoff.ts +13 -31
  185. package/src/runtime/important-line-classifier.ts +12 -2
  186. package/src/runtime/iteration-hooks.ts +25 -15
  187. package/src/runtime/live-agent-control.ts +55 -7
  188. package/src/runtime/live-agent-manager.ts +130 -27
  189. package/src/runtime/live-control-realtime.ts +23 -3
  190. package/src/runtime/live-irc.ts +4 -1
  191. package/src/runtime/live-session-health.ts +12 -4
  192. package/src/runtime/live-session-runtime.ts +379 -117
  193. package/src/runtime/manifest-cache.ts +28 -12
  194. package/src/runtime/mcp-proxy.ts +10 -18
  195. package/src/runtime/metric-parser.ts +1 -5
  196. package/src/runtime/model-fallback.ts +55 -18
  197. package/src/runtime/model-resolver.ts +2 -6
  198. package/src/runtime/model-scope.ts +19 -3
  199. package/src/runtime/notebook-helpers.ts +60 -62
  200. package/src/runtime/orphan-worker-registry.ts +37 -26
  201. package/src/runtime/output-validator.ts +18 -3
  202. package/src/runtime/overflow-recovery.ts +5 -4
  203. package/src/runtime/parallel-research.ts +29 -5
  204. package/src/runtime/parallel-utils.ts +9 -11
  205. package/src/runtime/path-overlap.ts +150 -0
  206. package/src/runtime/peer-dep.ts +12 -17
  207. package/src/runtime/per-write-validator.ts +1 -3
  208. package/src/runtime/phase-tracker.ts +342 -330
  209. package/src/runtime/pi-args.ts +26 -8
  210. package/src/runtime/pi-json-output.ts +1 -1
  211. package/src/runtime/pi-spawn.ts +30 -19
  212. package/src/runtime/pipeline-runner.ts +56 -55
  213. package/src/runtime/plan-templates.ts +5 -6
  214. package/src/runtime/policy-engine.ts +43 -7
  215. package/src/runtime/post-checks.ts +12 -4
  216. package/src/runtime/post-exit-stdio-guard.ts +2 -2
  217. package/src/runtime/process-lifecycle.ts +20 -10
  218. package/src/runtime/process-status.ts +16 -5
  219. package/src/runtime/progress-event-coalescer.ts +2 -1
  220. package/src/runtime/progress-tracker.ts +103 -103
  221. package/src/runtime/prose-compressor.ts +9 -11
  222. package/src/runtime/recovery-recipes.ts +118 -24
  223. package/src/runtime/replace.ts +25 -10
  224. package/src/runtime/resilient-edit.ts +10 -25
  225. package/src/runtime/result-extractor.ts +2 -6
  226. package/src/runtime/retry-executor.ts +20 -4
  227. package/src/runtime/retry-runner.ts +27 -51
  228. package/src/runtime/role-permission.ts +6 -1
  229. package/src/runtime/run-coalesced-task-group.ts +256 -0
  230. package/src/runtime/run-drift.ts +14 -15
  231. package/src/runtime/run-tracker.ts +6 -28
  232. package/src/runtime/runtime-policy.ts +1 -6
  233. package/src/runtime/runtime-resolver.ts +80 -15
  234. package/src/runtime/scheduler.ts +47 -18
  235. package/src/runtime/semaphore.ts +5 -7
  236. package/src/runtime/sensitive-paths.ts +2 -1
  237. package/src/runtime/session-usage.ts +1 -1
  238. package/src/runtime/settings-store.ts +16 -12
  239. package/src/runtime/sidechain-output.ts +6 -2
  240. package/src/runtime/single-agent-compose.ts +1 -4
  241. package/src/runtime/skill-effectiveness.ts +29 -97
  242. package/src/runtime/skill-instructions.ts +40 -83
  243. package/src/runtime/stale-reconciler.ts +73 -197
  244. package/src/runtime/stream-preview.ts +1 -1
  245. package/src/runtime/streaming-output.ts +1 -1
  246. package/src/runtime/subagent-manager.ts +44 -169
  247. package/src/runtime/subprocess-tool-registry.ts +4 -1
  248. package/src/runtime/supervisor-contact.ts +10 -5
  249. package/src/runtime/task-display.ts +19 -5
  250. package/src/runtime/task-graph-scheduler.ts +95 -21
  251. package/src/runtime/task-graph.ts +5 -11
  252. package/src/runtime/task-health.ts +54 -47
  253. package/src/runtime/task-id.ts +12 -19
  254. package/src/runtime/task-output-context.ts +265 -81
  255. package/src/runtime/task-packet.ts +12 -20
  256. package/src/runtime/task-quality.ts +6 -14
  257. package/src/runtime/task-runner/context-retrieval.ts +4 -13
  258. package/src/runtime/task-runner/live-executor.ts +114 -36
  259. package/src/runtime/task-runner/output-splitter.ts +152 -0
  260. package/src/runtime/task-runner/progress.ts +50 -12
  261. package/src/runtime/task-runner/prompt-builder.ts +31 -7
  262. package/src/runtime/task-runner/prompt-pipeline.ts +31 -7
  263. package/src/runtime/task-runner/result-utils.ts +3 -1
  264. package/src/runtime/task-runner/retrieval-orchestrator.ts +310 -0
  265. package/src/runtime/task-runner/run-projection.ts +27 -8
  266. package/src/runtime/task-runner/state-helpers.ts +50 -14
  267. package/src/runtime/task-runner/tail-read.ts +2 -6
  268. package/src/runtime/task-runner.ts +180 -326
  269. package/src/runtime/team-runner-artifacts.ts +13 -0
  270. package/src/runtime/team-runner.ts +456 -974
  271. package/src/runtime/tool-output-pruner.ts +6 -9
  272. package/src/runtime/tool-progress.ts +11 -21
  273. package/src/runtime/verification-gates.ts +33 -24
  274. package/src/runtime/verification-integrity.ts +2 -7
  275. package/src/runtime/verification-worktree.ts +62 -12
  276. package/src/runtime/worker-heartbeat.ts +5 -1
  277. package/src/runtime/worker-startup.ts +29 -5
  278. package/src/runtime/workflow-state.ts +17 -9
  279. package/src/runtime/workspace-lock.ts +30 -35
  280. package/src/runtime/workspace-tree.ts +20 -32
  281. package/src/runtime/yield-handler.ts +43 -9
  282. package/src/runtime/zombie-scanner.ts +5 -4
  283. package/src/schema/config-schema.ts +266 -172
  284. package/src/schema/team-tool-schema.ts +29 -74
  285. package/src/schema/validation-types.ts +25 -17
  286. package/src/skills/discover-skills.ts +35 -10
  287. package/src/skills/skill-templates.ts +109 -27
  288. package/src/skills/validate.ts +26 -8
  289. package/src/state/active-run-registry.ts +87 -28
  290. package/src/state/artifact-store.ts +9 -5
  291. package/src/state/atomic-write-v2.ts +85 -63
  292. package/src/state/atomic-write.ts +106 -27
  293. package/src/state/blob-store.ts +47 -20
  294. package/src/state/contracts.ts +20 -5
  295. package/src/state/crew-init.ts +5 -22
  296. package/src/state/decision-ledger.ts +19 -73
  297. package/src/state/event-log-rotation.ts +41 -15
  298. package/src/state/event-log.ts +168 -53
  299. package/src/state/event-reconstructor.ts +11 -1
  300. package/src/state/gitignore-manager.ts +2 -8
  301. package/src/state/health-store.ts +57 -57
  302. package/src/state/hook-instinct-bridge.ts +1 -1
  303. package/src/state/hook-integrations.ts +1 -1
  304. package/src/state/instinct-store.ts +17 -5
  305. package/src/state/jsonl-writer.ts +1 -1
  306. package/src/state/locks.ts +23 -9
  307. package/src/state/mailbox.ts +151 -28
  308. package/src/state/observation-store.ts +20 -14
  309. package/src/state/run-cache.ts +142 -135
  310. package/src/state/run-graph.ts +6 -15
  311. package/src/state/run-metrics.ts +5 -18
  312. package/src/state/schedule.ts +15 -9
  313. package/src/state/state-store.ts +137 -47
  314. package/src/state/task-claims.ts +12 -2
  315. package/src/state/tiered-eval.ts +52 -43
  316. package/src/state/types-eval.ts +2 -2
  317. package/src/state/types.ts +24 -20
  318. package/src/state/usage.ts +20 -4
  319. package/src/state/worker-atomic-writer.ts +6 -3
  320. package/src/subagents/index.ts +2 -2
  321. package/src/teams/discover-teams.ts +21 -6
  322. package/src/tools/safe-bash-extension.ts +5 -6
  323. package/src/tools/safe-bash.ts +10 -11
  324. package/src/types/new-api-types.ts +6 -10
  325. package/src/ui/agent-management-overlay.ts +52 -40
  326. package/src/ui/card-colors.ts +13 -4
  327. package/src/ui/crew-footer.ts +8 -7
  328. package/src/ui/crew-select-list.ts +1 -1
  329. package/src/ui/dashboard-panes/agents-pane.ts +41 -25
  330. package/src/ui/dashboard-panes/cancellation-pane.ts +1 -1
  331. package/src/ui/dashboard-panes/capability-pane.ts +32 -15
  332. package/src/ui/dashboard-panes/health-pane.ts +2 -1
  333. package/src/ui/dashboard-panes/metrics-pane.ts +4 -1
  334. package/src/ui/dashboard-panes/progress-pane.ts +12 -9
  335. package/src/ui/heartbeat-aggregator.ts +15 -4
  336. package/src/ui/keybinding-map.ts +40 -7
  337. package/src/ui/live-conversation-overlay.ts +36 -20
  338. package/src/ui/live-duration.ts +1 -4
  339. package/src/ui/live-run-sidebar.ts +88 -25
  340. package/src/ui/loaders.ts +2 -8
  341. package/src/ui/mascot.ts +20 -36
  342. package/src/ui/overlays/agent-picker-overlay.ts +11 -3
  343. package/src/ui/overlays/confirm-overlay.ts +4 -2
  344. package/src/ui/overlays/help-overlay.ts +25 -14
  345. package/src/ui/overlays/mailbox-compose-overlay.ts +48 -11
  346. package/src/ui/overlays/mailbox-compose-preview.ts +20 -5
  347. package/src/ui/overlays/mailbox-detail-overlay.ts +27 -6
  348. package/src/ui/pi-ui-compat.ts +7 -7
  349. package/src/ui/powerbar-publisher.ts +120 -42
  350. package/src/ui/render-diff.ts +10 -3
  351. package/src/ui/render-scheduler.ts +12 -4
  352. package/src/ui/run-action-dispatcher.ts +81 -18
  353. package/src/ui/run-dashboard.ts +172 -76
  354. package/src/ui/run-event-bus.ts +59 -37
  355. package/src/ui/run-snapshot-cache.ts +276 -86
  356. package/src/ui/settings-overlay.ts +361 -74
  357. package/src/ui/status-colors.ts +12 -1
  358. package/src/ui/syntax-highlight.ts +1 -1
  359. package/src/ui/terminal-status.ts +1 -3
  360. package/src/ui/theme-adapter.ts +16 -14
  361. package/src/ui/theme-discovery.ts +13 -2
  362. package/src/ui/tool-progress-formatter.ts +7 -7
  363. package/src/ui/tool-render.ts +128 -56
  364. package/src/ui/tool-renderers/brief-mode.ts +45 -27
  365. package/src/ui/tool-renderers/index.ts +109 -43
  366. package/src/ui/transcript-cache.ts +32 -6
  367. package/src/ui/transcript-entries.ts +25 -23
  368. package/src/ui/transcript-viewer.ts +78 -29
  369. package/src/ui/widget/index.ts +99 -40
  370. package/src/ui/widget/widget-formatters.ts +13 -6
  371. package/src/ui/widget/widget-model.ts +19 -8
  372. package/src/ui/widget/widget-renderer.ts +23 -13
  373. package/src/ui/widget/widget-types.ts +1 -1
  374. package/src/utils/bm25-search.ts +199 -199
  375. package/src/utils/conflict-detect.ts +22 -21
  376. package/src/utils/env-filter.ts +14 -7
  377. package/src/utils/file-coalescer.ts +5 -1
  378. package/src/utils/fingerprint.ts +3 -6
  379. package/src/utils/frontmatter.ts +3 -1
  380. package/src/utils/fs-watch.ts +2 -6
  381. package/src/utils/gh-protocol.ts +119 -44
  382. package/src/utils/git.ts +13 -15
  383. package/src/utils/guards.ts +2 -5
  384. package/src/utils/ids.ts +9 -2
  385. package/src/utils/incremental-reader.ts +14 -3
  386. package/src/utils/internal-error.ts +2 -1
  387. package/src/utils/names.ts +12 -3
  388. package/src/utils/paths.ts +49 -5
  389. package/src/utils/project-detector.ts +2 -2
  390. package/src/utils/redaction.ts +29 -19
  391. package/src/utils/resolve-shell.ts +9 -7
  392. package/src/utils/run-watcher-registry.ts +19 -31
  393. package/src/utils/safe-paths.ts +46 -29
  394. package/src/utils/scan-cache.ts +9 -2
  395. package/src/utils/session-utils.ts +2 -4
  396. package/src/utils/sleep.ts +12 -5
  397. package/src/utils/sse-parser.ts +5 -17
  398. package/src/utils/visual.ts +52 -32
  399. package/src/workflows/discover-workflows.ts +41 -109
  400. package/src/workflows/intermediate-store.ts +5 -21
  401. package/src/workflows/preflight-validator.ts +6 -33
  402. package/src/workflows/topology-analyzer.ts +5 -21
  403. package/src/workflows/workflow-config.ts +7 -6
  404. package/src/worktree/branch-freshness.ts +66 -8
  405. package/src/worktree/cleanup.ts +130 -20
  406. package/src/worktree/worktree-manager.ts +212 -69
  407. package/skills/artifact-analysis-loop/SKILL.md +0 -303
  408. package/skills/detection-pipeline-design/SKILL.md +0 -286
  409. package/skills/hunting-investigation-loop/SKILL.md +0 -402
  410. package/skills/incident-playbook-construction/SKILL.md +0 -384
  411. package/skills/security-review/SKILL.md +0 -561
  412. package/skills/threat-hypothesis-framework/SKILL.md +0 -176
  413. package/skills/ui-render-performance/SKILL.md +0 -58
  414. /package/docs/{followup-review-round3-2026-05-12.md → archive/followup-review-round3-2026-05-12.md} +0 -0
  415. /package/docs/{followup-review-round4-2026-05-13.md → archive/followup-review-round4-2026-05-13.md} +0 -0
  416. /package/docs/{pi-crew-bugs.md → archive/pi-crew-bugs.md} +0 -0
  417. /package/docs/{pi-crew-test-final.md → archive/pi-crew-test-final.md} +0 -0
  418. /package/docs/{pi-crew-test-results.md → archive/pi-crew-test-results.md} +0 -0
  419. /package/docs/{pi-crew-test-round2.md → archive/pi-crew-test-round2.md} +0 -0
  420. /package/docs/{pi-crew-test-round4.md → archive/pi-crew-test-round4.md} +0 -0
  421. /package/docs/{pi-crew-test-round5.md → archive/pi-crew-test-round5.md} +0 -0
  422. /package/docs/{pi-crew-test-round6.md → archive/pi-crew-test-round6.md} +0 -0
  423. /package/docs/{pi-crew-v0.5.10-audit-fix-plan.md → archive/pi-crew-v0.5.10-audit-fix-plan.md} +0 -0
  424. /package/docs/{pi-crew-v0.5.11-audit-fix-plan.md → archive/pi-crew-v0.5.11-audit-fix-plan.md} +0 -0
  425. /package/docs/{pi-crew-v0.5.12-audit-fix-plan.md → archive/pi-crew-v0.5.12-audit-fix-plan.md} +0 -0
  426. /package/docs/{pi-crew-v0.5.13-audit-fix-plan.md → archive/pi-crew-v0.5.13-audit-fix-plan.md} +0 -0
  427. /package/docs/{pi-crew-v0.5.14-audit-fix-plan.md → archive/pi-crew-v0.5.14-audit-fix-plan.md} +0 -0
  428. /package/docs/{pi-crew-v0.5.16-audit-fix-plan.md → archive/pi-crew-v0.5.16-audit-fix-plan.md} +0 -0
  429. /package/docs/{pi-crew-v0.5.17-audit-fix-plan.md → archive/pi-crew-v0.5.17-audit-fix-plan.md} +0 -0
  430. /package/docs/{pi-crew-v0.5.5-audit-fix-plan.md → archive/pi-crew-v0.5.5-audit-fix-plan.md} +0 -0
  431. /package/docs/{pi-crew-v0.5.9-audit-fix-plan.md → archive/pi-crew-v0.5.9-audit-fix-plan.md} +0 -0
  432. /package/docs/{pi-mono-opportunities.md → archive/pi-mono-opportunities.md} +0 -0
  433. /package/docs/{pi-mono-review.md → archive/pi-mono-review.md} +0 -0
  434. /package/docs/{pi-subagent4-comparison.md → archive/pi-subagent4-comparison.md} +0 -0
  435. /package/docs/{pi-subagents3-deep-analysis.md → archive/pi-subagents3-deep-analysis.md} +0 -0
@@ -2,14 +2,14 @@ import { execFileSync, spawnSync } from "node:child_process";
2
2
  import { randomBytes } from "node:crypto";
3
3
  import * as fs from "node:fs";
4
4
  import * as path from "node:path";
5
- import { WINDOWS_ESSENTIAL_ENV_VARS } from "../utils/env-allowlist.ts";
6
5
  import { loadConfig } from "../config/config.ts";
7
- import { projectCrewRoot } from "../utils/paths.ts";
8
6
  import { DEFAULT_PATHS } from "../config/defaults.ts";
9
- import { logInternalError } from "../utils/internal-error.ts";
10
- import { sanitizeEnvSecrets } from "../utils/env-filter.ts";
11
7
  import { writeArtifact } from "../state/artifact-store.ts";
12
8
  import type { TeamRunManifest, TeamTaskState } from "../state/types.ts";
9
+ import { WINDOWS_ESSENTIAL_ENV_VARS } from "../utils/env-allowlist.ts";
10
+ import { sanitizeEnvSecrets } from "../utils/env-filter.ts";
11
+ import { logInternalError } from "../utils/internal-error.ts";
12
+ import { projectCrewRoot } from "../utils/paths.ts";
13
13
 
14
14
  export interface PreparedTaskWorkspace {
15
15
  cwd: string;
@@ -29,15 +29,56 @@ export interface WorktreeDiffStat {
29
29
 
30
30
  function git(cwd: string, args: string[]): string {
31
31
  // SECURITY: PI_* and PI_CREW_* wildcards removed — they could match secret vars like PI_PASSWORD.
32
- // Git operations do not need PI_CREW_* execution-control vars.
33
- return execFileSync("git", args, { cwd, encoding: "utf-8", stdio: ["ignore", "pipe", "pipe"], env: { ...sanitizeEnvSecrets(process.env, { allowList: ["PATH", "HOME", "USER", ...WINDOWS_ESSENTIAL_ENV_VARS, "SHELL", "TERM", "LANG", "LC_ALL", "LC_COLLATE", "LC_CTYPE", "LC_MESSAGES", "XDG_CONFIG_HOME", "XDG_DATA_HOME", "XDG_CACHE_HOME", "NVM_BIN", "NVM_DIR", "NODE_PATH", "GIT_CONFIG_GLOBAL", "GIT_CONFIG_SYSTEM", "GIT_AUTHOR_NAME", "GIT_AUTHOR_EMAIL", "GIT_COMMITTER_NAME", "GIT_COMMITTER_EMAIL"] }), LANG: "en_US.UTF-8", LC_ALL: "en_US.UTF-8" }, windowsHide: true }).trim();
32
+ // Git operations do not need PI_CREW_* execution-control vars.
33
+ return execFileSync("git", args, {
34
+ cwd,
35
+ encoding: "utf-8",
36
+ stdio: ["ignore", "pipe", "pipe"],
37
+ env: {
38
+ ...sanitizeEnvSecrets(process.env, {
39
+ allowList: [
40
+ "PATH",
41
+ "HOME",
42
+ "USER",
43
+ ...WINDOWS_ESSENTIAL_ENV_VARS,
44
+ "SHELL",
45
+ "TERM",
46
+ "LANG",
47
+ "LC_ALL",
48
+ "LC_COLLATE",
49
+ "LC_CTYPE",
50
+ "LC_MESSAGES",
51
+ "XDG_CONFIG_HOME",
52
+ "XDG_DATA_HOME",
53
+ "XDG_CACHE_HOME",
54
+ "NVM_BIN",
55
+ "NVM_DIR",
56
+ "NODE_PATH",
57
+ "GIT_CONFIG_GLOBAL",
58
+ "GIT_CONFIG_SYSTEM",
59
+ "GIT_AUTHOR_NAME",
60
+ "GIT_AUTHOR_EMAIL",
61
+ "GIT_COMMITTER_NAME",
62
+ "GIT_COMMITTER_EMAIL",
63
+ ],
64
+ }),
65
+ LANG: "en_US.UTF-8",
66
+ LC_ALL: "en_US.UTF-8",
67
+ },
68
+ windowsHide: true,
69
+ }).trim();
34
70
  }
35
71
 
36
72
  // Dots are removed from branch names since they are used in path construction,
37
73
  // and dots could cause ambiguity with relative path handling on some platforms.
38
74
  // Branch names themselves support dots in git, but we strip them for safe path use.
39
75
  function sanitizeBranchPart(value: string): string {
40
- return value.toLowerCase().replace(/[^a-z0-9_/-]+/g, "-").replace(/^-+|-+$/g, "") || "task";
76
+ return (
77
+ value
78
+ .toLowerCase()
79
+ .replace(/[^a-z0-9_/-]+/g, "-")
80
+ .replace(/^-+|-+$/g, "") || "task"
81
+ );
41
82
  }
42
83
 
43
84
  export function findGitRoot(cwd: string): string {
@@ -55,16 +96,24 @@ function linkNodeModulesIfPresent(repoRoot: string, worktreePath: string): boole
55
96
  const source = path.join(repoRoot, "node_modules");
56
97
  const target = path.join(worktreePath, "node_modules");
57
98
  let sourceStat: fs.Stats;
58
- try { sourceStat = fs.statSync(source); } catch { return false; }
99
+ try {
100
+ sourceStat = fs.statSync(source);
101
+ } catch {
102
+ return false;
103
+ }
59
104
  if (!sourceStat.isDirectory()) return false;
60
105
  if (fs.existsSync(target)) return false;
61
- // M5 fix: log symlink failure reason, especially on Windows non-admin.
106
+ // M5 fix: log symlink failure reason, especially on Windows non-admin.
62
107
  try {
63
108
  fs.symlinkSync(source, target, process.platform === "win32" ? "junction" : "dir");
64
109
  return true;
65
110
  } catch (error) {
66
111
  const isWindows = process.platform === "win32";
67
- logInternalError("worktree.symlink-fail", error, isWindows ? "Windows non-admin: SeCreateSymbolicLinkPrivilege needed for node_modules symlink" : String(error));
112
+ logInternalError(
113
+ "worktree.symlink-fail",
114
+ error,
115
+ isWindows ? "Windows non-admin: SeCreateSymbolicLinkPrivilege needed for node_modules symlink" : String(error),
116
+ );
68
117
  return false;
69
118
  }
70
119
  }
@@ -133,13 +182,21 @@ function runSetupHook(manifest: TeamRunManifest, task: TeamTaskState, repoRoot:
133
182
  // (isAllowedSetupHook, isHookPathContainedInRepoRoot) prevents hook scripts from writing outside
134
183
  // the worktree, but cannot prevent a trusted hook from performing harmful operations within it.
135
184
  if (path.isAbsolute(rawHookPath)) {
136
- logInternalError("worktree.setupHook.homeHook", new Error("Home directory hook used — ensure ~/.pi/hooks/ is trusted"), `hookPath=${rawHookPath}`);
185
+ logInternalError(
186
+ "worktree.setupHook.homeHook",
187
+ new Error("Home directory hook used — ensure ~/.pi/hooks/ is trusted"),
188
+ `hookPath=${rawHookPath}`,
189
+ );
137
190
  }
138
191
  const hookPath = path.isAbsolute(rawHookPath) ? rawHookPath : path.resolve(repoRoot, rawHookPath);
139
192
  // SECURITY: Verify the resolved hook path is contained within the real repoRoot.
140
193
  // This prevents symlink-based escape where repoRoot is a symlink.
141
194
  if (!path.isAbsolute(rawHookPath) && !isHookPathContainedInRepoRoot(repoRoot, hookPath)) {
142
- logInternalError("worktree.setupHook.contained", new Error("hook path escapes repoRoot after realpath resolution: " + hookPath), `repoRoot=${repoRoot}`);
195
+ logInternalError(
196
+ "worktree.setupHook.contained",
197
+ new Error("hook path escapes repoRoot after realpath resolution: " + hookPath),
198
+ `repoRoot=${repoRoot}`,
199
+ );
143
200
  return [];
144
201
  }
145
202
  try {
@@ -160,7 +217,11 @@ function runSetupHook(manifest: TeamRunManifest, task: TeamTaskState, repoRoot:
160
217
  // running through a shell that could interpret malicious filenames.
161
218
  const useShell = false;
162
219
  if (process.platform === "win32" && !nodeHook && !isBatchFile) {
163
- logInternalError("worktree.setupHook.windowsNoShell", new Error("Non-node, non-batch hook skipped on Windows (shell:true disabled for security)"), `hook=${hookPath}`);
220
+ logInternalError(
221
+ "worktree.setupHook.windowsNoShell",
222
+ new Error("Non-node, non-batch hook skipped on Windows (shell:true disabled for security)"),
223
+ `hook=${hookPath}`,
224
+ );
164
225
  }
165
226
  // SECURITY: Resolve the hook to its real path before execution to close the TOCTOU window.
166
227
  // This prevents a symlink swap between the containment check and actual execution.
@@ -179,45 +240,76 @@ function runSetupHook(manifest: TeamRunManifest, task: TeamTaskState, repoRoot:
179
240
  }
180
241
  const result = isBatchFile
181
242
  ? spawnSync("cmd.exe", ["/c", realHookPath], {
182
- cwd: worktreePath,
183
- encoding: "utf-8",
184
- input: JSON.stringify({ version: 1, repoRoot, worktreePath, agentCwd: worktreePath, branch, runId: manifest.runId, taskId: task.id, agent: task.agent }),
185
- timeout: cfg.setupHookTimeoutMs ?? 30_000,
186
- shell: false, // cmd.exe /c handles batch files safely
187
- env: sanitizeEnvSecrets(process.env, {
188
- allowList: ["PATH", "HOME", ...WINDOWS_ESSENTIAL_ENV_VARS, "TMPDIR", "LANG", "LC_ALL"],
189
- }),
190
- windowsHide: true,
191
- })
243
+ cwd: worktreePath,
244
+ encoding: "utf-8",
245
+ input: JSON.stringify({
246
+ version: 1,
247
+ repoRoot,
248
+ worktreePath,
249
+ agentCwd: worktreePath,
250
+ branch,
251
+ runId: manifest.runId,
252
+ taskId: task.id,
253
+ agent: task.agent,
254
+ }),
255
+ timeout: cfg.setupHookTimeoutMs ?? 30_000,
256
+ shell: false, // cmd.exe /c handles batch files safely
257
+ env: sanitizeEnvSecrets(process.env, {
258
+ allowList: ["PATH", "HOME", ...WINDOWS_ESSENTIAL_ENV_VARS, "TMPDIR", "LANG", "LC_ALL"],
259
+ }),
260
+ windowsHide: true,
261
+ })
192
262
  : spawnSync(nodeHook ? process.execPath : realHookPath, nodeHook ? [realHookPath] : [], {
193
- cwd: worktreePath,
194
- encoding: "utf-8",
195
- input: JSON.stringify({ version: 1, repoRoot, worktreePath, agentCwd: worktreePath, branch, runId: manifest.runId, taskId: task.id, agent: task.agent }),
196
- timeout: cfg.setupHookTimeoutMs ?? 30_000,
197
- shell: false,
198
- env: sanitizeEnvSecrets(process.env, {
199
- allowList: ["PATH", "HOME", ...WINDOWS_ESSENTIAL_ENV_VARS, "TMPDIR", "LANG", "LC_ALL"],
200
- }),
201
- windowsHide: true,
202
- });
263
+ cwd: worktreePath,
264
+ encoding: "utf-8",
265
+ input: JSON.stringify({
266
+ version: 1,
267
+ repoRoot,
268
+ worktreePath,
269
+ agentCwd: worktreePath,
270
+ branch,
271
+ runId: manifest.runId,
272
+ taskId: task.id,
273
+ agent: task.agent,
274
+ }),
275
+ timeout: cfg.setupHookTimeoutMs ?? 30_000,
276
+ shell: false,
277
+ env: sanitizeEnvSecrets(process.env, {
278
+ allowList: ["PATH", "HOME", ...WINDOWS_ESSENTIAL_ENV_VARS, "TMPDIR", "LANG", "LC_ALL"],
279
+ }),
280
+ windowsHide: true,
281
+ });
203
282
  if (result.error) throw new Error(`worktree setup hook failed: ${result.error.message}`);
204
- if (result.status !== 0) throw new Error(`worktree setup hook failed with exit code ${result.status}: ${result.stderr || result.stdout || "no output"}`);
283
+ if (result.status !== 0)
284
+ throw new Error(`worktree setup hook failed with exit code ${result.status}: ${result.stderr || result.stdout || "no output"}`);
205
285
  const trimmed = result.stdout.trim();
206
286
  if (!trimmed) return [];
207
287
  try {
208
288
  // Extract JSON — hooks may output debug logging before JSON.
209
- // M4 fix: try full trimmed (multi-line JSON object) before falling back to last line.
210
- const lines = trimmed.split(/\r?\n/);
211
- let parsed: { syntheticPaths?: unknown } | null = null;
212
- try {
213
- parsed = JSON.parse(trimmed) as { syntheticPaths?: unknown };
214
- } catch { /* fall through — try last line */ }
215
- if (!parsed && lines.length > 0) {
216
- const lastLine = lines[lines.length - 1];
217
- try { parsed = JSON.parse(lastLine) as { syntheticPaths?: unknown }; } catch { /* give up */ }
218
- }
219
- if (!parsed || !Array.isArray(parsed.syntheticPaths)) return [];
220
- return [...new Set(parsed.syntheticPaths.filter((entry): entry is string => typeof entry === "string").map((entry) => normalizeSyntheticPath(worktreePath, entry)))];
289
+ // M4 fix: try full trimmed (multi-line JSON object) before falling back to last line.
290
+ const lines = trimmed.split(/\r?\n/);
291
+ let parsed: { syntheticPaths?: unknown } | null = null;
292
+ try {
293
+ parsed = JSON.parse(trimmed) as { syntheticPaths?: unknown };
294
+ } catch {
295
+ /* fall through try last line */
296
+ }
297
+ if (!parsed && lines.length > 0) {
298
+ const lastLine = lines[lines.length - 1];
299
+ try {
300
+ parsed = JSON.parse(lastLine) as { syntheticPaths?: unknown };
301
+ } catch {
302
+ /* give up */
303
+ }
304
+ }
305
+ if (!parsed || !Array.isArray(parsed.syntheticPaths)) return [];
306
+ return [
307
+ ...new Set(
308
+ parsed.syntheticPaths
309
+ .filter((entry): entry is string => typeof entry === "string")
310
+ .map((entry) => normalizeSyntheticPath(worktreePath, entry)),
311
+ ),
312
+ ];
221
313
  } catch (error) {
222
314
  logInternalError("worktree.setupHook.parse", error, `lastLine=${(trimmed.split(/\r?\n/).pop() ?? "").slice(0, 200)}`);
223
315
  return [];
@@ -226,19 +318,34 @@ function runSetupHook(manifest: TeamRunManifest, task: TeamTaskState, repoRoot:
226
318
 
227
319
  function branchExists(repoRoot: string, branch: string): { local: boolean; remoteOnly: boolean } {
228
320
  let local = false;
229
- try { git(repoRoot, ["rev-parse", "--verify", `refs/heads/${branch}`]); local = true; } catch {}
321
+ try {
322
+ git(repoRoot, ["rev-parse", "--verify", `refs/heads/${branch}`]);
323
+ local = true;
324
+ } catch {}
230
325
  if (local) return { local: true, remoteOnly: false };
231
326
  // Check remote-tracking branch
232
327
  try {
233
- const out = execFileSync("git", ["for-each-ref", "--format=%(refname)", `refs/remotes/*/${branch}`],
234
- { cwd: repoRoot, encoding: "utf-8", stdio: ["ignore", "pipe", "pipe"], windowsHide: true }).trim();
328
+ const out = execFileSync("git", ["for-each-ref", "--format=%(refname)", `refs/remotes/*/${branch}`], {
329
+ cwd: repoRoot,
330
+ encoding: "utf-8",
331
+ stdio: ["ignore", "pipe", "pipe"],
332
+ windowsHide: true,
333
+ }).trim();
235
334
  return { local: false, remoteOnly: out.length > 0 };
236
- } catch { return { local: false, remoteOnly: false }; }
335
+ } catch {
336
+ return { local: false, remoteOnly: false };
337
+ }
237
338
  }
238
339
 
239
340
  function pruneStaleWorktrees(repoRoot: string): void {
240
- try { execFileSync("git", ["worktree", "prune"], { cwd: repoRoot, stdio: "ignore" }); }
241
- catch { /* best-effort */ }
341
+ try {
342
+ execFileSync("git", ["worktree", "prune"], {
343
+ cwd: repoRoot,
344
+ stdio: "ignore",
345
+ });
346
+ } catch {
347
+ /* best-effort */
348
+ }
242
349
  }
243
350
 
244
351
  /**
@@ -344,7 +451,11 @@ export function prepareTaskWorkspace(manifest: TeamRunManifest, task: TeamTaskSt
344
451
  const r = fs.realpathSync.native(worktreeRoot);
345
452
  resolvedWorktreeRoot = r.startsWith("\\\\?\\") ? r.slice(4) : r;
346
453
  } catch {
347
- try { resolvedWorktreeRoot = fs.realpathSync(worktreeRoot); } catch { /* keep as-is */ }
454
+ try {
455
+ resolvedWorktreeRoot = fs.realpathSync(worktreeRoot);
456
+ } catch {
457
+ /* keep as-is */
458
+ }
348
459
  }
349
460
  const sanitizedTaskId = sanitizeBranchPart(task.id);
350
461
  const worktreePath = path.join(resolvedWorktreeRoot, sanitizedTaskId);
@@ -360,7 +471,19 @@ export function prepareTaskWorkspace(manifest: TeamRunManifest, task: TeamTaskSt
360
471
  // worktreePath uses short-name backslash form. Resolve both through
361
472
  // realpathSync.native (which always returns long-name on Windows)
362
473
  // for consistent comparison.
363
- const normalizedWtPath = process.platform === "win32" ? (() => { try { const r = fs.realpathSync.native(worktreePath); return r.startsWith("\\\\?\\") ? r.slice(4) : r; } catch { return worktreePath; } })().replace(/\\/g, "/").toLowerCase() : worktreePath;
474
+ const normalizedWtPath =
475
+ process.platform === "win32"
476
+ ? (() => {
477
+ try {
478
+ const r = fs.realpathSync.native(worktreePath);
479
+ return r.startsWith("\\\\?\\") ? r.slice(4) : r;
480
+ } catch {
481
+ return worktreePath;
482
+ }
483
+ })()
484
+ .replace(/\\/g, "/")
485
+ .toLowerCase()
486
+ : worktreePath;
364
487
  worktreeExists = worktreeList.split("\n").some((line) => {
365
488
  const trimmed = line.trim();
366
489
  const matchPath = trimmed.startsWith("worktree ") ? trimmed.slice(9) : trimmed;
@@ -369,13 +492,17 @@ export function prepareTaskWorkspace(manifest: TeamRunManifest, task: TeamTaskSt
369
492
  }
370
493
  return matchPath === worktreePath;
371
494
  });
372
- } catch { worktreeExists = false; }
495
+ } catch {
496
+ worktreeExists = false;
497
+ }
373
498
  if (worktreeExists) {
374
499
  let currentBranch: string;
375
500
  try {
376
501
  currentBranch = git(worktreePath, ["rev-parse", "--abbrev-ref", "HEAD"]);
377
502
  } catch (gitError) {
378
- throw new Error(`Existing worktree at ${worktreePath} is not a valid git repository; cannot verify branch: ${gitError instanceof Error ? gitError.message : String(gitError)}`);
503
+ throw new Error(
504
+ `Existing worktree at ${worktreePath} is not a valid git repository; cannot verify branch: ${gitError instanceof Error ? gitError.message : String(gitError)}`,
505
+ );
379
506
  }
380
507
  if (currentBranch !== branch) {
381
508
  throw new Error(`Existing worktree branch mismatch at ${worktreePath}: expected '${branch}', got '${currentBranch}'.`);
@@ -384,7 +511,11 @@ export function prepareTaskWorkspace(manifest: TeamRunManifest, task: TeamTaskSt
384
511
  const dirtyStatus = git(worktreePath, ["status", "--porcelain"]);
385
512
  if (dirtyStatus.trim()) {
386
513
  // Discard uncommitted changes to ensure clean slate for new task
387
- logInternalError("worktree.reused.dirty", new Error(`Discarding uncommitted changes in reused worktree at ${worktreePath}`), `runId=${manifest.runId}, taskId=${task.id}, dirtyStatus=${dirtyStatus.trim()}`);
514
+ logInternalError(
515
+ "worktree.reused.dirty",
516
+ new Error(`Discarding uncommitted changes in reused worktree at ${worktreePath}`),
517
+ `runId=${manifest.runId}, taskId=${task.id}, dirtyStatus=${dirtyStatus.trim()}`,
518
+ );
388
519
  git(worktreePath, ["checkout", "--", "."]);
389
520
  git(worktreePath, ["clean", "-fd"]);
390
521
  }
@@ -406,7 +537,11 @@ export function prepareTaskWorkspace(manifest: TeamRunManifest, task: TeamTaskSt
406
537
  git(repoRoot, ["worktree", "add", worktreePath, branch]);
407
538
  } else {
408
539
  if (exists.remoteOnly) {
409
- logInternalError("worktree.branchRemoteOnly", new Error(`Branch '${branch}' exists only on remote; creating local from HEAD instead of tracking remote.`), `branch=${branch}`);
540
+ logInternalError(
541
+ "worktree.branchRemoteOnly",
542
+ new Error(`Branch '${branch}' exists only on remote; creating local from HEAD instead of tracking remote.`),
543
+ `branch=${branch}`,
544
+ );
410
545
  }
411
546
  git(repoRoot, ["worktree", "add", "-b", branch, worktreePath, "HEAD"]);
412
547
  }
@@ -416,23 +551,35 @@ export function prepareTaskWorkspace(manifest: TeamRunManifest, task: TeamTaskSt
416
551
  if (fs.existsSync(worktreePath)) {
417
552
  try {
418
553
  fs.rmSync(worktreePath, { recursive: true, force: true });
419
- } catch { /* best-effort cleanup */ }
554
+ } catch {
555
+ /* best-effort cleanup */
556
+ }
420
557
  }
421
558
  const msg = error instanceof Error ? error.message : String(error);
422
559
  if (/already checked out|is already used by worktree/i.test(msg)) {
423
- throw new Error(`Branch '${branch}' is checked out at another worktree. Run \`team cleanup runId=${manifest.runId} force=true\` or manually remove the conflicting worktree.`);
560
+ throw new Error(
561
+ `Branch '${branch}' is checked out at another worktree. Run \`team cleanup runId=${manifest.runId} force=true\` or manually remove the conflicting worktree.`,
562
+ );
424
563
  }
425
564
  throw error;
426
565
  }
427
566
  const syntheticPaths = runSetupHook(manifest, task, repoRoot, worktreePath, branch);
428
- const nodeModulesLinked = loadedConfig.config.worktree?.linkNodeModules === true ? linkNodeModulesIfPresent(repoRoot, worktreePath) : false;
567
+ const nodeModulesLinked =
568
+ loadedConfig.config.worktree?.linkNodeModules === true ? linkNodeModulesIfPresent(repoRoot, worktreePath) : false;
429
569
  // Overlay seed paths from config + step-level seedPaths
430
570
  const globalSeedPaths = loadedConfig.config.worktree?.seedPaths ?? [];
431
571
  const merged = normalizeSeedPaths([...globalSeedPaths, ...(stepSeedPaths ?? [])], repoRoot);
432
572
  if (merged.length > 0) {
433
573
  overlaySeedPaths(repoRoot, worktreePath, merged);
434
574
  }
435
- return { cwd: worktreePath, worktreePath, branch, reused: false, nodeModulesLinked, syntheticPaths };
575
+ return {
576
+ cwd: worktreePath,
577
+ worktreePath,
578
+ branch,
579
+ reused: false,
580
+ nodeModulesLinked,
581
+ syntheticPaths,
582
+ };
436
583
  }
437
584
 
438
585
  export function captureWorktreeDiffStat(worktreePath: string): WorktreeDiffStat {
@@ -475,10 +622,7 @@ export function captureWorktreeDiff(worktreePath: string): string {
475
622
  * Returns `undefined` when worktree creation is unavailable (no git repo, dirty
476
623
  * leader, git error) so the caller (`ctx.agent`) can fall back gracefully.
477
624
  */
478
- export function prepareAgentWorktree(
479
- manifest: TeamRunManifest,
480
- agentId: string,
481
- ): PreparedTaskWorkspace | undefined {
625
+ export function prepareAgentWorktree(manifest: TeamRunManifest, agentId: string): PreparedTaskWorkspace | undefined {
482
626
  try {
483
627
  const repoRoot = findGitRoot(manifest.cwd);
484
628
  const loadedConfig = loadConfig(manifest.cwd);
@@ -491,9 +635,8 @@ export function prepareAgentWorktree(
491
635
  const branch = `pi-crew/${sanitizedRunId}/${sanitizedAgentId}`;
492
636
  pruneStaleWorktrees(repoRoot);
493
637
  git(repoRoot, ["worktree", "add", "-b", branch, worktreePath, "HEAD"]);
494
- const nodeModulesLinked = loadedConfig.config.worktree?.linkNodeModules === true
495
- ? linkNodeModulesIfPresent(repoRoot, worktreePath)
496
- : false;
638
+ const nodeModulesLinked =
639
+ loadedConfig.config.worktree?.linkNodeModules === true ? linkNodeModulesIfPresent(repoRoot, worktreePath) : false;
497
640
  return { cwd: worktreePath, worktreePath, branch, nodeModulesLinked };
498
641
  } catch {
499
642
  // Graceful fallback: no git repo, dirty leader, or git error → run normally.