@bastani/atomic 0.9.5-alpha.8 → 0.9.5

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 (530) hide show
  1. package/CHANGELOG.md +122 -0
  2. package/README.md +2 -2
  3. package/dist/builtin/cursor/CHANGELOG.md +12 -0
  4. package/dist/builtin/cursor/package.json +3 -3
  5. package/dist/builtin/cursor/src/model-mapper.ts +6 -3
  6. package/dist/builtin/intercom/CHANGELOG.md +37 -0
  7. package/dist/builtin/intercom/README.md +4 -2
  8. package/dist/builtin/intercom/broker/broker.ts +6 -114
  9. package/dist/builtin/intercom/broker/client.ts +29 -54
  10. package/dist/builtin/intercom/broker/delivered-message-cache.ts +44 -0
  11. package/dist/builtin/intercom/broker/pending-send-registry.ts +142 -0
  12. package/dist/builtin/intercom/broker/send-handler.ts +106 -0
  13. package/dist/builtin/intercom/broker/send-signature.ts +37 -0
  14. package/dist/builtin/intercom/foreground-detach-handoff.ts +136 -0
  15. package/dist/builtin/intercom/index-heavy.ts +49 -53
  16. package/dist/builtin/intercom/index.ts +278 -262
  17. package/dist/builtin/intercom/lazy-heavy-proxy.ts +114 -0
  18. package/dist/builtin/intercom/lazy-subagent-ack.ts +20 -0
  19. package/dist/builtin/intercom/lazy-tool-execution.ts +39 -0
  20. package/dist/builtin/intercom/lifecycle-lease.ts +51 -0
  21. package/dist/builtin/intercom/lifecycle.ts +37 -20
  22. package/dist/builtin/intercom/package.json +3 -6
  23. package/dist/builtin/intercom/reply-routing.ts +17 -0
  24. package/dist/builtin/intercom/subagent-relay.ts +58 -12
  25. package/dist/builtin/intercom/types.ts +3 -3
  26. package/dist/builtin/mcp/CHANGELOG.md +38 -0
  27. package/dist/builtin/mcp/OAUTH.md +1 -0
  28. package/dist/builtin/mcp/README.md +10 -6
  29. package/dist/builtin/mcp/apps-cancellation.ts +32 -0
  30. package/dist/builtin/mcp/call-tool-result.ts +9 -0
  31. package/dist/builtin/mcp/caller-wait.ts +50 -0
  32. package/dist/builtin/mcp/command-registration.ts +82 -0
  33. package/dist/builtin/mcp/direct-tool-executor.ts +279 -0
  34. package/dist/builtin/mcp/direct-tools.ts +40 -255
  35. package/dist/builtin/mcp/host-html-template.ts +4 -2
  36. package/dist/builtin/mcp/index.ts +274 -239
  37. package/dist/builtin/mcp/init.ts +96 -126
  38. package/dist/builtin/mcp/mcp-auth-flow.ts +247 -237
  39. package/dist/builtin/mcp/mcp-callback-server.ts +89 -68
  40. package/dist/builtin/mcp/mcp-oauth-provider.ts +23 -1
  41. package/dist/builtin/mcp/metadata-hydration.ts +52 -0
  42. package/dist/builtin/mcp/package.json +3 -3
  43. package/dist/builtin/mcp/proxy-auth.ts +4 -4
  44. package/dist/builtin/mcp/proxy-call.ts +111 -40
  45. package/dist/builtin/mcp/proxy-connect.ts +35 -15
  46. package/dist/builtin/mcp/proxy-info-modes.ts +106 -23
  47. package/dist/builtin/mcp/proxy-modes.ts +3 -3
  48. package/dist/builtin/mcp/session-cleanup-barrier.ts +43 -0
  49. package/dist/builtin/mcp/startup-warmup.ts +98 -0
  50. package/dist/builtin/mcp/state-lease.ts +12 -0
  51. package/dist/builtin/mcp/tool-result-renderer.ts +3 -3
  52. package/dist/builtin/mcp/ui-server.ts +8 -8
  53. package/dist/builtin/mcp/ui-session.ts +9 -18
  54. package/dist/builtin/subagents/CHANGELOG.md +78 -0
  55. package/dist/builtin/subagents/README.md +30 -29
  56. package/dist/builtin/subagents/agents/code-simplifier.md +2 -2
  57. package/dist/builtin/subagents/agents/codebase-analyzer.md +2 -2
  58. package/dist/builtin/subagents/agents/codebase-locator.md +2 -2
  59. package/dist/builtin/subagents/agents/codebase-online-researcher.md +2 -2
  60. package/dist/builtin/subagents/agents/codebase-pattern-finder.md +2 -2
  61. package/dist/builtin/subagents/agents/codebase-research-analyzer.md +2 -2
  62. package/dist/builtin/subagents/agents/codebase-research-locator.md +2 -2
  63. package/dist/builtin/subagents/agents/debugger.md +2 -2
  64. package/dist/builtin/subagents/agents/worker.md +2 -2
  65. package/dist/builtin/subagents/package.json +5 -5
  66. package/dist/builtin/subagents/prompts/review-loop.md +1 -1
  67. package/dist/builtin/subagents/skills/subagent/SKILL.md +37 -36
  68. package/dist/builtin/subagents/src/extension/api-lifecycle.ts +64 -0
  69. package/dist/builtin/subagents/src/extension/fanout-child.ts +44 -51
  70. package/dist/builtin/subagents/src/extension/index.ts +289 -320
  71. package/dist/builtin/subagents/src/extension/prompt-guidance.ts +7 -10
  72. package/dist/builtin/subagents/src/extension/schemas.ts +22 -5
  73. package/dist/builtin/subagents/src/extension/startup-maintenance.ts +89 -0
  74. package/dist/builtin/subagents/src/extension/tool-description.ts +29 -0
  75. package/dist/builtin/subagents/src/intercom/intercom-bridge.ts +13 -2
  76. package/dist/builtin/subagents/src/intercom/result-intercom.ts +4 -4
  77. package/dist/builtin/subagents/src/runs/background/async-event-journal.ts +106 -0
  78. package/dist/builtin/subagents/src/runs/background/async-execution-common.ts +26 -20
  79. package/dist/builtin/subagents/src/runs/background/async-execution-single.ts +13 -2
  80. package/dist/builtin/subagents/src/runs/background/async-execution-types.ts +3 -0
  81. package/dist/builtin/subagents/src/runs/background/async-job-tracker.ts +1 -1
  82. package/dist/builtin/subagents/src/runs/background/completion-claims.ts +189 -0
  83. package/dist/builtin/subagents/src/runs/background/completion-dedupe.ts +44 -7
  84. package/dist/builtin/subagents/src/runs/background/completion-notification.ts +34 -0
  85. package/dist/builtin/subagents/src/runs/background/notify.ts +72 -22
  86. package/dist/builtin/subagents/src/runs/background/result-delivery-processor.ts +232 -0
  87. package/dist/builtin/subagents/src/runs/background/result-file-claims.ts +151 -0
  88. package/dist/builtin/subagents/src/runs/background/result-quarantine.ts +72 -0
  89. package/dist/builtin/subagents/src/runs/background/result-retry-scheduler.ts +48 -0
  90. package/dist/builtin/subagents/src/runs/background/result-status.ts +81 -0
  91. package/dist/builtin/subagents/src/runs/background/result-watcher-data.ts +59 -0
  92. package/dist/builtin/subagents/src/runs/background/result-watcher.ts +177 -233
  93. package/dist/builtin/subagents/src/runs/background/run-id-resolver.ts +3 -2
  94. package/dist/builtin/subagents/src/runs/background/stale-run-reconciler.ts +73 -14
  95. package/dist/builtin/subagents/src/runs/background/subagent-runner-streaming.ts +29 -15
  96. package/dist/builtin/subagents/src/runs/background/top-level-async.ts +1 -2
  97. package/dist/builtin/subagents/src/runs/foreground/chain-execution-dynamic-step.ts +1 -0
  98. package/dist/builtin/subagents/src/runs/foreground/chain-execution-parallel-runner.ts +1 -0
  99. package/dist/builtin/subagents/src/runs/foreground/chain-execution-parallel-step.ts +1 -0
  100. package/dist/builtin/subagents/src/runs/foreground/chain-execution-sequential-step.ts +7 -9
  101. package/dist/builtin/subagents/src/runs/foreground/chain-execution-types.ts +3 -13
  102. package/dist/builtin/subagents/src/runs/foreground/chain-execution.ts +2 -15
  103. package/dist/builtin/subagents/src/runs/foreground/execution-attempt-finalize.ts +2 -2
  104. package/dist/builtin/subagents/src/runs/foreground/execution-attempt.ts +63 -46
  105. package/dist/builtin/subagents/src/runs/foreground/execution-detach-reservations.ts +48 -0
  106. package/dist/builtin/subagents/src/runs/foreground/execution-detach-route.ts +17 -0
  107. package/dist/builtin/subagents/src/runs/foreground/execution-run-sync.ts +39 -26
  108. package/dist/builtin/subagents/src/runs/foreground/subagent-executor-async.ts +3 -1
  109. package/dist/builtin/subagents/src/runs/foreground/subagent-executor-chain.ts +3 -51
  110. package/dist/builtin/subagents/src/runs/foreground/subagent-executor-context.ts +6 -11
  111. package/dist/builtin/subagents/src/runs/foreground/subagent-executor-input.ts +11 -2
  112. package/dist/builtin/subagents/src/runs/foreground/subagent-executor-parallel-task.ts +2 -0
  113. package/dist/builtin/subagents/src/runs/foreground/subagent-executor-parallel.ts +5 -112
  114. package/dist/builtin/subagents/src/runs/foreground/subagent-executor-resume.ts +2 -0
  115. package/dist/builtin/subagents/src/runs/foreground/subagent-executor-single.ts +68 -118
  116. package/dist/builtin/subagents/src/runs/foreground/subagent-executor-status.ts +79 -7
  117. package/dist/builtin/subagents/src/runs/foreground/subagent-executor-types.ts +2 -2
  118. package/dist/builtin/subagents/src/runs/foreground/subagent-executor.ts +3 -0
  119. package/dist/builtin/subagents/src/runs/shared/pi-args.ts +2 -2
  120. package/dist/builtin/subagents/src/runs/shared/pi-spawn.ts +55 -12
  121. package/dist/builtin/subagents/src/shared/artifacts.ts +22 -11
  122. package/dist/builtin/subagents/src/shared/event-jsonl-writer.ts +294 -0
  123. package/dist/builtin/subagents/src/shared/exclusive-file-publication.ts +44 -0
  124. package/dist/builtin/subagents/src/shared/jsonl-writer.ts +1 -0
  125. package/dist/builtin/subagents/src/shared/model-info.ts +2 -2
  126. package/dist/builtin/subagents/src/shared/settings.ts +20 -10
  127. package/dist/builtin/subagents/src/shared/types-async.ts +3 -1
  128. package/dist/builtin/subagents/src/shared/types-config.ts +2 -0
  129. package/dist/builtin/subagents/src/shared/types-runtime.ts +3 -2
  130. package/dist/builtin/subagents/src/slash/slash-commands.ts +9 -12
  131. package/dist/builtin/subagents/src/slash/slash-live-state.ts +63 -32
  132. package/dist/builtin/subagents/src/tui/render-result.ts +7 -0
  133. package/dist/builtin/subagents/src/tui/render-stable-output.ts +1 -0
  134. package/dist/builtin/subagents/src/tui/render-widget.ts +157 -89
  135. package/dist/builtin/web-access/CHANGELOG.md +28 -0
  136. package/dist/builtin/web-access/README.md +4 -0
  137. package/dist/builtin/web-access/content-tools.ts +8 -3
  138. package/dist/builtin/web-access/index-heavy.ts +1 -1
  139. package/dist/builtin/web-access/index.ts +190 -46
  140. package/dist/builtin/web-access/lifecycle-lease.ts +38 -0
  141. package/dist/builtin/web-access/package.json +2 -2
  142. package/dist/builtin/web-access/result-renderers.ts +1 -1
  143. package/dist/builtin/web-access/summary-review.ts +1 -1
  144. package/dist/builtin/web-access/web-search-activity.ts +1 -1
  145. package/dist/builtin/web-access/web-search-return.ts +7 -0
  146. package/dist/builtin/web-access/web-search-summary.ts +1 -1
  147. package/dist/builtin/web-access/web-search-tool.ts +4 -2
  148. package/dist/builtin/workflows/CHANGELOG.md +86 -0
  149. package/dist/builtin/workflows/README.md +5 -5
  150. package/dist/builtin/workflows/builtin/deep-research-codebase-utils.ts +27 -4
  151. package/dist/builtin/workflows/builtin/goal-runner.ts +86 -27
  152. package/dist/builtin/workflows/builtin/open-claude-design-runner.ts +10 -0
  153. package/dist/builtin/workflows/builtin/ralph-core.ts +9 -9
  154. package/dist/builtin/workflows/builtin/ralph-models.ts +71 -36
  155. package/dist/builtin/workflows/builtin/ralph-runner.ts +20 -31
  156. package/dist/builtin/workflows/package.json +2 -2
  157. package/dist/builtin/workflows/skills/impeccable/SKILL.md +16 -13
  158. package/dist/builtin/workflows/skills/impeccable/reference/adapt.md +1 -0
  159. package/dist/builtin/workflows/skills/impeccable/reference/adapt.native.md +58 -0
  160. package/dist/builtin/workflows/skills/impeccable/reference/android.md +40 -0
  161. package/dist/builtin/workflows/skills/impeccable/reference/animate.md +2 -0
  162. package/dist/builtin/workflows/skills/impeccable/reference/audit.md +2 -0
  163. package/dist/builtin/workflows/skills/impeccable/reference/audit.native.md +139 -0
  164. package/dist/builtin/workflows/skills/impeccable/reference/bolder.md +69 -62
  165. package/dist/builtin/workflows/skills/impeccable/reference/critique.md +21 -7
  166. package/dist/builtin/workflows/skills/impeccable/reference/document.md +1 -1
  167. package/dist/builtin/workflows/skills/impeccable/reference/hooks.md +92 -0
  168. package/dist/builtin/workflows/skills/impeccable/reference/init.md +29 -7
  169. package/dist/builtin/workflows/skills/impeccable/reference/ios.md +45 -0
  170. package/dist/builtin/workflows/skills/impeccable/reference/layout.md +25 -1
  171. package/dist/builtin/workflows/skills/impeccable/reference/typeset.md +23 -1
  172. package/dist/builtin/workflows/skills/impeccable/scripts/context-signals.mjs +2 -1
  173. package/dist/builtin/workflows/skills/impeccable/scripts/context.mjs +75 -14
  174. package/dist/builtin/workflows/skills/impeccable/scripts/detector/browser/injected/index.mjs +1 -1
  175. package/dist/builtin/workflows/skills/impeccable/scripts/detector/cli/main.mjs +31 -0
  176. package/dist/builtin/workflows/skills/impeccable/scripts/detector/design-system.mjs +64 -0
  177. package/dist/builtin/workflows/skills/impeccable/scripts/detector/detect-antipatterns-browser.js +118 -11
  178. package/dist/builtin/workflows/skills/impeccable/scripts/detector/engines/regex/detect-text.mjs +16 -11
  179. package/dist/builtin/workflows/skills/impeccable/scripts/detector/registry/antipatterns.mjs +66 -0
  180. package/dist/builtin/workflows/skills/impeccable/scripts/detector/rules/checks.mjs +42 -10
  181. package/dist/builtin/workflows/skills/impeccable/scripts/detector/shared/fonts.mjs +30 -0
  182. package/dist/builtin/workflows/skills/impeccable/scripts/detector/shared/page.mjs +4 -6
  183. package/dist/builtin/workflows/skills/impeccable/scripts/hook-admin.mjs +660 -0
  184. package/dist/builtin/workflows/skills/impeccable/scripts/hook-before-edit.mjs +516 -0
  185. package/dist/builtin/workflows/skills/impeccable/scripts/hook-lib.mjs +1764 -0
  186. package/dist/builtin/workflows/skills/impeccable/scripts/hook.mjs +61 -0
  187. package/dist/builtin/workflows/skills/impeccable/scripts/lib/impeccable-config.mjs +4 -2
  188. package/dist/builtin/workflows/skills/impeccable/scripts/lib/is-generated.mjs +2 -2
  189. package/dist/builtin/workflows/skills/impeccable/scripts/live/svelte-component.mjs +13 -16
  190. package/dist/builtin/workflows/skills/impeccable/scripts/live-accept.mjs +17 -11
  191. package/dist/builtin/workflows/skills/impeccable/scripts/live-browser.js +104 -37
  192. package/dist/builtin/workflows/skills/impeccable/scripts/live-wrap.mjs +9 -0
  193. package/dist/builtin/workflows/src/durable/backend.ts +12 -0
  194. package/dist/builtin/workflows/src/durable/dbos-backend.ts +17 -1
  195. package/dist/builtin/workflows/src/durable/resume-catalog.ts +12 -0
  196. package/dist/builtin/workflows/src/durable/resume-runtime.ts +5 -2
  197. package/dist/builtin/workflows/src/durable/stage-primitive.ts +2 -1
  198. package/dist/builtin/workflows/src/durable/types.ts +16 -0
  199. package/dist/builtin/workflows/src/engine/primitives/task.ts +3 -1
  200. package/dist/builtin/workflows/src/engine/run-durable-finalize.ts +1 -2
  201. package/dist/builtin/workflows/src/engine/run-returned-status.ts +50 -16
  202. package/dist/builtin/workflows/src/engine/run.ts +20 -19
  203. package/dist/builtin/workflows/src/engine/runtime.ts +5 -0
  204. package/dist/builtin/workflows/src/extension/extension-factory.ts +3 -0
  205. package/dist/builtin/workflows/src/extension/extension-lifecycle.ts +9 -2
  206. package/dist/builtin/workflows/src/extension/extension-runtime-state.ts +137 -27
  207. package/dist/builtin/workflows/src/extension/lifecycle-notifications.ts +22 -6
  208. package/dist/builtin/workflows/src/extension/public-types.ts +1 -1
  209. package/dist/builtin/workflows/src/extension/workflow-command-completions.ts +13 -1
  210. package/dist/builtin/workflows/src/extension/workflow-command-registration.ts +19 -4
  211. package/dist/builtin/workflows/src/extension/workflow-command-surfaces.ts +9 -0
  212. package/dist/builtin/workflows/src/extension/workflow-prompts.ts +17 -22
  213. package/dist/builtin/workflows/src/extension/workflow-run-control-command.ts +48 -23
  214. package/dist/builtin/workflows/src/extension/workflow-schema.ts +15 -2
  215. package/dist/builtin/workflows/src/extension/workflow-tool-control.ts +20 -8
  216. package/dist/builtin/workflows/src/extension/workflow-tool.ts +24 -8
  217. package/dist/builtin/workflows/src/runs/background/status.ts +4 -3
  218. package/dist/builtin/workflows/src/runs/foreground/executor-direct-helpers.ts +29 -8
  219. package/dist/builtin/workflows/src/runs/foreground/executor-hil.ts +1 -1
  220. package/dist/builtin/workflows/src/runs/foreground/executor-stage-factory.ts +3 -2
  221. package/dist/builtin/workflows/src/runs/shared/model-fallback-candidates.ts +1 -1
  222. package/dist/builtin/workflows/src/runs/shared/worktree-git.ts +155 -20
  223. package/dist/builtin/workflows/src/runs/shared/worktree-types.ts +6 -0
  224. package/dist/builtin/workflows/src/runs/shared/worktree.ts +2 -1
  225. package/dist/builtin/workflows/src/shared/authoring-contract-stage.d.ts +2 -2
  226. package/dist/builtin/workflows/src/shared/authoring-contract-stage.ts +2 -2
  227. package/dist/builtin/workflows/src/shared/resume-continuation.ts +2 -0
  228. package/dist/builtin/workflows/src/shared/returned-run-status.ts +116 -0
  229. package/dist/builtin/workflows/src/shared/workflow-failures-decisions.ts +2 -0
  230. package/dist/builtin/workflows/src/tui/graph-view-render-helpers.ts +21 -3
  231. package/dist/builtin/workflows/src/tui/graph-view-state.ts +3 -0
  232. package/dist/builtin/workflows/src/tui/graph-view-types.ts +3 -0
  233. package/dist/builtin/workflows/src/tui/stage-chat-view-archive-history.ts +1 -23
  234. package/dist/builtin/workflows/src/tui/stage-chat-view-footer-status.ts +54 -9
  235. package/dist/builtin/workflows/src/tui/stage-chat-view.ts +5 -2
  236. package/dist/builtin/workflows/src/tui/status-list.ts +22 -15
  237. package/dist/builtin/workflows/src/tui/workflow-attach-pane.ts +4 -4
  238. package/dist/cli/args.d.ts.map +1 -1
  239. package/dist/cli/args.js +2 -2
  240. package/dist/cli/args.js.map +1 -1
  241. package/dist/core/agent-session-auto-compaction.d.ts +23 -3
  242. package/dist/core/agent-session-auto-compaction.d.ts.map +1 -1
  243. package/dist/core/agent-session-auto-compaction.js +129 -17
  244. package/dist/core/agent-session-auto-compaction.js.map +1 -1
  245. package/dist/core/agent-session-events.d.ts.map +1 -1
  246. package/dist/core/agent-session-events.js +9 -1
  247. package/dist/core/agent-session-events.js.map +1 -1
  248. package/dist/core/agent-session-message-queue.d.ts.map +1 -1
  249. package/dist/core/agent-session-message-queue.js +1 -1
  250. package/dist/core/agent-session-message-queue.js.map +1 -1
  251. package/dist/core/agent-session-methods.d.ts +6 -3
  252. package/dist/core/agent-session-methods.d.ts.map +1 -1
  253. package/dist/core/agent-session-methods.js.map +1 -1
  254. package/dist/core/agent-session-prompt.d.ts.map +1 -1
  255. package/dist/core/agent-session-prompt.js +2 -2
  256. package/dist/core/agent-session-prompt.js.map +1 -1
  257. package/dist/core/agent-session-retry.d.ts.map +1 -1
  258. package/dist/core/agent-session-retry.js +1 -1
  259. package/dist/core/agent-session-retry.js.map +1 -1
  260. package/dist/core/agent-session-services.d.ts.map +1 -1
  261. package/dist/core/agent-session-services.js +3 -2
  262. package/dist/core/agent-session-services.js.map +1 -1
  263. package/dist/core/agent-session-types.d.ts.map +1 -1
  264. package/dist/core/agent-session-types.js +1 -1
  265. package/dist/core/agent-session-types.js.map +1 -1
  266. package/dist/core/agent-session.d.ts +4 -2
  267. package/dist/core/agent-session.d.ts.map +1 -1
  268. package/dist/core/agent-session.js +4 -2
  269. package/dist/core/agent-session.js.map +1 -1
  270. package/dist/core/anthropic-thinking-guard.d.ts +5 -5
  271. package/dist/core/anthropic-thinking-guard.d.ts.map +1 -1
  272. package/dist/core/anthropic-thinking-guard.js +42 -32
  273. package/dist/core/anthropic-thinking-guard.js.map +1 -1
  274. package/dist/core/atomic-guide-command.d.ts.map +1 -1
  275. package/dist/core/atomic-guide-command.js +15 -15
  276. package/dist/core/atomic-guide-command.js.map +1 -1
  277. package/dist/core/auth-storage.d.ts.map +1 -1
  278. package/dist/core/auth-storage.js +14 -9
  279. package/dist/core/auth-storage.js.map +1 -1
  280. package/dist/core/compaction/compaction.d.ts +2 -0
  281. package/dist/core/compaction/compaction.d.ts.map +1 -1
  282. package/dist/core/compaction/compaction.js +79 -46
  283. package/dist/core/compaction/compaction.js.map +1 -1
  284. package/dist/core/compaction/context-assistant-turns.d.ts +42 -0
  285. package/dist/core/compaction/context-assistant-turns.d.ts.map +1 -0
  286. package/dist/core/compaction/context-assistant-turns.js +87 -0
  287. package/dist/core/compaction/context-assistant-turns.js.map +1 -0
  288. package/dist/core/compaction/context-compaction-critical.d.ts +1 -1
  289. package/dist/core/compaction/context-compaction-critical.d.ts.map +1 -1
  290. package/dist/core/compaction/context-compaction-critical.js +2 -2
  291. package/dist/core/compaction/context-compaction-critical.js.map +1 -1
  292. package/dist/core/compaction/context-compaction-eviction-alternates.d.ts +18 -0
  293. package/dist/core/compaction/context-compaction-eviction-alternates.d.ts.map +1 -0
  294. package/dist/core/compaction/context-compaction-eviction-alternates.js +186 -0
  295. package/dist/core/compaction/context-compaction-eviction-alternates.js.map +1 -0
  296. package/dist/core/compaction/context-compaction-eviction.d.ts +10 -2
  297. package/dist/core/compaction/context-compaction-eviction.d.ts.map +1 -1
  298. package/dist/core/compaction/context-compaction-eviction.js +196 -146
  299. package/dist/core/compaction/context-compaction-eviction.js.map +1 -1
  300. package/dist/core/compaction/context-compaction-prompt.d.ts.map +1 -1
  301. package/dist/core/compaction/context-compaction-prompt.js +1 -1
  302. package/dist/core/compaction/context-compaction-prompt.js.map +1 -1
  303. package/dist/core/compaction/context-compaction-types.d.ts +2 -0
  304. package/dist/core/compaction/context-compaction-types.d.ts.map +1 -1
  305. package/dist/core/compaction/context-compaction-types.js.map +1 -1
  306. package/dist/core/compaction/context-deletion-application.d.ts +5 -4
  307. package/dist/core/compaction/context-deletion-application.d.ts.map +1 -1
  308. package/dist/core/compaction/context-deletion-application.js +17 -15
  309. package/dist/core/compaction/context-deletion-application.js.map +1 -1
  310. package/dist/core/compaction/context-deletion-store.d.ts.map +1 -1
  311. package/dist/core/compaction/context-deletion-store.js +1 -1
  312. package/dist/core/compaction/context-deletion-store.js.map +1 -1
  313. package/dist/core/compaction/context-deletion-targets.d.ts +2 -1
  314. package/dist/core/compaction/context-deletion-targets.d.ts.map +1 -1
  315. package/dist/core/compaction/context-deletion-targets.js +36 -31
  316. package/dist/core/compaction/context-deletion-targets.js.map +1 -1
  317. package/dist/core/compaction/context-deletion-tool-helpers.d.ts.map +1 -1
  318. package/dist/core/compaction/context-deletion-tool-helpers.js +116 -43
  319. package/dist/core/compaction/context-deletion-tool-helpers.js.map +1 -1
  320. package/dist/core/compaction/context-transcript-analysis.d.ts +1 -2
  321. package/dist/core/compaction/context-transcript-analysis.d.ts.map +1 -1
  322. package/dist/core/compaction/context-transcript-analysis.js +33 -37
  323. package/dist/core/compaction/context-transcript-analysis.js.map +1 -1
  324. package/dist/core/copilot-model-synthesis.d.ts.map +1 -1
  325. package/dist/core/copilot-model-synthesis.js +3 -1
  326. package/dist/core/copilot-model-synthesis.js.map +1 -1
  327. package/dist/core/extensions/loader-virtual-modules.d.ts +8 -1
  328. package/dist/core/extensions/loader-virtual-modules.d.ts.map +1 -1
  329. package/dist/core/extensions/loader-virtual-modules.js +2 -1
  330. package/dist/core/extensions/loader-virtual-modules.js.map +1 -1
  331. package/dist/core/extensions/provider-types.d.ts +2 -7
  332. package/dist/core/extensions/provider-types.d.ts.map +1 -1
  333. package/dist/core/extensions/provider-types.js.map +1 -1
  334. package/dist/core/footer-data-provider.d.ts +6 -0
  335. package/dist/core/footer-data-provider.d.ts.map +1 -1
  336. package/dist/core/footer-data-provider.js +72 -29
  337. package/dist/core/footer-data-provider.js.map +1 -1
  338. package/dist/core/messages.d.ts +9 -0
  339. package/dist/core/messages.d.ts.map +1 -1
  340. package/dist/core/messages.js +100 -18
  341. package/dist/core/messages.js.map +1 -1
  342. package/dist/core/model-registry-builtins.d.ts.map +1 -1
  343. package/dist/core/model-registry-builtins.js +5 -0
  344. package/dist/core/model-registry-builtins.js.map +1 -1
  345. package/dist/core/model-registry-custom-loader.d.ts.map +1 -1
  346. package/dist/core/model-registry-custom-loader.js +49 -8
  347. package/dist/core/model-registry-custom-loader.js.map +1 -1
  348. package/dist/core/model-registry-dynamic.d.ts.map +1 -1
  349. package/dist/core/model-registry-dynamic.js +11 -5
  350. package/dist/core/model-registry-dynamic.js.map +1 -1
  351. package/dist/core/model-registry-loader.d.ts.map +1 -1
  352. package/dist/core/model-registry-loader.js +8 -0
  353. package/dist/core/model-registry-loader.js.map +1 -1
  354. package/dist/core/model-registry-schemas.d.ts +93 -8
  355. package/dist/core/model-registry-schemas.d.ts.map +1 -1
  356. package/dist/core/model-registry-schemas.js +24 -12
  357. package/dist/core/model-registry-schemas.js.map +1 -1
  358. package/dist/core/model-registry-types.d.ts +7 -6
  359. package/dist/core/model-registry-types.d.ts.map +1 -1
  360. package/dist/core/model-registry-types.js.map +1 -1
  361. package/dist/core/model-registry.d.ts +5 -0
  362. package/dist/core/model-registry.d.ts.map +1 -1
  363. package/dist/core/model-registry.js +23 -0
  364. package/dist/core/model-registry.js.map +1 -1
  365. package/dist/core/model-resolver-cli.d.ts.map +1 -1
  366. package/dist/core/model-resolver-cli.js +33 -5
  367. package/dist/core/model-resolver-cli.js.map +1 -1
  368. package/dist/core/model-resolver-initial.d.ts +6 -1
  369. package/dist/core/model-resolver-initial.d.ts.map +1 -1
  370. package/dist/core/model-resolver-initial.js +12 -7
  371. package/dist/core/model-resolver-initial.js.map +1 -1
  372. package/dist/core/model-resolver.d.ts +1 -1
  373. package/dist/core/model-resolver.d.ts.map +1 -1
  374. package/dist/core/model-resolver.js +1 -1
  375. package/dist/core/model-resolver.js.map +1 -1
  376. package/dist/core/openai-responses-payload-sanitizer.d.ts +1 -0
  377. package/dist/core/openai-responses-payload-sanitizer.d.ts.map +1 -1
  378. package/dist/core/openai-responses-payload-sanitizer.js +24 -9
  379. package/dist/core/openai-responses-payload-sanitizer.js.map +1 -1
  380. package/dist/core/resource-loader-context-files.d.ts +1 -0
  381. package/dist/core/resource-loader-context-files.d.ts.map +1 -1
  382. package/dist/core/resource-loader-context-files.js +13 -10
  383. package/dist/core/resource-loader-context-files.js.map +1 -1
  384. package/dist/core/sdk.d.ts.map +1 -1
  385. package/dist/core/sdk.js +2 -2
  386. package/dist/core/sdk.js.map +1 -1
  387. package/dist/core/session-entry-normalization.d.ts +7 -0
  388. package/dist/core/session-entry-normalization.d.ts.map +1 -0
  389. package/dist/core/session-entry-normalization.js +14 -0
  390. package/dist/core/session-entry-normalization.js.map +1 -0
  391. package/dist/core/session-manager-core.d.ts.map +1 -1
  392. package/dist/core/session-manager-core.js +1 -0
  393. package/dist/core/session-manager-core.js.map +1 -1
  394. package/dist/core/session-manager-history.d.ts +2 -2
  395. package/dist/core/session-manager-history.d.ts.map +1 -1
  396. package/dist/core/session-manager-history.js +127 -108
  397. package/dist/core/session-manager-history.js.map +1 -1
  398. package/dist/core/settings-manager-basic-accessors.d.ts +2 -2
  399. package/dist/core/settings-manager-basic-accessors.d.ts.map +1 -1
  400. package/dist/core/settings-manager-basic-accessors.js.map +1 -1
  401. package/dist/core/settings-types.d.ts +1 -1
  402. package/dist/core/settings-types.d.ts.map +1 -1
  403. package/dist/core/settings-types.js.map +1 -1
  404. package/dist/core/slash-commands.d.ts +2 -0
  405. package/dist/core/slash-commands.d.ts.map +1 -1
  406. package/dist/core/slash-commands.js +141 -0
  407. package/dist/core/slash-commands.js.map +1 -1
  408. package/dist/core/tools/bash.d.ts.map +1 -1
  409. package/dist/core/tools/bash.js +11 -8
  410. package/dist/core/tools/bash.js.map +1 -1
  411. package/dist/index.d.ts +1 -0
  412. package/dist/index.d.ts.map +1 -1
  413. package/dist/index.js +1 -0
  414. package/dist/index.js.map +1 -1
  415. package/dist/main-deferred-startup.d.ts.map +1 -1
  416. package/dist/main-deferred-startup.js +2 -2
  417. package/dist/main-deferred-startup.js.map +1 -1
  418. package/dist/main-early-input.d.ts.map +1 -1
  419. package/dist/main-early-input.js +7 -0
  420. package/dist/main-early-input.js.map +1 -1
  421. package/dist/main-session.d.ts.map +1 -1
  422. package/dist/main-session.js +1 -0
  423. package/dist/main-session.js.map +1 -1
  424. package/dist/main.d.ts.map +1 -1
  425. package/dist/main.js +1 -1
  426. package/dist/main.js.map +1 -1
  427. package/dist/modes/interactive/components/chat-session-host-actions.d.ts.map +1 -1
  428. package/dist/modes/interactive/components/chat-session-host-actions.js +0 -1
  429. package/dist/modes/interactive/components/chat-session-host-actions.js.map +1 -1
  430. package/dist/modes/interactive/components/settings-selector-options.d.ts.map +1 -1
  431. package/dist/modes/interactive/components/settings-selector-options.js +3 -1
  432. package/dist/modes/interactive/components/settings-selector-options.js.map +1 -1
  433. package/dist/modes/interactive/components/thinking-selector.d.ts.map +1 -1
  434. package/dist/modes/interactive/components/thinking-selector.js +2 -1
  435. package/dist/modes/interactive/components/thinking-selector.js.map +1 -1
  436. package/dist/modes/interactive/interactive-agent-events.d.ts.map +1 -1
  437. package/dist/modes/interactive/interactive-agent-events.js +3 -1
  438. package/dist/modes/interactive/interactive-agent-events.js.map +1 -1
  439. package/dist/modes/interactive/interactive-autocomplete.d.ts.map +1 -1
  440. package/dist/modes/interactive/interactive-autocomplete.js +21 -9
  441. package/dist/modes/interactive/interactive-autocomplete.js.map +1 -1
  442. package/dist/modes/interactive/interactive-child-ordering.d.ts +7 -0
  443. package/dist/modes/interactive/interactive-child-ordering.d.ts.map +1 -0
  444. package/dist/modes/interactive/interactive-child-ordering.js +26 -0
  445. package/dist/modes/interactive/interactive-child-ordering.js.map +1 -0
  446. package/dist/modes/interactive/interactive-deferred-startup.d.ts.map +1 -1
  447. package/dist/modes/interactive/interactive-deferred-startup.js +43 -30
  448. package/dist/modes/interactive/interactive-deferred-startup.js.map +1 -1
  449. package/dist/modes/interactive/interactive-hotkeys-debug.d.ts.map +1 -1
  450. package/dist/modes/interactive/interactive-hotkeys-debug.js +1 -0
  451. package/dist/modes/interactive/interactive-hotkeys-debug.js.map +1 -1
  452. package/dist/modes/interactive/interactive-input-handling.d.ts.map +1 -1
  453. package/dist/modes/interactive/interactive-input-handling.js +41 -6
  454. package/dist/modes/interactive/interactive-input-handling.js.map +1 -1
  455. package/dist/modes/interactive/interactive-mode-base.d.ts +3 -0
  456. package/dist/modes/interactive/interactive-mode-base.d.ts.map +1 -1
  457. package/dist/modes/interactive/interactive-mode-base.js +3 -0
  458. package/dist/modes/interactive/interactive-mode-base.js.map +1 -1
  459. package/dist/modes/interactive/interactive-mode-deps.d.ts +2 -2
  460. package/dist/modes/interactive/interactive-mode-deps.d.ts.map +1 -1
  461. package/dist/modes/interactive/interactive-mode-deps.js +2 -2
  462. package/dist/modes/interactive/interactive-mode-deps.js.map +1 -1
  463. package/dist/modes/interactive/interactive-mode-surface.d.ts +2 -2
  464. package/dist/modes/interactive/interactive-mode-surface.d.ts.map +1 -1
  465. package/dist/modes/interactive/interactive-mode-surface.js.map +1 -1
  466. package/dist/modes/interactive/interactive-model-routing.d.ts.map +1 -1
  467. package/dist/modes/interactive/interactive-model-routing.js +11 -4
  468. package/dist/modes/interactive/interactive-model-routing.js.map +1 -1
  469. package/dist/modes/interactive/interactive-process-lifecycle.d.ts.map +1 -1
  470. package/dist/modes/interactive/interactive-process-lifecycle.js +0 -3
  471. package/dist/modes/interactive/interactive-process-lifecycle.js.map +1 -1
  472. package/dist/modes/interactive/interactive-render-chat.d.ts.map +1 -1
  473. package/dist/modes/interactive/interactive-render-chat.js +15 -1
  474. package/dist/modes/interactive/interactive-render-chat.js.map +1 -1
  475. package/dist/modes/interactive/interactive-session-routing.d.ts.map +1 -1
  476. package/dist/modes/interactive/interactive-session-routing.js +5 -1
  477. package/dist/modes/interactive/interactive-session-routing.js.map +1 -1
  478. package/dist/modes/interactive/interactive-startup.d.ts.map +1 -1
  479. package/dist/modes/interactive/interactive-startup.js +20 -21
  480. package/dist/modes/interactive/interactive-startup.js.map +1 -1
  481. package/dist/modes/interactive/theme/global-theme.d.ts.map +1 -1
  482. package/dist/modes/interactive/theme/global-theme.js +26 -2
  483. package/dist/modes/interactive/theme/global-theme.js.map +1 -1
  484. package/dist/modes/interactive/theme/theme-class.d.ts +1 -1
  485. package/dist/modes/interactive/theme/theme-class.d.ts.map +1 -1
  486. package/dist/modes/interactive/theme/theme-class.js +2 -0
  487. package/dist/modes/interactive/theme/theme-class.js.map +1 -1
  488. package/dist/utils/clipboard-image.d.ts.map +1 -1
  489. package/dist/utils/clipboard-image.js +3 -0
  490. package/dist/utils/clipboard-image.js.map +1 -1
  491. package/dist/utils/fs-watch.d.ts +24 -1
  492. package/dist/utils/fs-watch.d.ts.map +1 -1
  493. package/dist/utils/fs-watch.js +60 -5
  494. package/dist/utils/fs-watch.js.map +1 -1
  495. package/docs/changelog.mdx +19 -0
  496. package/docs/compaction.md +60 -49
  497. package/docs/custom-provider.md +18 -5
  498. package/docs/development.md +4 -0
  499. package/docs/extensions.md +11 -2
  500. package/docs/json.md +1 -1
  501. package/docs/models.md +69 -10
  502. package/docs/providers.md +1 -1
  503. package/docs/quickstart.md +12 -8
  504. package/docs/rpc.md +2 -2
  505. package/docs/sdk.md +1 -1
  506. package/docs/settings.md +4 -4
  507. package/docs/subagents.md +40 -5
  508. package/docs/tools.md +1 -1
  509. package/docs/usage.md +4 -2
  510. package/docs/windows.md +4 -0
  511. package/docs/workflows.md +33 -48
  512. package/examples/extensions/preset.ts +2 -2
  513. package/examples/extensions/subagent/README.md +2 -2
  514. package/examples/extensions/subagent/index.ts +1 -2
  515. package/examples/extensions/subagent/schemas.ts +4 -1
  516. package/examples/sdk/12-full-control.ts +1 -1
  517. package/npm-shrinkwrap.json +48 -51
  518. package/package.json +7 -7
  519. package/dist/builtin/subagents/src/runs/foreground/chain-clarify-behavior.ts +0 -75
  520. package/dist/builtin/subagents/src/runs/foreground/chain-clarify-component.ts +0 -202
  521. package/dist/builtin/subagents/src/runs/foreground/chain-clarify-edit.ts +0 -97
  522. package/dist/builtin/subagents/src/runs/foreground/chain-clarify-editor.ts +0 -160
  523. package/dist/builtin/subagents/src/runs/foreground/chain-clarify-frame.ts +0 -72
  524. package/dist/builtin/subagents/src/runs/foreground/chain-clarify-render-modes.ts +0 -161
  525. package/dist/builtin/subagents/src/runs/foreground/chain-clarify-render-selectors.ts +0 -203
  526. package/dist/builtin/subagents/src/runs/foreground/chain-clarify-selectors.ts +0 -234
  527. package/dist/builtin/subagents/src/runs/foreground/chain-clarify-state.ts +0 -103
  528. package/dist/builtin/subagents/src/runs/foreground/chain-clarify-types.ts +0 -29
  529. package/dist/builtin/subagents/src/runs/foreground/chain-clarify.ts +0 -9
  530. package/dist/builtin/subagents/src/runs/foreground/chain-execution-clarify.ts +0 -117
