@selesai/code 0.8.3 → 0.8.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 (518) hide show
  1. package/CHANGELOG.md +15 -0
  2. package/README.md +7 -1
  3. package/dist/core/slash-commands.js +1 -0
  4. package/dist/defaults/models.json +41 -55
  5. package/dist/defaults/settings.json +7 -8
  6. package/dist/extensions/handoff-new.ts +1 -1
  7. package/dist/extensions/inline-skills.test.ts +1 -0
  8. package/dist/extensions/inline-skills.ts +1 -1
  9. package/dist/extensions/pi-intercom/CHANGELOG.md +25 -3
  10. package/dist/extensions/pi-intercom/README.md +34 -15
  11. package/dist/extensions/pi-intercom/broker/broker.ts +38 -141
  12. package/dist/extensions/pi-intercom/broker/client-liveness.test.ts +173 -0
  13. package/dist/extensions/pi-intercom/broker/client.ts +78 -150
  14. package/dist/extensions/pi-intercom/broker/extension-state.ts +18 -7
  15. package/dist/extensions/pi-intercom/broker/framing.ts +1 -1
  16. package/dist/extensions/pi-intercom/broker/protocol.ts +182 -0
  17. package/dist/extensions/pi-intercom/broker/spawn.test.ts +106 -7
  18. package/dist/extensions/pi-intercom/broker/spawn.ts +37 -11
  19. package/dist/extensions/pi-intercom/config.test.ts +8 -10
  20. package/dist/extensions/pi-intercom/config.ts +3 -3
  21. package/dist/extensions/pi-intercom/index.ts +218 -147
  22. package/dist/extensions/pi-intercom/intercom.integration.test.ts +891 -103
  23. package/dist/extensions/pi-intercom/package.json +3 -2
  24. package/dist/extensions/pi-intercom/project-agent.test.ts +145 -0
  25. package/dist/extensions/pi-intercom/project-agent.ts +324 -0
  26. package/dist/extensions/pi-intercom/reply-tracker.test.ts +86 -1
  27. package/dist/extensions/pi-intercom/reply-tracker.ts +41 -9
  28. package/dist/extensions/pi-intercom/skills/pi-intercom/SKILL.md +49 -9
  29. package/dist/extensions/pi-intercom/test/inline-message.test.ts +9 -9
  30. package/dist/extensions/pi-intercom/types.ts +3 -1
  31. package/dist/extensions/pi-intercom/ui/inline-message.ts +7 -7
  32. package/dist/extensions/pi-powerline-footer/.github/workflows/test.yml +2 -2
  33. package/dist/extensions/pi-powerline-footer/CHANGELOG.md +14 -1
  34. package/dist/extensions/pi-powerline-footer/README.md +20 -37
  35. package/dist/extensions/pi-powerline-footer/bash-mode/completion.ts +40 -25
  36. package/dist/extensions/pi-powerline-footer/bash-mode/editor.ts +149 -18
  37. package/dist/extensions/pi-powerline-footer/bash-mode/types.ts +1 -0
  38. package/dist/extensions/pi-powerline-footer/editor-performance.ts +99 -0
  39. package/dist/extensions/pi-powerline-footer/git-status.ts +15 -0
  40. package/dist/extensions/pi-powerline-footer/index.ts +394 -317
  41. package/dist/extensions/pi-powerline-footer/package.json +1 -1
  42. package/dist/extensions/pi-powerline-footer/powerline-config.ts +0 -12
  43. package/dist/extensions/pi-powerline-footer/queue/store.ts +8 -56
  44. package/dist/extensions/pi-powerline-footer/queue/types.ts +1 -2
  45. package/dist/extensions/pi-powerline-footer/segments.ts +0 -3
  46. package/dist/extensions/pi-powerline-footer/tests/bash-mode.test.ts +231 -1
  47. package/dist/extensions/pi-powerline-footer/tests/custom-items.test.ts +5 -19
  48. package/dist/extensions/pi-powerline-footer/tests/editor-performance.test.ts +43 -0
  49. package/dist/extensions/pi-powerline-footer/tests/git-optional-locks.test.ts +64 -0
  50. package/dist/extensions/pi-powerline-footer/tests/jump-shortcuts.test.ts +116 -0
  51. package/dist/extensions/pi-powerline-footer/tests/queue-store.test.ts +19 -149
  52. package/dist/extensions/pi-powerline-footer/tests/remaining-regressions.test.ts +6 -0
  53. package/dist/extensions/pi-powerline-footer/tests/usage-display.test.ts +5 -5
  54. package/dist/extensions/pi-powerline-footer/types.ts +1 -2
  55. package/dist/extensions/pi-subagents/CHANGELOG.md +225 -14
  56. package/dist/extensions/pi-subagents/README.md +66 -1613
  57. package/dist/extensions/pi-subagents/agents/builder.md +0 -1
  58. package/dist/extensions/pi-subagents/agents/delegate.md +14 -0
  59. package/dist/extensions/pi-subagents/agents/oracle.md +74 -0
  60. package/dist/extensions/pi-subagents/agents/reviewer.md +78 -0
  61. package/dist/extensions/pi-subagents/agents/scout.md +50 -0
  62. package/dist/extensions/pi-subagents/agents/worker.md +58 -0
  63. package/dist/extensions/pi-subagents/docs/configuration.md +372 -0
  64. package/dist/extensions/pi-subagents/docs/extension-api.md +308 -0
  65. package/dist/extensions/pi-subagents/docs/missions.md +119 -0
  66. package/dist/extensions/pi-subagents/docs/models.md +192 -0
  67. package/dist/extensions/pi-subagents/docs/observability.md +174 -0
  68. package/dist/extensions/pi-subagents/docs/tool-reference.md +343 -0
  69. package/dist/extensions/pi-subagents/docs/watchdog.md +176 -0
  70. package/dist/extensions/pi-subagents/docs/workflows.md +163 -0
  71. package/dist/extensions/pi-subagents/inspector-runner.mjs +11 -0
  72. package/dist/extensions/pi-subagents/package-lock.json +152 -194
  73. package/dist/extensions/pi-subagents/package.json +9 -10
  74. package/dist/extensions/pi-subagents/prompts/gather-context-and-clarify.md +1 -1
  75. package/dist/extensions/pi-subagents/prompts/parallel-cleanup.md +9 -9
  76. package/dist/extensions/pi-subagents/prompts/parallel-research.md +6 -6
  77. package/dist/extensions/pi-subagents/prompts/parallel-review.md +8 -8
  78. package/dist/extensions/pi-subagents/prompts/review-loop.md +12 -12
  79. package/dist/extensions/pi-subagents/skills/pi-subagents/SKILL.md +22 -17
  80. package/dist/extensions/pi-subagents/skills/pi-subagents/references/constraints-and-recipes.md +77 -72
  81. package/dist/extensions/pi-subagents/skills/pi-subagents/references/execution-controls.md +177 -69
  82. package/dist/extensions/pi-subagents/skills/pi-subagents/references/management-authoring-rpc.md +28 -8
  83. package/dist/extensions/pi-subagents/skills/pi-subagents/references/prompting-and-roles.md +88 -66
  84. package/dist/extensions/pi-subagents/src/agents/agent-management.ts +3 -3
  85. package/dist/extensions/pi-subagents/src/agents/agent-refinements.ts +624 -0
  86. package/dist/extensions/pi-subagents/src/agents/agents.ts +38 -19
  87. package/dist/extensions/pi-subagents/src/agents/frontmatter.ts +7 -3
  88. package/dist/extensions/pi-subagents/src/agents/proactive-skills.ts +2 -2
  89. package/dist/extensions/pi-subagents/src/agents/skills.ts +2 -9
  90. package/dist/extensions/pi-subagents/src/api/delegation.ts +1 -2
  91. package/dist/extensions/pi-subagents/src/api/project-panes.ts +30 -0
  92. package/dist/extensions/pi-subagents/src/extension/config.ts +62 -8
  93. package/dist/extensions/pi-subagents/src/extension/control-notices.ts +2 -2
  94. package/dist/extensions/pi-subagents/src/extension/doctor.ts +40 -0
  95. package/dist/extensions/pi-subagents/src/extension/fanout-child.ts +51 -26
  96. package/dist/extensions/pi-subagents/src/extension/index.ts +140 -50
  97. package/dist/extensions/pi-subagents/src/extension/public-execution.ts +77 -0
  98. package/dist/extensions/pi-subagents/src/extension/rpc.ts +18 -24
  99. package/dist/extensions/pi-subagents/src/extension/schemas.ts +58 -21
  100. package/dist/extensions/pi-subagents/src/extension/subagent-guide.ts +39 -0
  101. package/dist/extensions/pi-subagents/src/extension/tool-description.ts +47 -25
  102. package/dist/extensions/pi-subagents/src/inspectors/herdr/actions.ts +3 -3
  103. package/dist/extensions/pi-subagents/src/inspectors/herdr/project-panes.ts +460 -64
  104. package/dist/extensions/pi-subagents/src/intercom/intercom-bridge.ts +4 -1
  105. package/dist/extensions/pi-subagents/src/intercom/native-supervisor-channel.ts +102 -4
  106. package/dist/extensions/pi-subagents/src/missions/actions.ts +77 -16
  107. package/dist/extensions/pi-subagents/src/missions/goal-driver.ts +162 -0
  108. package/dist/extensions/pi-subagents/src/missions/lifecycle.ts +65 -17
  109. package/dist/extensions/pi-subagents/src/missions/store.ts +151 -9
  110. package/dist/extensions/pi-subagents/src/missions/types.ts +58 -3
  111. package/dist/extensions/pi-subagents/src/missions/workflow-state.ts +260 -0
  112. package/dist/extensions/pi-subagents/src/profiles/profiles.ts +8 -8
  113. package/dist/extensions/pi-subagents/src/runs/background/active-async-capacity.ts +374 -0
  114. package/dist/extensions/pi-subagents/src/runs/background/active-run-index.ts +46 -0
  115. package/dist/extensions/pi-subagents/src/runs/background/async-execution.ts +158 -36
  116. package/dist/extensions/pi-subagents/src/runs/background/async-job-tracker.ts +294 -134
  117. package/dist/extensions/pi-subagents/src/runs/background/async-resume.ts +26 -4
  118. package/dist/extensions/pi-subagents/src/runs/background/async-status.ts +45 -6
  119. package/dist/extensions/pi-subagents/src/runs/background/chain-append.ts +33 -15
  120. package/dist/extensions/pi-subagents/src/runs/background/completion-replay.ts +267 -0
  121. package/dist/extensions/pi-subagents/src/runs/background/control-channel.ts +145 -60
  122. package/dist/extensions/pi-subagents/src/runs/background/owned-process-tree.ts +104 -0
  123. package/dist/extensions/pi-subagents/src/runs/background/process-terminal.ts +17 -3
  124. package/dist/extensions/pi-subagents/src/runs/background/result-watcher.ts +114 -6
  125. package/dist/extensions/pi-subagents/src/runs/background/resume-guidance.ts +33 -0
  126. package/dist/extensions/pi-subagents/src/runs/background/retained-children.ts +68 -0
  127. package/dist/extensions/pi-subagents/src/runs/background/run-id-resolver.ts +71 -0
  128. package/dist/extensions/pi-subagents/src/runs/background/run-status.ts +26 -3
  129. package/dist/extensions/pi-subagents/src/runs/background/scheduled-runs.ts +42 -14
  130. package/dist/extensions/pi-subagents/src/runs/background/stale-run-reconciler.ts +12 -24
  131. package/dist/extensions/pi-subagents/src/runs/background/steering.ts +7 -5
  132. package/dist/extensions/pi-subagents/src/runs/background/subagent-runner.ts +233 -101
  133. package/dist/extensions/pi-subagents/src/runs/background/subagent-wait.ts +17 -4
  134. package/dist/extensions/pi-subagents/src/runs/background/wait-completions.ts +146 -0
  135. package/dist/extensions/pi-subagents/src/runs/background/wait-subscriptions.ts +21 -5
  136. package/dist/extensions/pi-subagents/src/runs/foreground/async-dismiss-action.ts +85 -0
  137. package/dist/extensions/pi-subagents/src/runs/foreground/async-steering-action.ts +43 -18
  138. package/dist/extensions/pi-subagents/src/runs/foreground/chain-clarify.ts +20 -19
  139. package/dist/extensions/pi-subagents/src/runs/foreground/chain-execution.ts +40 -2
  140. package/dist/extensions/pi-subagents/src/runs/foreground/execution.ts +188 -46
  141. package/dist/extensions/pi-subagents/src/runs/foreground/foreground-control.ts +12 -0
  142. package/dist/extensions/pi-subagents/src/runs/foreground/foreground-history.ts +137 -0
  143. package/dist/extensions/pi-subagents/src/runs/foreground/prompt-audit.ts +171 -0
  144. package/dist/extensions/pi-subagents/src/runs/foreground/subagent-executor.ts +1365 -252
  145. package/dist/extensions/pi-subagents/src/runs/foreground/workflow-foreground-steering.ts +187 -0
  146. package/dist/extensions/pi-subagents/src/runs/shared/acceptance.ts +178 -26
  147. package/dist/extensions/pi-subagents/src/runs/shared/dynamic-fanout.ts +1 -1
  148. package/dist/extensions/pi-subagents/src/runs/shared/llm-intent-arbiter.ts +286 -0
  149. package/dist/extensions/pi-subagents/src/runs/shared/mcp-direct-tool-allowlist.ts +2 -0
  150. package/dist/extensions/pi-subagents/src/runs/shared/model-fallback.ts +32 -5
  151. package/dist/extensions/pi-subagents/src/runs/shared/model-scope.ts +12 -2
  152. package/dist/extensions/pi-subagents/src/runs/shared/parallel-utils.ts +3 -0
  153. package/dist/extensions/pi-subagents/src/runs/shared/pi-args.ts +509 -117
  154. package/dist/extensions/pi-subagents/src/runs/shared/pi-spawn.ts +10 -10
  155. package/dist/extensions/pi-subagents/src/runs/shared/run-fanout-budget.ts +280 -0
  156. package/dist/extensions/pi-subagents/src/runs/shared/single-output.ts +4 -2
  157. package/dist/extensions/pi-subagents/src/runs/shared/subagent-prompt-runtime.ts +189 -32
  158. package/dist/extensions/pi-subagents/src/runs/shared/task-intent.ts +21 -5
  159. package/dist/extensions/pi-subagents/src/runs/shared/worktree.ts +20 -8
  160. package/dist/extensions/pi-subagents/src/shared/artifacts.ts +128 -3
  161. package/dist/extensions/pi-subagents/src/shared/display-text.ts +100 -0
  162. package/dist/extensions/pi-subagents/src/shared/file-coalescer.ts +9 -0
  163. package/dist/extensions/pi-subagents/src/shared/fork-context.ts +13 -0
  164. package/dist/extensions/pi-subagents/src/shared/formatters.ts +4 -6
  165. package/dist/extensions/pi-subagents/src/shared/prompt-resources.ts +51 -0
  166. package/dist/extensions/pi-subagents/src/shared/settings.ts +41 -11
  167. package/dist/extensions/pi-subagents/src/shared/types.ts +192 -3
  168. package/dist/extensions/pi-subagents/src/shared/utf8.ts +11 -0
  169. package/dist/extensions/pi-subagents/src/shared/utils.ts +46 -34
  170. package/dist/extensions/pi-subagents/src/slash/delegation-adapters.ts +1 -14
  171. package/dist/extensions/pi-subagents/src/slash/inline-subagents.ts +1 -1
  172. package/dist/extensions/pi-subagents/src/slash/prompt-template-bridge.ts +14 -12
  173. package/dist/extensions/pi-subagents/src/slash/prompt-workflows.ts +176 -21
  174. package/dist/extensions/pi-subagents/src/slash/slash-bridge.ts +12 -6
  175. package/dist/extensions/pi-subagents/src/slash/slash-commands.ts +52 -18
  176. package/dist/extensions/pi-subagents/src/slash/slash-live-state.ts +36 -5
  177. package/dist/extensions/pi-subagents/src/tui/fleet-status.ts +37 -21
  178. package/dist/extensions/pi-subagents/src/tui/fleet.ts +375 -42
  179. package/dist/extensions/pi-subagents/src/tui/render.ts +201 -68
  180. package/dist/extensions/pi-subagents/src/types/pi-runtime-compat.d.ts +0 -6
  181. package/dist/extensions/pi-subagents/src/watchdog/change-signature.ts +5 -4
  182. package/dist/extensions/pi-subagents/src/watchdog/lsp-diagnostics.ts +0 -1
  183. package/dist/extensions/pi-subagents/src/workflows/scripted-workflow.ts +332 -27
  184. package/dist/extensions/pi-subagents/test/e2e/real-session-subagent.test.ts +15 -15
  185. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/bun/cli.d.ts +3 -0
  186. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/bun/register-bedrock.d.ts +2 -0
  187. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/bun/restore-sandbox-env.d.ts +17 -0
  188. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/cli/args.d.ts +57 -0
  189. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/cli/config-selector.d.ts +16 -0
  190. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/cli/file-processor.d.ts +15 -0
  191. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/cli/initial-message.d.ts +18 -0
  192. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/cli/list-models.d.ts +9 -0
  193. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/cli/project-trust.d.ts +10 -0
  194. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/cli/session-picker.d.ts +10 -0
  195. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/cli/startup-ui.d.ts +20 -0
  196. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/cli.d.ts +3 -0
  197. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/config.d.ts +96 -0
  198. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/agent-session-runtime.d.ts +119 -0
  199. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/agent-session-services.d.ts +85 -0
  200. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/agent-session.d.ts +620 -0
  201. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/auth-guidance.d.ts +5 -0
  202. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/auth-storage.d.ts +56 -0
  203. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/bash-executor.d.ts +32 -0
  204. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/cache-stats.d.ts +49 -0
  205. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/compaction/branch-summarization.d.ts +93 -0
  206. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/compaction/compaction.d.ts +128 -0
  207. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/compaction/index.d.ts +7 -0
  208. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/compaction/utils.d.ts +38 -0
  209. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/defaults.d.ts +3 -0
  210. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/diagnostics.d.ts +15 -0
  211. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/event-bus.d.ts +9 -0
  212. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/exec.d.ts +29 -0
  213. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/experimental.d.ts +2 -0
  214. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/export-html/ansi-to-html.d.ts +22 -0
  215. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/export-html/index.d.ts +37 -0
  216. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/export-html/tool-renderer.d.ts +34 -0
  217. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/extensions/index.d.ts +12 -0
  218. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/extensions/loader.d.ts +23 -0
  219. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/extensions/runner.d.ts +171 -0
  220. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/extensions/types.d.ts +1261 -0
  221. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/extensions/wrapper.d.ts +20 -0
  222. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/footer-data-provider.d.ts +54 -0
  223. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/http-dispatcher.d.ts +22 -0
  224. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/index.d.ts +13 -0
  225. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/keybindings.d.ts +358 -0
  226. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/messages.d.ts +77 -0
  227. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/model-config.d.ts +512 -0
  228. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/model-registry.d.ts +43 -0
  229. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/model-resolver.d.ts +121 -0
  230. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/model-runtime.d.ts +82 -0
  231. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/models-store.d.ts +17 -0
  232. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/output-guard.d.ts +7 -0
  233. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/package-manager.d.ts +210 -0
  234. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/project-trust.d.ts +15 -0
  235. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/prompt-templates.d.ts +54 -0
  236. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/provider-attribution.d.ts +4 -0
  237. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/provider-composer.d.ts +55 -0
  238. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/radius.d.ts +2 -0
  239. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/remote-catalog-provider.d.ts +5 -0
  240. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/resolve-config-value.d.ts +30 -0
  241. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/resource-loader.d.ts +206 -0
  242. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/runtime-credentials.d.ts +15 -0
  243. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/sdk.d.ts +106 -0
  244. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/session-cwd.d.ts +19 -0
  245. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/session-manager.d.ts +356 -0
  246. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/settings-manager.d.ts +297 -0
  247. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/skills.d.ts +60 -0
  248. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/slash-commands.d.ts +15 -0
  249. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/source-info.d.ts +18 -0
  250. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/system-prompt.d.ts +28 -0
  251. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/telemetry.d.ts +3 -0
  252. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/timings.d.ts +10 -0
  253. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/tools/bash.d.ts +68 -0
  254. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/tools/edit-diff.d.ts +106 -0
  255. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/tools/edit.d.ts +51 -0
  256. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/tools/file-mutation-queue.d.ts +6 -0
  257. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/tools/find.d.ts +35 -0
  258. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/tools/grep.d.ts +37 -0
  259. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/tools/index.d.ts +40 -0
  260. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/tools/ls.d.ts +37 -0
  261. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/tools/output-accumulator.d.ts +52 -0
  262. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/tools/path-utils.d.ts +10 -0
  263. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/tools/read.d.ts +35 -0
  264. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/tools/render-utils.d.ts +24 -0
  265. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/tools/tool-definition-wrapper.d.ts +14 -0
  266. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/tools/truncate.d.ts +70 -0
  267. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/tools/write.d.ts +26 -0
  268. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/trust-manager.d.ts +36 -0
  269. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/usage-totals.d.ts +19 -0
  270. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/extensions/index.d.ts +3 -0
  271. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/extensions/llama/client.d.ts +61 -0
  272. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/extensions/llama/huggingface.d.ts +23 -0
  273. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/extensions/llama/index.d.ts +3 -0
  274. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/extensions/llama/provider.d.ts +10 -0
  275. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/extensions/llama/ui.d.ts +42 -0
  276. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/index.d.ts +35 -0
  277. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/main.d.ts +12 -0
  278. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/migrations.d.ts +33 -0
  279. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/index.d.ts +9 -0
  280. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/armin.d.ts +34 -0
  281. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/assistant-message.d.ts +22 -0
  282. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/bash-execution.d.ts +34 -0
  283. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/bordered-loader.d.ts +16 -0
  284. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/branch-summary-message.d.ts +16 -0
  285. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/compaction-summary-message.d.ts +16 -0
  286. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/config-selector.d.ts +102 -0
  287. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/countdown-timer.d.ts +14 -0
  288. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/custom-editor.d.ts +21 -0
  289. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/custom-entry.d.ts +19 -0
  290. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/custom-message.d.ts +20 -0
  291. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/daxnuts.d.ts +23 -0
  292. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/diff.d.ts +12 -0
  293. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/dynamic-border.d.ts +15 -0
  294. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/earendil-announcement.d.ts +5 -0
  295. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/extension-editor.d.ts +22 -0
  296. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/extension-input.d.ts +23 -0
  297. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/extension-selector.d.ts +26 -0
  298. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/first-time-setup.d.ts +25 -0
  299. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/footer.d.ts +32 -0
  300. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/index.d.ts +34 -0
  301. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/keybinding-hints.d.ts +13 -0
  302. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/login-dialog.d.ts +52 -0
  303. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/model-selector.d.ts +54 -0
  304. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/oauth-selector.d.ts +33 -0
  305. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/scoped-models-selector.d.ts +42 -0
  306. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/session-selector-search.d.ts +23 -0
  307. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/session-selector.d.ts +95 -0
  308. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/settings-selector.d.ts +77 -0
  309. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/show-images-selector.d.ts +10 -0
  310. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/skill-invocation-message.d.ts +17 -0
  311. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/status-indicator.d.ts +28 -0
  312. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/theme-selector.d.ts +11 -0
  313. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/thinking-selector.d.ts +11 -0
  314. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/tool-execution.d.ts +63 -0
  315. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/tree-selector.d.ts +94 -0
  316. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/trust-selector.d.ts +23 -0
  317. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/user-message-selector.d.ts +30 -0
  318. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/user-message.d.ts +14 -0
  319. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/visual-truncate.d.ts +24 -0
  320. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/interactive-mode.d.ts +394 -0
  321. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/model-search.d.ts +12 -0
  322. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/theme/theme-controller.d.ts +29 -0
  323. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/theme/theme.d.ts +120 -0
  324. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/print-mode.d.ts +28 -0
  325. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/rpc/jsonl.d.ts +17 -0
  326. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/rpc/rpc-client.d.ts +246 -0
  327. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/rpc/rpc-mode.d.ts +20 -0
  328. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/rpc/rpc-types.d.ts +457 -0
  329. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/package-manager-cli.d.ts +8 -0
  330. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/rpc-entry.d.ts +3 -0
  331. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/ansi.d.ts +2 -0
  332. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/changelog.d.ts +22 -0
  333. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/child-process.d.ts +18 -0
  334. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/clipboard-image.d.ts +11 -0
  335. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/clipboard-native.d.ts +11 -0
  336. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/clipboard.d.ts +4 -0
  337. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/deprecation.d.ts +4 -0
  338. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/exif-orientation.d.ts +5 -0
  339. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/frontmatter.d.ts +8 -0
  340. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/fs-watch.d.ts +5 -0
  341. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/git.d.ts +26 -0
  342. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/html.d.ts +7 -0
  343. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/image-convert.d.ts +10 -0
  344. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/image-process.d.ts +18 -0
  345. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/image-resize-core.d.ts +30 -0
  346. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/image-resize-worker.d.ts +2 -0
  347. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/image-resize.d.ts +16 -0
  348. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/json.d.ts +3 -0
  349. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/mime.d.ts +3 -0
  350. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/open-browser.d.ts +9 -0
  351. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/paths.d.ts +31 -0
  352. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/photon.d.ts +21 -0
  353. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/pi-user-agent.d.ts +2 -0
  354. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/shell.d.ts +31 -0
  355. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/sleep.d.ts +5 -0
  356. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/syntax-highlight.d.ts +12 -0
  357. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/tools-manager.d.ts +3 -0
  358. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/version-check.d.ts +15 -0
  359. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/windows-self-update.d.ts +3 -0
  360. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/index.mjs +84 -0
  361. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/package.json +14 -0
  362. package/dist/extensions/pi-subagents/test/integration/acceptance-file-report.test.ts +102 -15
  363. package/dist/extensions/pi-subagents/test/integration/async-execution.test.ts +507 -306
  364. package/dist/extensions/pi-subagents/test/integration/async-job-tracker.test.ts +309 -123
  365. package/dist/extensions/pi-subagents/test/integration/async-status.test.ts +124 -58
  366. package/dist/extensions/pi-subagents/test/integration/chain-clarify.test.ts +62 -16
  367. package/dist/extensions/pi-subagents/test/integration/chain-execution.test.ts +167 -113
  368. package/dist/extensions/pi-subagents/test/integration/detect-error.test.ts +1 -1
  369. package/dist/extensions/pi-subagents/test/integration/external-cli-runner.test.ts +4 -2
  370. package/dist/extensions/pi-subagents/test/integration/fork-context-execution.test.ts +139 -58
  371. package/dist/extensions/pi-subagents/test/integration/intercom-result-delivery.test.ts +324 -59
  372. package/dist/extensions/pi-subagents/test/integration/parallel-execution.test.ts +98 -22
  373. package/dist/extensions/pi-subagents/test/integration/render-fork-badge.test.ts +106 -106
  374. package/dist/extensions/pi-subagents/test/integration/render-widget.test.ts +416 -106
  375. package/dist/extensions/pi-subagents/test/integration/result-watcher.test.ts +287 -17
  376. package/dist/extensions/pi-subagents/test/integration/single-execution.test.ts +1122 -96
  377. package/dist/extensions/pi-subagents/test/integration/slash-commands.test.ts +107 -20
  378. package/dist/extensions/pi-subagents/test/integration/slash-live-state.test.ts +9 -9
  379. package/dist/extensions/pi-subagents/test/integration/template-resolution.test.ts +26 -6
  380. package/dist/extensions/pi-subagents/test/integration/top-level-async.test.ts +2 -2
  381. package/dist/extensions/pi-subagents/test/support/helpers.ts +2 -0
  382. package/dist/extensions/pi-subagents/test/support/mock-pi-script.mjs +1 -1
  383. package/dist/extensions/pi-subagents/test/support/ts-loader.mjs +0 -8
  384. package/dist/extensions/pi-subagents/test/unit/acceptance.test.ts +194 -59
  385. package/dist/extensions/pi-subagents/test/unit/active-async-capacity.test.ts +317 -0
  386. package/dist/extensions/pi-subagents/test/unit/agent-disabled.test.ts +15 -15
  387. package/dist/extensions/pi-subagents/test/unit/agent-eject-disable.test.ts +66 -66
  388. package/dist/extensions/pi-subagents/test/unit/agent-frontmatter.test.ts +334 -248
  389. package/dist/extensions/pi-subagents/test/unit/agent-management.test.ts +52 -52
  390. package/dist/extensions/pi-subagents/test/unit/agent-memory.test.ts +26 -26
  391. package/dist/extensions/pi-subagents/test/unit/agent-overrides.test.ts +118 -99
  392. package/dist/extensions/pi-subagents/test/unit/agent-refinements.test.ts +160 -0
  393. package/dist/extensions/pi-subagents/test/unit/agent-selection.test.ts +9 -9
  394. package/dist/extensions/pi-subagents/test/unit/artifacts.test.ts +43 -1
  395. package/dist/extensions/pi-subagents/test/unit/async-execution.test.ts +36 -10
  396. package/dist/extensions/pi-subagents/test/unit/async-interrupt-action.test.ts +387 -30
  397. package/dist/extensions/pi-subagents/test/unit/async-permission-session.test.ts +9 -9
  398. package/dist/extensions/pi-subagents/test/unit/async-recovery-descriptor.test.ts +18 -3
  399. package/dist/extensions/pi-subagents/test/unit/async-resume.test.ts +99 -40
  400. package/dist/extensions/pi-subagents/test/unit/background-work.test.ts +5 -3
  401. package/dist/extensions/pi-subagents/test/unit/builtin-agent-documentation.test.ts +7 -7
  402. package/dist/extensions/pi-subagents/test/unit/capability-ceiling-agent-allowlist.test.ts +19 -19
  403. package/dist/extensions/pi-subagents/test/unit/chain-append.test.ts +94 -23
  404. package/dist/extensions/pi-subagents/test/unit/chain-root-attachment.test.ts +9 -9
  405. package/dist/extensions/pi-subagents/test/unit/chain-serializer.test.ts +20 -20
  406. package/dist/extensions/pi-subagents/test/unit/child-transcript.test.ts +9 -9
  407. package/dist/extensions/pi-subagents/test/unit/compaction-resume.test.ts +35 -5
  408. package/dist/extensions/pi-subagents/test/unit/completion-dedupe.test.ts +2 -2
  409. package/dist/extensions/pi-subagents/test/unit/completion-guard.test.ts +70 -52
  410. package/dist/extensions/pi-subagents/test/unit/completion-replay.test.ts +187 -0
  411. package/dist/extensions/pi-subagents/test/unit/control-channel.test.ts +125 -71
  412. package/dist/extensions/pi-subagents/test/unit/control-notices.test.ts +18 -3
  413. package/dist/extensions/pi-subagents/test/unit/default-extensions.test.ts +12 -12
  414. package/dist/extensions/pi-subagents/test/unit/delegation-api.test.ts +17 -23
  415. package/dist/extensions/pi-subagents/test/unit/doctor.test.ts +30 -2
  416. package/dist/extensions/pi-subagents/test/unit/dynamic-fanout.test.ts +25 -25
  417. package/dist/extensions/pi-subagents/test/unit/extra-agent-dirs.test.ts +3 -3
  418. package/dist/extensions/pi-subagents/test/unit/file-coalescer.test.ts +15 -0
  419. package/dist/extensions/pi-subagents/test/unit/fleet-status.test.ts +91 -47
  420. package/dist/extensions/pi-subagents/test/unit/fleet.test.ts +468 -38
  421. package/dist/extensions/pi-subagents/test/unit/foreground-control.test.ts +14 -4
  422. package/dist/extensions/pi-subagents/test/unit/foreground-tool-call-compaction.test.ts +37 -0
  423. package/dist/extensions/pi-subagents/test/unit/herdr-inspector-bootstrap.test.ts +69 -0
  424. package/dist/extensions/pi-subagents/test/unit/herdr-inspector.test.ts +79 -2
  425. package/dist/extensions/pi-subagents/test/unit/herdr-status-bridge.test.ts +102 -49
  426. package/dist/extensions/pi-subagents/test/unit/index-child-registration.test.ts +98 -32
  427. package/dist/extensions/pi-subagents/test/unit/intercom-bridge.test.ts +7 -6
  428. package/dist/extensions/pi-subagents/test/unit/llm-intent-arbiter.test.ts +171 -0
  429. package/dist/extensions/pi-subagents/test/unit/mission-goal-driver.test.ts +116 -0
  430. package/dist/extensions/pi-subagents/test/unit/mission-lifecycle.test.ts +81 -7
  431. package/dist/extensions/pi-subagents/test/unit/mission-store.test.ts +289 -13
  432. package/dist/extensions/pi-subagents/test/unit/model-fallback.test.ts +42 -1
  433. package/dist/extensions/pi-subagents/test/unit/model-scope-settings.test.ts +2 -2
  434. package/dist/extensions/pi-subagents/test/unit/model-scope.test.ts +11 -2
  435. package/dist/extensions/pi-subagents/test/unit/native-supervisor-channel.test.ts +84 -10
  436. package/dist/extensions/pi-subagents/test/unit/nested-control.test.ts +122 -8
  437. package/dist/extensions/pi-subagents/test/unit/nested-events.test.ts +8 -8
  438. package/dist/extensions/pi-subagents/test/unit/notify.test.ts +24 -24
  439. package/dist/extensions/pi-subagents/test/unit/owned-process-tree.test.ts +69 -0
  440. package/dist/extensions/pi-subagents/test/unit/package-manifest.test.ts +16 -2
  441. package/dist/extensions/pi-subagents/test/unit/parallel-handoff.test.ts +7 -7
  442. package/dist/extensions/pi-subagents/test/unit/parallel-utils.test.ts +10 -10
  443. package/dist/extensions/pi-subagents/test/unit/path-handling.test.ts +3 -3
  444. package/dist/extensions/pi-subagents/test/unit/path-resolution.test.ts +26 -17
  445. package/dist/extensions/pi-subagents/test/unit/pi-args-permission-system.test.ts +405 -0
  446. package/dist/extensions/pi-subagents/test/unit/pi-args.test.ts +440 -92
  447. package/dist/extensions/pi-subagents/test/unit/pi-coding-agent-dir.test.ts +24 -8
  448. package/dist/extensions/pi-subagents/test/unit/pi-spawn.test.ts +6 -6
  449. package/dist/extensions/pi-subagents/test/unit/preflight.test.ts +43 -43
  450. package/dist/extensions/pi-subagents/test/unit/proactive-skills.test.ts +13 -13
  451. package/dist/extensions/pi-subagents/test/unit/process-terminal.test.ts +59 -6
  452. package/dist/extensions/pi-subagents/test/unit/profiles.test.ts +19 -19
  453. package/dist/extensions/pi-subagents/test/unit/project-panes-public-api.test.ts +243 -0
  454. package/dist/extensions/pi-subagents/test/unit/prompt-template-bridge.test.ts +68 -168
  455. package/dist/extensions/pi-subagents/test/unit/prompt-workflows.test.ts +58 -15
  456. package/dist/extensions/pi-subagents/test/unit/public-execution.test.ts +51 -0
  457. package/dist/extensions/pi-subagents/test/unit/reads-resolution.test.ts +66 -0
  458. package/dist/extensions/pi-subagents/test/unit/render-helpers.test.ts +47 -28
  459. package/dist/extensions/pi-subagents/test/unit/result-intercom.test.ts +12 -12
  460. package/dist/extensions/pi-subagents/test/unit/retained-children.test.ts +57 -0
  461. package/dist/extensions/pi-subagents/test/unit/rpc.test.ts +111 -31
  462. package/dist/extensions/pi-subagents/test/unit/run-fanout-budget.test.ts +121 -0
  463. package/dist/extensions/pi-subagents/test/unit/run-id-resolver.test.ts +1 -1
  464. package/dist/extensions/pi-subagents/test/unit/run-status.test.ts +65 -50
  465. package/dist/extensions/pi-subagents/test/unit/scheduled-runs.test.ts +69 -28
  466. package/dist/extensions/pi-subagents/test/unit/scheduled-store-root.test.ts +67 -0
  467. package/dist/extensions/pi-subagents/test/unit/schemas.test.ts +60 -44
  468. package/dist/extensions/pi-subagents/test/unit/scripted-workflow.test.ts +424 -49
  469. package/dist/extensions/pi-subagents/test/unit/single-output.test.ts +28 -0
  470. package/dist/extensions/pi-subagents/test/unit/skills-fallback.test.ts +23 -1
  471. package/dist/extensions/pi-subagents/test/unit/slash-bridge.test.ts +32 -5
  472. package/dist/extensions/pi-subagents/test/unit/stale-run-reconciler.test.ts +13 -13
  473. package/dist/extensions/pi-subagents/test/unit/steering-action.test.ts +130 -92
  474. package/dist/extensions/pi-subagents/test/unit/steering.test.ts +2 -2
  475. package/dist/extensions/pi-subagents/test/unit/subagent-action-recovery.test.ts +85 -0
  476. package/dist/extensions/pi-subagents/test/unit/subagent-control.test.ts +35 -35
  477. package/dist/extensions/pi-subagents/test/unit/subagent-guide.test.ts +24 -0
  478. package/dist/extensions/pi-subagents/test/unit/subagent-prompt-runtime.test.ts +312 -22
  479. package/dist/extensions/pi-subagents/test/unit/subagent-wait.test.ts +150 -15
  480. package/dist/extensions/pi-subagents/test/unit/task-intent.test.ts +65 -26
  481. package/dist/extensions/pi-subagents/test/unit/timeout-defaults.test.ts +138 -0
  482. package/dist/extensions/pi-subagents/test/unit/tool-description.test.ts +76 -25
  483. package/dist/extensions/pi-subagents/test/unit/turn-budget.test.ts +5 -5
  484. package/dist/extensions/pi-subagents/test/unit/wait-subscriptions.test.ts +55 -6
  485. package/dist/extensions/pi-subagents/test/unit/watchdog-child-status.test.ts +13 -13
  486. package/dist/extensions/pi-subagents/test/unit/watchdog-lsp-diagnostics.test.ts +1 -1
  487. package/dist/extensions/pi-subagents/test/unit/watchdog-runtime.test.ts +1 -1
  488. package/dist/extensions/pi-subagents/test/unit/watchdog-settings.test.ts +8 -8
  489. package/dist/extensions/pi-subagents/test/unit/widget-nested-render.test.ts +6 -6
  490. package/dist/extensions/pi-subagents/test/unit/workflow-chat-progress.test.ts +138 -11
  491. package/dist/extensions/pi-subagents/test/unit/workflow-graph.test.ts +8 -8
  492. package/dist/extensions/pi-subagents/test/unit/workflow-launch-params.test.ts +113 -0
  493. package/dist/extensions/pi-subagents/test/unit/worktree.test.ts +68 -7
  494. package/dist/extensions/pi-subagents/test/unit/writer-budget-guidance.test.ts +6 -6
  495. package/dist/extensions/workflow/extension.ts +21 -19
  496. package/dist/extensions/workflow/modes.ts +65 -0
  497. package/dist/modes/interactive/interactive-mode.d.ts +1 -0
  498. package/dist/modes/interactive/interactive-mode.js +48 -1
  499. package/dist/skills/pi-subagents/SKILL.md +20 -15
  500. package/dist/skills/pi-subagents/references/constraints-and-recipes.md +77 -83
  501. package/dist/skills/pi-subagents/references/execution-controls.md +215 -106
  502. package/dist/skills/pi-subagents/references/management-authoring-rpc.md +29 -9
  503. package/dist/skills/pi-subagents/references/prompting-and-roles.md +58 -43
  504. package/docs/plans/workflow-autoloop-reference.md +192 -0
  505. package/docs/plans/workflow-subagent-consolidation-planb.md +374 -0
  506. package/docs/plans/workflow-subagent-scripted-merge.md +406 -0
  507. package/docs/quickstart.md +27 -43
  508. package/docs/settings.md +4 -0
  509. package/docs/usage.md +1 -0
  510. package/package.json +2 -1
  511. package/dist/extensions/workflow/adapter.ts +0 -949
  512. package/dist/extensions/workflow/modes/loop.ts +0 -74
  513. package/dist/extensions/workflow/modes/prototype.ts +0 -170
  514. package/dist/extensions/workflow/modes/quicktype.ts +0 -150
  515. package/dist/extensions/workflow/modes/task.ts +0 -105
  516. package/dist/extensions/workflow/run-state.ts +0 -124
  517. package/dist/extensions/workflow/state-machine.ts +0 -484
  518. package/dist/extensions/workflow/validators.ts +0 -42
