@selesai/code 0.8.3 → 0.8.4

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 (493) hide show
  1. package/CHANGELOG.md +5 -0
  2. package/dist/extensions/handoff-new.ts +1 -1
  3. package/dist/extensions/inline-skills.test.ts +1 -0
  4. package/dist/extensions/inline-skills.ts +1 -1
  5. package/dist/extensions/pi-intercom/CHANGELOG.md +25 -3
  6. package/dist/extensions/pi-intercom/README.md +34 -15
  7. package/dist/extensions/pi-intercom/broker/broker.ts +38 -141
  8. package/dist/extensions/pi-intercom/broker/client-liveness.test.ts +173 -0
  9. package/dist/extensions/pi-intercom/broker/client.ts +78 -150
  10. package/dist/extensions/pi-intercom/broker/extension-state.ts +18 -7
  11. package/dist/extensions/pi-intercom/broker/framing.ts +1 -1
  12. package/dist/extensions/pi-intercom/broker/protocol.ts +182 -0
  13. package/dist/extensions/pi-intercom/broker/spawn.test.ts +106 -7
  14. package/dist/extensions/pi-intercom/broker/spawn.ts +37 -11
  15. package/dist/extensions/pi-intercom/config.test.ts +8 -10
  16. package/dist/extensions/pi-intercom/config.ts +3 -3
  17. package/dist/extensions/pi-intercom/index.ts +218 -147
  18. package/dist/extensions/pi-intercom/intercom.integration.test.ts +891 -103
  19. package/dist/extensions/pi-intercom/package.json +3 -2
  20. package/dist/extensions/pi-intercom/project-agent.test.ts +145 -0
  21. package/dist/extensions/pi-intercom/project-agent.ts +324 -0
  22. package/dist/extensions/pi-intercom/reply-tracker.test.ts +86 -1
  23. package/dist/extensions/pi-intercom/reply-tracker.ts +41 -9
  24. package/dist/extensions/pi-intercom/skills/pi-intercom/SKILL.md +49 -9
  25. package/dist/extensions/pi-intercom/test/inline-message.test.ts +9 -9
  26. package/dist/extensions/pi-intercom/types.ts +3 -1
  27. package/dist/extensions/pi-intercom/ui/inline-message.ts +7 -7
  28. package/dist/extensions/pi-powerline-footer/.github/workflows/test.yml +2 -2
  29. package/dist/extensions/pi-powerline-footer/CHANGELOG.md +14 -1
  30. package/dist/extensions/pi-powerline-footer/README.md +20 -37
  31. package/dist/extensions/pi-powerline-footer/bash-mode/completion.ts +40 -25
  32. package/dist/extensions/pi-powerline-footer/bash-mode/editor.ts +149 -18
  33. package/dist/extensions/pi-powerline-footer/bash-mode/types.ts +1 -0
  34. package/dist/extensions/pi-powerline-footer/editor-performance.ts +99 -0
  35. package/dist/extensions/pi-powerline-footer/git-status.ts +15 -0
  36. package/dist/extensions/pi-powerline-footer/index.ts +394 -317
  37. package/dist/extensions/pi-powerline-footer/package.json +1 -1
  38. package/dist/extensions/pi-powerline-footer/powerline-config.ts +0 -12
  39. package/dist/extensions/pi-powerline-footer/queue/store.ts +8 -56
  40. package/dist/extensions/pi-powerline-footer/queue/types.ts +1 -2
  41. package/dist/extensions/pi-powerline-footer/segments.ts +0 -3
  42. package/dist/extensions/pi-powerline-footer/tests/bash-mode.test.ts +231 -1
  43. package/dist/extensions/pi-powerline-footer/tests/custom-items.test.ts +5 -19
  44. package/dist/extensions/pi-powerline-footer/tests/editor-performance.test.ts +43 -0
  45. package/dist/extensions/pi-powerline-footer/tests/git-optional-locks.test.ts +64 -0
  46. package/dist/extensions/pi-powerline-footer/tests/jump-shortcuts.test.ts +116 -0
  47. package/dist/extensions/pi-powerline-footer/tests/queue-store.test.ts +19 -149
  48. package/dist/extensions/pi-powerline-footer/tests/remaining-regressions.test.ts +6 -0
  49. package/dist/extensions/pi-powerline-footer/tests/usage-display.test.ts +5 -5
  50. package/dist/extensions/pi-powerline-footer/types.ts +1 -2
  51. package/dist/extensions/pi-subagents/CHANGELOG.md +202 -14
  52. package/dist/extensions/pi-subagents/README.md +65 -1614
  53. package/dist/extensions/pi-subagents/agents/builder.md +0 -1
  54. package/dist/extensions/pi-subagents/agents/delegate.md +14 -0
  55. package/dist/extensions/pi-subagents/agents/oracle.md +74 -0
  56. package/dist/extensions/pi-subagents/agents/reviewer.md +78 -0
  57. package/dist/extensions/pi-subagents/agents/scout.md +50 -0
  58. package/dist/extensions/pi-subagents/agents/worker.md +58 -0
  59. package/dist/extensions/pi-subagents/docs/configuration.md +328 -0
  60. package/dist/extensions/pi-subagents/docs/extension-api.md +308 -0
  61. package/dist/extensions/pi-subagents/docs/missions.md +119 -0
  62. package/dist/extensions/pi-subagents/docs/models.md +192 -0
  63. package/dist/extensions/pi-subagents/docs/observability.md +174 -0
  64. package/dist/extensions/pi-subagents/docs/tool-reference.md +343 -0
  65. package/dist/extensions/pi-subagents/docs/watchdog.md +176 -0
  66. package/dist/extensions/pi-subagents/docs/workflows.md +163 -0
  67. package/dist/extensions/pi-subagents/inspector-runner.mjs +11 -0
  68. package/dist/extensions/pi-subagents/package-lock.json +152 -194
  69. package/dist/extensions/pi-subagents/package.json +9 -10
  70. package/dist/extensions/pi-subagents/prompts/gather-context-and-clarify.md +1 -1
  71. package/dist/extensions/pi-subagents/prompts/parallel-cleanup.md +9 -9
  72. package/dist/extensions/pi-subagents/prompts/parallel-research.md +6 -6
  73. package/dist/extensions/pi-subagents/prompts/parallel-review.md +8 -8
  74. package/dist/extensions/pi-subagents/prompts/review-loop.md +12 -12
  75. package/dist/extensions/pi-subagents/skills/pi-subagents/SKILL.md +22 -17
  76. package/dist/extensions/pi-subagents/skills/pi-subagents/references/constraints-and-recipes.md +77 -72
  77. package/dist/extensions/pi-subagents/skills/pi-subagents/references/execution-controls.md +177 -69
  78. package/dist/extensions/pi-subagents/skills/pi-subagents/references/management-authoring-rpc.md +28 -8
  79. package/dist/extensions/pi-subagents/skills/pi-subagents/references/prompting-and-roles.md +88 -66
  80. package/dist/extensions/pi-subagents/src/agents/agent-management.ts +3 -3
  81. package/dist/extensions/pi-subagents/src/agents/agent-refinements.ts +624 -0
  82. package/dist/extensions/pi-subagents/src/agents/agents.ts +29 -16
  83. package/dist/extensions/pi-subagents/src/agents/frontmatter.ts +7 -3
  84. package/dist/extensions/pi-subagents/src/agents/proactive-skills.ts +2 -2
  85. package/dist/extensions/pi-subagents/src/agents/skills.ts +2 -9
  86. package/dist/extensions/pi-subagents/src/api/delegation.ts +1 -2
  87. package/dist/extensions/pi-subagents/src/api/project-panes.ts +30 -0
  88. package/dist/extensions/pi-subagents/src/extension/config.ts +56 -8
  89. package/dist/extensions/pi-subagents/src/extension/control-notices.ts +2 -2
  90. package/dist/extensions/pi-subagents/src/extension/fanout-child.ts +51 -26
  91. package/dist/extensions/pi-subagents/src/extension/index.ts +119 -50
  92. package/dist/extensions/pi-subagents/src/extension/public-execution.ts +72 -0
  93. package/dist/extensions/pi-subagents/src/extension/rpc.ts +15 -15
  94. package/dist/extensions/pi-subagents/src/extension/schemas.ts +58 -21
  95. package/dist/extensions/pi-subagents/src/extension/subagent-guide.ts +39 -0
  96. package/dist/extensions/pi-subagents/src/extension/tool-description.ts +47 -25
  97. package/dist/extensions/pi-subagents/src/inspectors/herdr/actions.ts +3 -3
  98. package/dist/extensions/pi-subagents/src/inspectors/herdr/project-panes.ts +460 -64
  99. package/dist/extensions/pi-subagents/src/intercom/native-supervisor-channel.ts +102 -4
  100. package/dist/extensions/pi-subagents/src/missions/actions.ts +77 -16
  101. package/dist/extensions/pi-subagents/src/missions/goal-driver.ts +162 -0
  102. package/dist/extensions/pi-subagents/src/missions/lifecycle.ts +65 -14
  103. package/dist/extensions/pi-subagents/src/missions/store.ts +147 -5
  104. package/dist/extensions/pi-subagents/src/missions/types.ts +58 -3
  105. package/dist/extensions/pi-subagents/src/missions/workflow-state.ts +256 -0
  106. package/dist/extensions/pi-subagents/src/profiles/profiles.ts +8 -8
  107. package/dist/extensions/pi-subagents/src/runs/background/active-run-index.ts +42 -0
  108. package/dist/extensions/pi-subagents/src/runs/background/async-execution.ts +41 -7
  109. package/dist/extensions/pi-subagents/src/runs/background/async-job-tracker.ts +294 -134
  110. package/dist/extensions/pi-subagents/src/runs/background/async-resume.ts +19 -3
  111. package/dist/extensions/pi-subagents/src/runs/background/async-status.ts +39 -6
  112. package/dist/extensions/pi-subagents/src/runs/background/completion-replay.ts +267 -0
  113. package/dist/extensions/pi-subagents/src/runs/background/control-channel.ts +145 -60
  114. package/dist/extensions/pi-subagents/src/runs/background/result-watcher.ts +114 -6
  115. package/dist/extensions/pi-subagents/src/runs/background/resume-guidance.ts +33 -0
  116. package/dist/extensions/pi-subagents/src/runs/background/retained-children.ts +68 -0
  117. package/dist/extensions/pi-subagents/src/runs/background/run-id-resolver.ts +71 -0
  118. package/dist/extensions/pi-subagents/src/runs/background/run-status.ts +21 -2
  119. package/dist/extensions/pi-subagents/src/runs/background/scheduled-runs.ts +42 -14
  120. package/dist/extensions/pi-subagents/src/runs/background/stale-run-reconciler.ts +12 -24
  121. package/dist/extensions/pi-subagents/src/runs/background/steering.ts +7 -5
  122. package/dist/extensions/pi-subagents/src/runs/background/subagent-runner.ts +152 -68
  123. package/dist/extensions/pi-subagents/src/runs/background/subagent-wait.ts +17 -4
  124. package/dist/extensions/pi-subagents/src/runs/background/wait-completions.ts +146 -0
  125. package/dist/extensions/pi-subagents/src/runs/background/wait-subscriptions.ts +21 -5
  126. package/dist/extensions/pi-subagents/src/runs/foreground/async-dismiss-action.ts +85 -0
  127. package/dist/extensions/pi-subagents/src/runs/foreground/async-steering-action.ts +43 -18
  128. package/dist/extensions/pi-subagents/src/runs/foreground/chain-clarify.ts +20 -19
  129. package/dist/extensions/pi-subagents/src/runs/foreground/chain-execution.ts +3 -0
  130. package/dist/extensions/pi-subagents/src/runs/foreground/execution.ts +55 -26
  131. package/dist/extensions/pi-subagents/src/runs/foreground/foreground-history.ts +137 -0
  132. package/dist/extensions/pi-subagents/src/runs/foreground/subagent-executor.ts +798 -112
  133. package/dist/extensions/pi-subagents/src/runs/foreground/workflow-foreground-steering.ts +187 -0
  134. package/dist/extensions/pi-subagents/src/runs/shared/acceptance.ts +165 -22
  135. package/dist/extensions/pi-subagents/src/runs/shared/dynamic-fanout.ts +1 -1
  136. package/dist/extensions/pi-subagents/src/runs/shared/mcp-direct-tool-allowlist.ts +2 -0
  137. package/dist/extensions/pi-subagents/src/runs/shared/model-fallback.ts +9 -5
  138. package/dist/extensions/pi-subagents/src/runs/shared/model-scope.ts +12 -2
  139. package/dist/extensions/pi-subagents/src/runs/shared/parallel-utils.ts +1 -0
  140. package/dist/extensions/pi-subagents/src/runs/shared/pi-args.ts +465 -116
  141. package/dist/extensions/pi-subagents/src/runs/shared/pi-spawn.ts +10 -10
  142. package/dist/extensions/pi-subagents/src/runs/shared/subagent-prompt-runtime.ts +189 -32
  143. package/dist/extensions/pi-subagents/src/runs/shared/task-intent.ts +2 -2
  144. package/dist/extensions/pi-subagents/src/runs/shared/worktree.ts +3 -3
  145. package/dist/extensions/pi-subagents/src/shared/artifacts.ts +128 -3
  146. package/dist/extensions/pi-subagents/src/shared/display-text.ts +100 -0
  147. package/dist/extensions/pi-subagents/src/shared/file-coalescer.ts +9 -0
  148. package/dist/extensions/pi-subagents/src/shared/fork-context.ts +13 -0
  149. package/dist/extensions/pi-subagents/src/shared/formatters.ts +4 -6
  150. package/dist/extensions/pi-subagents/src/shared/prompt-resources.ts +51 -0
  151. package/dist/extensions/pi-subagents/src/shared/settings.ts +41 -11
  152. package/dist/extensions/pi-subagents/src/shared/types.ts +100 -3
  153. package/dist/extensions/pi-subagents/src/shared/utf8.ts +11 -0
  154. package/dist/extensions/pi-subagents/src/shared/utils.ts +43 -33
  155. package/dist/extensions/pi-subagents/src/slash/delegation-adapters.ts +1 -14
  156. package/dist/extensions/pi-subagents/src/slash/inline-subagents.ts +1 -1
  157. package/dist/extensions/pi-subagents/src/slash/prompt-template-bridge.ts +14 -12
  158. package/dist/extensions/pi-subagents/src/slash/prompt-workflows.ts +176 -21
  159. package/dist/extensions/pi-subagents/src/slash/slash-bridge.ts +12 -6
  160. package/dist/extensions/pi-subagents/src/slash/slash-commands.ts +52 -18
  161. package/dist/extensions/pi-subagents/src/slash/slash-live-state.ts +36 -5
  162. package/dist/extensions/pi-subagents/src/tui/fleet-status.ts +30 -16
  163. package/dist/extensions/pi-subagents/src/tui/fleet.ts +151 -31
  164. package/dist/extensions/pi-subagents/src/tui/render.ts +201 -68
  165. package/dist/extensions/pi-subagents/src/types/pi-runtime-compat.d.ts +0 -6
  166. package/dist/extensions/pi-subagents/src/watchdog/change-signature.ts +5 -4
  167. package/dist/extensions/pi-subagents/src/watchdog/lsp-diagnostics.ts +0 -1
  168. package/dist/extensions/pi-subagents/src/workflows/scripted-workflow.ts +313 -25
  169. package/dist/extensions/pi-subagents/test/e2e/real-session-subagent.test.ts +15 -15
  170. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/bun/cli.d.ts +3 -0
  171. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/bun/register-bedrock.d.ts +2 -0
  172. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/bun/restore-sandbox-env.d.ts +17 -0
  173. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/cli/args.d.ts +57 -0
  174. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/cli/config-selector.d.ts +16 -0
  175. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/cli/file-processor.d.ts +15 -0
  176. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/cli/initial-message.d.ts +18 -0
  177. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/cli/list-models.d.ts +9 -0
  178. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/cli/project-trust.d.ts +10 -0
  179. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/cli/session-picker.d.ts +10 -0
  180. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/cli/startup-ui.d.ts +20 -0
  181. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/cli.d.ts +3 -0
  182. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/config.d.ts +96 -0
  183. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/agent-session-runtime.d.ts +119 -0
  184. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/agent-session-services.d.ts +85 -0
  185. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/agent-session.d.ts +620 -0
  186. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/auth-guidance.d.ts +5 -0
  187. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/auth-storage.d.ts +56 -0
  188. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/bash-executor.d.ts +32 -0
  189. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/cache-stats.d.ts +49 -0
  190. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/compaction/branch-summarization.d.ts +93 -0
  191. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/compaction/compaction.d.ts +128 -0
  192. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/compaction/index.d.ts +7 -0
  193. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/compaction/utils.d.ts +38 -0
  194. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/defaults.d.ts +3 -0
  195. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/diagnostics.d.ts +15 -0
  196. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/event-bus.d.ts +9 -0
  197. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/exec.d.ts +29 -0
  198. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/experimental.d.ts +2 -0
  199. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/export-html/ansi-to-html.d.ts +22 -0
  200. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/export-html/index.d.ts +37 -0
  201. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/export-html/tool-renderer.d.ts +34 -0
  202. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/extensions/index.d.ts +12 -0
  203. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/extensions/loader.d.ts +23 -0
  204. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/extensions/runner.d.ts +171 -0
  205. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/extensions/types.d.ts +1261 -0
  206. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/extensions/wrapper.d.ts +20 -0
  207. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/footer-data-provider.d.ts +54 -0
  208. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/http-dispatcher.d.ts +22 -0
  209. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/index.d.ts +13 -0
  210. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/keybindings.d.ts +358 -0
  211. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/messages.d.ts +77 -0
  212. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/model-config.d.ts +512 -0
  213. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/model-registry.d.ts +43 -0
  214. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/model-resolver.d.ts +121 -0
  215. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/model-runtime.d.ts +82 -0
  216. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/models-store.d.ts +17 -0
  217. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/output-guard.d.ts +7 -0
  218. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/package-manager.d.ts +210 -0
  219. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/project-trust.d.ts +15 -0
  220. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/prompt-templates.d.ts +54 -0
  221. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/provider-attribution.d.ts +4 -0
  222. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/provider-composer.d.ts +55 -0
  223. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/radius.d.ts +2 -0
  224. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/remote-catalog-provider.d.ts +5 -0
  225. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/resolve-config-value.d.ts +30 -0
  226. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/resource-loader.d.ts +206 -0
  227. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/runtime-credentials.d.ts +15 -0
  228. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/sdk.d.ts +106 -0
  229. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/session-cwd.d.ts +19 -0
  230. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/session-manager.d.ts +356 -0
  231. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/settings-manager.d.ts +297 -0
  232. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/skills.d.ts +60 -0
  233. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/slash-commands.d.ts +15 -0
  234. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/source-info.d.ts +18 -0
  235. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/system-prompt.d.ts +28 -0
  236. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/telemetry.d.ts +3 -0
  237. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/timings.d.ts +10 -0
  238. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/tools/bash.d.ts +68 -0
  239. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/tools/edit-diff.d.ts +106 -0
  240. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/tools/edit.d.ts +51 -0
  241. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/tools/file-mutation-queue.d.ts +6 -0
  242. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/tools/find.d.ts +35 -0
  243. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/tools/grep.d.ts +37 -0
  244. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/tools/index.d.ts +40 -0
  245. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/tools/ls.d.ts +37 -0
  246. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/tools/output-accumulator.d.ts +52 -0
  247. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/tools/path-utils.d.ts +10 -0
  248. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/tools/read.d.ts +35 -0
  249. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/tools/render-utils.d.ts +24 -0
  250. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/tools/tool-definition-wrapper.d.ts +14 -0
  251. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/tools/truncate.d.ts +70 -0
  252. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/tools/write.d.ts +26 -0
  253. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/trust-manager.d.ts +36 -0
  254. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/usage-totals.d.ts +19 -0
  255. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/extensions/index.d.ts +3 -0
  256. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/extensions/llama/client.d.ts +61 -0
  257. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/extensions/llama/huggingface.d.ts +23 -0
  258. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/extensions/llama/index.d.ts +3 -0
  259. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/extensions/llama/provider.d.ts +10 -0
  260. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/extensions/llama/ui.d.ts +42 -0
  261. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/index.d.ts +35 -0
  262. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/main.d.ts +12 -0
  263. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/migrations.d.ts +33 -0
  264. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/index.d.ts +9 -0
  265. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/armin.d.ts +34 -0
  266. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/assistant-message.d.ts +22 -0
  267. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/bash-execution.d.ts +34 -0
  268. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/bordered-loader.d.ts +16 -0
  269. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/branch-summary-message.d.ts +16 -0
  270. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/compaction-summary-message.d.ts +16 -0
  271. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/config-selector.d.ts +102 -0
  272. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/countdown-timer.d.ts +14 -0
  273. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/custom-editor.d.ts +21 -0
  274. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/custom-entry.d.ts +19 -0
  275. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/custom-message.d.ts +20 -0
  276. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/daxnuts.d.ts +23 -0
  277. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/diff.d.ts +12 -0
  278. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/dynamic-border.d.ts +15 -0
  279. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/earendil-announcement.d.ts +5 -0
  280. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/extension-editor.d.ts +22 -0
  281. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/extension-input.d.ts +23 -0
  282. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/extension-selector.d.ts +26 -0
  283. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/first-time-setup.d.ts +25 -0
  284. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/footer.d.ts +32 -0
  285. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/index.d.ts +34 -0
  286. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/keybinding-hints.d.ts +13 -0
  287. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/login-dialog.d.ts +52 -0
  288. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/model-selector.d.ts +54 -0
  289. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/oauth-selector.d.ts +33 -0
  290. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/scoped-models-selector.d.ts +42 -0
  291. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/session-selector-search.d.ts +23 -0
  292. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/session-selector.d.ts +95 -0
  293. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/settings-selector.d.ts +77 -0
  294. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/show-images-selector.d.ts +10 -0
  295. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/skill-invocation-message.d.ts +17 -0
  296. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/status-indicator.d.ts +28 -0
  297. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/theme-selector.d.ts +11 -0
  298. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/thinking-selector.d.ts +11 -0
  299. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/tool-execution.d.ts +63 -0
  300. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/tree-selector.d.ts +94 -0
  301. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/trust-selector.d.ts +23 -0
  302. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/user-message-selector.d.ts +30 -0
  303. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/user-message.d.ts +14 -0
  304. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/visual-truncate.d.ts +24 -0
  305. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/interactive-mode.d.ts +394 -0
  306. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/model-search.d.ts +12 -0
  307. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/theme/theme-controller.d.ts +29 -0
  308. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/theme/theme.d.ts +120 -0
  309. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/print-mode.d.ts +28 -0
  310. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/rpc/jsonl.d.ts +17 -0
  311. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/rpc/rpc-client.d.ts +246 -0
  312. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/rpc/rpc-mode.d.ts +20 -0
  313. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/rpc/rpc-types.d.ts +457 -0
  314. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/package-manager-cli.d.ts +8 -0
  315. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/rpc-entry.d.ts +3 -0
  316. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/ansi.d.ts +2 -0
  317. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/changelog.d.ts +22 -0
  318. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/child-process.d.ts +18 -0
  319. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/clipboard-image.d.ts +11 -0
  320. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/clipboard-native.d.ts +11 -0
  321. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/clipboard.d.ts +4 -0
  322. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/deprecation.d.ts +4 -0
  323. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/exif-orientation.d.ts +5 -0
  324. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/frontmatter.d.ts +8 -0
  325. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/fs-watch.d.ts +5 -0
  326. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/git.d.ts +26 -0
  327. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/html.d.ts +7 -0
  328. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/image-convert.d.ts +10 -0
  329. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/image-process.d.ts +18 -0
  330. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/image-resize-core.d.ts +30 -0
  331. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/image-resize-worker.d.ts +2 -0
  332. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/image-resize.d.ts +16 -0
  333. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/json.d.ts +3 -0
  334. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/mime.d.ts +3 -0
  335. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/open-browser.d.ts +9 -0
  336. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/paths.d.ts +31 -0
  337. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/photon.d.ts +21 -0
  338. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/pi-user-agent.d.ts +2 -0
  339. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/shell.d.ts +31 -0
  340. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/sleep.d.ts +5 -0
  341. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/syntax-highlight.d.ts +12 -0
  342. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/tools-manager.d.ts +3 -0
  343. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/version-check.d.ts +15 -0
  344. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/windows-self-update.d.ts +3 -0
  345. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/index.mjs +84 -0
  346. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/package.json +14 -0
  347. package/dist/extensions/pi-subagents/test/integration/acceptance-file-report.test.ts +15 -15
  348. package/dist/extensions/pi-subagents/test/integration/async-execution.test.ts +411 -300
  349. package/dist/extensions/pi-subagents/test/integration/async-job-tracker.test.ts +309 -123
  350. package/dist/extensions/pi-subagents/test/integration/async-status.test.ts +99 -56
  351. package/dist/extensions/pi-subagents/test/integration/chain-clarify.test.ts +62 -16
  352. package/dist/extensions/pi-subagents/test/integration/chain-execution.test.ts +159 -108
  353. package/dist/extensions/pi-subagents/test/integration/detect-error.test.ts +1 -1
  354. package/dist/extensions/pi-subagents/test/integration/external-cli-runner.test.ts +4 -2
  355. package/dist/extensions/pi-subagents/test/integration/fork-context-execution.test.ts +56 -56
  356. package/dist/extensions/pi-subagents/test/integration/intercom-result-delivery.test.ts +114 -45
  357. package/dist/extensions/pi-subagents/test/integration/parallel-execution.test.ts +57 -19
  358. package/dist/extensions/pi-subagents/test/integration/render-fork-badge.test.ts +106 -106
  359. package/dist/extensions/pi-subagents/test/integration/render-widget.test.ts +416 -106
  360. package/dist/extensions/pi-subagents/test/integration/result-watcher.test.ts +287 -17
  361. package/dist/extensions/pi-subagents/test/integration/single-execution.test.ts +809 -87
  362. package/dist/extensions/pi-subagents/test/integration/slash-commands.test.ts +107 -20
  363. package/dist/extensions/pi-subagents/test/integration/slash-live-state.test.ts +9 -9
  364. package/dist/extensions/pi-subagents/test/integration/template-resolution.test.ts +26 -6
  365. package/dist/extensions/pi-subagents/test/integration/top-level-async.test.ts +2 -2
  366. package/dist/extensions/pi-subagents/test/support/helpers.ts +2 -0
  367. package/dist/extensions/pi-subagents/test/support/mock-pi-script.mjs +1 -1
  368. package/dist/extensions/pi-subagents/test/support/ts-loader.mjs +0 -8
  369. package/dist/extensions/pi-subagents/test/unit/acceptance.test.ts +163 -58
  370. package/dist/extensions/pi-subagents/test/unit/agent-disabled.test.ts +15 -15
  371. package/dist/extensions/pi-subagents/test/unit/agent-eject-disable.test.ts +66 -66
  372. package/dist/extensions/pi-subagents/test/unit/agent-frontmatter.test.ts +334 -248
  373. package/dist/extensions/pi-subagents/test/unit/agent-management.test.ts +52 -52
  374. package/dist/extensions/pi-subagents/test/unit/agent-memory.test.ts +26 -26
  375. package/dist/extensions/pi-subagents/test/unit/agent-overrides.test.ts +99 -99
  376. package/dist/extensions/pi-subagents/test/unit/agent-refinements.test.ts +160 -0
  377. package/dist/extensions/pi-subagents/test/unit/agent-selection.test.ts +9 -9
  378. package/dist/extensions/pi-subagents/test/unit/artifacts.test.ts +43 -1
  379. package/dist/extensions/pi-subagents/test/unit/async-execution.test.ts +36 -10
  380. package/dist/extensions/pi-subagents/test/unit/async-interrupt-action.test.ts +387 -30
  381. package/dist/extensions/pi-subagents/test/unit/async-permission-session.test.ts +9 -9
  382. package/dist/extensions/pi-subagents/test/unit/async-recovery-descriptor.test.ts +2 -2
  383. package/dist/extensions/pi-subagents/test/unit/async-resume.test.ts +94 -40
  384. package/dist/extensions/pi-subagents/test/unit/background-work.test.ts +5 -3
  385. package/dist/extensions/pi-subagents/test/unit/builtin-agent-documentation.test.ts +7 -7
  386. package/dist/extensions/pi-subagents/test/unit/capability-ceiling-agent-allowlist.test.ts +19 -19
  387. package/dist/extensions/pi-subagents/test/unit/chain-append.test.ts +19 -19
  388. package/dist/extensions/pi-subagents/test/unit/chain-root-attachment.test.ts +9 -9
  389. package/dist/extensions/pi-subagents/test/unit/chain-serializer.test.ts +20 -20
  390. package/dist/extensions/pi-subagents/test/unit/child-transcript.test.ts +9 -9
  391. package/dist/extensions/pi-subagents/test/unit/compaction-resume.test.ts +35 -5
  392. package/dist/extensions/pi-subagents/test/unit/completion-dedupe.test.ts +2 -2
  393. package/dist/extensions/pi-subagents/test/unit/completion-guard.test.ts +52 -52
  394. package/dist/extensions/pi-subagents/test/unit/completion-replay.test.ts +187 -0
  395. package/dist/extensions/pi-subagents/test/unit/control-channel.test.ts +125 -71
  396. package/dist/extensions/pi-subagents/test/unit/control-notices.test.ts +18 -3
  397. package/dist/extensions/pi-subagents/test/unit/default-extensions.test.ts +12 -12
  398. package/dist/extensions/pi-subagents/test/unit/delegation-api.test.ts +17 -23
  399. package/dist/extensions/pi-subagents/test/unit/doctor.test.ts +1 -1
  400. package/dist/extensions/pi-subagents/test/unit/dynamic-fanout.test.ts +25 -25
  401. package/dist/extensions/pi-subagents/test/unit/extra-agent-dirs.test.ts +3 -3
  402. package/dist/extensions/pi-subagents/test/unit/file-coalescer.test.ts +15 -0
  403. package/dist/extensions/pi-subagents/test/unit/fleet-status.test.ts +62 -44
  404. package/dist/extensions/pi-subagents/test/unit/fleet.test.ts +329 -37
  405. package/dist/extensions/pi-subagents/test/unit/foreground-control.test.ts +4 -4
  406. package/dist/extensions/pi-subagents/test/unit/foreground-tool-call-compaction.test.ts +37 -0
  407. package/dist/extensions/pi-subagents/test/unit/herdr-inspector-bootstrap.test.ts +69 -0
  408. package/dist/extensions/pi-subagents/test/unit/herdr-inspector.test.ts +79 -2
  409. package/dist/extensions/pi-subagents/test/unit/herdr-status-bridge.test.ts +102 -49
  410. package/dist/extensions/pi-subagents/test/unit/index-child-registration.test.ts +98 -32
  411. package/dist/extensions/pi-subagents/test/unit/intercom-bridge.test.ts +5 -5
  412. package/dist/extensions/pi-subagents/test/unit/mission-goal-driver.test.ts +116 -0
  413. package/dist/extensions/pi-subagents/test/unit/mission-lifecycle.test.ts +55 -7
  414. package/dist/extensions/pi-subagents/test/unit/mission-store.test.ts +289 -13
  415. package/dist/extensions/pi-subagents/test/unit/model-fallback.test.ts +28 -1
  416. package/dist/extensions/pi-subagents/test/unit/model-scope-settings.test.ts +2 -2
  417. package/dist/extensions/pi-subagents/test/unit/model-scope.test.ts +11 -2
  418. package/dist/extensions/pi-subagents/test/unit/native-supervisor-channel.test.ts +84 -10
  419. package/dist/extensions/pi-subagents/test/unit/nested-control.test.ts +122 -8
  420. package/dist/extensions/pi-subagents/test/unit/nested-events.test.ts +8 -8
  421. package/dist/extensions/pi-subagents/test/unit/notify.test.ts +24 -24
  422. package/dist/extensions/pi-subagents/test/unit/package-manifest.test.ts +16 -2
  423. package/dist/extensions/pi-subagents/test/unit/parallel-handoff.test.ts +7 -7
  424. package/dist/extensions/pi-subagents/test/unit/parallel-utils.test.ts +10 -10
  425. package/dist/extensions/pi-subagents/test/unit/path-handling.test.ts +3 -3
  426. package/dist/extensions/pi-subagents/test/unit/path-resolution.test.ts +26 -17
  427. package/dist/extensions/pi-subagents/test/unit/pi-args-permission-system.test.ts +405 -0
  428. package/dist/extensions/pi-subagents/test/unit/pi-args.test.ts +357 -92
  429. package/dist/extensions/pi-subagents/test/unit/pi-coding-agent-dir.test.ts +22 -6
  430. package/dist/extensions/pi-subagents/test/unit/pi-spawn.test.ts +6 -6
  431. package/dist/extensions/pi-subagents/test/unit/preflight.test.ts +43 -43
  432. package/dist/extensions/pi-subagents/test/unit/proactive-skills.test.ts +13 -13
  433. package/dist/extensions/pi-subagents/test/unit/process-terminal.test.ts +4 -4
  434. package/dist/extensions/pi-subagents/test/unit/profiles.test.ts +19 -19
  435. package/dist/extensions/pi-subagents/test/unit/project-panes-public-api.test.ts +243 -0
  436. package/dist/extensions/pi-subagents/test/unit/prompt-template-bridge.test.ts +68 -168
  437. package/dist/extensions/pi-subagents/test/unit/prompt-workflows.test.ts +58 -15
  438. package/dist/extensions/pi-subagents/test/unit/public-execution.test.ts +40 -0
  439. package/dist/extensions/pi-subagents/test/unit/reads-resolution.test.ts +66 -0
  440. package/dist/extensions/pi-subagents/test/unit/render-helpers.test.ts +47 -28
  441. package/dist/extensions/pi-subagents/test/unit/result-intercom.test.ts +12 -12
  442. package/dist/extensions/pi-subagents/test/unit/retained-children.test.ts +57 -0
  443. package/dist/extensions/pi-subagents/test/unit/rpc.test.ts +107 -27
  444. package/dist/extensions/pi-subagents/test/unit/run-id-resolver.test.ts +1 -1
  445. package/dist/extensions/pi-subagents/test/unit/run-status.test.ts +56 -50
  446. package/dist/extensions/pi-subagents/test/unit/scheduled-runs.test.ts +69 -28
  447. package/dist/extensions/pi-subagents/test/unit/scheduled-store-root.test.ts +67 -0
  448. package/dist/extensions/pi-subagents/test/unit/schemas.test.ts +59 -44
  449. package/dist/extensions/pi-subagents/test/unit/scripted-workflow.test.ts +424 -49
  450. package/dist/extensions/pi-subagents/test/unit/skills-fallback.test.ts +23 -1
  451. package/dist/extensions/pi-subagents/test/unit/slash-bridge.test.ts +32 -5
  452. package/dist/extensions/pi-subagents/test/unit/stale-run-reconciler.test.ts +13 -13
  453. package/dist/extensions/pi-subagents/test/unit/steering-action.test.ts +120 -91
  454. package/dist/extensions/pi-subagents/test/unit/steering.test.ts +2 -2
  455. package/dist/extensions/pi-subagents/test/unit/subagent-action-recovery.test.ts +85 -0
  456. package/dist/extensions/pi-subagents/test/unit/subagent-control.test.ts +35 -35
  457. package/dist/extensions/pi-subagents/test/unit/subagent-guide.test.ts +24 -0
  458. package/dist/extensions/pi-subagents/test/unit/subagent-prompt-runtime.test.ts +312 -22
  459. package/dist/extensions/pi-subagents/test/unit/subagent-wait.test.ts +150 -15
  460. package/dist/extensions/pi-subagents/test/unit/task-intent.test.ts +26 -26
  461. package/dist/extensions/pi-subagents/test/unit/timeout-defaults.test.ts +73 -0
  462. package/dist/extensions/pi-subagents/test/unit/tool-description.test.ts +76 -25
  463. package/dist/extensions/pi-subagents/test/unit/turn-budget.test.ts +5 -5
  464. package/dist/extensions/pi-subagents/test/unit/wait-subscriptions.test.ts +55 -6
  465. package/dist/extensions/pi-subagents/test/unit/watchdog-child-status.test.ts +13 -13
  466. package/dist/extensions/pi-subagents/test/unit/watchdog-lsp-diagnostics.test.ts +1 -1
  467. package/dist/extensions/pi-subagents/test/unit/watchdog-runtime.test.ts +1 -1
  468. package/dist/extensions/pi-subagents/test/unit/watchdog-settings.test.ts +8 -8
  469. package/dist/extensions/pi-subagents/test/unit/widget-nested-render.test.ts +6 -6
  470. package/dist/extensions/pi-subagents/test/unit/workflow-chat-progress.test.ts +138 -11
  471. package/dist/extensions/pi-subagents/test/unit/workflow-graph.test.ts +8 -8
  472. package/dist/extensions/pi-subagents/test/unit/workflow-launch-params.test.ts +113 -0
  473. package/dist/extensions/pi-subagents/test/unit/worktree.test.ts +7 -7
  474. package/dist/extensions/pi-subagents/test/unit/writer-budget-guidance.test.ts +6 -6
  475. package/dist/extensions/workflow/extension.ts +21 -19
  476. package/dist/extensions/workflow/modes.ts +65 -0
  477. package/dist/skills/pi-subagents/SKILL.md +20 -15
  478. package/dist/skills/pi-subagents/references/constraints-and-recipes.md +77 -83
  479. package/dist/skills/pi-subagents/references/execution-controls.md +215 -106
  480. package/dist/skills/pi-subagents/references/management-authoring-rpc.md +29 -9
  481. package/dist/skills/pi-subagents/references/prompting-and-roles.md +58 -43
  482. package/docs/plans/workflow-autoloop-reference.md +192 -0
  483. package/docs/plans/workflow-subagent-consolidation-planb.md +374 -0
  484. package/docs/plans/workflow-subagent-scripted-merge.md +406 -0
  485. package/package.json +1 -1
  486. package/dist/extensions/workflow/adapter.ts +0 -949
  487. package/dist/extensions/workflow/modes/loop.ts +0 -74
  488. package/dist/extensions/workflow/modes/prototype.ts +0 -170
  489. package/dist/extensions/workflow/modes/quicktype.ts +0 -150
  490. package/dist/extensions/workflow/modes/task.ts +0 -105
  491. package/dist/extensions/workflow/run-state.ts +0 -124
  492. package/dist/extensions/workflow/state-machine.ts +0 -484
  493. package/dist/extensions/workflow/validators.ts +0 -42