@@ -0,0 +1,189 @@
1
+ import type { FrozenCompletionEnvelope } from "./result-file-claims.js";
2
+
3
+ type CompletionClaimStatus = "delivered" | "retry" | "exhausted" | "conflict" | "released";
4
+ type TerminalStatus = Extract<CompletionClaimStatus, "delivered" | "exhausted">;
5
+
6
+ interface CompletionAttempt {
7
+ status: CompletionClaimStatus;
8
+ noProgressFailures: number;
9
+ }
10
+
11
+ interface CompletionFlight {
12
+ promise: Promise<CompletionAttempt>;
13
+ }
14
+
15
+ export interface CompletionClaimSnapshot {
16
+ intercomDelivered: boolean;
17
+ localDelivered: boolean;
18
+ noProgressFailures: number;
19
+ terminalStatus?: TerminalStatus;
20
+ envelope: FrozenCompletionEnvelope;
21
+ }
22
+
23
+ interface CompletionClaim extends CompletionClaimSnapshot {
24
+ signature: string;
25
+ inFlight?: CompletionFlight;
26
+ completedAt?: number;
27
+ lastTouchedAt: number;
28
+ }
29
+
30
+ export interface CompletionClaimResult extends CompletionAttempt {
31
+ owner: boolean;
32
+ }
33
+
34
+ export interface CompletionDeliveryPhases {
35
+ intercom?: (envelope: FrozenCompletionEnvelope) => Promise<boolean> | boolean;
36
+ local?: (envelope: FrozenCompletionEnvelope) => Promise<boolean> | boolean;
37
+ isOwned?: () => boolean;
38
+ onState?: (snapshot: CompletionClaimSnapshot) => void;
39
+ }
40
+
41
+ export interface CompletionClaimInitial {
42
+ intercomDelivered?: boolean;
43
+ localDelivered?: boolean;
44
+ noProgressFailures?: number;
45
+ terminalStatus?: TerminalStatus;
46
+ envelope?: FrozenCompletionEnvelope;
47
+ }
48
+
49
+ const STORE_KEY = "__atomicSubagentCompletionClaims";
50
+ const DEFAULT_MAX_NO_PROGRESS_FAILURES = 8;
51
+ const MAX_CLAIMS = 2048;
52
+
53
+ function cloneEnvelope(envelope: FrozenCompletionEnvelope): FrozenCompletionEnvelope {
54
+ return JSON.parse(JSON.stringify(envelope)) as FrozenCompletionEnvelope;
55
+ }
56
+
57
+ function claims(): Map<string, CompletionClaim> {
58
+ const globalStore = globalThis as Record<string, unknown>;
59
+ const existing = globalStore[STORE_KEY];
60
+ if (existing instanceof Map) return existing as Map<string, CompletionClaim>;
61
+ const created = new Map<string, CompletionClaim>();
62
+ globalStore[STORE_KEY] = created;
63
+ return created;
64
+ }
65
+
66
+ function prune(store: Map<string, CompletionClaim>, now: number, ttlMs: number): void {
67
+ for (const [key, claim] of store) {
68
+ if (claim.completedAt !== undefined && now - claim.completedAt > ttlMs) store.delete(key);
69
+ }
70
+ if (store.size <= MAX_CLAIMS) return;
71
+ const disposable = [...store.entries()]
72
+ .filter(([, claim]) => !claim.inFlight && !claim.intercomDelivered && !claim.localDelivered)
73
+ .sort((a, b) => a[1].lastTouchedAt - b[1].lastTouchedAt);
74
+ for (const [key] of disposable) {
75
+ if (store.size <= MAX_CLAIMS) break;
76
+ store.delete(key);
77
+ }
78
+ }
79
+
80
+ function snapshot(claim: CompletionClaim): CompletionClaimSnapshot {
81
+ return {
82
+ intercomDelivered: claim.intercomDelivered,
83
+ localDelivered: claim.localDelivered,
84
+ noProgressFailures: claim.noProgressFailures,
85
+ terminalStatus: claim.terminalStatus,
86
+ envelope: cloneEnvelope(claim.envelope),
87
+ };
88
+ }
89
+
90
+ function persist(claim: CompletionClaim, callback: CompletionDeliveryPhases["onState"]): void {
91
+ claim.lastTouchedAt = Date.now();
92
+ callback?.(snapshot(claim));
93
+ }
94
+
95
+ /** Atomically owns and advances one completion across aliases and watcher replacements. */
96
+ export async function deliverClaimedCompletion(
97
+ key: string,
98
+ signature: string,
99
+ ttlMs: number,
100
+ phases: CompletionDeliveryPhases,
101
+ maxNoProgressFailures = DEFAULT_MAX_NO_PROGRESS_FAILURES,
102
+ initial: CompletionClaimInitial = {},
103
+ envelope: FrozenCompletionEnvelope = { local: {} },
104
+ ): Promise<CompletionClaimResult> {
105
+ const store = claims();
106
+ const now = Date.now();
107
+ prune(store, now, ttlMs);
108
+ let claim = store.get(key);
109
+ if (!claim) {
110
+ claim = {
111
+ signature,
112
+ envelope: cloneEnvelope(initial.envelope ?? envelope),
113
+ intercomDelivered: initial.intercomDelivered === true,
114
+ localDelivered: initial.localDelivered === true,
115
+ noProgressFailures: initial.noProgressFailures ?? 0,
116
+ terminalStatus: initial.terminalStatus,
117
+ completedAt: initial.terminalStatus ? now : undefined,
118
+ lastTouchedAt: now,
119
+ };
120
+ store.set(key, claim);
121
+ persist(claim, phases.onState);
122
+ } else if (claim.signature !== signature) {
123
+ return { owner: false, status: "conflict", noProgressFailures: claim.noProgressFailures };
124
+ }
125
+ claim.lastTouchedAt = now;
126
+ if (claim.terminalStatus) return { owner: false, status: claim.terminalStatus, noProgressFailures: claim.noProgressFailures };
127
+ if (claim.inFlight) return { owner: false, ...await claim.inFlight.promise };
128
+
129
+ const ownedClaim = claim;
130
+ const hasVisibleProgress = () => ownedClaim.intercomDelivered || ownedClaim.localDelivered;
131
+ const retireForOwnershipLoss = (): CompletionAttempt => {
132
+ if (!hasVisibleProgress()) {
133
+ store.delete(key);
134
+ return { status: "released", noProgressFailures: ownedClaim.noProgressFailures };
135
+ }
136
+ persist(ownedClaim, phases.onState);
137
+ return { status: "released", noProgressFailures: ownedClaim.noProgressFailures };
138
+ };
139
+ const attempt = (async (): Promise<CompletionAttempt> => {
140
+ let progressed = false;
141
+ const failed = (): CompletionAttempt => {
142
+ if (phases.isOwned && !phases.isOwned()) return retireForOwnershipLoss();
143
+ ownedClaim.noProgressFailures = progressed ? 0 : ownedClaim.noProgressFailures + 1;
144
+ if (ownedClaim.noProgressFailures >= Math.max(1, maxNoProgressFailures)) {
145
+ ownedClaim.terminalStatus = "exhausted";
146
+ ownedClaim.completedAt = Date.now();
147
+ persist(ownedClaim, phases.onState);
148
+ return { status: "exhausted", noProgressFailures: ownedClaim.noProgressFailures };
149
+ }
150
+ persist(ownedClaim, phases.onState);
151
+ return { status: "retry", noProgressFailures: ownedClaim.noProgressFailures };
152
+ };
153
+ const runPhase = async (phase: ((value: FrozenCompletionEnvelope) => Promise<boolean> | boolean) | undefined): Promise<boolean | undefined> => {
154
+ if (!phase) return undefined;
155
+ if (phases.isOwned && !phases.isOwned()) return false;
156
+ try { return await phase(cloneEnvelope(ownedClaim.envelope)); } catch { return false; }
157
+ };
158
+ if (!ownedClaim.intercomDelivered && phases.intercom) {
159
+ const delivered = await runPhase(phases.intercom);
160
+ if (!delivered) return failed();
161
+ ownedClaim.intercomDelivered = true;
162
+ progressed = true;
163
+ persist(ownedClaim, phases.onState);
164
+ if (phases.isOwned && !phases.isOwned()) return retireForOwnershipLoss();
165
+ }
166
+ if (!ownedClaim.localDelivered && phases.local) {
167
+ const delivered = await runPhase(phases.local);
168
+ if (!delivered) return failed();
169
+ ownedClaim.localDelivered = true;
170
+ progressed = true;
171
+ persist(ownedClaim, phases.onState);
172
+ if (phases.isOwned && !phases.isOwned()) return retireForOwnershipLoss();
173
+ }
174
+ ownedClaim.noProgressFailures = 0;
175
+ ownedClaim.terminalStatus = "delivered";
176
+ ownedClaim.completedAt = Date.now();
177
+ persist(ownedClaim, phases.onState);
178
+ return { status: "delivered", noProgressFailures: 0 };
179
+ })();
180
+ const flight: CompletionFlight = { promise: attempt };
181
+ ownedClaim.inFlight = flight;
182
+ try {
183
+ return { owner: true, ...await flight.promise };
184
+ } finally {
185
+ // The explicit flight handle is the ownership token; comparing resolved
186
+ // values would let an older attempt clear a newer in-flight claim.
187
+ if (ownedClaim.inFlight === flight) ownedClaim.inFlight = undefined;
188
+ }
189
+ }
@@ -1,4 +1,13 @@
1
+ export interface CompletionSeenRecord {
2
+ seenAt: number;
3
+ signature?: string;
4
+ }
5
+
6
+ export type CompletionSeenMap = Map<string, number | CompletionSeenRecord>;
7
+ export type CompletionSeenMatch = "miss" | "match" | "conflict";
8
+
1
9
  interface CompletionDataLike {
10
+ runId?: unknown;
2
11
  id?: unknown;
3
12
  agent?: unknown;
4
13
  timestamp?: unknown;
@@ -20,6 +29,8 @@ function asFiniteNumber(value: unknown): number | undefined {
20
29
  }
21
30
 
22
31
  export function buildCompletionKey(data: CompletionDataLike, fallback: string): string {
32
+ const runId = asNonEmptyString(data.runId);
33
+ if (runId) return `run:${runId}`;
23
34
  const id = asNonEmptyString(data.id);
24
35
  if (id) return `id:${id}`;
25
36
  const sessionId = asNonEmptyString(data.sessionId) ?? "no-session";
@@ -40,24 +51,50 @@ export function buildCompletionKey(data: CompletionDataLike, fallback: string):
40
51
  ].join(":");
41
52
  }