@@ -20,13 +20,16 @@ import {
20
20
  } from "../../intercom/result-intercom.ts";
21
21
  import { projectNestedRegistryForRoot, sanitizeSummary } from "../shared/nested-events.ts";
22
22
  import { resolveWatchPath } from "../../shared/utils.ts";
23
+ import { recordWaitCompletion } from "./wait-completions.ts";
24
+ import { MISSION_BINDING_FILE, syncMissionFromAsyncCompletion } from "../../missions/lifecycle.ts";
23
25
  import type { CompletionNotifier, CompletionNotification } from "./notify.ts";
24
26
 
25
27
  const WATCHER_RESTART_DELAY_MS = 3000;
26
28
  const POLL_INTERVAL_MS = 3000;
29
+ const HEALTHY_SCAN_INTERVAL_MS = 60_000;
27
30
  const RETRY_DELAY_MS = 100;
28
31
 
29
- type ResultWatcherFs = Pick<typeof fs, "existsSync" | "readFileSync" | "unlinkSync" | "readdirSync" | "mkdirSync" | "realpathSync" | "watch">;
32
+ type ResultWatcherFs = Pick<typeof fs, "existsSync" | "readFileSync" | "unlinkSync" | "readdirSync" | "mkdirSync" | "realpathSync" | "statSync" | "watch">;
30
33
 
