pi-crew 0.9.16 → 0.9.18

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (435) hide show
  1. package/CHANGELOG.md +130 -0
  2. package/README.md +19 -0
  3. package/dist/build-meta.json +21784 -0
  4. package/dist/index.mjs +83169 -0
  5. package/dist/index.mjs.map +7 -0
  6. package/docs/A +358 -0
  7. package/docs/M-A +357 -0
  8. package/docs/REVIEW-FINDINGS-2026-06 +357 -0
  9. package/docs/Y +357 -0
  10. package/docs/a +357 -0
  11. package/docs/aA +358 -0
  12. package/docs/archive/README.md +91 -0
  13. package/docs/migration/atomic-write-v2-migration.md +297 -0
  14. package/docs/patterns/command-agent-skill.md +1 -1
  15. package/docs/perf/performance-review-2026-07.md +287 -0
  16. package/docs/skills/REFERENCE.md +0 -17
  17. package/docs//303/242mmaAAA/303/242 +357 -0
  18. package/index.bundle.ts +25 -0
  19. package/index.ts +95 -4
  20. package/package.json +15 -4
  21. package/skills/iterative-audit/SKILL.md +0 -1
  22. package/skills/widget-rendering/SKILL.md +17 -0
  23. package/src/adapters/claude-adapter.ts +1 -3
  24. package/src/adapters/export-util.ts +16 -16
  25. package/src/adapters/index.ts +5 -5
  26. package/src/agents/agent-config.ts +20 -14
  27. package/src/agents/agent-serializer.ts +1 -1
  28. package/src/agents/discover-agents.ts +83 -39
  29. package/src/benchmark/benchmark-runner.ts +51 -51
  30. package/src/benchmark/feedback-loop.ts +1 -1
  31. package/src/config/config.ts +303 -591
  32. package/src/config/defaults.ts +28 -2
  33. package/src/config/drift-detector.ts +11 -14
  34. package/src/config/markers.ts +201 -203
  35. package/src/config/resilient-parser.ts +14 -6
  36. package/src/config/role-tools.ts +3 -3
  37. package/src/config/suggestions.ts +5 -12
  38. package/src/config/types.ts +9 -25
  39. package/src/errors.ts +151 -157
  40. package/src/extension/action-suggestions.ts +54 -9
  41. package/src/extension/async-notifier.ts +43 -13
  42. package/src/extension/autonomous-policy.ts +77 -37
  43. package/src/extension/command-completions.ts +9 -8
  44. package/src/extension/context-status-injection.ts +14 -12
  45. package/src/extension/crew-autocomplete.ts +8 -16
  46. package/src/extension/crew-cleanup.ts +2 -1
  47. package/src/extension/crew-shortcuts.ts +9 -6
  48. package/src/extension/cross-extension-rpc.ts +136 -42
  49. package/src/extension/help.ts +1 -1
  50. package/src/extension/import-index.ts +10 -5
  51. package/src/extension/knowledge-injection.ts +88 -15
  52. package/src/extension/management.ts +89 -349
  53. package/src/extension/message-renderers.ts +3 -4
  54. package/src/extension/notification-router.ts +22 -5
  55. package/src/extension/notification-sink.ts +6 -3
  56. package/src/extension/pi-api.ts +17 -8
  57. package/src/extension/plan-orchestrate.ts +8 -27
  58. package/src/extension/project-init.ts +21 -6
  59. package/src/extension/register.ts +329 -975
  60. package/src/extension/registration/artifact-cleanup.ts +9 -4
  61. package/src/extension/registration/command-utils.ts +5 -1
  62. package/src/extension/registration/commands.ts +806 -314
  63. package/src/extension/registration/compaction-guard.ts +15 -15
  64. package/src/extension/registration/lifecycle.ts +259 -0
  65. package/src/extension/registration/observability.ts +293 -0
  66. package/src/extension/registration/subagent-helpers.ts +29 -7
  67. package/src/extension/registration/subagent-tools.ts +253 -44
  68. package/src/extension/registration/team-tool.ts +19 -84
  69. package/src/extension/registration/ui.ts +168 -0
  70. package/src/extension/registration/viewers.ts +64 -24
  71. package/src/extension/result-watcher.ts +18 -7
  72. package/src/extension/run-bundle-schema.ts +21 -6
  73. package/src/extension/run-export.ts +15 -6
  74. package/src/extension/run-import.ts +64 -29
  75. package/src/extension/run-index.ts +28 -9
  76. package/src/extension/run-maintenance.ts +32 -12
  77. package/src/extension/session-summary.ts +1 -1
  78. package/src/extension/team-manager-command.ts +64 -7
  79. package/src/extension/team-onboard.ts +149 -150
  80. package/src/extension/team-recommendation.ts +121 -21
  81. package/src/extension/team-tool/anchor.ts +31 -64
  82. package/src/extension/team-tool/api.ts +929 -141
  83. package/src/extension/team-tool/auto-summarize.ts +14 -26
  84. package/src/extension/team-tool/cache-control.ts +1 -5
  85. package/src/extension/team-tool/cancel.ts +138 -38
  86. package/src/extension/team-tool/chain-dispatch.ts +5 -13
  87. package/src/extension/team-tool/chain-executor.ts +29 -51
  88. package/src/extension/team-tool/config-patch.ts +1 -1
  89. package/src/extension/team-tool/context.ts +40 -20
  90. package/src/extension/team-tool/destructive-gate.ts +10 -5
  91. package/src/extension/team-tool/doctor.ts +170 -51
  92. package/src/extension/team-tool/explain.ts +228 -214
  93. package/src/extension/team-tool/failure-patterns.ts +3 -9
  94. package/src/extension/team-tool/goal-wrap.ts +71 -29
  95. package/src/extension/team-tool/goal.ts +185 -35
  96. package/src/extension/team-tool/handle-schedule.ts +34 -15
  97. package/src/extension/team-tool/handle-settings.ts +94 -56
  98. package/src/extension/team-tool/health-monitor.ts +27 -108
  99. package/src/extension/team-tool/inspect.ts +42 -9
  100. package/src/extension/team-tool/intent-policy.ts +4 -1
  101. package/src/extension/team-tool/lifecycle-actions.ts +244 -48
  102. package/src/extension/team-tool/orchestrate.ts +7 -18
  103. package/src/extension/team-tool/parallel-dispatch.ts +51 -29
  104. package/src/extension/team-tool/plan.ts +29 -5
  105. package/src/extension/team-tool/respond.ts +49 -16
  106. package/src/extension/team-tool/run-not-found.ts +3 -8
  107. package/src/extension/team-tool/run.ts +80 -317
  108. package/src/extension/team-tool/status.ts +135 -43
  109. package/src/extension/team-tool/workflow-manage.ts +92 -25
  110. package/src/extension/team-tool-types.ts +8 -1
  111. package/src/extension/team-tool.ts +142 -551
  112. package/src/extension/validate-resources.ts +39 -8
  113. package/src/hooks/registry.ts +66 -17
  114. package/src/hooks/types.ts +1 -1
  115. package/src/i18n.ts +25 -11
  116. package/src/observability/correlation.ts +17 -3
  117. package/src/observability/event-bus.ts +51 -56
  118. package/src/observability/event-to-metric.ts +117 -15
  119. package/src/observability/exporters/otlp-exporter.ts +56 -17
  120. package/src/observability/exporters/prometheus-exporter.ts +1 -1
  121. package/src/observability/metric-registry.ts +16 -4
  122. package/src/observability/metric-retention.ts +8 -2
  123. package/src/observability/metric-sink.ts +11 -3
  124. package/src/observability/metrics-primitives.ts +42 -9
  125. package/src/plugins/plugin-define.ts +2 -2
  126. package/src/plugins/plugin-registry.ts +25 -25
  127. package/src/plugins/plugins/index.ts +1 -1
  128. package/src/plugins/plugins/nextjs.ts +16 -16
  129. package/src/plugins/plugins/vite.ts +7 -11
  130. package/src/plugins/plugins/vitest.ts +6 -11
  131. package/src/runtime/adaptive-plan.ts +225 -40
  132. package/src/runtime/agent-control.ts +58 -15
  133. package/src/runtime/agent-memory.ts +15 -9
  134. package/src/runtime/agent-observability.ts +10 -2
  135. package/src/runtime/anchor-manager.ts +27 -25
  136. package/src/runtime/async-marker.ts +7 -1
  137. package/src/runtime/async-runner.ts +39 -24
  138. package/src/runtime/auto-summarize.ts +7 -13
  139. package/src/runtime/background-runner.ts +189 -251
  140. package/src/runtime/batch-barrier.ts +18 -16
  141. package/src/runtime/cancellation-token.ts +16 -6
  142. package/src/runtime/cancellation.ts +46 -8
  143. package/src/runtime/capability-inventory.ts +6 -4
  144. package/src/runtime/chain-parser.ts +44 -11
  145. package/src/runtime/chain-runner.ts +63 -69
  146. package/src/runtime/checkpoint.ts +12 -56
  147. package/src/runtime/child-pi.ts +344 -79
  148. package/src/runtime/coalesce-tasks.ts +268 -0
  149. package/src/runtime/code-summary.ts +71 -26
  150. package/src/runtime/compact-stages/index.ts +15 -5
  151. package/src/runtime/compact-stages/tail-capture-stage.ts +7 -2
  152. package/src/runtime/compact-stages/truncation-stage.ts +4 -1
  153. package/src/runtime/compaction-summary.ts +17 -10
  154. package/src/runtime/completion-guard.ts +33 -16
  155. package/src/runtime/crash-classification.ts +28 -7
  156. package/src/runtime/crash-recovery.ts +177 -37
  157. package/src/runtime/crew-agent-records.ts +145 -47
  158. package/src/runtime/crew-hooks.ts +9 -24
  159. package/src/runtime/cross-extension-rpc.ts +25 -23
  160. package/src/runtime/custom-tools/irc-tool.ts +43 -15
  161. package/src/runtime/custom-tools/submit-result-tool.ts +16 -5
  162. package/src/runtime/delivery-coordinator.ts +34 -7
  163. package/src/runtime/delta-conflict.ts +9 -21
  164. package/src/runtime/deterministic-ast.ts +1 -1
  165. package/src/runtime/diagnostic-export.ts +53 -20
  166. package/src/runtime/direct-run.ts +12 -2
  167. package/src/runtime/dwf-state-store.ts +1 -1
  168. package/src/runtime/dynamic-workflow-context.ts +187 -59
  169. package/src/runtime/dynamic-workflow-runner.ts +42 -20
  170. package/src/runtime/effectiveness.ts +16 -8
  171. package/src/runtime/errors/crew-errors.ts +7 -11
  172. package/src/runtime/event-stream-bridge.ts +9 -3
  173. package/src/runtime/foreground-control.ts +54 -14
  174. package/src/runtime/foreground-watchdog.ts +9 -6
  175. package/src/runtime/goal-achievement.ts +27 -10
  176. package/src/runtime/goal-evaluator.ts +54 -19
  177. package/src/runtime/goal-loop-runner.ts +280 -99
  178. package/src/runtime/goal-state-store.ts +27 -17
  179. package/src/runtime/green-contract.ts +11 -2
  180. package/src/runtime/group-join.ts +64 -31
  181. package/src/runtime/handoff-manager.ts +37 -42
  182. package/src/runtime/heartbeat-gradient.ts +10 -2
  183. package/src/runtime/heartbeat-watcher.ts +32 -6
  184. package/src/runtime/hidden-handoff.ts +13 -31
  185. package/src/runtime/important-line-classifier.ts +12 -2
  186. package/src/runtime/iteration-hooks.ts +25 -15
  187. package/src/runtime/live-agent-control.ts +55 -7
  188. package/src/runtime/live-agent-manager.ts +130 -27
  189. package/src/runtime/live-control-realtime.ts +23 -3
  190. package/src/runtime/live-irc.ts +4 -1
  191. package/src/runtime/live-session-health.ts +12 -4
  192. package/src/runtime/live-session-runtime.ts +379 -117
  193. package/src/runtime/manifest-cache.ts +28 -12
  194. package/src/runtime/mcp-proxy.ts +10 -18
  195. package/src/runtime/metric-parser.ts +1 -5
  196. package/src/runtime/model-fallback.ts +55 -18
  197. package/src/runtime/model-resolver.ts +2 -6
  198. package/src/runtime/model-scope.ts +19 -3
  199. package/src/runtime/notebook-helpers.ts +60 -62
  200. package/src/runtime/orphan-worker-registry.ts +37 -26
  201. package/src/runtime/output-validator.ts +18 -3
  202. package/src/runtime/overflow-recovery.ts +5 -4
  203. package/src/runtime/parallel-research.ts +29 -5
  204. package/src/runtime/parallel-utils.ts +9 -11
  205. package/src/runtime/path-overlap.ts +150 -0
  206. package/src/runtime/peer-dep.ts +12 -17
  207. package/src/runtime/per-write-validator.ts +1 -3
  208. package/src/runtime/phase-tracker.ts +342 -330
  209. package/src/runtime/pi-args.ts +26 -8
  210. package/src/runtime/pi-json-output.ts +1 -1
  211. package/src/runtime/pi-spawn.ts +30 -19
  212. package/src/runtime/pipeline-runner.ts +56 -55
  213. package/src/runtime/plan-templates.ts +5 -6
  214. package/src/runtime/policy-engine.ts +43 -7
  215. package/src/runtime/post-checks.ts +12 -4
  216. package/src/runtime/post-exit-stdio-guard.ts +2 -2
  217. package/src/runtime/process-lifecycle.ts +20 -10
  218. package/src/runtime/process-status.ts +16 -5
  219. package/src/runtime/progress-event-coalescer.ts +2 -1
  220. package/src/runtime/progress-tracker.ts +103 -103
  221. package/src/runtime/prose-compressor.ts +9 -11
  222. package/src/runtime/recovery-recipes.ts +118 -24
  223. package/src/runtime/replace.ts +25 -10
  224. package/src/runtime/resilient-edit.ts +10 -25
  225. package/src/runtime/result-extractor.ts +2 -6
  226. package/src/runtime/retry-executor.ts +20 -4
  227. package/src/runtime/retry-runner.ts +27 -51
  228. package/src/runtime/role-permission.ts +6 -1
  229. package/src/runtime/run-coalesced-task-group.ts +256 -0
  230. package/src/runtime/run-drift.ts +14 -15
  231. package/src/runtime/run-tracker.ts +6 -28
  232. package/src/runtime/runtime-policy.ts +1 -6
  233. package/src/runtime/runtime-resolver.ts +80 -15
  234. package/src/runtime/scheduler.ts +47 -18
  235. package/src/runtime/semaphore.ts +5 -7
  236. package/src/runtime/sensitive-paths.ts +2 -1
  237. package/src/runtime/session-usage.ts +1 -1
  238. package/src/runtime/settings-store.ts +16 -12
  239. package/src/runtime/sidechain-output.ts +6 -2
  240. package/src/runtime/single-agent-compose.ts +1 -4
  241. package/src/runtime/skill-effectiveness.ts +29 -97
  242. package/src/runtime/skill-instructions.ts +40 -83
  243. package/src/runtime/stale-reconciler.ts +73 -197
  244. package/src/runtime/stream-preview.ts +1 -1
  245. package/src/runtime/streaming-output.ts +1 -1
  246. package/src/runtime/subagent-manager.ts +44 -169
  247. package/src/runtime/subprocess-tool-registry.ts +4 -1
  248. package/src/runtime/supervisor-contact.ts +10 -5
  249. package/src/runtime/task-display.ts +19 -5
  250. package/src/runtime/task-graph-scheduler.ts +95 -21
  251. package/src/runtime/task-graph.ts +5 -11
  252. package/src/runtime/task-health.ts +54 -47
  253. package/src/runtime/task-id.ts +12 -19
  254. package/src/runtime/task-output-context.ts +265 -81
  255. package/src/runtime/task-packet.ts +12 -20
  256. package/src/runtime/task-quality.ts +6 -14
  257. package/src/runtime/task-runner/context-retrieval.ts +4 -13
  258. package/src/runtime/task-runner/live-executor.ts +114 -36
  259. package/src/runtime/task-runner/output-splitter.ts +152 -0
  260. package/src/runtime/task-runner/progress.ts +50 -12
  261. package/src/runtime/task-runner/prompt-builder.ts +31 -7
  262. package/src/runtime/task-runner/prompt-pipeline.ts +31 -7
  263. package/src/runtime/task-runner/result-utils.ts +3 -1
  264. package/src/runtime/task-runner/retrieval-orchestrator.ts +310 -0
  265. package/src/runtime/task-runner/run-projection.ts +27 -8
  266. package/src/runtime/task-runner/state-helpers.ts +50 -14
  267. package/src/runtime/task-runner/tail-read.ts +2 -6
  268. package/src/runtime/task-runner.ts +180 -326
  269. package/src/runtime/team-runner-artifacts.ts +13 -0
  270. package/src/runtime/team-runner.ts +456 -974
  271. package/src/runtime/tool-output-pruner.ts +6 -9
  272. package/src/runtime/tool-progress.ts +11 -21
  273. package/src/runtime/verification-gates.ts +33 -24
  274. package/src/runtime/verification-integrity.ts +2 -7
  275. package/src/runtime/verification-worktree.ts +62 -12
  276. package/src/runtime/worker-heartbeat.ts +5 -1
  277. package/src/runtime/worker-startup.ts +29 -5
  278. package/src/runtime/workflow-state.ts +17 -9
  279. package/src/runtime/workspace-lock.ts +30 -35
  280. package/src/runtime/workspace-tree.ts +20 -32
  281. package/src/runtime/yield-handler.ts +43 -9
  282. package/src/runtime/zombie-scanner.ts +5 -4
  283. package/src/schema/config-schema.ts +266 -172
  284. package/src/schema/team-tool-schema.ts +29 -74
  285. package/src/schema/validation-types.ts +25 -17
  286. package/src/skills/discover-skills.ts +35 -10
  287. package/src/skills/skill-templates.ts +109 -27
  288. package/src/skills/validate.ts +26 -8
  289. package/src/state/active-run-registry.ts +87 -28
  290. package/src/state/artifact-store.ts +9 -5
  291. package/src/state/atomic-write-v2.ts +85 -63
  292. package/src/state/atomic-write.ts +106 -27
  293. package/src/state/blob-store.ts +47 -20
  294. package/src/state/contracts.ts +20 -5
  295. package/src/state/crew-init.ts +5 -22
  296. package/src/state/decision-ledger.ts +19 -73
  297. package/src/state/event-log-rotation.ts +41 -15
  298. package/src/state/event-log.ts +168 -53
  299. package/src/state/event-reconstructor.ts +11 -1
  300. package/src/state/gitignore-manager.ts +2 -8
  301. package/src/state/health-store.ts +57 -57
  302. package/src/state/hook-instinct-bridge.ts +1 -1
  303. package/src/state/hook-integrations.ts +1 -1
  304. package/src/state/instinct-store.ts +17 -5
  305. package/src/state/jsonl-writer.ts +1 -1
  306. package/src/state/locks.ts +23 -9
  307. package/src/state/mailbox.ts +151 -28
  308. package/src/state/observation-store.ts +20 -14
  309. package/src/state/run-cache.ts +142 -135
  310. package/src/state/run-graph.ts +6 -15
  311. package/src/state/run-metrics.ts +5 -18
  312. package/src/state/schedule.ts +15 -9
  313. package/src/state/state-store.ts +137 -47
  314. package/src/state/task-claims.ts +12 -2
  315. package/src/state/tiered-eval.ts +52 -43
  316. package/src/state/types-eval.ts +2 -2
  317. package/src/state/types.ts +24 -20
  318. package/src/state/usage.ts +20 -4
  319. package/src/state/worker-atomic-writer.ts +6 -3
  320. package/src/subagents/index.ts +2 -2
  321. package/src/teams/discover-teams.ts +21 -6
  322. package/src/tools/safe-bash-extension.ts +5 -6
  323. package/src/tools/safe-bash.ts +10 -11
  324. package/src/types/new-api-types.ts +6 -10
  325. package/src/ui/agent-management-overlay.ts +52 -40
  326. package/src/ui/card-colors.ts +13 -4
  327. package/src/ui/crew-footer.ts +8 -7
  328. package/src/ui/crew-select-list.ts +1 -1
  329. package/src/ui/dashboard-panes/agents-pane.ts +41 -25
  330. package/src/ui/dashboard-panes/cancellation-pane.ts +1 -1
  331. package/src/ui/dashboard-panes/capability-pane.ts +32 -15
  332. package/src/ui/dashboard-panes/health-pane.ts +2 -1
  333. package/src/ui/dashboard-panes/metrics-pane.ts +4 -1
  334. package/src/ui/dashboard-panes/progress-pane.ts +12 -9
  335. package/src/ui/heartbeat-aggregator.ts +15 -4
  336. package/src/ui/keybinding-map.ts +40 -7
  337. package/src/ui/live-conversation-overlay.ts +36 -20
  338. package/src/ui/live-duration.ts +1 -4
  339. package/src/ui/live-run-sidebar.ts +88 -25
  340. package/src/ui/loaders.ts +2 -8
  341. package/src/ui/mascot.ts +20 -36
  342. package/src/ui/overlays/agent-picker-overlay.ts +11 -3
  343. package/src/ui/overlays/confirm-overlay.ts +4 -2
  344. package/src/ui/overlays/help-overlay.ts +25 -14
  345. package/src/ui/overlays/mailbox-compose-overlay.ts +48 -11
  346. package/src/ui/overlays/mailbox-compose-preview.ts +20 -5
  347. package/src/ui/overlays/mailbox-detail-overlay.ts +27 -6
  348. package/src/ui/pi-ui-compat.ts +7 -7
  349. package/src/ui/powerbar-publisher.ts +120 -42
  350. package/src/ui/render-diff.ts +10 -3
  351. package/src/ui/render-scheduler.ts +12 -4
  352. package/src/ui/run-action-dispatcher.ts +81 -18
  353. package/src/ui/run-dashboard.ts +172 -76
  354. package/src/ui/run-event-bus.ts +59 -37
  355. package/src/ui/run-snapshot-cache.ts +276 -86
  356. package/src/ui/settings-overlay.ts +361 -74
  357. package/src/ui/status-colors.ts +12 -1
  358. package/src/ui/syntax-highlight.ts +1 -1
  359. package/src/ui/terminal-status.ts +1 -3
  360. package/src/ui/theme-adapter.ts +16 -14
  361. package/src/ui/theme-discovery.ts +13 -2
  362. package/src/ui/tool-progress-formatter.ts +7 -7
  363. package/src/ui/tool-render.ts +128 -56
  364. package/src/ui/tool-renderers/brief-mode.ts +45 -27
  365. package/src/ui/tool-renderers/index.ts +109 -43
  366. package/src/ui/transcript-cache.ts +32 -6
  367. package/src/ui/transcript-entries.ts +25 -23
  368. package/src/ui/transcript-viewer.ts +78 -29
  369. package/src/ui/widget/index.ts +99 -40
  370. package/src/ui/widget/widget-formatters.ts +13 -6
  371. package/src/ui/widget/widget-model.ts +19 -8
  372. package/src/ui/widget/widget-renderer.ts +23 -13
  373. package/src/ui/widget/widget-types.ts +1 -1
  374. package/src/utils/bm25-search.ts +199 -199
  375. package/src/utils/conflict-detect.ts +22 -21
  376. package/src/utils/env-filter.ts +14 -7
  377. package/src/utils/file-coalescer.ts +5 -1
  378. package/src/utils/fingerprint.ts +3 -6
  379. package/src/utils/frontmatter.ts +3 -1
  380. package/src/utils/fs-watch.ts +2 -6
  381. package/src/utils/gh-protocol.ts +119 -44
  382. package/src/utils/git.ts +13 -15
  383. package/src/utils/guards.ts +2 -5
  384. package/src/utils/ids.ts +9 -2
  385. package/src/utils/incremental-reader.ts +14 -3
  386. package/src/utils/internal-error.ts +2 -1
  387. package/src/utils/names.ts +12 -3
  388. package/src/utils/paths.ts +49 -5
  389. package/src/utils/project-detector.ts +2 -2
  390. package/src/utils/redaction.ts +29 -19
  391. package/src/utils/resolve-shell.ts +9 -7
  392. package/src/utils/run-watcher-registry.ts +19 -31
  393. package/src/utils/safe-paths.ts +46 -29
  394. package/src/utils/scan-cache.ts +9 -2
  395. package/src/utils/session-utils.ts +2 -4
  396. package/src/utils/sleep.ts +12 -5
  397. package/src/utils/sse-parser.ts +5 -17
  398. package/src/utils/visual.ts +52 -32
  399. package/src/workflows/discover-workflows.ts +41 -109
  400. package/src/workflows/intermediate-store.ts +5 -21
  401. package/src/workflows/preflight-validator.ts +6 -33
  402. package/src/workflows/topology-analyzer.ts +5 -21
  403. package/src/workflows/workflow-config.ts +7 -6
  404. package/src/worktree/branch-freshness.ts +66 -8
  405. package/src/worktree/cleanup.ts +130 -20
  406. package/src/worktree/worktree-manager.ts +212 -69
  407. package/skills/artifact-analysis-loop/SKILL.md +0 -303
  408. package/skills/detection-pipeline-design/SKILL.md +0 -286
  409. package/skills/hunting-investigation-loop/SKILL.md +0 -402
  410. package/skills/incident-playbook-construction/SKILL.md +0 -384
  411. package/skills/security-review/SKILL.md +0 -561
  412. package/skills/threat-hypothesis-framework/SKILL.md +0 -176
  413. package/skills/ui-render-performance/SKILL.md +0 -58
  414. /package/docs/{followup-review-round3-2026-05-12.md → archive/followup-review-round3-2026-05-12.md} +0 -0
  415. /package/docs/{followup-review-round4-2026-05-13.md → archive/followup-review-round4-2026-05-13.md} +0 -0
  416. /package/docs/{pi-crew-bugs.md → archive/pi-crew-bugs.md} +0 -0
  417. /package/docs/{pi-crew-test-final.md → archive/pi-crew-test-final.md} +0 -0
  418. /package/docs/{pi-crew-test-results.md → archive/pi-crew-test-results.md} +0 -0
  419. /package/docs/{pi-crew-test-round2.md → archive/pi-crew-test-round2.md} +0 -0
  420. /package/docs/{pi-crew-test-round4.md → archive/pi-crew-test-round4.md} +0 -0
  421. /package/docs/{pi-crew-test-round5.md → archive/pi-crew-test-round5.md} +0 -0
  422. /package/docs/{pi-crew-test-round6.md → archive/pi-crew-test-round6.md} +0 -0
  423. /package/docs/{pi-crew-v0.5.10-audit-fix-plan.md → archive/pi-crew-v0.5.10-audit-fix-plan.md} +0 -0
  424. /package/docs/{pi-crew-v0.5.11-audit-fix-plan.md → archive/pi-crew-v0.5.11-audit-fix-plan.md} +0 -0
  425. /package/docs/{pi-crew-v0.5.12-audit-fix-plan.md → archive/pi-crew-v0.5.12-audit-fix-plan.md} +0 -0
  426. /package/docs/{pi-crew-v0.5.13-audit-fix-plan.md → archive/pi-crew-v0.5.13-audit-fix-plan.md} +0 -0
  427. /package/docs/{pi-crew-v0.5.14-audit-fix-plan.md → archive/pi-crew-v0.5.14-audit-fix-plan.md} +0 -0
  428. /package/docs/{pi-crew-v0.5.16-audit-fix-plan.md → archive/pi-crew-v0.5.16-audit-fix-plan.md} +0 -0
  429. /package/docs/{pi-crew-v0.5.17-audit-fix-plan.md → archive/pi-crew-v0.5.17-audit-fix-plan.md} +0 -0
  430. /package/docs/{pi-crew-v0.5.5-audit-fix-plan.md → archive/pi-crew-v0.5.5-audit-fix-plan.md} +0 -0
  431. /package/docs/{pi-crew-v0.5.9-audit-fix-plan.md → archive/pi-crew-v0.5.9-audit-fix-plan.md} +0 -0
  432. /package/docs/{pi-mono-opportunities.md → archive/pi-mono-opportunities.md} +0 -0
  433. /package/docs/{pi-mono-review.md → archive/pi-mono-review.md} +0 -0
  434. /package/docs/{pi-subagent4-comparison.md → archive/pi-subagent4-comparison.md} +0 -0
  435. /package/docs/{pi-subagents3-deep-analysis.md → archive/pi-subagents3-deep-analysis.md} +0 -0
