pi-crew 0.9.16 → 0.9.17

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