31
34
  type ResultWatcherTimers = {
32
35
  setTimeout: typeof setTimeout;
@@ -41,6 +44,10 @@ type ResultWatcherDeps = {
41
44
  notifier?: Pick<CompletionNotifier, "deliver">;
42
45
  /** Receives persisted completions before active-session delivery filtering. */
43
46
  observeCompletion?: (result: CompletionNotification & { runId: string }) => void;
47
+ /** Returns cross-session run ids that the completion observer currently owns. */
48
+ observedCompletionRunIds?: () => Iterable<string>;
49
+ /** Parses a relevant result payload after its lightweight identity check. */
50
+ parseResult?: (raw: string) => ResultFileData;
44
51
  /** External grouped-result transport. Disable when native completion notifications own delivery. */
45
52
  deliverIntercomResults?: boolean;
46
53
  };
@@ -74,6 +81,33 @@ type ResultFileData = CompletionNotification & {
74
81
  parallelHandoff?: ParallelHandoffReference;
75
82
  };
76
83
 
84
+ type ResultFileIdentity = {
85
+ sessionId?: string;
86
+ runId?: string;
87
+ asyncDir?: string;
88
+ };
89
+
90
+ function jsonStringProperty(raw: string, property: string): string | undefined {
91
+ const matches = raw.matchAll(new RegExp(`"${property}"\\s*:\\s*("(?:\\\\.|[^"\\\\])*")`, "g"));
92
+ let encoded: string | undefined;
93
+ for (const match of matches) encoded = match[1];
94
+ if (!encoded) return undefined;
95
+ try {
96
+ const value = JSON.parse(encoded) as unknown;
97
+ return typeof value === "string" && value ? value : undefined;
98
+ } catch {
99
+ return undefined;
100
+ }
101
+ }
102
+
103
+ function resultFileIdentity(raw: string, file: string): ResultFileIdentity {
104
+ return {
105
+ sessionId: jsonStringProperty(raw, "sessionId"),
106
+ runId: file.replace(/\.json$/i, ""),
107
+ asyncDir: jsonStringProperty(raw, "asyncDir"),
108
+ };
109
+ }
110
+
77
111
  function sanitizeNestedResultChildren(value: unknown, resultPath: string, label: string): NestedRunSummary[] | undefined {
78
112
  if (value === undefined) return undefined;
79
113
  if (!Array.isArray(value)) {
@@ -119,11 +153,14 @@ export function createResultWatcher(
119
153
  const fsApi = deps.fs ?? fs;
120
154
  const timers = deps.timers ?? { setTimeout, clearTimeout, setInterval, clearInterval };
121
155
  const notifier = deps.notifier ?? { deliver: async () => true };
156
+ const parseResult = deps.parseResult ?? ((raw: string) => JSON.parse(raw) as ResultFileData);
122
157
  const deliverIntercomResults = deps.deliverIntercomResults !== false;
123
158
  const pendingTriggerTurn = new Map<string, boolean>();
124
159
  const processing = new Set<string>();
160
+ const identityCache = new Map<string, { signature: string; identity: ResultFileIdentity }>();
125
161
  let deliveryActive = true;
126
162
  let deliveryEpoch = 0;
163
+ let resultScanTimer: ReturnType<typeof setInterval> | null = null;
127
164
  // The sole in-memory ownership lease. It is acquired for one active session
128
165
  // and revoked before the watcher, queues, or callbacks are torn down.
129
166
  let activeSessionId: string | null = null;
@@ -140,14 +177,58 @@ export function createResultWatcher(
140
177
  state.resultFileCoalescer.schedule(file, delayMs);
141
178
  };
142
179
 
180
+ const inspectResult = (file: string): ResultFileIdentity | undefined => {
181
+ const resultPath = path.join(resultsDir, file);
182
+ try {
183
+ const stat = fsApi.statSync(resultPath);
184
+ const signature = `${stat.size}:${stat.mtimeMs}`;
185
+ const cached = identityCache.get(file);
186
+ if (cached?.signature === signature) return cached.identity;
187
+ const identity = resultFileIdentity(fsApi.readFileSync(resultPath, "utf-8"), file);
188
+ identityCache.set(file, { signature, identity });
189
+ return identity;
190
+ } catch (error) {
191
+ identityCache.delete(file);
192
+ if (!isNotFound(error)) console.error(`Failed to inspect subagent result file '${resultPath}':`, error);
193
+ return undefined;
194
+ }
195
+ };
196
+
197
+ const observedRunIds = (): ReadonlySet<string> => {
198
+ try {
199
+ return new Set(deps.observedCompletionRunIds?.() ?? []);
200
+ } catch (error) {
201
+ console.error("Failed to inspect observed subagent completion ids:", error);
202
+ return new Set();
203
+ }
204
+ };
205
+
206
+ const shouldProcessResult = (file: string, observed?: ReadonlySet<string>): boolean => {
207
+ const identity = inspectResult(file);
208
+ if (!identity) return false;
209
+ // Missing identity stays on the normal parser path so malformed or legacy
210
+ // files keep their existing diagnostics and compatibility behavior.
211
+ if (!identity.sessionId) return true;
212
+ if (identity.sessionId === state.currentSessionId) return true;
213
+ if (identity.asyncDir && fsApi.existsSync(path.join(identity.asyncDir, MISSION_BINDING_FILE))) return true;
214
+ if (identity.runId && (observed ?? observedRunIds()).has(identity.runId)) return true;
215
+ return Boolean(deps.observeCompletion && !deps.observedCompletionRunIds);
216
+ };
217
+
143
218
  const handleResult = async (file: string, triggerTurn: boolean) => {
144
219
  const resultPath = path.join(resultsDir, file);
145
220
  if (processing.has(file) || !fsApi.existsSync(resultPath)) return;
221
+ if (!shouldProcessResult(file)) return;
146
222
  processing.add(file);
147
223
  try {
148
- const data = JSON.parse(fsApi.readFileSync(resultPath, "utf-8")) as ResultFileData;
224
+ const data = parseResult(fsApi.readFileSync(resultPath, "utf-8"));
149
225
  if (typeof data.sessionId !== "string" || !data.sessionId) return;
150
226
  const runId = data.runId ?? data.id ?? file.replace(/\.json$/i, "");
227
+ try {
228
+ syncMissionFromAsyncCompletion({ ...data, runId });
229
+ } catch (error) {
230
+ console.error(`Mission completion sync failed for '${resultPath}':`, error);
231
+ }
151
232
  try {
152
233
  deps.observeCompletion?.({ ...data, runId });
153
234
  } catch (error) {
@@ -155,6 +236,12 @@ export function createResultWatcher(
155
236
  }
156
237
  const epoch = deliveryEpoch;
157
238
  if (!ownsSession(data.sessionId, epoch)) return;
239
+ // Recorded before dedupe and before the unlink below so subagent_wait can
240
+ // use the in-memory record or its bounded durable replay after cleanup.
241
+ recordWaitCompletion(state, runId, data, Date.now(), completionTtlMs, {
242
+ resultsDir,
243
+ sessionId: data.sessionId,
244
+ });
158
245
  const hasExplicitNestedChildren = data.nestedChildren !== undefined;
159
246
  let nestedChildren = compactNestedResultChildren(sanitizeNestedResultChildren(data.nestedChildren, resultPath, "nestedChildren"));
160
247
  if (!nestedChildren?.length && !hasExplicitNestedChildren) {
@@ -175,6 +262,7 @@ export function createResultWatcher(
175
262
  if (!ownsSession(data.sessionId, epoch) || !fsApi.existsSync(resultPath)) return;
176
263
  try {
177
264
  fsApi.unlinkSync(resultPath);
265
+ identityCache.delete(file);
178
266
  } catch (error) {
179
267
  if (!isNotFound(error)) {
180
268
  console.error(`Failed to remove delivered subagent result '${resultPath}'; will retry:`, error);
@@ -300,6 +388,7 @@ export function createResultWatcher(
300
388
  if (!ownsSession(data.sessionId, epoch) || !fsApi.existsSync(resultPath)) return;
301
389
  try {
302
390
  fsApi.unlinkSync(resultPath);
391
+ identityCache.delete(file);
303
392
  } catch (error) {
304
393
  if (!isNotFound(error)) {
305
394
  console.error(`Failed to remove delivered subagent result '${resultPath}'; will retry:`, error);
@@ -324,15 +413,23 @@ export function createResultWatcher(
324
413
  const triggerTurn = options.triggerTurn !== false;
325
414
  fsApi.readdirSync(resultsDir)
326
415
  .filter((f) => f.endsWith(".json"))
327
- .forEach((file) => scheduleResult(file, triggerTurn));
416
+ .forEach((file) => {
417
+ if (shouldProcessResult(file)) scheduleResult(file, triggerTurn);
418
+ });
328
419
  } catch (error) {
329
420
  if (!isNotFound(error)) console.error(`Failed to scan subagent result directory '${resultsDir}':`, error);
330
421
  }
331
422
  };
332
423
 
424
+ const clearResultScan = () => {
425
+ if (resultScanTimer) timers.clearInterval(resultScanTimer);
426
+ resultScanTimer = null;
427
+ };
428
+
333
429
  const startPolling = (reason: unknown) => {
334
430
  state.watcher?.close();
335
431
  state.watcher = null;
432
+ clearResultScan();
336
433
  if (state.watcherRestartTimer) return;
337
434
  console.error(`Subagent result watcher for '${resultsDir}' fell back to polling because native fs.watch is unavailable (${errorCode(reason) ?? "unknown error"}).`);
338
435
  primeExistingResults();
@@ -341,6 +438,7 @@ export function createResultWatcher(
341
438
  };
342
439
 
343
440
  const scheduleRestart = () => {
441
+ clearResultScan();
344
442
  if (state.watcherRestartTimer) return;
345
443
  state.watcherRestartTimer = timers.setTimeout(() => {
346
444
  state.watcherRestartTimer = null;
@@ -368,10 +466,16 @@ export function createResultWatcher(
368
466
  }
369
467
  try {
370
468
  const watchDir = resolveWatchPath(resultsDir, fsApi.realpathSync.native);
371
- state.watcher = fsApi.watch(watchDir, (event, file) => {
372
- if (event !== "rename" || !file) return;
469
+ state.watcher = fsApi.watch(watchDir, (_event, file) => {
470
+ if (!file) {
471
+ primeExistingResults();
472
+ return;
473
+ }
373
474
  const fileName = file.toString();
374
- if (fileName.endsWith(".json")) scheduleResult(fileName, true);
475
+ if (fileName.endsWith(".json")) {
476
+ identityCache.delete(fileName);
477
+ scheduleResult(fileName, true);
478
+ }
375
479
  });
376
480
  state.watcher.on("error", (error) => {
377
481
  if (shouldPoll(error)) return startPolling(error);
@@ -381,6 +485,8 @@ export function createResultWatcher(
381
485
  scheduleRestart();
382
486
  });
383
487
  state.watcher.unref?.();
488
+ resultScanTimer = timers.setInterval(primeExistingResults, HEALTHY_SCAN_INTERVAL_MS);
489
+ resultScanTimer.unref?.();
384
490
  } catch (error) {
385
491
  if (shouldPoll(error)) return startPolling(error);
386
492
  console.error(`Failed to start subagent result watcher for '${resultsDir}':`, error);
@@ -400,9 +506,11 @@ export function createResultWatcher(
400
506
  timers.clearInterval(state.watcherRestartTimer);
401
507
  }
402
508
  state.watcherRestartTimer = null;
509
+ clearResultScan();
403
510
  state.resultFileCoalescer.clear();
404
511
  pendingTriggerTurn.clear();
405
512
  processing.clear();
513
+ identityCache.clear();
406
514
  };
407
515
 
408
516
  return { startResultWatcher, primeExistingResults, stopResultWatcher };
@@ -0,0 +1,33 @@
1
+ import * as fs from "node:fs";
2
+ import type { AsyncRunSummary } from "./async-status.ts";
3
+
4
+ export function formatAsyncReviveCommand(run: AsyncRunSummary): string | undefined {
5
+ const step = run.steps.find((candidate) => candidate.status === "failed" && candidate.sessionFile && fs.existsSync(candidate.sessionFile));
6
+ if (!step) {
7
+ if (run.steps.length === 1 && run.sessionFile && fs.existsSync(run.sessionFile)) {
8
+ return `subagent({ action: "resume", id: "${run.id}", message: "Continue from the persisted child session and report the result." })`;
9
+ }
10
+ return undefined;
11
+ }
12
+ const index = run.steps.length === 1 ? "" : `, index: ${step.index}`;
13
+ return `subagent({ action: "resume", id: "${run.id}"${index}, message: "Continue from the persisted child session and report the result." })`;
14
+ }
15
+
16
+ export function formatResumeFirstFailedRunDetail(run: AsyncRunSummary): string | undefined {
17
+ if (run.state !== "failed") return undefined;
18
+ const command = formatAsyncReviveCommand(run);
19
+ if (!command) return undefined;
20
+ return `Resume-first: failed run "${run.id}" has a persisted child session. Revive the original run with ${command} before reporting failure or launching a replacement. Launch a replacement only if revive fails or the user explicitly asks for one.`;
21
+ }
22
+
23
+ export function formatResumeFirstFailedRunsNote(runs: AsyncRunSummary[]): string {
24
+ const resumable = runs
25
+ .filter((run) => run.state === "failed")
26
+ .map((run) => ({ run, command: formatAsyncReviveCommand(run) }))
27
+ .filter((entry): entry is { run: AsyncRunSummary; command: string } => Boolean(entry.command));
28
+ if (resumable.length === 0) return "";
29
+ const guidance = resumable.length === 1
30
+ ? `failed run "${resumable[0]!.run.id}" has a persisted child session. Revive the original run with ${resumable[0]!.command}`
31
+ : `${resumable.length} failed runs have persisted child sessions. Inspect status and revive each original run before retrying`;
32
+ return ` Resume-first: ${guidance} before reporting failure or launching a replacement. Launch a replacement only if revive fails or the user explicitly asks for one.`;
33
+ }
@@ -0,0 +1,68 @@
1
+ import * as fs from "node:fs";
2
+ import { listAsyncRuns } from "./async-status.ts";
3
+ import type { TokenUsage } from "../../shared/types.ts";
4
+
5
+ const MAX_RETAINED_CHILDREN = 10;
6
+ const MAX_TASK_SUMMARY_LENGTH = 120;
7
+
8
+ export interface RetainedChild {
9
+ runId: string;
10
+ parentRunId?: string;
11
+ agent: string;
12
+ taskSummary: string;
13
+ completedAt: number;
14
+ sessionPath: string;
15
+ tokenTotals?: TokenUsage;
16
+ }
17
+
18
+ function retainedSessionFile(sessionFile: string | undefined): sessionFile is string {
19
+ if (!sessionFile?.endsWith(".jsonl")) return false;
20
+ try {
21
+ const stat = fs.lstatSync(sessionFile);
22
+ return stat.isFile() && !stat.isSymbolicLink();
23
+ } catch {
24
+ return false;
25
+ }
26
+ }
27
+
28
+ function boundedTaskSummary(value: string | undefined): string {
29
+ const normalized = value?.replace(/\s+/g, " ").trim() ?? "";
30
+ return normalized.length > MAX_TASK_SUMMARY_LENGTH
31
+ ? `${normalized.slice(0, MAX_TASK_SUMMARY_LENGTH - 1)}…`
32
+ : normalized;
33
+ }
34
+
35
+ export function listRetainedChildren(asyncDirRoot: string, sessionId: string): RetainedChild[] {
36
+ return listAsyncRuns(asyncDirRoot, { sessionId, states: ["complete"], reconcile: false })
37
+ .flatMap((run) => {
38
+ if (!run.parentWorkflowRunId || run.steps.length !== 1) return [];
39
+ const step = run.steps[0]!;
40
+ if ((step.status !== "complete" && step.status !== "completed") || !retainedSessionFile(step.sessionFile ?? run.sessionFile)) return [];
41
+ const completedAt = run.endedAt;
42
+ if (completedAt === undefined) return [];
43
+ return [{
44
+ runId: run.id,
45
+ ...(run.parentWorkflowRunId ? { parentRunId: run.parentWorkflowRunId } : {}),
46
+ agent: step.agent,
47
+ taskSummary: boundedTaskSummary(step.description),
48
+ completedAt,
49
+ sessionPath: step.sessionFile ?? run.sessionFile!,
50
+ ...(step.tokens ?? run.totalTokens ? { tokenTotals: step.tokens ?? run.totalTokens } : {}),
51
+ }];
52
+ })
53
+ .sort((left, right) => right.completedAt - left.completedAt)
54
+ .slice(0, MAX_RETAINED_CHILDREN);
55
+ }
56
+
57
+ export function formatRetainedChildren(children: RetainedChild[]): string {
58
+ if (children.length === 0) return "No completed retained children in the active parent session.";
59
+ return [
60
+ `Completed retained children (newest first, last ${MAX_RETAINED_CHILDREN}):`,
61
+ ...children.flatMap((child) => [
62
+ `- ${child.runId} | ${child.agent} | ${new Date(child.completedAt).toISOString()}`,
63
+ ` task: ${child.taskSummary || "(no task summary)"}`,
64
+ ` session: ${child.sessionPath}`,
65
+ ...(child.tokenTotals ? [` tokens: input ${child.tokenTotals.input}, output ${child.tokenTotals.output}, total ${child.tokenTotals.total}`] : []),
66
+ ]),
67
+ ].join("\n");
68
+ }
@@ -1,6 +1,7 @@
1
1
  import * as fs from "node:fs";
2
2
  import * as path from "node:path";
3
3
  import { DIRS, type SubagentState } from "../../shared/types.ts";
4
+ import { readStatus } from "../../shared/utils.ts";
4
5
  import { findAsyncRunPrefixMatches, type AsyncRunLocation } from "./async-resume.ts";
5
6
  import { assertSafeNestedId, findNestedRunMatchesById, type NestedRoute, type NestedRunMatch, type NestedRunResolutionScope } from "../shared/nested-events.ts";
6
7
 
@@ -27,6 +28,70 @@ function exactAsyncLocation(id: string, asyncDirRoot: string, resultsDir: string
27
28
  };
28
29
  }
29
30
 
31
+ type AsyncRunMatch = { id: string; location: AsyncRunLocation };
32
+
33
+ type WorkflowResultIdentity = {
34
+ id?: string;
35
+ runId?: string;
36
+ toolCallId?: string;
37
+ };
38
+
39
+ function readWorkflowResultIdentity(resultPath: string): WorkflowResultIdentity | undefined {
40
+ let parsed: unknown;
41
+ try {
42
+ parsed = JSON.parse(fs.readFileSync(resultPath, "utf-8")) as unknown;
43
+ } catch {
44
+ return undefined;
45
+ }
46
+ if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) return undefined;
47
+ const record = parsed as Record<string, unknown>;
48
+ return {
49
+ ...(typeof record.id === "string" ? { id: record.id } : {}),
50
+ ...(typeof record.runId === "string" ? { runId: record.runId } : {}),
51
+ ...(typeof record.toolCallId === "string" ? { toolCallId: record.toolCallId } : {}),
52
+ };
53
+ }
54
+
55
+ function directoryEntries(root: string): string[] {
56
+ try {
57
+ return fs.readdirSync(root);
58
+ } catch (error) {
59
+ if ((error as NodeJS.ErrnoException).code === "ENOENT") return [];
60
+ throw error;
61
+ }
62
+ }
63
+
64
+ function resultPathFor(resultsDir: string, runId: string): string | null {
65
+ const resultPath = path.join(resultsDir, `${runId}.json`);
66
+ return fs.existsSync(resultPath) ? resultPath : null;
67
+ }
68
+
69
+ function toolCallIdMatches(value: string | undefined, query: string, options: { prefix?: boolean }): boolean {
70
+ if (value === undefined) return false;
71
+ return options.prefix === true ? value.startsWith(query) : value === query;
72
+ }
73
+
74
+ function toolCallIdAsyncLocations(toolCallId: string, asyncDirRoot: string, resultsDir: string, options: { prefix?: boolean } = {}): AsyncRunMatch[] {
75
+ const byId = new Map<string, AsyncRunLocation>();
76
+ for (const entry of directoryEntries(asyncDirRoot)) {
77
+ const asyncDir = path.join(asyncDirRoot, entry);
78
+ const status = readStatus(asyncDir);
79
+ if (!status || !toolCallIdMatches(status.toolCallId, toolCallId, options)) continue;
80
+ const runId = status.runId || entry;
81
+ byId.set(runId, { asyncDir, resultPath: resultPathFor(resultsDir, runId), resolvedId: runId });
82
+ }
83
+ for (const entry of directoryEntries(resultsDir)) {
84
+ if (!entry.endsWith(".json")) continue;
85
+ const resultPath = path.join(resultsDir, entry);
86
+ const identity = readWorkflowResultIdentity(resultPath);
87
+ if (!identity || !toolCallIdMatches(identity.toolCallId, toolCallId, options)) continue;
88
+ const runId = identity.runId ?? identity.id ?? entry.slice(0, -".json".length);
89
+ const asyncDir = path.join(asyncDirRoot, runId);
90
+ byId.set(runId, { asyncDir: fs.existsSync(asyncDir) ? asyncDir : null, resultPath, resolvedId: runId });
91
+ }
92
+ return [...byId.entries()].map(([id, location]) => ({ id, location }));
93
+ }
94
+
30
95
  function foregroundIds(state: SubagentState | undefined): string[] {
31
96
  if (!state) return [];
32
97
  const remembered = state.currentSessionId
@@ -73,6 +138,9 @@ export function resolveSubagentRunId(id: string, deps: ResolveSubagentRunIdDeps
73
138
  if (hasExactForegroundId(deps.state, id)) return { kind: "foreground", id };
74
139
  const exactAsync = exactAsyncLocation(id, asyncDirRoot, resultsDir);
75
140
  if (exactAsync) return { kind: "async", id, location: exactAsync };
141
+ const exactToolCallIdMatches = toolCallIdAsyncLocations(id, asyncDirRoot, resultsDir);
142
+ if (exactToolCallIdMatches.length > 1) throw new Error(`Subagent tool-call id '${id}' is ambiguous across async runs. Use the returned asyncId instead.`);
143
+ if (exactToolCallIdMatches[0]) return { kind: "async", id: exactToolCallIdMatches[0].id, location: exactToolCallIdMatches[0].location };
76
144
  const exactNested = findNestedRunMatchesById(id, nestedScope ? { scope: nestedScope } : {});
77
145
  if (exactNested.length > 1) throw new Error(`Nested run id '${id}' is ambiguous across authorized registries. Provide the full id after stale registries are cleaned up.`);
78
146
  if (exactNested[0]) return { kind: "nested", id, match: exactNested[0] };
@@ -84,6 +152,9 @@ export function resolveSubagentRunId(id: string, deps: ResolveSubagentRunIdDeps
84
152
  for (const match of asyncPrefixMatches(id, asyncDirRoot, resultsDir)) {
85
153
  matches.push({ kind: "async", id: match.id, location: match.location });
86
154
  }
155
+ for (const match of toolCallIdAsyncLocations(id, asyncDirRoot, resultsDir, { prefix: true })) {
156
+ matches.push({ kind: "async", id: match.id, location: match.location });
157
+ }
87
158
  for (const match of findNestedRunMatchesById(id, nestedScope ? { prefix: true, scope: nestedScope } : { prefix: true })) {
88
159
  matches.push({ kind: "nested", id: match.run.id, match });
89
160
  }
@@ -7,6 +7,7 @@ import { formatNestedRunStatusLines } from "../shared/nested-render.ts";
7
7
  import { formatModelThinking } from "../../shared/formatters.ts";
8
8
  import { formatActivityLabel } from "../../shared/status-format.ts";
9
9
  import { DIRS, type AsyncStatus, type Details, type ForegroundResumeRun, type NestedRunSummary, type SteeringStatus, type SubagentState } from "../../shared/types.ts";
10
+ import { readStatus } from "../../shared/utils.ts";
10
11
  import { resolveSubagentIntercomTarget } from "../../intercom/intercom-bridge.ts";
11
12
  import { resolveSubagentResultStatus } from "../../intercom/result-intercom.ts";
12
13
  import { readProcessTerminal, sanitizeProcessTerminal } from "./process-terminal.ts";
@@ -18,6 +19,7 @@ import { reconcileAsyncRun, reconcileNestedAsyncDescendants } from "./stale-run-
18
19
  import { attachRootChildrenToSteps, findNestedRouteForRootId, projectNestedRegistryForRoot, type NestedRunResolutionScope } from "../shared/nested-events.ts";
19
20
  import { readMissionBinding } from "../../missions/lifecycle.ts";
20
21
  import { formatWorkflowJsonPreview } from "../../workflows/scripted-workflow.ts";
22
+ import { formatRunFanoutBudget, getRunFanoutBudgetSnapshot, readRunFanoutBudgetDescriptor } from "../shared/run-fanout-budget.ts";
21
23
 
22
24
  interface RunStatusParams {
23
25
  action?: string;
@@ -315,6 +317,7 @@ export function inspectSubagentStatus(params: RunStatusParams, deps: RunStatusDe
315
317
  }
316
318
 
317
319
  if (asyncDir) {
320
+ const diskStatus = readStatus(asyncDir);
318
321
  let reconciliation;
319
322
  try {
320
323
  reconciliation = reconcileAsyncRun(asyncDir, { resultsDir, kill: deps.kill, now: deps.now });
@@ -327,6 +330,22 @@ export function inspectSubagentStatus(params: RunStatusParams, deps: RunStatusDe
327
330
  };
328
331
  }
329
332
  const status = reconciliation.status;
333
+ if (!status && diskStatus?.displayDismissedAt !== undefined) {
334
+ if (params.view === "transcript") {
335
+ if (currentSessionId && diskStatus.sessionId !== currentSessionId) {
336
+ return {
337
+ content: [{ type: "text", text: "Transcript view is only available for async runs owned by the current session." }],
338
+ isError: true,
339
+ details: { mode: "single", results: [] },
340
+ };
341
+ }
342
+ return { content: [{ type: "text", text: formatAsyncRunTranscript(diskStatus, asyncDir, { index: params.index, lines: params.lines, sessionRoots: deps.sessionRoots }) }], details: { mode: "single", results: [] } };
343
+ }
344
+ return {
345
+ content: [{ type: "text", text: `Run: ${diskStatus.runId}\nState: display-dismissed\nDismissed: ${new Date(diskStatus.displayDismissedAt).toISOString()}\nNo running work was terminated.` }],
346
+ details: { mode: "single", results: [] },
347
+ };
348
+ }
330
349
  const effectiveRunId = status?.runId ?? resolvedId ?? "unknown";
331
350
  const logPath = path.join(asyncDir, `subagent-log-${effectiveRunId}.md`);
332
351
  const eventsPath = path.join(asyncDir, "events.jsonl");
@@ -371,6 +390,8 @@ export function inspectSubagentStatus(params: RunStatusParams, deps: RunStatusDe
371
390
  const steeringText = formatSteeringSummary(status);
372
391
  const processTerminal = readProcessTerminal(asyncDir, { runId: status.runId, runnerProcessInstanceId: status.processTerminal?.runnerProcessInstanceId })
373
392
  ?? sanitizeProcessTerminal(status.processTerminal, { runId: status.runId, runnerProcessInstanceId: status.processTerminal?.runnerProcessInstanceId }, path.join(asyncDir, "status.json"));
393
+ const runFanoutBudgetDescriptor = readRunFanoutBudgetDescriptor(asyncDir);
394
+ const runFanoutBudget = runFanoutBudgetDescriptor ? getRunFanoutBudgetSnapshot(runFanoutBudgetDescriptor) : status.runFanoutBudget;
374
395
  let missionId: string | undefined;
375
396
  try {
376
397
  missionId = readMissionBinding(asyncDir)?.missionId;
@@ -382,6 +403,7 @@ export function inspectSubagentStatus(params: RunStatusParams, deps: RunStatusDe
382
403
  const workflowEmitPreview = status.workflow?.emits.length ? formatWorkflowJsonPreview(status.workflow.emits.at(-1), 240) : undefined;
383
404
  const lines = [
384
405
  `Run: ${status.runId}`,
406
+ status.toolCallId ? `Tool call: ${status.toolCallId}` : undefined,
385
407
  missionId ? `Mission: ${missionId}` : undefined,
386
408
  `State: ${status.state}`,
387
409
  processTerminal ? `Process terminal: ${processTerminal.state}${processTerminal.reason ? ` (${processTerminal.reason})` : ""}` : undefined,
@@ -391,6 +413,7 @@ export function inspectSubagentStatus(params: RunStatusParams, deps: RunStatusDe
391
413
  statusActivityText ? `Activity: ${statusActivityText}` : undefined,
392
414
  steeringText ? `Steering: ${steeringText}` : undefined,
393
415
  `Mode: ${status.mode}`,
416
+ runFanoutBudget ? formatRunFanoutBudget(runFanoutBudget) : undefined,
394
417
  status.parentWorkflowRunId ? `Workflow parent: ${status.parentWorkflowRunId}${status.workflowKey ? ` (${status.workflowKey})` : ""}` : undefined,
395
418
  status.mode === "workflow" && workflowReturnPreview !== undefined ? `Return: ${workflowReturnPreview}` : undefined,
396
419
  status.mode === "workflow" && workflowEmitPreview !== undefined ? `Latest emit: ${workflowEmitPreview}` : undefined,
@@ -447,14 +470,14 @@ export function inspectSubagentStatus(params: RunStatusParams, deps: RunStatusDe
447
470
  if (fs.existsSync(logPath)) lines.push(`Log: ${logPath}`);
448
471
  if (fs.existsSync(eventsPath)) lines.push(`Events: ${eventsPath}`);
449
472
 
450
- return { content: [{ type: "text", text: lines.join("\n") }], details: { mode: "single", results: [], ...(processTerminal ? { lifecycleStatus: { processTerminal } } : {}) } };
473
+ return { content: [{ type: "text", text: lines.join("\n") }], details: { mode: "single", results: [], ...(runFanoutBudget ? { runFanoutBudget } : {}), ...(processTerminal ? { lifecycleStatus: { processTerminal } } : {}) } };
451
474
  }
452
475
  }
453
476
 
454
477
  if (resultPath) {
455
478
  try {
456
479
  const raw = fs.readFileSync(resultPath, "utf-8");
457
- const data = JSON.parse(raw) as { id?: string; runId?: string; agent?: string; success?: boolean; summary?: string; output?: string; exitCode?: number; state?: string; stopped?: boolean; timedOut?: boolean; turnBudgetExceeded?: boolean; processSignal?: string | null; sessionFile?: string; parallelHandoff?: { path?: string }; results?: Array<{ agent?: string; output?: string; summary?: string; sessionFile?: string; state?: string; success?: boolean; exitCode?: number | null; stopped?: boolean; timedOut?: boolean; turnBudgetExceeded?: boolean; interrupted?: boolean; processSignal?: string | null }> };
480
+ const data = JSON.parse(raw) as { id?: string; runId?: string; toolCallId?: string; agent?: string; success?: boolean; summary?: string; output?: string; exitCode?: number; state?: string; stopped?: boolean; timedOut?: boolean; turnBudgetExceeded?: boolean; processSignal?: string | null; sessionFile?: string; parallelHandoff?: { path?: string }; results?: Array<{ agent?: string; output?: string; summary?: string; sessionFile?: string; state?: string; success?: boolean; exitCode?: number | null; stopped?: boolean; timedOut?: boolean; turnBudgetExceeded?: boolean; interrupted?: boolean; processSignal?: string | null }> };
458
481
  if (params.view === "transcript") {
459
482
  try {
460
483
  return { content: [{ type: "text", text: formatAsyncResultTranscript(data, resultPath, { index: params.index, lines: params.lines }) }], details: { mode: "single", results: [] } };
@@ -479,7 +502,7 @@ export function inspectSubagentStatus(params: RunStatusParams, deps: RunStatusDe
479
502
  ? "stopped"
480
503
  : data.success ? "complete" : data.state === "paused" || data.exitCode === 0 ? "paused" : "failed";
481
504
  const runId = data.runId ?? data.id ?? resolvedId;
482
- const lines = [`Run: ${runId}`, `State: ${status}`, `Result: ${resultPath}`];
505
+ const lines = [`Run: ${runId}`, data.toolCallId ? `Tool call: ${data.toolCallId}` : undefined, `State: ${status}`, `Result: ${resultPath}`].filter((line): line is string => Boolean(line));
483
506
  if (data.parallelHandoff?.path) lines.push(`Parallel handoff: ${data.parallelHandoff.path}`);
484
507
  const children = Array.isArray(data.results) ? data.results : data.agent ? [{ agent: data.agent, sessionFile: data.sessionFile }] : [];
485
508
  lines.push(formatResumeGuidance(runId, children, data.sessionFile, { stopped: status === "stopped" }));
@@ -3,12 +3,14 @@ import * as fs from "node:fs";
3
3
  import * as path from "node:path";
4
4
  import type { AgentToolResult } from "@earendil-works/pi-agent-core";
5
5
  import type { ExtensionContext } from "@selesai/code";
6
+ import { getProjectSubagentsDir } from "../../shared/artifacts.ts";
6
7
  import { writePrivateAtomicJson } from "../../shared/atomic-json.ts";
7
8
  import { shortenPath } from "../../shared/formatters.ts";
8
9
  import type { AsyncStatus, Details, ExtensionConfig } from "../../shared/types.ts";
9
10
  import type { SubagentParamsLike } from "../foreground/subagent-executor.ts";
10
11
  import { validateExecutionAcceptance } from "../shared/acceptance.ts";
11
12
  import type { ResolvedSubagentCapabilityCeiling } from "../shared/capability-ceiling.ts";
13
+ import { previewSimpleWorkflowRun } from "../../workflows/scripted-workflow.ts";
12
14
 
13
15
  export const SCHEDULED_RUN_ACTIONS = [
14
16
  "schedule.create",
@@ -34,7 +36,7 @@ export type ScheduleRunState = "running" | "skipped" | "missed" | "completed" |
34
36
  export type ScheduleTrigger =
35
37
  | { kind: "once"; at: string; nextRunAt?: string }
36
38
  | { kind: "interval"; every: string; everyMs: number; anchorAt: string; nextRunAt: string };
37
- export type ScheduleTarget = { workflowScript: string } | { agent: string; task?: string };
39
+ export type ScheduleTarget = { workflowScript: string };
38
40
 
39
41
  export interface ScheduleRecord {
40
42
  schemaVersion: 1;
@@ -86,7 +88,7 @@ export function scheduledRunsEnabled(config: ExtensionConfig): boolean {
86
88
  }
87
89
 
88
90
  export function scheduledRunStorePath(cwd: string, _sessionId?: string, root?: string): string {
89
- if (!root) return path.join(path.resolve(cwd), ".pi-subagents", "schedules");
91
+ if (!root) return path.join(getProjectSubagentsDir(path.resolve(cwd)), "schedules");
90
92
  const projectKey = createHash("sha256").update(path.resolve(cwd)).digest("hex").slice(0, 20);
91
93
  return path.join(root, projectKey);
92
94
  }
@@ -188,6 +190,14 @@ function readJson(file: string, label: string): unknown {
188
190
  }
189
191
  }
190
192
 
193
+ function parseScheduleTarget(value: unknown, file: string): ScheduleTarget {
194
+ if (!value || typeof value !== "object" || Array.isArray(value)) throw new Error(`Schedule record '${file}' has invalid trigger or target.`);
195
+ const target = value as { workflowScript?: unknown; agent?: unknown; task?: unknown };
196
+ if (typeof target.workflowScript === "string" && target.workflowScript.trim()) return { workflowScript: target.workflowScript.trim() };
197
+ if (target.agent !== undefined || target.task !== undefined) throw new Error(`Schedule record '${file}' uses a removed legacy agent target; recreate it with target.workflowScript.`);
198
+ throw new Error(`Schedule record '${file}' requires a workflowScript target.`);
199
+ }
200
+
191
201
  function parseSchedule(value: unknown, file: string): ScheduleRecord {
192
202
  if (!value || typeof value !== "object" || Array.isArray(value)) throw new Error(`Schedule record '${file}' must be a JSON object.`);
193
203
  const record = value as Partial<ScheduleRecord>;
@@ -200,10 +210,7 @@ function parseSchedule(value: unknown, file: string): ScheduleRecord {
200
210
  } else if (record.trigger.kind === "interval") {
201
211
  if (typeof record.trigger.every !== "string" || typeof record.trigger.everyMs !== "number" || typeof record.trigger.anchorAt !== "string" || typeof record.trigger.nextRunAt !== "string") throw new Error(`Schedule record '${file}' has an invalid interval trigger.`);
202
212
  } else throw new Error(`Schedule record '${file}' has an unsupported trigger.`);
203
- const workflow = "workflowScript" in record.target && typeof record.target.workflowScript === "string";
204
- const agent = "agent" in record.target && typeof record.target.agent === "string";
205
- if (workflow === agent) throw new Error(`Schedule record '${file}' has an invalid target.`);
206
- return record as ScheduleRecord;
213
+ return { ...record, target: parseScheduleTarget(record.target, file) } as ScheduleRecord;
207
214
  }
208
215
 
209
216
  class ScheduleStore {
@@ -304,27 +311,25 @@ function textResult(text: string, schedules?: ScheduleRecord[], runs?: ScheduleR
304
311
  }
305
312
 
306
313
  function targetLabel(target: ScheduleTarget): string {
307
- return "workflowScript" in target ? "workflowScript" : `agent ${target.agent}`;
314
+ const preview = previewSimpleWorkflowRun(target.workflowScript);
315
+ return preview?.agent ? `workflowScript -> agent ${preview.agent}` : "workflowScript (dynamic)";
308
316
  }
309
317
 
310
318
  function sanitizeTarget(params: SubagentParamsLike): { target?: ScheduleTarget; error?: string } {
311
- if (params.tasks || params.chain) return { error: "Recurring schedules support workflowScript or one agent/task target, not legacy tasks or chain inputs." };
312
- const hasWorkflow = typeof params.workflowScript === "string" && params.workflowScript.trim().length > 0;
313
- const hasAgent = typeof params.agent === "string" && params.agent.trim().length > 0;
314
- if (hasWorkflow === hasAgent) return { error: "schedule.create requires exactly one target: workflowScript or agent with optional task." };
319
+ if (params.tasks || params.chain) return { error: "Recurring schedules require workflowScript; legacy tasks and chain inputs are unsupported." };
320
+ if (params.agent !== undefined || params.task !== undefined) return { error: "schedule.create requires workflowScript. Use workflowScript: \"return runs.run('main', { agent, task })\"." };
321
+ if (typeof params.workflowScript !== "string" || !params.workflowScript.trim()) return { error: "schedule.create requires a non-empty workflowScript." };
315
322
  if (params.context === "fork") return { error: "Scheduled runs require fresh context." };
316
323
  if (params.async === false) return { error: "Scheduled runs are always async." };
317
- if (params.clarify === true) return { error: "Scheduled runs cannot open clarify UI." };
318
324
  const acceptanceErrors = validateExecutionAcceptance(params as Parameters<typeof validateExecutionAcceptance>[0]);
319
325
  if (acceptanceErrors.length) return { error: acceptanceErrors.join(" ") };
320
- return hasWorkflow ? { target: { workflowScript: params.workflowScript!.trim() } } : { target: { agent: params.agent!.trim(), ...(params.task === undefined ? {} : { task: params.task }) } };
326
+ return { target: { workflowScript: params.workflowScript.trim() } };
321
327
  }
322
328
 
323
329
  function executionParams(schedule: ScheduleRecord): SubagentParamsLike {
324
330
  return {
325
331
  ...schedule.target,
326
332
  async: true,
327
- clarify: false,
328
333
  context: "fresh",
329
334
  cwd: schedule.cwd,
330
335
  mission: false,
@@ -401,6 +406,29 @@ export class ScheduledRunManager {
401
406
  }
402
407
  }
403
408
 
409
+ observedCompletionRunIds(): Set<string> {
410
+ const runIds = new Set<string>();
411
+ for (const store of this.stores.values()) {
412
+ let ids: string[];
413
+ try {
414
+ ids = store.ids();
415
+ } catch (error) {
416
+ console.error(`Failed to inspect schedule store '${store.root}' during async completion discovery:`, error);
417
+ continue;
418
+ }
419
+ for (const id of ids) {
420
+ try {
421
+ for (const run of store.history(id)) {
422
+ if (run.state === "running" && run.asyncId) runIds.add(run.asyncId);
423
+ }
424
+ } catch (error) {
425
+ console.error(`Failed to inspect schedule '${id}' in '${store.root}' during async completion discovery:`, error);
426
+ }
427
+ }
428
+ }
429
+ return runIds;
430
+ }
431
+
404
432
  handleAsyncCompletion(payload: unknown): void {
405
433
  if (!payload || typeof payload !== "object") return;
406
434
  const data = payload as { id?: unknown; runId?: unknown; success?: unknown; state?: unknown; summary?: unknown };