@@ -1,4 +1,5 @@
1
1
  import assert from "node:assert/strict";
2
+ import { spawn } from "node:child_process";
2
3
  import * as fs from "node:fs";
3
4
  import * as os from "node:os";
4
5
  import * as path from "node:path";
@@ -12,6 +13,7 @@ import {
12
13
  resolveMissionStoreLocation,
13
14
  updateMission,
14
15
  } from "../../src/missions/store.ts";
16
+ import { createMissionWorkflowState, MISSION_STATE_MAX_BYTES, missionStatePath } from "../../src/missions/workflow-state.ts";
15
17
 
16
18
  function fixture() {
17
19
  const root = fs.mkdtempSync(path.join(os.tmpdir(), "pi-subagents-missions-"));
@@ -22,13 +24,22 @@ function fixture() {
22
24
  return { root, projectRoot, agentDir, location };
23
25
  }
24
26
 
27
+ async function waitForFile(filePath: string, timeoutMs = 10_000): Promise<void> {
28
+ const deadline = Date.now() + timeoutMs;
29
+ while (Date.now() < deadline) {
30
+ if (fs.existsSync(filePath)) return;
31
+ await new Promise((resolve) => setTimeout(resolve, 10));
32
+ }
33
+ throw new Error(`Timed out waiting for ${filePath} after ${timeoutMs} ms`);
34
+ }
35
+
25
36
  describe("mission store", () => {
26
37
  it("creates, reads, updates, lists, and globally indexes project missions", () => {
27
38
  const test = fixture();
28
39
  try {
29
40
  const created = createMission(test.location, {
30
41
  title: "Ship durable missions",
31
- goal: "Make delegated work resumable",
42
+ objective: "Make delegated work resumable",
32
43
  labels: ["phase-1"],
33
44
  });
34
45
  const updated = updateMission(test.location, created.id, {
@@ -43,7 +54,7 @@ describe("mission store", () => {
43
54
  addDecisions: [{ title: "Choose release window", options: ["now", "later"] }],
44
55
  });
45
56
 
46
- assert.equal(readMission(test.location, created.id).status, "active");
57
+ assert.equal(readMission(test.location, created.id).status, "needs_decision");
47
58
  assert.equal(updated.runs[0]?.runId, "run-1");
48
59
  assert.equal(readMission(test.location, created.id).runs[1]?.mode, "workflow");
49
60
  assert.equal(updated.decisions[0]?.status, "open");
@@ -62,15 +73,279 @@ describe("mission store", () => {
62
73
  }
63
74
  });
64
75
 
65
- it("loads older records that do not have receipts", () => {
76
+ it("persists workflow child attempts and projects their latest heartbeat", () => {
77
+ const test = fixture();
78
+ try {
79
+ const mission = createMission(test.location, { title: "Dispatch ledger", objective: "Track workflow children", status: "active" });
80
+ updateMission(test.location, mission.id, {
81
+ upsertWorkflowChildren: [{
82
+ workflowRunId: "workflow-1",
83
+ key: "review",
84
+ status: "running",
85
+ agent: "reviewer",
86
+ task: "Review the diff",
87
+ phase: "review",
88
+ sessionPath: "/tmp/review.jsonl",
89
+ heartbeat: { status: "running", phase: "review" },
90
+ }],
91
+ }, new Date("2026-08-11T10:00:00.000Z"));
92
+ const completed = updateMission(test.location, mission.id, {
93
+ upsertWorkflowChildren: [{
94
+ workflowRunId: "workflow-1",
95
+ key: "review",
96
+ status: "completed",
97
+ runId: "child-1",
98
+ completedAt: "2026-08-11T10:05:00.000Z",
99
+ artifactPaths: ["/tmp/review.md"],
100
+ heartbeat: { status: "completed", phase: "review" },
101
+ }],
102
+ }, new Date("2026-08-11T10:05:00.000Z"));
103
+
104
+ assert.equal(completed.workflowChildren.length, 1);
105
+ assert.deepEqual(completed.workflowChildren[0], {
106
+ workflowRunId: "workflow-1",
107
+ key: "review",
108
+ status: "completed",
109
+ startedAt: "2026-08-11T10:00:00.000Z",
110
+ updatedAt: "2026-08-11T10:05:00.000Z",
111
+ runId: "child-1",
112
+ agent: "reviewer",
113
+ task: "Review the diff",
114
+ phase: "review",
115
+ completedAt: "2026-08-11T10:05:00.000Z",
116
+ sessionPath: "/tmp/review.jsonl",
117
+ artifactPaths: ["/tmp/review.md"],
118
+ heartbeat: { status: "completed", phase: "review", updatedAt: "2026-08-11T10:05:00.000Z" },
119
+ });
120
+ const shown = handleMissionAction("mission.show", { missionId: mission.id }, { cwd: test.projectRoot, agentDir: test.agentDir });
121
+ assert.match(shown.content[0]?.type === "text" ? shown.content[0].text : "", /review \(child-1\): completed — reviewer \[review\]; updated .*; heartbeat completed\/review at/);
122
+ } finally {
123
+ fs.rmSync(test.root, { recursive: true, force: true });
124
+ }
125
+ });
126
+
127
+ it("gates a mission on open decisions and resolves them explicitly", () => {
128
+ const test = fixture();
129
+ try {
130
+ const ctx = { cwd: test.projectRoot, agentDir: test.agentDir };
131
+ const mission = createMission(test.location, { title: "Decision gate", objective: "Wait for owner", status: "active" });
132
+ const pending = handleMissionAction("mission.update", {
133
+ missionId: mission.id,
134
+ missionUpdate: { decisions: [{ title: "Choose release window", options: ["now", "later"], recommendation: "later" }] },
135
+ }, ctx);
136
+ const decisionId = pending.details?.mission?.decisions[0]?.id;
137
+ assert.ok(decisionId);
138
+ assert.equal(pending.details?.mission?.status, "needs_decision");
139
+ assert.match(handleMissionAction("mission.list", {}, ctx).content[0]?.type === "text" ? handleMissionAction("mission.list", {}, ctx).content[0].text : "", /decisions: 1 open, 0 resolved/);
140
+
141
+ const refreshed = updateMission(test.location, mission.id, {
142
+ status: "active",
143
+ addRuns: [{ runId: "run-1", mode: "single", status: "running" }],
144
+ });
145
+ assert.equal(refreshed.status, "needs_decision");
146
+
147
+ const resolved = handleMissionAction("mission.resolve-decision", { missionId: mission.id, id: decisionId, summary: "Release later" }, ctx);
148
+ assert.equal(resolved.details?.mission?.status, "active");
149
+ assert.equal(resolved.details?.mission?.decisions[0]?.status, "resolved");
150
+ assert.equal(resolved.details?.mission?.decisions[0]?.resolution, "Release later");
151
+ assert.match(resolved.content[0]?.type === "text" ? resolved.content[0].text : "", /resolved — Choose release window; resolution: Release later/);
152
+ assert.throws(() => handleMissionAction("mission.resolve-decision", { missionId: mission.id, id: decisionId, summary: "Again" }, ctx), /already resolved/);
153
+ } finally {
154
+ fs.rmSync(test.root, { recursive: true, force: true });
155
+ }
156
+ });
157
+
158
+ it("keeps planned and waiting missions in their lifecycle state while decisions are resolved", () => {
159
+ const test = fixture();
160
+ try {
161
+ for (const status of ["planned", "waiting"] as const) {
162
+ const mission = createMission(test.location, { title: `${status} decision`, objective: "Keep state", status });
163
+ const pending = updateMission(test.location, mission.id, { addDecisions: [{ title: "Choose next step" }] });
164
+ const decisionId = pending.decisions[0]?.id;
165
+ assert.ok(decisionId);
166
+ assert.equal(pending.status, status);
167
+
168
+ const resolved = updateMission(test.location, mission.id, { resolveDecision: { id: decisionId, resolution: "Later" } });
169
+ assert.equal(resolved.status, status);
170
+ assert.equal(resolved.decisions[0]?.status, "resolved");
171
+ }
172
+ } finally {
173
+ fs.rmSync(test.root, { recursive: true, force: true });
174
+ }
175
+ });
176
+
177
+ it("persists bounded workflow state and reads its file once per workflow", () => {
178
+ const test = fixture();
179
+ try {
180
+ const mission = createMission(test.location, { title: "Stateful mission", objective: "Keep workflow state" });
181
+ const state = createMissionWorkflowState(test.location, mission.id);
182
+ assert.equal(state.get("missing"), undefined);
183
+ fs.mkdirSync(path.dirname(state.path), { recursive: true });
184
+ fs.writeFileSync(state.path, JSON.stringify({ external: true }), "utf-8");
185
+ assert.equal(state.get("external"), undefined);
186
+
187
+ const nextWorkflow = createMissionWorkflowState(test.location, mission.id);
188
+ assert.equal(nextWorkflow.get("external"), true);
189
+ nextWorkflow.set("review.stage", { count: 2 });
190
+ const concurrentWorkflow = createMissionWorkflowState(test.location, mission.id);
191
+ assert.deepEqual(concurrentWorkflow.get("review.stage"), { count: 2 });
192
+ nextWorkflow.set("approved", false);
193
+ concurrentWorkflow.set("reviewer", "ready");
194
+ assert.deepEqual(JSON.parse(fs.readFileSync(missionStatePath(test.location, mission.id), "utf-8")), {
195
+ external: true,
196
+ "review.stage": { count: 2 },
197
+ approved: false,
198
+ reviewer: "ready",
199
+ });
200
+ assert.throws(() => nextWorkflow.set("bad key", true), /state key must be 1-128 characters/);
201
+ assert.throws(() => nextWorkflow.set("too-large", "x".repeat(MISSION_STATE_MAX_BYTES)), /256 KiB limit/);
202
+ assert.equal(nextWorkflow.get("too-large"), undefined);
203
+ } finally {
204
+ fs.rmSync(test.root, { recursive: true, force: true });
205
+ }
206
+ });
207
+
208
+ it("serializes workflow state writes behind the state-file lock", async () => {
209
+ const test = fixture();
210
+ try {
211
+ const mission = createMission(test.location, { title: "Locked state", objective: "Serialize state writes" });
212
+ const statePath = missionStatePath(test.location, mission.id);
213
+ fs.mkdirSync(path.dirname(statePath), { recursive: true });
214
+ fs.writeFileSync(statePath, JSON.stringify({ external: true }, null, 2), "utf-8");
215
+ const lockPath = `${statePath}.lock`;
216
+ const readyPath = path.join(test.root, "writer-ready");
217
+ fs.mkdirSync(lockPath);
218
+ const script = `
219
+ import * as fs from "node:fs";
220
+ import { createMissionWorkflowState } from "./src/missions/workflow-state.ts";
221
+ const location = JSON.parse(process.env.MISSION_LOCATION);
222
+ fs.writeFileSync(process.env.READY_FILE, "ready", "utf-8");
223
+ createMissionWorkflowState(location, process.env.MISSION_ID).set("reviewer", "ready");
224
+ `;
225
+ const child = spawn(process.execPath, ["--experimental-strip-types", "--input-type=module", "--eval", script], {
226
+ cwd: process.cwd(),
227
+ env: { ...process.env, MISSION_LOCATION: JSON.stringify(test.location), MISSION_ID: mission.id, READY_FILE: readyPath },
228
+ stdio: ["ignore", "pipe", "pipe"],
229
+ });
230
+ let stderr = "";
231
+ child.stderr?.on("data", (chunk) => { stderr += String(chunk); });
232
+ await waitForFile(readyPath);
233
+ fs.writeFileSync(statePath, JSON.stringify({ external: true, approved: false }, null, 2), "utf-8");
234
+ fs.rmSync(lockPath, { recursive: true, force: true });
235
+ const exit = await Promise.race([
236
+ new Promise<{ code: number | null; signal: NodeJS.Signals | null }>((resolve) => child.on("exit", (code, signal) => resolve({ code, signal }))),
237
+ new Promise<{ code: "timeout"; signal: null }>((resolve) => setTimeout(() => { child.kill(); resolve({ code: "timeout", signal: null }); }, 5_000)),
238
+ ]);
239
+ assert.deepEqual(exit, { code: 0, signal: null }, stderr);
240
+ assert.deepEqual(JSON.parse(fs.readFileSync(statePath, "utf-8")), {
241
+ external: true,
242
+ approved: false,
243
+ reviewer: "ready",
244
+ });
245
+ } finally {
246
+ fs.rmSync(test.root, { recursive: true, force: true });
247
+ }
248
+ });
249
+
250
+ it("recovers abandoned workflow state locks", () => {
66
251
  const test = fixture();
67
252
  try {
68
- const created = createMission(test.location, { title: "Older record", goal: "Stay readable" });
253
+ const mission = createMission(test.location, { title: "Stale lock", objective: "Recover state writes" });
254
+ const state = createMissionWorkflowState(test.location, mission.id);
255
+ const lockPath = `${state.path}.lock`;
256
+ fs.mkdirSync(lockPath, { recursive: true });
257
+ const staleAt = new Date(Date.now() - 120_000);
258
+ fs.utimesSync(lockPath, staleAt, staleAt);
259
+
260
+ state.set("reviewer", "ready");
261
+
262
+ assert.equal(fs.existsSync(lockPath), false);
263
+ assert.deepEqual(JSON.parse(fs.readFileSync(state.path, "utf-8")), { reviewer: "ready" });
264
+ } finally {
265
+ fs.rmSync(test.root, { recursive: true, force: true });
266
+ }
267
+ });
268
+
269
+ it("recovers abandoned workflow state locks even when the owner pid was reused", () => {
270
+ const test = fixture();
271
+ try {
272
+ const mission = createMission(test.location, { title: "Reused pid", objective: "Recover by lock age" });
273
+ const state = createMissionWorkflowState(test.location, mission.id);
274
+ const lockPath = `${state.path}.lock`;
275
+ fs.mkdirSync(lockPath, { recursive: true });
276
+ fs.writeFileSync(path.join(lockPath, "owner.json"), JSON.stringify({ pid: process.pid, token: "abandoned", createdAt: Date.now(), processKey: "stale-process" }), "utf-8");
277
+
278
+ state.set("reviewer", "ready");
279
+
280
+ assert.equal(fs.existsSync(lockPath), false);
281
+ assert.deepEqual(JSON.parse(fs.readFileSync(state.path, "utf-8")), { reviewer: "ready" });
282
+ } finally {
283
+ fs.rmSync(test.root, { recursive: true, force: true });
284
+ }
285
+ });
286
+
287
+ it("serializes competing abandoned-lock recovery", async () => {
288
+ const test = fixture();
289
+ try {
290
+ const mission = createMission(test.location, { title: "Competing stale lock", objective: "Recover once" });
291
+ const statePath = missionStatePath(test.location, mission.id);
292
+ fs.mkdirSync(path.dirname(statePath), { recursive: true });
293
+ fs.writeFileSync(statePath, JSON.stringify({ external: true }, null, 2), "utf-8");
294
+ const lockPath = `${statePath}.lock`;
295
+ fs.mkdirSync(lockPath, { recursive: true });
296
+ const staleAt = new Date(Date.now() - 120_000);
297
+ fs.utimesSync(lockPath, staleAt, staleAt);
298
+ const script = `
299
+ import { createMissionWorkflowState } from "./src/missions/workflow-state.ts";
300
+ const location = JSON.parse(process.env.MISSION_LOCATION);
301
+ createMissionWorkflowState(location, process.env.MISSION_ID).set(process.env.STATE_KEY, process.env.STATE_VALUE);
302
+ `;
303
+ const spawnWriter = (key: string, value: string) => {
304
+ let stderr = "";
305
+ const child = spawn(process.execPath, ["--experimental-strip-types", "--input-type=module", "--eval", script], {
306
+ cwd: process.cwd(),
307
+ env: { ...process.env, MISSION_LOCATION: JSON.stringify(test.location), MISSION_ID: mission.id, STATE_KEY: key, STATE_VALUE: value },
308
+ stdio: ["ignore", "pipe", "pipe"],
309
+ });
310
+ child.stderr?.on("data", (chunk) => { stderr += String(chunk); });
311
+ return new Promise<void>((resolve, reject) => {
312
+ const timeout = setTimeout(() => { child.kill(); reject(new Error(`${key} writer timed out`)); }, 5_000);
313
+ child.on("exit", (code, signal) => {
314
+ clearTimeout(timeout);
315
+ if (code === 0 && signal === null) resolve();
316
+ else reject(new Error(`${key} writer failed with code ${code} signal ${signal}: ${stderr}`));
317
+ });
318
+ });
319
+ };
320
+
321
+ await Promise.all([spawnWriter("reviewer", "ready"), spawnWriter("approved", "false")]);
322
+
323
+ assert.deepEqual(JSON.parse(fs.readFileSync(statePath, "utf-8")), {
324
+ external: true,
325
+ reviewer: "ready",
326
+ approved: "false",
327
+ });
328
+ } finally {
329
+ fs.rmSync(test.root, { recursive: true, force: true });
330
+ }
331
+ });
332
+
333
+ it("loads older records that do not have receipts or objective", () => {
334
+ const test = fixture();
335
+ try {
336
+ const created = createMission(test.location, { title: "Older record", objective: "Stay readable" });
69
337
  const recordPath = path.join(test.location.missionDir, `${created.id}.json`);
70
338
  const raw = JSON.parse(fs.readFileSync(recordPath, "utf-8")) as Record<string, unknown>;
71
339
  delete raw.receipts;
340
+ delete raw.objective;
341
+ raw.goal = "Stay readable";
72
342
  fs.writeFileSync(recordPath, JSON.stringify(raw), "utf-8");
73
- assert.deepEqual(readMission(test.location, created.id).receipts, []);
343
+
344
+ const mission = readMission(test.location, created.id);
345
+ assert.equal(mission.objective, "Stay readable");
346
+ assert.equal(mission.goal, undefined);
347
+ assert.deepEqual(mission.receipts, []);
348
+ assert.deepEqual(mission.workflowChildren, []);
74
349
  } finally {
75
350
  fs.rmSync(test.root, { recursive: true, force: true });
76
351
  }
@@ -79,8 +354,8 @@ describe("mission store", () => {
79
354
  it("skips corrupt records, removes missing pointers, and preserves parse-error pointers", () => {
80
355
  const test = fixture();
81
356
  try {
82
- const missing = createMission(test.location, { title: "Missing record", goal: "Heal its pointer" });
83
- const corrupt = createMission(test.location, { title: "Corrupt record", goal: "Keep evidence" });
357
+ const missing = createMission(test.location, { title: "Missing record", objective: "Heal its pointer" });
358
+ const corrupt = createMission(test.location, { title: "Corrupt record", objective: "Keep evidence" });
84
359
  fs.writeFileSync(path.join(test.location.missionDir, "broken.json"), "{not json", "utf-8");
85
360
  assert.equal(listMissions(test.location).warnings.length, 1);
86
361
 
@@ -100,10 +375,10 @@ describe("mission store", () => {
100
375
  const test = fixture();
101
376
  const location = { ...test.location, retainTerminal: 1 };
102
377
  try {
103
- const oldest = createMission(location, { title: "Old terminal", goal: "Prune me" }, new Date("2026-01-01T00:00:00Z"));
104
- const newest = createMission(location, { title: "New terminal", goal: "Keep me" }, new Date("2026-01-02T00:00:00Z"));
105
- const active = createMission(location, { title: "Active", goal: "Never prune", status: "active" }, new Date("2026-01-03T00:00:00Z"));
106
- const planned = createMission(location, { title: "Planned", goal: "Never prune", status: "planned" }, new Date("2026-01-04T00:00:00Z"));
378
+ const oldest = createMission(location, { title: "Old terminal", objective: "Prune me" }, new Date("2026-01-01T00:00:00Z"));
379
+ const newest = createMission(location, { title: "New terminal", objective: "Keep me" }, new Date("2026-01-02T00:00:00Z"));
380
+ const active = createMission(location, { title: "Active", objective: "Never prune", status: "active" }, new Date("2026-01-03T00:00:00Z"));
381
+ const planned = createMission(location, { title: "Planned", objective: "Never prune", status: "planned" }, new Date("2026-01-04T00:00:00Z"));
107
382
  updateMission(location, oldest.id, { status: "completed" }, new Date("2026-01-05T00:00:00Z"));
108
383
  updateMission(location, newest.id, { status: "failed" }, new Date("2026-01-06T00:00:00Z"));
109
384
 
@@ -121,7 +396,7 @@ describe("mission store", () => {
121
396
  const test = fixture();
122
397
  try {
123
398
  const ctx = { cwd: test.projectRoot, agentDir: test.agentDir, currentSessionId: "session-1" };
124
- const created = handleMissionAction("mission.create", { mission: { title: "Unreadable status", goal: "Keep mission readable" } }, ctx);
399
+ const created = handleMissionAction("mission.create", { mission: { title: "Unreadable status", objective: "Keep mission readable" } }, ctx);
125
400
  const missionId = created.details?.missionId;
126
401
  assert.ok(missionId);
127
402
  const asyncDir = path.join(test.root, "async-run");
@@ -143,7 +418,7 @@ describe("mission store", () => {
143
418
  const test = fixture();
144
419
  try {
145
420
  const ctx = { cwd: test.projectRoot, agentDir: test.agentDir, currentSessionId: "session-1" };
146
- const created = handleMissionAction("mission.create", { mission: { title: "Action mission", goal: "Exercise actions" } }, ctx);
421
+ const created = handleMissionAction("mission.create", { mission: { title: "Action mission", objective: "Exercise actions" } }, ctx);
147
422
  const missionId = created.details?.missionId;
148
423
  assert.ok(missionId);
149
424
  const asyncDir = path.join(test.root, "async-run");
@@ -153,6 +428,7 @@ describe("mission store", () => {
153
428
  fs.writeFileSync(path.join(asyncDir, "status.json"), JSON.stringify({ state: "complete" }), "utf-8");
154
429
  const shown = handleMissionAction("mission.show", { missionId }, ctx);
155
430
  assert.equal(shown.details?.mission?.status, "completed");
431
+ assert.match(shown.content[0]?.type === "text" ? shown.content[0].text : "", new RegExp(`State: .*${missionId}[/\\\\]state\\.json`));
156
432
  assert.equal(shown.details?.mission?.runs[0]?.status, "complete");
157
433
  const receipt = handleMissionAction("mission.update", {
158
434
  missionId,
@@ -117,7 +117,7 @@ describe("resolveSubagentModelOverride (cross-session inherit, issue #266)", ()
117
117
  );
118
118
  });
119
119
 
120
- it("inherits the parent session model when the agent config sets model: false (explorer)", () => {
120
+ it("inherits the parent session model when the agent config sets model: false (delegate)", () => {
121
121
  assert.equal(
122
122
  resolveSubagentModelOverride(false, parentModel, availableModels),
123
123
  "deepseek/deepseek-v4-flash",
@@ -335,6 +335,15 @@ describe("resolveSubagentModelOverride scope enforcement", () => {
335
335
  assert.equal(warnings.length, 1);
336
336
  });
337
337
 
338
+ it("throws for an inherited parent-session model in strict mode", () => {
339
+ assert.throws(
340
+ () => resolveSubagentModelOverride(undefined, parentModel, availableModels, undefined, {
341
+ scope: { ...scope, strict: true },
342
+ }),
343
+ /deepseek\/deepseek-v4.*outside the configured subagent model scope/,
344
+ );
345
+ });
346
+
338
347
  it("passes through an in-scope explicit model without warning or error", () => {
339
348
  const warnings: string[] = [];
340
349
  const resolved = resolveSubagentModelOverride("gpt-5-mini", parentModel, availableModels, undefined, {
@@ -379,4 +388,22 @@ describe("resolveSubagentModelOverride scope enforcement", () => {
379
388
  assert.equal(warnings.length, 1);
380
389
  assert.match(warnings[0]!, /deepseek\/deepseek-v4/);
381
390
  });
391
+
392
+ it("throws for an out-of-scope primary candidate in strict mode", () => {
393
+ assert.throws(
394
+ () => buildModelCandidates("deepseek/deepseek-v4", undefined, availableModels, undefined, {
395
+ scope: { ...scope, strict: true },
396
+ }),
397
+ /deepseek\/deepseek-v4.*outside the configured subagent model scope/,
398
+ );
399
+ });
400
+
401
+ it("throws instead of pruning an out-of-scope fallback in strict mode", () => {
402
+ assert.throws(
403
+ () => buildModelCandidates("gpt-5-mini", ["deepseek/deepseek-v4"], availableModels, undefined, {
404
+ scope: { ...scope, strict: true },
405
+ }),
406
+ /deepseek\/deepseek-v4.*outside the configured subagent model scope/,
407
+ );
408
+ });
382
409
  });
@@ -42,10 +42,10 @@ describe("subagents.modelScope discovery", () => {
42
42
 
43
43
  it("exposes a user modelScope from discoverAgents", () => {
44
44
  writeJson(path.join(tempHome, ".selesai", "agent", "settings.json"), {
45
- subagents: { modelScope: { enforce: true, allow: ["anthropic/*", "openai/gpt-5-*"] } },
45
+ subagents: { modelScope: { enforce: true, strict: true, allow: ["anthropic/*", "openai/gpt-5-*"] } },
46
46
  });
47
47
  const result = discoverAgents(tempProject, "both");
48
- assert.deepEqual(result.modelScope, { enforce: true, allow: ["anthropic/*", "openai/gpt-5-*"] });
48
+ assert.deepEqual(result.modelScope, { enforce: true, strict: true, allow: ["anthropic/*", "openai/gpt-5-*"] });
49
49
  });
50
50
 
51
51
  it("returns undefined when no modelScope is configured", () => {
@@ -81,6 +81,11 @@ describe("checkModelScope", () => {
81
81
  assert.equal(violation?.severity, "warn");
82
82
  });
83
83
 
84
+ it("returns an error violation for an inherited model in strict mode", () => {
85
+ const violation = checkModelScope("deepseek/deepseek-v4", { ...scope, strict: true }, "inherited");
86
+ assert.equal(violation?.severity, "error");
87
+ });
88
+
84
89
  it("defaults to inherited (warn) severity when source is omitted-ish via inherited", () => {
85
90
  // Caller passes "inherited" for frontmatter/parent-inherited models.
86
91
  assert.equal(checkModelScope("meta/llama-4", scope, "inherited")?.severity, "warn");
@@ -105,8 +110,8 @@ describe("parseModelScopeConfig", () => {
105
110
 
106
111
  it("parses a well-formed config", () => {
107
112
  assert.deepEqual(
108
- parseModelScopeConfig({ enforce: true, allow: ["anthropic/*", "openai/gpt-5-*"] }, meta),
109
- { enforce: true, allow: ["anthropic/*", "openai/gpt-5-*"] },
113
+ parseModelScopeConfig({ enforce: true, strict: true, allow: ["anthropic/*", "openai/gpt-5-*"] }, meta),
114
+ { enforce: true, strict: true, allow: ["anthropic/*", "openai/gpt-5-*"] },
110
115
  );
111
116
  });
112
117
 
@@ -130,6 +135,10 @@ describe("parseModelScopeConfig", () => {
130
135
  assert.throws(() => parseModelScopeConfig({ enforce: "yes" }, meta), /invalid 'modelScope.enforce'/);
131
136
  });
132
137
 
138
+ it("rejects a non-boolean strict value", () => {
139
+ assert.throws(() => parseModelScopeConfig({ strict: "yes" }, meta), /invalid 'modelScope.strict'/);
140
+ });
141
+
133
142
  it("rejects a non-array allow", () => {
134
143
  assert.throws(() => parseModelScopeConfig({ allow: "anthropic/*" }, meta), /invalid 'modelScope.allow'/);
135
144
  });
@@ -49,7 +49,7 @@ function makeState(sessionId: string | null, ctx: unknown): SubagentState {
49
49
  }
50
50
 
51
51
  function writeRequest(input: { sessionId: string; runId: string; agent?: string; index?: number; message?: string; createdAt?: number; expiresAt?: number }): string {
52
- const agent = input.agent ?? "builder";
52
+ const agent = input.agent ?? "worker";
53
53
  const index = input.index ?? 0;
54
54
  const channelDir = resolveSupervisorChannelDir(input.runId, agent, index);
55
55
  createdChannels.push(channelDir);
@@ -72,16 +72,16 @@ function writeRequest(input: { sessionId: string; runId: string; agent?: string;
72
72
  return requestId;
73
73
  }
74
74
 
75
- function requestFile(runId: string, requestId: string, agent = "builder", index = 0): string {
75
+ function requestFile(runId: string, requestId: string, agent = "worker", index = 0): string {
76
76
  return path.join(resolveSupervisorChannelDir(runId, agent, index), "requests", `${requestId}.json`);
77
77
  }
78
78
 
79
- function replyFile(runId: string, requestId: string, agent = "builder", index = 0): string {
79
+ function replyFile(runId: string, requestId: string, agent = "worker", index = 0): string {
80
80
  return path.join(resolveSupervisorChannelDir(runId, agent, index), "replies", `${requestId}.json`);
81
81
  }
82
82
 
83
83
  function makeEmptyChannel(runId: string): string {
84
- const channelDir = resolveSupervisorChannelDir(runId, "builder", 0);
84
+ const channelDir = resolveSupervisorChannelDir(runId, "worker", 0);
85
85
  createdChannels.push(channelDir);
86
86
  ensureSupervisorChannelDir(channelDir);
87
87
  return channelDir;
@@ -94,6 +94,14 @@ function ageChannel(channelDir: string, ageMs: number): void {
94
94
  }
95
95
  }
96
96
 
97
+ async function waitForCondition(condition: () => boolean, description: string): Promise<void> {
98
+ const deadline = Date.now() + 1000;
99
+ while (!condition()) {
100
+ if (Date.now() > deadline) assert.fail(`Timed out waiting for ${description}`);
101
+ await new Promise((resolve) => setTimeout(resolve, 10));
102
+ }
103
+ }
104
+
97
105
  function restoreEnv(): void {
98
106
  for (const [key, value] of Object.entries(savedEnv)) {
99
107
  if (value === undefined) delete process.env[key];
@@ -149,6 +157,72 @@ describe("native supervisor channel", () => {
149
157
  assert.equal(sent.some(({ message }) => message.details?.id === otherId), false);
150
158
  });
151
159
 
160
+ it("uses polling instead of native watchers on Windows", () => {
161
+ const currentSessionId = `session-${randomUUID()}`;
162
+ const requestId = writeRequest({ sessionId: currentSessionId, runId: `run-${randomUUID()}` });
163
+ const sent: Array<{ details?: { id?: string } }> = [];
164
+ const ctx = {
165
+ cwd: process.cwd(),
166
+ hasUI: false,
167
+ sessionManager: {
168
+ getSessionId: () => currentSessionId,
169
+ getSessionFile: () => null,
170
+ getEntries: () => [],
171
+ },
172
+ };
173
+ const pi = {
174
+ getAllTools: () => [],
175
+ registerTool: () => {},
176
+ sendMessage: (message: { details?: { id?: string } }) => { sent.push(message); },
177
+ getSessionName: () => "shared-name",
178
+ };
179
+ let watchCalls = 0;
180
+ const channel = createNativeSupervisorChannel(pi as never, makeState(currentSessionId, ctx), {
181
+ platform: "win32",
182
+ watch: (() => {
183
+ watchCalls += 1;
184
+ throw new Error("Windows supervisor channel must not call fs.watch.");
185
+ }) as never,
186
+ });
187
+
188
+ channel.start();
189
+ channel.dispose();
190
+
191
+ assert.equal(watchCalls, 0);
192
+ assert.deepEqual(sent.map((message) => message.details?.id), [requestId]);
193
+ });
194
+
195
+ it("delivers requests written under an existing request directory by watch event", async () => {
196
+ const currentSessionId = `session-${randomUUID()}`;
197
+ const runId = `run-${randomUUID()}`;
198
+ makeEmptyChannel(runId);
199
+ const sent: Array<{ details?: { id?: string } }> = [];
200
+ const ctx = {
201
+ cwd: process.cwd(),
202
+ hasUI: false,
203
+ sessionManager: {
204
+ getSessionId: () => currentSessionId,
205
+ getSessionFile: () => null,
206
+ getEntries: () => [],
207
+ },
208
+ };
209
+ const pi = {
210
+ getAllTools: () => [],
211
+ registerTool: () => {},
212
+ sendMessage: (message: { details?: { id?: string } }) => { sent.push(message); },
213
+ getSessionName: () => "shared-name",
214
+ };
215
+ const channel = createNativeSupervisorChannel(pi as never, makeState(currentSessionId, ctx));
216
+
217
+ try {
218
+ channel.start();
219
+ const requestId = writeRequest({ sessionId: currentSessionId, runId });
220
+ await waitForCondition(() => sent.some((message) => message.details?.id === requestId), "supervisor request watch delivery");
221
+ } finally {
222
+ channel.dispose();
223
+ }
224
+ });
225
+
152
226
  it("prunes stale empty supervisor channel directories before polling", () => {
153
227
  const currentSessionId = `session-${randomUUID()}`;
154
228
  const staleEmptyChannel = makeEmptyChannel(`run-${randomUUID()}`);
@@ -211,7 +285,7 @@ describe("native supervisor channel", () => {
211
285
  it("emits foreground detach only after displaying a pending supervisor request", () => {
212
286
  const currentSessionId = `session-${randomUUID()}`;
213
287
  const runId = `run-${randomUUID()}`;
214
- const requestId = writeRequest({ sessionId: currentSessionId, runId, agent: "builder", index: 2 });
288
+ const requestId = writeRequest({ sessionId: currentSessionId, runId, agent: "worker", index: 2 });
215
289
  const log: string[] = [];
216
290
  const emitted: Array<{ channel: string; payload: { requestId?: string; runId?: string; agent?: string; childIndex?: number } }> = [];
217
291
  const ctx = {
@@ -242,7 +316,7 @@ describe("native supervisor channel", () => {
242
316
  assert.deepEqual(log, ["send", "emit"]);
243
317
  assert.deepEqual(emitted, [{
244
318
  channel: INTERCOM_DETACH_REQUEST_EVENT,
245
- payload: { requestId, runId, agent: "builder", childIndex: 2 },
319
+ payload: { requestId, runId, agent: "worker", childIndex: 2 },
246
320
  }]);
247
321
  assert.equal(channel.pending.has(requestId), true);
248
322
  } finally {
@@ -271,7 +345,7 @@ describe("native supervisor channel", () => {
271
345
  cwd: process.cwd(),
272
346
  sessionId: currentSessionId,
273
347
  updatedAt: 1,
274
- children: [{ agent: "builder", index: 0, status: "detached", updatedAt: 1 }],
348
+ children: [{ agent: "worker", index: 0, status: "detached", updatedAt: 1 }],
275
349
  }]]);
276
350
  const pi = {
277
351
  getAllTools: () => [...registeredTools.keys()].map((name) => ({ name })),
@@ -398,7 +472,7 @@ describe("native supervisor channel", () => {
398
472
  mode: "single",
399
473
  cwd: process.cwd(),
400
474
  updatedAt: Date.now(),
401
- children: [{ agent: "builder", index: 0, status: "completed", updatedAt: Date.now() }],
475
+ children: [{ agent: "worker", index: 0, status: "completed", updatedAt: Date.now() }],
402
476
  }]]);
403
477
  const pi = {
404
478
  getAllTools: () => [],
@@ -464,13 +538,13 @@ describe("native supervisor channel", () => {
464
538
 
465
539
  it("removes the request file when a child supervisor ask is cancelled", async () => {
466
540
  const runId = `run-${randomUUID()}`;
467
- const channelDir = resolveSupervisorChannelDir(runId, "builder", 0);
541
+ const channelDir = resolveSupervisorChannelDir(runId, "worker", 0);
468
542
  createdChannels.push(channelDir);
469
543
  process.env[SUBAGENT_ORCHESTRATOR_TARGET_ENV] = "shared-name";
470
544
  process.env[SUBAGENT_ORCHESTRATOR_SESSION_ID_ENV] = "session-parent";
471
545
  process.env[SUBAGENT_SUPERVISOR_CHANNEL_DIR_ENV] = channelDir;
472
546
  process.env[SUBAGENT_RUN_ID_ENV] = runId;
473
- process.env[SUBAGENT_CHILD_AGENT_ENV] = "builder";
547
+ process.env[SUBAGENT_CHILD_AGENT_ENV] = "worker";
474
548
  process.env[SUBAGENT_CHILD_INDEX_ENV] = "0";
475
549
  const registeredTools = new Map<string, { execute: (_id: string, params: { reason: string; message?: string }, signal?: AbortSignal) => Promise<unknown> | unknown }>();
476
550
  const pi = {