42
53
 
43
- function pruneSeenMap(seen: Map<string, number>, now: number, ttlMs: number): void {
44
- for (const [key, ts] of seen.entries()) {
45
- if (now - ts > ttlMs) seen.delete(key);
54
+ function recordTimestamp(record: number | CompletionSeenRecord): number {
55
+ return typeof record === "number" ? record : record.seenAt;
56
+ }
57
+
58
+ function pruneSeenMap(seen: CompletionSeenMap, now: number, ttlMs: number): void {
59
+ for (const [key, record] of seen.entries()) {
60
+ if (now - recordTimestamp(record) > ttlMs) seen.delete(key);
46
61
  }
47
62
  }
48
63
 
49
- export function markSeenWithTtl(seen: Map<string, number>, key: string, now: number, ttlMs: number): boolean {
64
+ export function lookupSeenWithTtl(
65
+ seen: CompletionSeenMap,
66
+ key: string,
67
+ signature: string | undefined,
68
+ now: number,
69
+ ttlMs: number,
70
+ ): CompletionSeenMatch {
71
+ pruneSeenMap(seen, now, ttlMs);
72
+ const record = seen.get(key);
73
+ if (record === undefined) return "miss";
74
+ const recordedSignature = typeof record === "number" ? undefined : record.signature;
75
+ return recordedSignature === undefined || signature === undefined || recordedSignature === signature ? "match" : "conflict";
76
+ }
77
+
78
+ export function hasSeenWithTtl(seen: CompletionSeenMap, key: string, now: number, ttlMs: number): boolean {
79
+ return lookupSeenWithTtl(seen, key, undefined, now, ttlMs) !== "miss";
80
+ }
81
+
82
+ export function recordSeen(seen: CompletionSeenMap, key: string, now: number, signature?: string): void {
83
+ seen.set(key, signature === undefined ? now : { seenAt: now, signature });
84
+ }
85
+
86
+ export function markSeenWithTtl(seen: CompletionSeenMap, key: string, now: number, ttlMs: number): boolean {
50
87
  pruneSeenMap(seen, now, ttlMs);
51
88
  if (seen.has(key)) return true;
52
89
  seen.set(key, now);
53
90
  return false;
54
91
  }
55
92
 
56
- export function getGlobalSeenMap(storeKey: string): Map<string, number> {
93
+ export function getGlobalSeenMap(storeKey: string): CompletionSeenMap {
57
94
  const globalStore = globalThis as Record<string, unknown>;
58
95
  const existing = globalStore[storeKey];
59
- if (existing instanceof Map) return existing as Map<string, number>;
60
- const map = new Map<string, number>();
96
+ if (existing instanceof Map) return existing as CompletionSeenMap;
97
+ const map: CompletionSeenMap = new Map();
61
98
  globalStore[storeKey] = map;
62
99
  return map;
63
100
  }
@@ -0,0 +1,34 @@
1
+ import type { IntercomEventBus } from "../../shared/types.ts";
2
+ import { SUBAGENT_ASYNC_COMPLETE_EVENT } from "../../shared/types.ts";
3
+
4
+ export interface CompletionNotificationEnvelope extends Record<string, unknown> {
5
+ notificationId: string;
6
+ acknowledge: (delivered: boolean) => void;
7
+ }
8
+
9
+ export function deliverLocalCompletionNotification(
10
+ events: IntercomEventBus,
11
+ payload: Record<string, unknown>,
12
+ notificationId: string,
13
+ ): Promise<boolean> {
14
+ return new Promise((resolve) => {
15
+ let settled = false;
16
+ const finish = (delivered: boolean) => {
17
+ if (settled) return;
18
+ settled = true;
19
+ resolve(delivered);
20
+ };
21
+ try {
22
+ events.emit(SUBAGENT_ASYNC_COMPLETE_EVENT, {
23
+ ...payload,
24
+ notificationId,
25
+ acknowledge: finish,
26
+ } satisfies CompletionNotificationEnvelope);
27
+ // The established event contract treats successful synchronous emission as
28
+ // delivery. Production listeners can synchronously reject via acknowledge(false).
29
+ finish(true);
30
+ } catch {
31
+ finish(false);
32
+ }
33
+ });
34
+ }
@@ -3,7 +3,8 @@
3
3
  */
4
4
 
5
5
  import type { ExtensionAPI } from "@bastani/atomic";
6
- import { buildCompletionKey, getGlobalSeenMap, markSeenWithTtl } from "./completion-dedupe.ts";
6
+ import { buildCompletionKey, hasSeenWithTtl, recordSeen } from "./completion-dedupe.ts";
7
+ import type { CompletionNotificationEnvelope } from "./completion-notification.ts";
7
8
  import { SUBAGENT_ASYNC_COMPLETE_EVENT } from "../../shared/types.ts";
8
9
 
9
10
  interface ChainStepResult {
@@ -40,27 +41,62 @@ interface SubagentResult {
40
41
  totalTasks?: number;
41
42
  }
42
43
 
43
- export default function registerSubagentNotify(pi: ExtensionAPI): void {
44
- const unsubscribeStoreKey = "__pi_subagents_notify_unsubscribe__";
45
- const globalStore = globalThis as Record<string, unknown>;
46
- const previousUnsubscribe = globalStore[unsubscribeStoreKey];
47
- if (typeof previousUnsubscribe === "function") {
44
+ interface NotifyRegistration {
45
+ unsubscribe: () => void;
46
+ }
47
+
48
+ function getNotifyRegistry(): WeakMap<ExtensionAPI, NotifyRegistration> {
49
+ const key = "__piSubagentsNotifyRegistrations";
50
+ const store = globalThis as Record<string, unknown>;
51
+ const existing = store[key];
52
+ if (existing instanceof WeakMap) return existing as WeakMap<ExtensionAPI, NotifyRegistration>;
53
+ const registry = new WeakMap<ExtensionAPI, NotifyRegistration>();
54
+ store[key] = registry;
55
+ return registry;
56
+ }
57
+
58
+ function getNotifySeenRegistry(): WeakMap<ExtensionAPI, Map<string, number>> {
59
+ const key = "__piSubagentsNotifySeenByApi";
60
+ const store = globalThis as Record<string, unknown>;
61
+ const existing = store[key];
62
+ if (existing instanceof WeakMap) return existing as WeakMap<ExtensionAPI, Map<string, number>>;
63
+ const registry = new WeakMap<ExtensionAPI, Map<string, number>>();
64
+ store[key] = registry;
65
+ return registry;
66
+ }
67
+
68
+ function getNotifySeen(pi: ExtensionAPI): Map<string, number> {
69
+ const registry = getNotifySeenRegistry();
70
+ const existing = registry.get(pi);
71
+ if (existing) return existing;
72
+ const seen = new Map<string, number>();
73
+ registry.set(pi, seen);
74
+ return seen;
75
+ }
76
+
77
+ export default function registerSubagentNotify(pi: ExtensionAPI): () => void {
78
+ const registry = getNotifyRegistry();
79
+ const previous = registry.get(pi);
80
+ if (previous) {
48
81
  try {
49
- previousUnsubscribe();
82
+ previous.unsubscribe();
50
83
  } catch {
51
84
  // Best effort cleanup for stale handlers from an older reload.
52
85
  }
53
86
  }
54
-
55
- const seen = getGlobalSeenMap("__pi_subagents_notify_seen__");
87
+ const seen = getNotifySeen(pi);
56
88
  const ttlMs = 10 * 60 * 1000;
57
89
 
90
+ let registration: NotifyRegistration;
58
91
  const handleComplete = (data: unknown) => {
59
- const result = data as SubagentResult;
92
+ if (registry.get(pi) !== registration) return;
93
+ const result = data as SubagentResult & Partial<CompletionNotificationEnvelope>;
60
94
  const now = Date.now();
61
- const key = buildCompletionKey(result, "notify");
62
- if (markSeenWithTtl(seen, key, now, ttlMs)) return;
63
-
95
+ const key = result.notificationId ? `notification:${result.notificationId}` : buildCompletionKey(result, "notify");
96
+ if (hasSeenWithTtl(seen, key, now, ttlMs)) {
97
+ result.acknowledge?.(true);
98
+ return;
99
+ }
64
100
  const agent = result.agent ?? "unknown";
65
101
  const summary = typeof result.summary === "string" ? result.summary : "";
66
102
  const paused = !result.success && (
@@ -94,15 +130,29 @@ export default function registerSubagentNotify(pi: ExtensionAPI): void {
94
130
  .filter((line) => line !== undefined)
95
131
  .join("\n");
96
132
 
97
- pi.sendMessage(
98
- {
99
- customType: "subagent-notify",
100
- content,
101
- display: true,
102
- },
103
- { triggerTurn: true },
104
- );
133
+ try {
134
+ pi.sendMessage(
135
+ {
136
+ customType: "subagent-notify",
137
+ content,
138
+ display: true,
139
+ },
140
+ { triggerTurn: true },
141
+ );
142
+ recordSeen(seen, key, Date.now());
143
+ result.acknowledge?.(true);
144
+ } catch (error) {
145
+ result.acknowledge?.(false);
146
+ console.error("Failed to deliver async subagent completion notification:", error);
147
+ }
105
148
  };
106
149
 
107
- globalStore[unsubscribeStoreKey] = pi.events.on(SUBAGENT_ASYNC_COMPLETE_EVENT, handleComplete);
150
+ const unsubscribe = pi.events.on(SUBAGENT_ASYNC_COMPLETE_EVENT, handleComplete);
151
+ registration = { unsubscribe };
152
+ registry.set(pi, registration);
153
+ return () => {
154
+ if (registry.get(pi) !== registration) return;
155
+ registry.delete(pi);
156
+ unsubscribe();
157
+ };
108
158
  }
@@ -0,0 +1,232 @@
1
+ import * as fs from "node:fs";
2
+ import { createHash } from "node:crypto";
3
+ import * as path from "node:path";
4
+ import { buildCompletionKey, lookupSeenWithTtl, recordSeen } from "./completion-dedupe.js";
5
+ import { deliverClaimedCompletion, type CompletionClaimSnapshot } from "./completion-claims.js";
6
+ import { deliverLocalCompletionNotification } from "./completion-notification.js";
7
+ import { quarantineResultFile } from "./result-quarantine.js";
8
+ import {
9
+ claimIdFromScheduleKey,
10
+ claimPublicResult,
11
+ claimScheduleKey,
12
+ loadResultClaim,
13
+ readClaimData,
14
+ removeResultClaim,
15
+ updateResultClaim,
16
+ type FrozenCompletionEnvelope,
17
+ type ResultClaimFs,
18
+ type ResultFileClaim,
19
+ } from "./result-file-claims.js";
20
+ import { modernResultHasTerminalStatus, type ResultStatusFs } from "./result-status.js";
21
+ import {
22
+ attachNestedChildrenToResultChildren,
23
+ buildSubagentResultIntercomPayload,
24
+ compactNestedResultChildren,
25
+ deliverSubagentResultIntercomEvent,
26
+ resolveSubagentResultStatus,
27
+ } from "../../intercom/result-intercom.js";
28
+ import { projectNestedRegistryForRoot } from "../shared/nested-events.js";
29
+ import { buildCompletionSignature, sanitizeNestedResultChildren, type ResultFileData } from "./result-watcher-data.js";
30
+ import type { IntercomEventBus, SubagentResultIntercomChild, SubagentState } from "../../shared/types.js";
31
+
32
+ export interface ResultProcessOutcome {
33
+ status: "done" | "status-pending" | "delivery-retry" | "inactive";
34
+ entry?: string;
35
+ }
36
+
37
+ export interface ResultProcessorFs extends ResultClaimFs, Partial<ResultStatusFs> {
38
+ existsSync?: typeof fs.existsSync;
39
+ unlinkSync?: typeof fs.unlinkSync;
40
+ linkSync?: typeof fs.linkSync;
41
+ copyFileSync?: typeof fs.copyFileSync;
42
+ openSync?: typeof fs.openSync;
43
+ readSync?: typeof fs.readSync;
44
+ closeSync?: typeof fs.closeSync;
45
+ }
46
+
47
+ export interface ResultProcessorContext {
48
+ pi: { events: IntercomEventBus };
49
+ state: SubagentState;
50
+ resultsDir: string;
51
+ completionTtlMs: number;
52
+ fsApi?: ResultProcessorFs;
53
+ allowedStatusRoots?: string[];
54
+ maxStatusBytes?: number;
55
+ maxNoProgressFailures?: number;
56
+ intercomTimeoutMs?: number | false;
57
+ isActive: () => boolean;
58
+ ownsResult: (data: ResultFileData) => boolean;
59
+ }
60
+
61
+ function statusFs(fsApi: ResultProcessorFs): ResultStatusFs {
62
+ return {
63
+ realpathSync: fsApi.realpathSync ?? fs.realpathSync,
64
+ lstatSync: fsApi.lstatSync ?? fs.lstatSync,
65
+ openSync: fsApi.openSync ?? fs.openSync,
66
+ fstatSync: fsApi.fstatSync ?? fs.fstatSync,
67
+ readSync: fsApi.readSync ?? fs.readSync,
68
+ closeSync: fsApi.closeSync ?? fs.closeSync,
69
+ };
70
+ }
71
+
72
+ function readPublic(resultsDir: string, file: string, fsApi: ResultProcessorFs): ResultFileData {
73
+ return JSON.parse((fsApi.readFileSync ?? fs.readFileSync)(path.join(resultsDir, file), "utf-8")) as ResultFileData;
74
+ }
75
+
76
+ function markClaimState(claim: ResultFileClaim, value: CompletionClaimSnapshot, fsApi: ResultProcessorFs): void {
77
+ updateResultClaim(claim, {
78
+ intercomDelivered: value.intercomDelivered,
79
+ localDelivered: value.localDelivered,
80
+ noProgressFailures: value.noProgressFailures,
81
+ envelope: value.envelope,
82
+ ...(value.terminalStatus === "delivered" ? { state: "delivered" as const } : {}),
83
+ ...(value.terminalStatus === "exhausted" ? { state: "undelivered" as const } : {}),
84
+ }, fsApi);
85
+ }
86
+
87
+ function buildEnvelope(data: ResultFileData, resultPath: string, fsApi: ResultProcessorFs): FrozenCompletionEnvelope {
88
+ const runId = data.runId ?? data.id ?? path.basename(resultPath, ".json");
89
+ const explicitNested = data.nestedChildren !== undefined;
90
+ let nestedChildren = compactNestedResultChildren(sanitizeNestedResultChildren(data.nestedChildren, resultPath, "nestedChildren"));
91
+ if (!nestedChildren?.length && !explicitNested) nestedChildren = compactNestedResultChildren(projectNestedRegistryForRoot(runId)?.children);
92
+ const hasResults = Array.isArray(data.results) && data.results.length > 0;
93
+ const resultChildren = hasResults ? data.results! : [{ agent: data.agent, output: data.summary, success: data.success }];
94
+ const normalized = attachNestedChildrenToResultChildren(runId, resultChildren.map((result = {}, index): SubagentResultIntercomChild => {
95
+ const baseOutput = result.output ?? data.summary;
96
+ const hasOutput = typeof baseOutput === "string" && baseOutput.trim().length > 0;
97
+ const output = hasOutput ? baseOutput : "(no output)";
98
+ const summary = result.success === false && result.error
99
+ ? `${result.error}${hasOutput ? `\n\nOutput:\n${baseOutput}` : ""}`
100
+ : output;
101
+ const sessionPath = result.sessionFile ?? (resultChildren.length === 1 ? data.sessionFile : undefined);
102
+ const children = sanitizeNestedResultChildren(result.children, resultPath, `results[${index}].children`);
103
+ return {
104
+ agent: result.agent ?? data.agent ?? `step-${index + 1}`,
105
+ status: resolveSubagentResultStatus({
106
+ success: result.success,
107
+ state: data.state === "paused" || typeof result.success !== "boolean" ? data.state : undefined,
108
+ }),
109
+ summary,
110
+ index,
111
+ artifactPath: result.artifactPaths?.outputPath,
112
+ ...(typeof sessionPath === "string" && (fsApi.existsSync ?? fs.existsSync)(sessionPath) ? { sessionPath } : {}),
113
+ ...(result.intercomTarget ? { intercomTarget: result.intercomTarget } : {}),
114
+ ...(children ? { children } : {}),
115
+ };
116
+ }), nestedChildren);
117
+ const local: Record<string, unknown> = {
118
+ ...data,
119
+ runId,
120
+ ...(nestedChildren?.length ? { nestedChildren } : {}),
121
+ ...(Array.isArray(data.results) ? {
122
+ results: hasResults ? normalized.map((child, index) => ({
123
+ ...data.results![index], agent: child.agent, status: child.status, summary: child.summary,
124
+ index: child.index, artifactPath: child.artifactPath, sessionPath: child.sessionPath, children: child.children,
125
+ })) : [],
126
+ } : {}),
127
+ };
128
+ const target = data.intercomTarget?.trim();
129
+ const mode = data.mode === "single" || data.mode === "parallel" || data.mode === "chain"
130
+ ? data.mode : resultChildren.length > 1 ? "chain" : "single";
131
+ return {
132
+ local,
133
+ ...(target ? { intercom: { to: target, runId, mode, source: "async", children: normalized, asyncId: data.id, asyncDir: data.asyncDir } } : {}),
134
+ };
135
+ }
136
+
137
+ function quarantineClaim(context: ResultProcessorContext, claim: ResultFileClaim): void {
138
+ const fsApi = context.fsApi ?? fs;
139
+ updateResultClaim(claim, { state: "undelivered" }, fsApi);
140
+ quarantineResultFile(context.resultsDir, claim.meta.originalFile, claim.payloadPath, fsApi as typeof fs);
141
+ removeResultClaim(claim, fsApi);
142
+ }
143
+
144
+ export async function processResultEntry(entry: string, context: ResultProcessorContext): Promise<ResultProcessOutcome> {
145
+ const fsApi = context.fsApi ?? fs;
146
+ let claim: ResultFileClaim | undefined;
147
+ const existingClaimId = claimIdFromScheduleKey(entry);
148
+ if (existingClaimId) {
149
+ claim = loadResultClaim(context.resultsDir, existingClaimId, fsApi);
150
+ if (!claim) return { status: "done" };
151
+ if (claim.meta.state === "delivered") { removeResultClaim(claim, fsApi); return { status: "done" }; }
152
+ if (claim.meta.state === "undelivered") { quarantineClaim(context, claim); return { status: "done" }; }
153
+ } else {
154
+ const publicPath = path.join(context.resultsDir, entry);
155
+ if (!(fsApi.existsSync ?? fs.existsSync)(publicPath)) return { status: "done" };
156
+ const preliminary = readPublic(context.resultsDir, entry, fsApi);
157
+ if (!context.ownsResult(preliminary)) return { status: "inactive" };
158
+ if (!modernResultHasTerminalStatus(preliminary, statusFs(fsApi), {
159
+ allowedRoots: context.allowedStatusRoots,
160
+ maxBytes: context.maxStatusBytes,
161
+ })) return { status: "status-pending", entry };
162
+ claim = claimPublicResult(context.resultsDir, entry, fsApi);
163
+ }
164
+
165
+ const { data } = readClaimData(claim, fsApi);
166
+ if (!context.ownsResult(data)) return { status: "inactive" };
167
+ if (!modernResultHasTerminalStatus(data, statusFs(fsApi), {
168
+ allowedRoots: context.allowedStatusRoots,
169
+ maxBytes: context.maxStatusBytes,
170
+ })) return { status: "status-pending", entry: claim ? claimScheduleKey(claim.id) : entry };
171
+ const sourceSignature = buildCompletionSignature({ source: data });
172
+ if (claim.meta.sourceSignature && claim.meta.sourceSignature !== sourceSignature) {
173
+ quarantineClaim(context, claim);
174
+ return { status: "done" };
175
+ }
176
+ let envelope = claim.meta.envelope;
177
+ if (!envelope) {
178
+ envelope = buildEnvelope(data, claim.payloadPath, fsApi);
179
+ updateResultClaim(claim, { sourceSignature, envelope }, fsApi);
180
+ }
181
+ const completionKey = buildCompletionKey(data, `result:${claim.meta.originalFile}`);
182
+ const claimKey = `${path.resolve(context.resultsDir)}:${completionKey}`;
183
+ const stableHash = createHash("sha256").update(`${claimKey}:${sourceSignature}`).digest("hex");
184
+ const seen = lookupSeenWithTtl(context.state.completionSeen, completionKey, sourceSignature, Date.now(), context.completionTtlMs);
185
+ if (seen === "match") {
186
+ updateResultClaim(claim, { state: "delivered" }, fsApi);
187
+ removeResultClaim(claim, fsApi);
188
+ return { status: "done" };
189
+ }
190
+ if (seen === "conflict") {
191
+ quarantineClaim(context, claim);
192
+ return { status: "done" };
193
+ }
194
+ const claimResult = await deliverClaimedCompletion(
195
+ claimKey,
196
+ sourceSignature,
197
+ context.completionTtlMs,
198
+ {
199
+ isOwned: () => context.isActive() && context.ownsResult(data),
200
+ onState: (value) => markClaimState(claim!, value, fsApi),
201
+ intercom: envelope.intercom ? async (frozen) => {
202
+ const payload = buildSubagentResultIntercomPayload(frozen.intercom!);
203
+ payload.requestId = `completion-${stableHash}`;
204
+ return deliverSubagentResultIntercomEvent(context.pi.events, payload, context.intercomTimeoutMs ?? 500);
205
+ } : undefined,
206
+ local: async (frozen) => deliverLocalCompletionNotification(
207
+ context.pi.events, frozen.local, `completion-notify-${stableHash}`,
208
+ ),
209
+ },
210
+ context.maxNoProgressFailures,
211
+ {
212
+ envelope: claim.meta.envelope,
213
+ intercomDelivered: claim.meta.intercomDelivered,
214
+ localDelivered: claim.meta.localDelivered,
215
+ noProgressFailures: claim.meta.noProgressFailures,
216
+ },
217
+ envelope,
218
+ );
219
+ if (claimResult.status === "retry" || claimResult.status === "released") {
220
+ return context.isActive() && context.ownsResult(data)
221
+ ? { status: "delivery-retry", entry: claimScheduleKey(claim.id) }
222
+ : { status: "inactive" };
223
+ }
224
+ if (claimResult.status === "conflict" || claimResult.status === "exhausted") {
225
+ quarantineClaim(context, claim);
226
+ return { status: "done" };
227
+ }
228
+ recordSeen(context.state.completionSeen, completionKey, Date.now(), sourceSignature);
229
+ updateResultClaim(claim, { state: "delivered" }, fsApi);
230
+ removeResultClaim(claim, fsApi);
231
+ return { status: "done" };
232
+ }