@@ -1,5 +1,6 @@
1
- import type { CrewAgentRecord } from "./crew-agent-runtime.ts";
2
1
  import type { TeamRunManifest } from "../state/types.ts";
2
+ import type { CrewAgentRecord } from "./crew-agent-runtime.ts";
3
+
3
4
  export { hasAsyncStartMarker } from "./async-marker.ts";
4
5
 
5
6
  export interface ProcessLiveness {
@@ -34,7 +35,12 @@ export function checkProcessLiveness(pid: number | undefined): ProcessLiveness {
34
35
  return { pid, alive: true, detail: "process is alive" };
35
36
  } catch (error) {
36
37
  const nodeError = error as NodeJS.ErrnoException;
37
- if (nodeError.code === "EPERM") return { pid, alive: true, detail: "process exists but permission is denied" };
38
+ if (nodeError.code === "EPERM")
39
+ return {
40
+ pid,
41
+ alive: true,
42
+ detail: "process exists but permission is denied",
43
+ };
38
44
  if (nodeError.code === "ESRCH") return { pid, alive: false, detail: "process does not exist" };
39
45
  const message = error instanceof Error ? error.message : String(error);
40
46
  return { pid, alive: false, detail: message };
@@ -56,7 +62,12 @@ export function isFinishedRunStatus(status: string): boolean {
56
62
  */
57
63
  const ORPHANED_NO_PROGRESS_MS = 5 * 60 * 1000;
58
64
 
59
- export function isLikelyOrphanedActiveRun(run: TeamRunManifest, agents: CrewAgentRecord[] = [], now = Date.now(), staleMs = ORPHANED_ACTIVE_RUN_MS): boolean {
65
+ export function isLikelyOrphanedActiveRun(
66
+ run: TeamRunManifest,
67
+ agents: CrewAgentRecord[] = [],
68
+ now = Date.now(),
69
+ staleMs = ORPHANED_ACTIVE_RUN_MS,
70
+ ): boolean {
60
71
  if (!isActiveRunStatus(run.status)) return false;
61
72
  if (run.async?.pid !== undefined) return false;
62
73
  const updatedAt = new Date(run.updatedAt).getTime();
@@ -91,8 +102,8 @@ function hasDurableActiveAgentEvidence(agent: CrewAgentRecord): boolean {
91
102
  // spawned-but-never-executed agents should not appear as active.
92
103
  return Boolean(
93
104
  (agent.progress && (agent.progress.toolCount > 0 || agent.progress.recentOutput.length > 0)) ||
94
- (agent.jsonEvents && agent.jsonEvents > 0) ||
95
- (agent.toolUses && agent.toolUses > 0),
105
+ (agent.jsonEvents && agent.jsonEvents > 0) ||
106
+ (agent.toolUses && agent.toolUses > 0),
96
107
  );
97
108
  }
98
109
  return false;
@@ -38,6 +38,7 @@ export function shouldAppendProgressEventUpdate(input: ProgressEventCoalesceInpu
38
38
  if (numericIncrease(input.previous.turns, input.next.turns) > 0) return { shouldAppend: true, reason: "turns_increased" };
39
39
  const tokenIncrease = numericIncrease(input.previous.tokens, input.next.tokens);
40
40
  if (tokenIncrease >= (input.tokenThreshold ?? DEFAULT_TOKEN_THRESHOLD)) return { shouldAppend: true, reason: "tokens_increased" };
41
- if (input.lastAppendMs === undefined || input.nowMs - input.lastAppendMs >= input.minIntervalMs) return { shouldAppend: true, reason: "interval" };
41
+ if (input.lastAppendMs === undefined || input.nowMs - input.lastAppendMs >= input.minIntervalMs)
42
+ return { shouldAppend: true, reason: "interval" };
42
43
  return { shouldAppend: false, reason: "coalesced" };
43
44
  }
@@ -2,123 +2,123 @@ import type { AgentSessionEvent } from "@earendil-works/pi-coding-agent";
2
2
  import { crewEventBus } from "../observability/event-bus.ts";
3
3
 
4
4
  export interface AgentProgress {
5
- toolCalls: number;
6
- currentTool: string | null;
7
- toolStartTime: number | null;
8
- errors: string[];
9
- turns: number;
10
- tokens: { input: number; output: number };
11
- status: "idle" | "running" | "completed" | "error";
5
+ toolCalls: number;
6
+ currentTool: string | null;
7
+ toolStartTime: number | null;
8
+ errors: string[];
9
+ turns: number;
10
+ tokens: { input: number; output: number };
11
+ status: "idle" | "running" | "completed" | "error";
12
12
  }
13
13
 
14
14
  export class ProgressTracker {
15
- private sessions = new Map<string, {
16
- unsubscribe: () => void;
17
- progress: AgentProgress;
18
- }>();
15
+ private sessions = new Map<
16
+ string,
17
+ {
18
+ unsubscribe: () => void;
19
+ progress: AgentProgress;
20
+ }
21
+ >();
19
22
 
20
- track(
21
- session: { subscribe: (listener: (event: AgentSessionEvent) => void) => () => void },
22
- agentId: string,
23
- runId: string
24
- ): AgentProgress {
25
- if (this.sessions.has(agentId)) {
26
- return this.sessions.get(agentId)!.progress;
27
- }
23
+ track(
24
+ session: {
25
+ subscribe: (listener: (event: AgentSessionEvent) => void) => () => void;
26
+ },
27
+ agentId: string,
28
+ runId: string,
29
+ ): AgentProgress {
30
+ if (this.sessions.has(agentId)) {
31
+ return this.sessions.get(agentId)!.progress;
32
+ }
28
33
 
29
- const progress: AgentProgress = {
30
- toolCalls: 0,
31
- currentTool: null,
32
- toolStartTime: null,
33
- errors: [],
34
- turns: 0,
35
- tokens: { input: 0, output: 0 },
36
- status: "running",
37
- };
34
+ const progress: AgentProgress = {
35
+ toolCalls: 0,
36
+ currentTool: null,
37
+ toolStartTime: null,
38
+ errors: [],
39
+ turns: 0,
40
+ tokens: { input: 0, output: 0 },
41
+ status: "running",
42
+ };
38
43
 
39
- const unsubscribe = session.subscribe((event: AgentSessionEvent) => {
40
- this.handleEvent(event, progress, agentId, runId);
41
- });
44
+ const unsubscribe = session.subscribe((event: AgentSessionEvent) => {
45
+ this.handleEvent(event, progress, agentId, runId);
46
+ });
42
47
 
43
- this.sessions.set(agentId, { unsubscribe, progress });
44
- return progress;
45
- }
48
+ this.sessions.set(agentId, { unsubscribe, progress });
49
+ return progress;
50
+ }
46
51
 
47
- private handleEvent(
48
- event: AgentSessionEvent,
49
- progress: AgentProgress,
50
- agentId: string,
51
- runId: string
52
- ): void {
53
- switch (event.type) {
54
- case "tool_execution_start":
55
- progress.toolCalls++;
56
- progress.currentTool = event.toolName;
57
- progress.toolStartTime = Date.now();
58
- crewEventBus.emit({
59
- type: "agent:progress",
60
- runId,
61
- agentId,
62
- payload: { ...progress },
63
- timestamp: Date.now(),
64
- });
65
- break;
52
+ private handleEvent(event: AgentSessionEvent, progress: AgentProgress, agentId: string, runId: string): void {
53
+ switch (event.type) {
54
+ case "tool_execution_start":
55
+ progress.toolCalls++;
56
+ progress.currentTool = event.toolName;
57
+ progress.toolStartTime = Date.now();
58
+ crewEventBus.emit({
59
+ type: "agent:progress",
60
+ runId,
61
+ agentId,
62
+ payload: { ...progress },
63
+ timestamp: Date.now(),
64
+ });
65
+ break;
66
66
 
67
- case "tool_execution_end":
68
- progress.currentTool = null;
69
- progress.toolStartTime = null;
70
- if (event.isError) {
71
- progress.errors.push(String(event.result ?? "Unknown error"));
72
- crewEventBus.emit({
73
- type: "agent:error",
74
- runId,
75
- agentId,
76
- payload: String(event.result ?? "Unknown error"),
77
- timestamp: Date.now(),
78
- });
79
- }
80
- crewEventBus.emit({
81
- type: "agent:progress",
82
- runId,
83
- agentId,
84
- payload: { ...progress },
85
- timestamp: Date.now(),
86
- });
87
- break;
67
+ case "tool_execution_end":
68
+ progress.currentTool = null;
69
+ progress.toolStartTime = null;
70
+ if (event.isError) {
71
+ progress.errors.push(String(event.result ?? "Unknown error"));
72
+ crewEventBus.emit({
73
+ type: "agent:error",
74
+ runId,
75
+ agentId,
76
+ payload: String(event.result ?? "Unknown error"),
77
+ timestamp: Date.now(),
78
+ });
79
+ }
80
+ crewEventBus.emit({
81
+ type: "agent:progress",
82
+ runId,
83
+ agentId,
84
+ payload: { ...progress },
85
+ timestamp: Date.now(),
86
+ });
87
+ break;
88
88
 
89
- case "turn_start":
90
- progress.turns++;
91
- break;
89
+ case "turn_start":
90
+ progress.turns++;
91
+ break;
92
92
 
93
- case "agent_end":
94
- progress.status = "completed";
95
- crewEventBus.emit({
96
- type: "agent:complete",
97
- runId,
98
- agentId,
99
- payload: { ...progress },
100
- timestamp: Date.now(),
101
- });
102
- break;
93
+ case "agent_end":
94
+ progress.status = "completed";
95
+ crewEventBus.emit({
96
+ type: "agent:complete",
97
+ runId,
98
+ agentId,
99
+ payload: { ...progress },
100
+ timestamp: Date.now(),
101
+ });
102
+ break;
103
103
 
104
- case "agent_start":
105
- progress.status = "running";
106
- break;
107
- }
108
- }
104
+ case "agent_start":
105
+ progress.status = "running";
106
+ break;
107
+ }
108
+ }
109
109
 
110
- untrack(agentId: string): void {
111
- const tracked = this.sessions.get(agentId);
112
- if (tracked) {
113
- tracked.unsubscribe();
114
- this.sessions.delete(agentId);
115
- }
116
- }
110
+ untrack(agentId: string): void {
111
+ const tracked = this.sessions.get(agentId);
112
+ if (tracked) {
113
+ tracked.unsubscribe();
114
+ this.sessions.delete(agentId);
115
+ }
116
+ }
117
117
 
118
- getProgress(agentId: string): AgentProgress | undefined {
119
- return this.sessions.get(agentId)?.progress;
120
- }
118
+ getProgress(agentId: string): AgentProgress | undefined {
119
+ return this.sessions.get(agentId)?.progress;
120
+ }
121
121
  }
122
122
 
123
123
  // Export singleton instance
124
- export const globalProgressTracker = new ProgressTracker();
124
+ export const globalProgressTracker = new ProgressTracker();
@@ -14,14 +14,14 @@
14
14
  // ---------------------------------------------------------------------------
15
15
 
16
16
  const PROTECTED_PATTERNS: readonly RegExp[] = [
17
- /```[\s\S]*?```/g, // fenced code blocks
18
- /`[^`\n]+`/g, // inline code
19
- /\bhttps?:\/\/\S+/gi, // URLs
20
- /\b[\w.-]*[/\\][\w./\\-]+/g, // paths with / or \
21
- /\b[A-Z][A-Z0-9]*(?:_[A-Z][A-Z0-9]*)+\b/g, // CONSTANT_CASE
22
- /\b\w+(?:\.\w+)+\(\)/g, // dotted.method() calls
23
- /[A-Za-z_][A-Za-z0-9_]*\s*\([^)]*\)/g, // function calls: name(args)
24
- /\b\d+\.\d+\.\d+\b/g, // version numbers x.y.z
17
+ /```[\s\S]*?```/g, // fenced code blocks
18
+ /`[^`\n]+`/g, // inline code
19
+ /\bhttps?:\/\/\S+/gi, // URLs
20
+ /\b[\w.-]*[/\\][\w./\\-]+/g, // paths with / or \
21
+ /\b[A-Z][A-Z0-9]*(?:_[A-Z][A-Z0-9]*)+\b/g, // CONSTANT_CASE
22
+ /\b\w+(?:\.\w+)+\(\)/g, // dotted.method() calls
23
+ /[A-Za-z_][A-Za-z0-9_]*\s*\([^)]*\)/g, // function calls: name(args)
24
+ /\b\d+\.\d+\.\d+\b/g, // version numbers x.y.z
25
25
  ];
26
26
 
27
27
  // ---------------------------------------------------------------------------
@@ -143,9 +143,7 @@ export function compressProse(text: string): CompressResult {
143
143
 
144
144
  const originalLength = text.length;
145
145
  const compressedLength = restored.length;
146
- const savingsPercent = originalLength > 0
147
- ? Math.round(((originalLength - compressedLength) / originalLength) * 100 * 100) / 100
148
- : 0;
146
+ const savingsPercent = originalLength > 0 ? Math.round(((originalLength - compressedLength) / originalLength) * 100 * 100) / 100 : 0;
149
147
 
150
148
  return {
151
149
  compressed: restored,
@@ -1,7 +1,27 @@
1
1
  import type { PolicyDecision, PolicyDecisionReason } from "../state/types.ts";
2
2
 
3
- export type FailureScenario = "trust_prompt_unresolved" | "prompt_misdelivery" | "stale_branch" | "compile_red_cross_crate" | "mcp_handshake_failure" | "partial_plugin_startup" | "provider_failure" | "task_failed" | "worker_stale" | "green_unsatisfied";
4
- export type RecoveryStep = "accept_trust_prompt" | "redirect_prompt_to_agent" | "rebase_branch" | "clean_build" | "retry_mcp_handshake" | "restart_plugin" | "restart_worker" | "rerun_task" | "collect_verification_evidence" | "escalate_to_human";
3
+ export type FailureScenario =
4
+ | "trust_prompt_unresolved"
5
+ | "prompt_misdelivery"
6
+ | "stale_branch"
7
+ | "compile_red_cross_crate"
8
+ | "mcp_handshake_failure"
9
+ | "partial_plugin_startup"
10
+ | "provider_failure"
11
+ | "task_failed"
12
+ | "worker_stale"
13
+ | "green_unsatisfied";
14
+ export type RecoveryStep =
15
+ | "accept_trust_prompt"
16
+ | "redirect_prompt_to_agent"
17
+ | "rebase_branch"
18
+ | "clean_build"
19
+ | "retry_mcp_handshake"
20
+ | "restart_plugin"
21
+ | "restart_worker"
22
+ | "rerun_task"
23
+ | "collect_verification_evidence"
24
+ | "escalate_to_human";
5
25
  export type RecoveryResultState = "planned" | "skipped" | "escalation_required";
6
26
 
7
27
  export interface RecoveryRecipe {
@@ -28,26 +48,91 @@ export interface RecoveryLedger {
28
48
 
29
49
  export function scenarioForPolicyReason(reason: PolicyDecisionReason): FailureScenario {
30
50
  switch (reason) {
31
- case "branch_stale": return "stale_branch";
32
- case "worker_stale": return "worker_stale";
33
- case "green_unsatisfied": return "green_unsatisfied";
34
- case "task_failed": return "task_failed";
35
- default: return "provider_failure";
51
+ case "branch_stale":
52
+ return "stale_branch";
53
+ case "worker_stale":
54
+ return "worker_stale";
55
+ case "green_unsatisfied":
56
+ return "green_unsatisfied";
57
+ case "task_failed":
58
+ return "task_failed";
59
+ default:
60
+ return "provider_failure";
36
61
  }
37
62
  }
38
63
 
39
64
  export function recipeFor(scenario: FailureScenario): RecoveryRecipe {
40
65
  switch (scenario) {
41
- case "trust_prompt_unresolved": return { scenario, steps: ["accept_trust_prompt"], maxAttempts: 1, escalationPolicy: "alert_human" };
42
- case "prompt_misdelivery": return { scenario, steps: ["redirect_prompt_to_agent"], maxAttempts: 1, escalationPolicy: "alert_human" };
43
- case "stale_branch": return { scenario, steps: ["rebase_branch", "clean_build"], maxAttempts: 1, escalationPolicy: "alert_human" };
44
- case "compile_red_cross_crate": return { scenario, steps: ["clean_build"], maxAttempts: 1, escalationPolicy: "alert_human" };
45
- case "mcp_handshake_failure": return { scenario, steps: ["retry_mcp_handshake"], maxAttempts: 1, escalationPolicy: "abort" };
46
- case "partial_plugin_startup": return { scenario, steps: ["restart_plugin", "retry_mcp_handshake"], maxAttempts: 1, escalationPolicy: "log_and_continue" };
47
- case "worker_stale": return { scenario, steps: ["restart_worker"], maxAttempts: 1, escalationPolicy: "alert_human" };
48
- case "green_unsatisfied": return { scenario, steps: ["collect_verification_evidence"], maxAttempts: 1, escalationPolicy: "alert_human" };
49
- case "task_failed": return { scenario, steps: ["rerun_task"], maxAttempts: 1, escalationPolicy: "alert_human" };
50
- case "provider_failure": return { scenario, steps: ["restart_worker"], maxAttempts: 1, escalationPolicy: "alert_human" };
66
+ case "trust_prompt_unresolved":
67
+ return {
68
+ scenario,
69
+ steps: ["accept_trust_prompt"],
70
+ maxAttempts: 1,
71
+ escalationPolicy: "alert_human",
72
+ };
73
+ case "prompt_misdelivery":
74
+ return {
75
+ scenario,
76
+ steps: ["redirect_prompt_to_agent"],
77
+ maxAttempts: 1,
78
+ escalationPolicy: "alert_human",
79
+ };
80
+ case "stale_branch":
81
+ return {
82
+ scenario,
83
+ steps: ["rebase_branch", "clean_build"],
84
+ maxAttempts: 1,
85
+ escalationPolicy: "alert_human",
86
+ };
87
+ case "compile_red_cross_crate":
88
+ return {
89
+ scenario,
90
+ steps: ["clean_build"],
91
+ maxAttempts: 1,
92
+ escalationPolicy: "alert_human",
93
+ };
94
+ case "mcp_handshake_failure":
95
+ return {
96
+ scenario,
97
+ steps: ["retry_mcp_handshake"],
98
+ maxAttempts: 1,
99
+ escalationPolicy: "abort",
100
+ };
101
+ case "partial_plugin_startup":
102
+ return {
103
+ scenario,
104
+ steps: ["restart_plugin", "retry_mcp_handshake"],
105
+ maxAttempts: 1,
106
+ escalationPolicy: "log_and_continue",
107
+ };
108
+ case "worker_stale":
109
+ return {
110
+ scenario,
111
+ steps: ["restart_worker"],
112
+ maxAttempts: 1,
113
+ escalationPolicy: "alert_human",
114
+ };
115
+ case "green_unsatisfied":
116
+ return {
117
+ scenario,
118
+ steps: ["collect_verification_evidence"],
119
+ maxAttempts: 1,
120
+ escalationPolicy: "alert_human",
121
+ };
122
+ case "task_failed":
123
+ return {
124
+ scenario,
125
+ steps: ["rerun_task"],
126
+ maxAttempts: 1,
127
+ escalationPolicy: "alert_human",
128
+ };
129
+ case "provider_failure":
130
+ return {
131
+ scenario,
132
+ steps: ["restart_worker"],
133
+ maxAttempts: 1,
134
+ escalationPolicy: "alert_human",
135
+ };
51
136
  }
52
137
  }
53
138
 
@@ -93,17 +178,26 @@ export interface RerunDecision {
93
178
  reason: string;
94
179
  }
95
180
 
96
- export function shouldRerunFailedTask(
97
- task: { policy?: { retryCount?: number } },
98
- limits?: { maxRetriesPerTask?: number },
99
- ): RerunDecision {
181
+ export function shouldRerunFailedTask(task: { policy?: { retryCount?: number } }, limits?: { maxRetriesPerTask?: number }): RerunDecision {
100
182
  const maxRetries = limits?.maxRetriesPerTask ?? 0;
101
183
  const retryCount = task.policy?.retryCount ?? 0;
102
184
  if (maxRetries <= 0) {
103
- return { rerun: false, newRetryCount: retryCount, reason: "maxRetriesPerTask not set (opt-in) — no whole-task rerun" };
185
+ return {
186
+ rerun: false,
187
+ newRetryCount: retryCount,
188
+ reason: "maxRetriesPerTask not set (opt-in) — no whole-task rerun",
189
+ };
104
190
  }
105
191
  if (retryCount >= maxRetries) {
106
- return { rerun: false, newRetryCount: retryCount, reason: `retryCount ${retryCount} >= maxRetriesPerTask ${maxRetries} — rerun budget exhausted` };
192
+ return {
193
+ rerun: false,
194
+ newRetryCount: retryCount,
195
+ reason: `retryCount ${retryCount} >= maxRetriesPerTask ${maxRetries} — rerun budget exhausted`,
196
+ };
107
197
  }
108
- return { rerun: true, newRetryCount: retryCount + 1, reason: `whole-task rerun ${retryCount + 1}/${maxRetries}` };
198
+ return {
199
+ rerun: true,
200
+ newRetryCount: retryCount + 1,
201
+ reason: `whole-task rerun ${retryCount + 1}/${maxRetries}`,
202
+ };
109
203
  }
@@ -462,12 +462,7 @@ const REPLACERS: Replacer[] = [
462
462
  * occurrences. Only safe for exact matches (simple replacer).
463
463
  * @returns ReplaceResult with the new content and match strategy info.
464
464
  */
465
- export function replace(
466
- content: string,
467
- oldString: string,
468
- newString: string,
469
- options?: { replaceAll?: boolean },
470
- ): ReplaceResult {
465
+ export function replace(content: string, oldString: string, newString: string, options?: { replaceAll?: boolean }): ReplaceResult {
471
466
  if (oldString.length === 0) {
472
467
  return { content, changed: false, strategy: "none", count: 0 };
473
468
  }
@@ -482,7 +477,12 @@ export function replace(
482
477
  const result = content.replaceAll(oldString, newString);
483
478
  if (result !== content) {
484
479
  const count = countOccurrences(content, oldString);
485
- return { content: result, changed: true, strategy: "simple-replaceAll", count };
480
+ return {
481
+ content: result,
482
+ changed: true,
483
+ strategy: "simple-replaceAll",
484
+ count,
485
+ };
486
486
  }
487
487
  }
488
488
 
@@ -494,7 +494,12 @@ export function replace(
494
494
  if (idx === lastIdx) {
495
495
  // Exactly one occurrence
496
496
  const result = content.slice(0, idx) + newString + content.slice(idx + oldString.length);
497
- return { content: result, changed: true, strategy: "simple", count: 1 };
497
+ return {
498
+ content: result,
499
+ changed: true,
500
+ strategy: "simple",
501
+ count: 1,
502
+ };
498
503
  }
499
504
  // Multiple occurrences — fall through to fuzzy strategies
500
505
  // (we never auto-pick among duplicates)
@@ -529,7 +534,12 @@ export function replace(
529
534
  .replace("Replacer", "")
530
535
  .replace(/([a-z])([A-Z])/g, "$1-$2")
531
536
  .toLowerCase();
532
- return { content: result, changed: true, strategy: `${strategyName}-replaceAll`, count: totalCount };
537
+ return {
538
+ content: result,
539
+ changed: true,
540
+ strategy: `${strategyName}-replaceAll`,
541
+ count: totalCount,
542
+ };
533
543
  }
534
544
  continue;
535
545
  }
@@ -544,7 +554,12 @@ export function replace(
544
554
  .replace("Replacer", "")
545
555
  .replace(/([a-z])([A-Z])/g, "$1-$2")
546
556
  .toLowerCase();
547
- return { content: result, changed: true, strategy: strategyName, count: 1 };
557
+ return {
558
+ content: result,
559
+ changed: true,
560
+ strategy: strategyName,
561
+ count: 1,
562
+ };
548
563
  }
549
564
  }
550
565
  // Multiple candidates — skip this strategy (safety first)
@@ -23,7 +23,7 @@
23
23
  * }
24
24
  */
25
25
  import type { ExtensionAPI } from "@earendil-works/pi-coding-agent";
26
- import { replace, type ReplaceResult } from "../runtime/replace.ts";
26
+ import { type ReplaceResult, replace } from "../runtime/replace.ts";
27
27
 
28
28
  interface ToolLike {
29
29
  name: string;
@@ -50,13 +50,7 @@ interface EditResult {
50
50
  [key: string]: unknown;
51
51
  }
52
52
 
53
- const NOT_FOUND_PATTERNS = [
54
- /old_string not found/i,
55
- /oldstring not found/i,
56
- /no match/i,
57
- /could not find/i,
58
- /string not found/i,
59
- ];
53
+ const NOT_FOUND_PATTERNS = [/old_string not found/i, /oldstring not found/i, /no match/i, /could not find/i, /string not found/i];
60
54
 
61
55
  function isNotFoundResult(result: unknown): boolean {
62
56
  if (!result || typeof result !== "object") return false;
@@ -72,7 +66,7 @@ function isPiDiffLoaded(pi: ExtensionAPI): boolean {
72
66
  const piAny = pi as any;
73
67
  const extensions = piAny?.extensions ?? piAny?._extensions ?? [];
74
68
  const names = Array.isArray(extensions)
75
- ? extensions.map((e: unknown) => (typeof e === "string" ? e : (e as { name?: string })?.name ?? ""))
69
+ ? extensions.map((e: unknown) => (typeof e === "string" ? e : ((e as { name?: string })?.name ?? "")))
76
70
  : Object.keys(extensions);
77
71
  return names.some((n: string) => typeof n === "string" && n.includes("pi-diff"));
78
72
  } catch {
@@ -94,7 +88,7 @@ export function wrapEditWithResilientReplace(pi: ExtensionAPI, tools?: { edit: T
94
88
  return false;
95
89
  }
96
90
 
97
- const t = tools ?? ((pi as unknown as { tools?: { edit?: ToolLike } }).tools);
91
+ const t = tools ?? (pi as unknown as { tools?: { edit?: ToolLike } }).tools;
98
92
  if (!t?.edit?.execute) return false;
99
93
 
100
94
  const nativeExecute = t.edit.execute.bind(t.edit);
@@ -117,12 +111,7 @@ export function wrapEditWithResilientReplace(pi: ExtensionAPI, tools?: { edit: T
117
111
 
118
112
  return true;
119
113
 
120
- async function retryWithReplace(
121
- params: EditParams,
122
- toolCallId: string,
123
- signal: any,
124
- onUpdate: any,
125
- ): Promise<unknown> {
114
+ async function retryWithReplace(params: EditParams, toolCallId: string, signal: any, onUpdate: any): Promise<unknown> {
126
115
  const filePath = params.path ?? params.filePath;
127
116
  const oldStr = params.oldString ?? params.old_string;
128
117
  const newStr = params.newString ?? params.new_string;
@@ -139,18 +128,14 @@ export function wrapEditWithResilientReplace(pi: ExtensionAPI, tools?: { edit: T
139
128
  try {
140
129
  content = await fs.readFile(filePath, "utf8");
141
130
  } catch (readErr) {
142
- throw new Error(
143
- `resilient edit: could not read ${filePath}: ${
144
- readErr instanceof Error ? readErr.message : String(readErr)
145
- }`,
146
- );
131
+ throw new Error(`resilient edit: could not read ${filePath}: ${readErr instanceof Error ? readErr.message : String(readErr)}`);
147
132
  }
148
133
 
149
- const result: ReplaceResult = replace(content, oldStr, newStr, { replaceAll });
134
+ const result: ReplaceResult = replace(content, oldStr, newStr, {
135
+ replaceAll,
136
+ });
150
137
  if (!result.changed) {
151
- throw new Error(
152
- `old_string not found (resilient cascade exhausted, strategy=${result.strategy})`,
153
- );
138
+ throw new Error(`old_string not found (resilient cascade exhausted, strategy=${result.strategy})`);
154
139
  }
155
140
 
156
141
  await fs.writeFile(filePath, result.content, "utf8");
@@ -152,10 +152,7 @@ function tryScanJson(text: string): unknown | undefined {
152
152
  const candidate = rest.slice(0, end);
153
153
  try {
154
154
  return JSON.parse(candidate);
155
- } catch {
156
- // Not valid JSON at this position; keep scanning for the next '{'/'['.
157
- continue;
158
- }
155
+ } catch {}
159
156
  }
160
157
  return undefined;
161
158
  }
@@ -177,8 +174,7 @@ function tryMarkerExtraction(text: string): unknown | undefined {
177
174
  if (jsonEnd > 0) {
178
175
  try {
179
176
  return JSON.parse(after.slice(0, jsonEnd));
180
- } catch {
181
- }
177
+ } catch {}
182
178
  }
183
179
  }
184
180
  }