@selesai/code 0.13.15 → 0.13.18

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (473) hide show
  1. package/CHANGELOG.md +37 -0
  2. package/README.md +2 -14
  3. package/dist/bun/cli.d.ts +3 -1
  4. package/dist/bun/cli.js +3 -9
  5. package/dist/bun/{register-bedrock.js → runtime-setup.js} +5 -0
  6. package/dist/bun/sandbox-env-setup.d.ts +1 -0
  7. package/dist/bun/sandbox-env-setup.js +3 -0
  8. package/dist/cli/auth-command.d.ts +23 -0
  9. package/dist/cli/auth-command.js +102 -0
  10. package/dist/cli/config-selector.js +2 -1
  11. package/dist/cli/setup.d.ts +1 -0
  12. package/dist/cli/setup.js +11 -0
  13. package/dist/cli.js +2 -14
  14. package/dist/config.d.ts +3 -2
  15. package/dist/config.js +9 -4
  16. package/dist/core/agent-session-runtime.js +15 -7
  17. package/dist/core/agent-session.d.ts +2 -6
  18. package/dist/core/agent-session.js +15 -4
  19. package/dist/core/compaction/branch-summarization.d.ts +1 -1
  20. package/dist/core/compaction/branch-summarization.js +2 -1
  21. package/dist/core/extensions/loader.js +3 -0
  22. package/dist/core/extensions/types.d.ts +16 -2
  23. package/dist/core/http-dispatcher.js +2 -0
  24. package/dist/core/keybindings.d.ts +5 -0
  25. package/dist/core/keybindings.js +4 -0
  26. package/dist/core/messages.d.ts +1 -1
  27. package/dist/core/model-config.d.ts +15 -0
  28. package/dist/core/model-config.js +3 -0
  29. package/dist/core/model-runtime.d.ts +1 -0
  30. package/dist/core/model-runtime.js +5 -2
  31. package/dist/core/provider-composer.js +8 -2
  32. package/dist/core/session-export.d.ts +3 -0
  33. package/dist/core/session-export.js +31 -0
  34. package/dist/core/session-manager.d.ts +3 -2
  35. package/dist/core/session-manager.js +40 -13
  36. package/dist/core/skills.d.ts +1 -1
  37. package/dist/core/skills.js +4 -2
  38. package/dist/core/system-prompt.js +10 -10
  39. package/dist/core/tools/bash.js +3 -117
  40. package/dist/core/tools/edit.d.ts +1 -12
  41. package/dist/core/tools/edit.js +5 -163
  42. package/dist/core/tools/find.js +4 -55
  43. package/dist/core/tools/grep.js +4 -60
  44. package/dist/core/tools/ls.js +4 -49
  45. package/dist/core/tools/read.d.ts +4 -0
  46. package/dist/core/tools/read.js +10 -122
  47. package/dist/core/tools/renderers/bash.d.ts +11 -0
  48. package/dist/core/tools/renderers/bash.js +129 -0
  49. package/dist/core/tools/renderers/edit.d.ts +22 -0
  50. package/dist/core/tools/renderers/edit.js +166 -0
  51. package/dist/core/tools/renderers/find.d.ts +9 -0
  52. package/dist/core/tools/renderers/find.js +63 -0
  53. package/dist/core/tools/renderers/grep.d.ts +9 -0
  54. package/dist/core/tools/renderers/grep.js +68 -0
  55. package/dist/core/tools/renderers/index.d.ts +27 -0
  56. package/dist/core/tools/renderers/index.js +46 -0
  57. package/dist/core/tools/renderers/ls.d.ts +9 -0
  58. package/dist/core/tools/renderers/ls.js +57 -0
  59. package/dist/core/tools/renderers/read.d.ts +10 -0
  60. package/dist/core/tools/renderers/read.js +128 -0
  61. package/dist/core/tools/renderers/write.d.ts +9 -0
  62. package/dist/core/tools/renderers/write.js +152 -0
  63. package/dist/core/tools/write.js +5 -146
  64. package/dist/extensions/capability-gateway/index.ts +12 -1
  65. package/dist/extensions/capability-gateway/integration.test.ts +23 -0
  66. package/dist/extensions/pi-hermes-memory/CHANGELOG.md +18 -0
  67. package/dist/extensions/pi-hermes-memory/README.md +16 -12
  68. package/dist/extensions/pi-hermes-memory/docs/ROADMAP.md +1 -1
  69. package/dist/extensions/pi-hermes-memory/package-lock.json +587 -62
  70. package/dist/extensions/pi-hermes-memory/package.json +4 -4
  71. package/dist/extensions/pi-hermes-memory/src/config.ts +32 -0
  72. package/dist/extensions/pi-hermes-memory/src/constants.ts +12 -2
  73. package/dist/extensions/pi-hermes-memory/src/handlers/background-review.ts +109 -51
  74. package/dist/extensions/pi-hermes-memory/src/handlers/index-sessions.ts +9 -3
  75. package/dist/extensions/pi-hermes-memory/src/handlers/review-memory-ops.ts +257 -98
  76. package/dist/extensions/pi-hermes-memory/src/handlers/session-backfill.ts +9 -2
  77. package/dist/extensions/pi-hermes-memory/src/handlers/sync-markdown-memories.ts +5 -0
  78. package/dist/extensions/pi-hermes-memory/src/index.ts +22 -2
  79. package/dist/extensions/pi-hermes-memory/src/paths.ts +1 -1
  80. package/dist/extensions/pi-hermes-memory/src/store/db.ts +6 -0
  81. package/dist/extensions/pi-hermes-memory/src/store/fts-query.ts +58 -1
  82. package/dist/extensions/pi-hermes-memory/src/store/memory-store.ts +60 -8
  83. package/dist/extensions/pi-hermes-memory/src/store/session-indexer.ts +169 -7
  84. package/dist/extensions/pi-hermes-memory/src/store/session-search.ts +7 -21
  85. package/dist/extensions/pi-hermes-memory/src/store/sqlite-memory-store.ts +134 -15
  86. package/dist/extensions/pi-hermes-memory/src/tools/memory-search-tool.ts +4 -2
  87. package/dist/extensions/pi-hermes-memory/src/tools/memory-tool.ts +24 -9
  88. package/dist/extensions/pi-hermes-memory/src/types.ts +11 -0
  89. package/dist/extensions/pi-hermes-memory/tests/config.test.ts +42 -0
  90. package/dist/extensions/pi-hermes-memory/tests/handlers/background-review.test.ts +159 -3
  91. package/dist/extensions/pi-hermes-memory/tests/handlers/review-memory-ops.test.ts +452 -0
  92. package/dist/extensions/pi-hermes-memory/tests/handlers/session-backfill.test.ts +39 -0
  93. package/dist/extensions/pi-hermes-memory/tests/integration/corruption-recovery-integration.test.ts +91 -0
  94. package/dist/extensions/pi-hermes-memory/tests/store/db.test.ts +29 -0
  95. package/dist/extensions/pi-hermes-memory/tests/store/fts-query.test.ts +116 -0
  96. package/dist/extensions/pi-hermes-memory/tests/store/memory-store.test.ts +163 -0
  97. package/dist/extensions/pi-hermes-memory/tests/store/session-indexer.test.ts +233 -0
  98. package/dist/extensions/pi-hermes-memory/tests/store/session-search.test.ts +12 -0
  99. package/dist/extensions/pi-hermes-memory/tests/store/sqlite-memory-store.test.ts +175 -0
  100. package/dist/extensions/pi-hermes-memory/tests/store/sqlite-native.test.ts +2 -2
  101. package/dist/extensions/pi-hermes-memory/tests/tools/memory-search-tool.test.ts +22 -0
  102. package/dist/extensions/pi-hermes-memory/tests/tools/memory-tool.test.ts +37 -1
  103. package/dist/extensions/pi-intercom/CHANGELOG.md +13 -0
  104. package/dist/extensions/pi-intercom/README.md +16 -2
  105. package/dist/extensions/pi-intercom/broker/spawn.test.ts +19 -2
  106. package/dist/extensions/pi-intercom/broker/spawn.ts +4 -4
  107. package/dist/extensions/pi-intercom/index.ts +1 -1
  108. package/dist/extensions/pi-intercom/intercom.integration.test.ts +121 -2
  109. package/dist/extensions/pi-intercom/package.json +1 -1
  110. package/dist/extensions/pi-intercom/project-agent.test.ts +1 -1
  111. package/dist/extensions/pi-intercom/project-agent.ts +1 -6
  112. package/dist/extensions/pi-intercom/skills/pi-intercom/SKILL.md +7 -6
  113. package/dist/extensions/pi-rewind-hook/index.test.ts +7 -0
  114. package/dist/extensions/pi-subagents/.github/workflows/test.yml +36 -4
  115. package/dist/extensions/pi-subagents/CHANGELOG.md +120 -0
  116. package/dist/extensions/pi-subagents/README.md +3 -3
  117. package/dist/extensions/pi-subagents/agents/researcher.md +23 -13
  118. package/dist/extensions/pi-subagents/agents/reviewer.md +1 -1
  119. package/dist/extensions/pi-subagents/agents/scout.md +1 -1
  120. package/dist/extensions/pi-subagents/docs/agents.md +32 -16
  121. package/dist/extensions/pi-subagents/docs/configuration.md +41 -15
  122. package/dist/extensions/pi-subagents/docs/extension-api.md +109 -6
  123. package/dist/extensions/pi-subagents/docs/missions.md +2 -0
  124. package/dist/extensions/pi-subagents/docs/models.md +58 -1
  125. package/dist/extensions/pi-subagents/docs/observability.md +50 -12
  126. package/dist/extensions/pi-subagents/docs/tool-reference.md +17 -10
  127. package/dist/extensions/pi-subagents/docs/watchdog.md +1 -1
  128. package/dist/extensions/pi-subagents/docs/workflows.md +26 -9
  129. package/dist/extensions/pi-subagents/package-lock.json +747 -177
  130. package/dist/extensions/pi-subagents/package.json +6 -4
  131. package/dist/extensions/pi-subagents/runner-server-preload.mjs +13 -0
  132. package/dist/extensions/pi-subagents/skills/pi-subagents/SKILL.md +2 -1
  133. package/dist/extensions/pi-subagents/skills/pi-subagents/references/constraints-and-recipes.md +1 -1
  134. package/dist/extensions/pi-subagents/skills/pi-subagents/references/execution-controls.md +21 -4
  135. package/dist/extensions/pi-subagents/skills/pi-subagents/references/management-authoring-rpc.md +2 -1
  136. package/dist/extensions/pi-subagents/skills/pi-subagents/references/multi-lane-orchestration.md +2 -0
  137. package/dist/extensions/pi-subagents/src/agents/advertised-agent-prompt.ts +63 -0
  138. package/dist/extensions/pi-subagents/src/agents/agent-management.ts +61 -16
  139. package/dist/extensions/pi-subagents/src/agents/agent-serializer.ts +2 -0
  140. package/dist/extensions/pi-subagents/src/agents/agents.ts +8 -0
  141. package/dist/extensions/pi-subagents/src/api/capability-ceiling.ts +0 -1
  142. package/dist/extensions/pi-subagents/src/api/{pi-args.ts → child-tool-plan.ts} +1 -1
  143. package/dist/extensions/pi-subagents/src/api/preflight.ts +7 -4
  144. package/dist/extensions/pi-subagents/src/api/shared-types.ts +2 -2
  145. package/dist/extensions/pi-subagents/src/api/workflow-resources.ts +6 -0
  146. package/dist/extensions/pi-subagents/src/extension/config.ts +4 -2
  147. package/dist/extensions/pi-subagents/src/extension/doctor.ts +2 -10
  148. package/dist/extensions/pi-subagents/src/extension/fanout-child.ts +9 -11
  149. package/dist/extensions/pi-subagents/src/extension/index.ts +99 -10
  150. package/dist/extensions/pi-subagents/src/extension/public-execution.ts +13 -0
  151. package/dist/extensions/pi-subagents/src/extension/rpc.ts +7 -23
  152. package/dist/extensions/pi-subagents/src/extension/schemas.ts +11 -8
  153. package/dist/extensions/pi-subagents/src/extension/tool-description.ts +25 -7
  154. package/dist/extensions/pi-subagents/src/integrations/pi-web-session-liveness.ts +73 -0
  155. package/dist/extensions/pi-subagents/src/intercom/native-supervisor-channel.ts +228 -136
  156. package/dist/extensions/pi-subagents/src/intercom/supervisor-ui.ts +244 -0
  157. package/dist/extensions/pi-subagents/src/missions/workflow-state.ts +37 -16
  158. package/dist/extensions/pi-subagents/src/runs/background/active-async-capacity.ts +18 -18
  159. package/dist/extensions/pi-subagents/src/runs/background/async-execution.ts +51 -25
  160. package/dist/extensions/pi-subagents/src/runs/background/async-job-tracker.ts +46 -3
  161. package/dist/extensions/pi-subagents/src/runs/background/async-resume.ts +14 -3
  162. package/dist/extensions/pi-subagents/src/runs/background/async-retention.ts +9 -0
  163. package/dist/extensions/pi-subagents/src/runs/background/async-status-snapshot.ts +10 -12
  164. package/dist/extensions/pi-subagents/src/runs/background/async-status.ts +18 -15
  165. package/dist/extensions/pi-subagents/src/runs/background/auto-drain.ts +40 -29
  166. package/dist/extensions/pi-subagents/src/runs/background/chain-root-attachment.ts +8 -0
  167. package/dist/extensions/pi-subagents/src/runs/background/control-channel.ts +79 -247
  168. package/dist/extensions/pi-subagents/src/runs/background/notify.ts +88 -12
  169. package/dist/extensions/pi-subagents/src/runs/background/owned-process-tree.ts +6 -6
  170. package/dist/extensions/pi-subagents/src/runs/background/process-terminal.ts +24 -24
  171. package/dist/extensions/pi-subagents/src/runs/background/retained-nested-route-tracker.ts +96 -0
  172. package/dist/extensions/pi-subagents/src/runs/background/run-child-session.ts +642 -0
  173. package/dist/extensions/pi-subagents/src/runs/background/run-status.ts +75 -6
  174. package/dist/extensions/pi-subagents/src/runs/background/runner-aliases.ts +163 -0
  175. package/dist/extensions/pi-subagents/src/runs/background/runner-child-launch.ts +86 -0
  176. package/dist/extensions/pi-subagents/src/runs/background/runner-child-sessions.ts +31 -0
  177. package/dist/extensions/pi-subagents/src/runs/background/scheduled-runs.ts +18 -4
  178. package/dist/extensions/pi-subagents/src/runs/background/stale-run-reconciler.ts +3 -1
  179. package/dist/extensions/pi-subagents/src/runs/background/subagent-runner.ts +597 -1092
  180. package/dist/extensions/pi-subagents/src/runs/background/subagent-wait.ts +3 -0
  181. package/dist/extensions/pi-subagents/src/runs/background/wait-completions.ts +4 -0
  182. package/dist/extensions/pi-subagents/src/runs/foreground/async-steering-action.ts +20 -17
  183. package/dist/extensions/pi-subagents/src/runs/foreground/execution.ts +296 -394
  184. package/dist/extensions/pi-subagents/src/runs/foreground/foreground-control.ts +4 -0
  185. package/dist/extensions/pi-subagents/src/runs/foreground/foreground-history.ts +3 -1
  186. package/dist/extensions/pi-subagents/src/runs/foreground/prompt-audit.ts +9 -5
  187. package/dist/extensions/pi-subagents/src/runs/foreground/subagent-executor.ts +630 -283
  188. package/dist/extensions/pi-subagents/src/runs/foreground/workflow-detach-reconcile.ts +8 -5
  189. package/dist/extensions/pi-subagents/src/runs/foreground/workflow-foreground-steering.ts +78 -98
  190. package/dist/extensions/pi-subagents/src/runs/shared/abort-recovery.ts +3 -3
  191. package/dist/extensions/pi-subagents/src/runs/shared/acceptance.ts +16 -3
  192. package/dist/extensions/pi-subagents/src/runs/shared/agent-contract.ts +1 -1
  193. package/dist/extensions/pi-subagents/src/runs/shared/async-status-projection.ts +47 -47
  194. package/dist/extensions/pi-subagents/src/runs/shared/capability-ceiling.ts +1 -2
  195. package/dist/extensions/pi-subagents/src/runs/shared/child-hooks.ts +174 -0
  196. package/dist/extensions/pi-subagents/src/runs/shared/child-identity.ts +14 -3
  197. package/dist/extensions/pi-subagents/src/runs/shared/child-launch.ts +319 -0
  198. package/dist/extensions/pi-subagents/src/runs/shared/child-lifecycle.ts +25 -0
  199. package/dist/extensions/pi-subagents/src/runs/shared/child-runtime-config.ts +126 -0
  200. package/dist/extensions/pi-subagents/src/runs/shared/child-session.ts +373 -0
  201. package/dist/extensions/pi-subagents/src/runs/shared/child-tool-plan.ts +530 -0
  202. package/dist/extensions/pi-subagents/src/runs/shared/completion-evidence.ts +2 -2
  203. package/dist/extensions/pi-subagents/src/runs/shared/completion-guard.ts +2 -1
  204. package/dist/extensions/pi-subagents/src/runs/shared/external-cli-preflight.ts +16 -0
  205. package/dist/extensions/pi-subagents/src/runs/shared/host-step-status.ts +11 -11
  206. package/dist/extensions/pi-subagents/src/runs/shared/llm-intent-arbiter.ts +30 -20
  207. package/dist/extensions/pi-subagents/src/runs/shared/mcp-direct-tool-allowlist.ts +5 -4
  208. package/dist/extensions/pi-subagents/src/runs/shared/model-exclusions.ts +84 -15
  209. package/dist/extensions/pi-subagents/src/runs/shared/model-fallback.ts +88 -12
  210. package/dist/extensions/pi-subagents/src/runs/shared/nested-events.ts +37 -53
  211. package/dist/extensions/pi-subagents/src/runs/shared/nested-path.ts +1 -1
  212. package/dist/extensions/pi-subagents/src/runs/shared/orca-progress-tabs.ts +18 -7
  213. package/dist/extensions/pi-subagents/src/runs/shared/parallel-handoff.ts +57 -12
  214. package/dist/extensions/pi-subagents/src/runs/shared/parallel-utils.ts +3 -4
  215. package/dist/extensions/pi-subagents/src/runs/shared/permissions.ts +0 -11
  216. package/dist/extensions/pi-subagents/src/runs/shared/process-signal.ts +4 -1
  217. package/dist/extensions/pi-subagents/src/runs/shared/readonly-drain-observation.ts +42 -0
  218. package/dist/extensions/pi-subagents/src/runs/shared/readonly-model-continuation.ts +69 -0
  219. package/dist/extensions/pi-subagents/src/runs/shared/readonly-session-evidence.ts +307 -0
  220. package/dist/extensions/pi-subagents/src/runs/shared/run-fanout-budget.ts +8 -21
  221. package/dist/extensions/pi-subagents/src/runs/shared/runtime-acknowledged-extensions.ts +3 -30
  222. package/dist/extensions/pi-subagents/src/runs/shared/structured-output.ts +17 -4
  223. package/dist/extensions/pi-subagents/src/runs/shared/subagent-control.ts +2 -0
  224. package/dist/extensions/pi-subagents/src/runs/shared/subagent-prompt-runtime.ts +99 -386
  225. package/dist/extensions/pi-subagents/src/runs/shared/tool-availability.ts +18 -62
  226. package/dist/extensions/pi-subagents/src/runs/shared/tool-budget.ts +0 -14
  227. package/dist/extensions/pi-subagents/src/runs/shared/worktree-cleanup-plan.ts +31 -9
  228. package/dist/extensions/pi-subagents/src/runs/shared/worktree-setup-command.ts +190 -0
  229. package/dist/extensions/pi-subagents/src/runs/shared/worktree.ts +506 -226
  230. package/dist/extensions/pi-subagents/src/shared/child-session-name.ts +1 -1
  231. package/dist/extensions/pi-subagents/src/shared/jsonl-writer.ts +11 -0
  232. package/dist/extensions/pi-subagents/src/shared/model-response-aliases.ts +13 -0
  233. package/dist/extensions/pi-subagents/src/shared/thinking-ceiling.ts +0 -6
  234. package/dist/extensions/pi-subagents/src/shared/types.ts +145 -89
  235. package/dist/extensions/pi-subagents/src/shared/utils.ts +13 -6
  236. package/dist/extensions/pi-subagents/src/shared/watch-strategy.ts +2 -0
  237. package/dist/extensions/pi-subagents/src/shared/workflow-child-permit.ts +18 -13
  238. package/dist/extensions/pi-subagents/src/slash/slash-commands.ts +0 -6
  239. package/dist/extensions/pi-subagents/src/tui/fleet-status.ts +1 -1
  240. package/dist/extensions/pi-subagents/src/tui/fleet.ts +11 -6
  241. package/dist/extensions/pi-subagents/src/tui/render.ts +277 -46
  242. package/dist/extensions/pi-subagents/src/watchdog/child-status.ts +0 -1
  243. package/dist/extensions/pi-subagents/src/watchdog/register-child.ts +12 -12
  244. package/dist/extensions/pi-subagents/src/workflows/chat-progress.ts +3 -3
  245. package/dist/extensions/pi-subagents/src/workflows/scripted-workflow.ts +116 -15
  246. package/dist/extensions/pi-subagents/src/workflows/workflow-checklist.ts +15 -18
  247. package/dist/extensions/pi-subagents/src/workflows/workflow-child-summary.ts +57 -8
  248. package/dist/extensions/pi-subagents/src/workflows/workflow-preflight.ts +19 -19
  249. package/dist/extensions/pi-subagents/src/workflows/workflow-receipt.ts +3 -3
  250. package/dist/extensions/pi-subagents/src/workflows/workflow-resources.ts +97 -22
  251. package/dist/extensions/pi-subagents/src/workflows/workflow-settlement.ts +3 -0
  252. package/dist/extensions/pi-subagents/test/integration/acceptance-file-report.test.ts +336 -21
  253. package/dist/extensions/pi-subagents/test/integration/async-execution.part-1.test.ts +1181 -0
  254. package/dist/extensions/pi-subagents/test/integration/async-execution.part-2.test.ts +2240 -0
  255. package/dist/extensions/pi-subagents/test/integration/async-execution.part-3.test.ts +2268 -0
  256. package/dist/extensions/pi-subagents/test/integration/async-execution.part-4.test.ts +1512 -0
  257. package/dist/extensions/pi-subagents/test/integration/async-job-tracker.test.ts +231 -16
  258. package/dist/extensions/pi-subagents/test/integration/error-handling.test.ts +4 -18
  259. package/dist/extensions/pi-subagents/test/integration/foreign-workflow-steering.test.ts +95 -0
  260. package/dist/extensions/pi-subagents/test/integration/fork-context-execution.test.ts +9 -15
  261. package/dist/extensions/pi-subagents/test/integration/in-process-child.test.ts +374 -0
  262. package/dist/extensions/pi-subagents/test/integration/intercom-result-delivery.test.ts +20 -10
  263. package/dist/extensions/pi-subagents/test/integration/orca-progress-tabs.test.ts +18 -6
  264. package/dist/extensions/pi-subagents/test/integration/recovered-assistant-error.test.ts +151 -0
  265. package/dist/extensions/pi-subagents/test/integration/render-fork-badge.test.ts +42 -1
  266. package/dist/extensions/pi-subagents/test/integration/render-widget.test.ts +150 -25
  267. package/dist/extensions/pi-subagents/test/integration/result-publication.test.ts +354 -0
  268. package/dist/extensions/pi-subagents/test/integration/shared-cwd-terminal-evidence.test.ts +117 -0
  269. package/dist/extensions/pi-subagents/test/integration/single-execution.part-1.test.ts +3678 -0
  270. package/dist/extensions/pi-subagents/test/integration/{single-execution.test.ts → single-execution.part-2.test.ts} +500 -4207
  271. package/dist/extensions/pi-subagents/test/integration/slash-commands.test.ts +1 -2
  272. package/dist/extensions/pi-subagents/test/integration/workflow-result-publication.test.ts +127 -0
  273. package/dist/extensions/pi-subagents/test/integration/workflow-steer-inbox.test.ts +365 -0
  274. package/dist/extensions/pi-subagents/test/smoke/pi085-child.ts +31 -0
  275. package/dist/extensions/pi-subagents/test/smoke/pi085-clean-install.mjs +74 -0
  276. package/dist/extensions/pi-subagents/test/smoke/pi085-extension.ts +16 -0
  277. package/dist/extensions/pi-subagents/test/support/async-execution-fixture.ts +699 -0
  278. package/dist/extensions/pi-subagents/test/support/fake-child-session.ts +418 -0
  279. package/dist/extensions/pi-subagents/test/support/foreign-workflow-steer-host.mjs +13 -0
  280. package/dist/extensions/pi-subagents/test/support/mock-pi.ts +30 -76
  281. package/dist/extensions/pi-subagents/test/support/notify-diagnostics-fixture.ts +84 -0
  282. package/dist/extensions/pi-subagents/test/support/result-publication-capacity-preload.mjs +70 -0
  283. package/dist/extensions/pi-subagents/test/support/runner-child-session-factory.ts +17 -0
  284. package/dist/extensions/pi-subagents/test/support/single-execution-fixture.ts +390 -0
  285. package/dist/extensions/pi-subagents/test/unit/acceptance-compaction.test.ts +120 -0
  286. package/dist/extensions/pi-subagents/test/unit/acceptance.test.ts +24 -3
  287. package/dist/extensions/pi-subagents/test/unit/advertised-agent-prompt.test.ts +87 -0
  288. package/dist/extensions/pi-subagents/test/unit/advertised-agent-refresh.test.ts +163 -0
  289. package/dist/extensions/pi-subagents/test/unit/agent-frontmatter.test.ts +70 -31
  290. package/dist/extensions/pi-subagents/test/unit/agent-management.test.ts +78 -3
  291. package/dist/extensions/pi-subagents/test/unit/agent-overrides.test.ts +2 -8
  292. package/dist/extensions/pi-subagents/test/unit/async-execution.test.ts +1 -1
  293. package/dist/extensions/pi-subagents/test/unit/async-interrupt-action.test.ts +73 -66
  294. package/dist/extensions/pi-subagents/test/unit/async-recovery-descriptor.test.ts +51 -1
  295. package/dist/extensions/pi-subagents/test/unit/async-retention.test.ts +49 -1
  296. package/dist/extensions/pi-subagents/test/unit/async-spawn-preload.test.ts +103 -0
  297. package/dist/extensions/pi-subagents/test/unit/async-status-projection.test.ts +3 -3
  298. package/dist/extensions/pi-subagents/test/unit/capability-ceiling-agent-allowlist.test.ts +9 -8
  299. package/dist/extensions/pi-subagents/test/unit/capability-ceiling.test.ts +10 -7
  300. package/dist/extensions/pi-subagents/test/unit/chain-root-attachment.test.ts +48 -6
  301. package/dist/extensions/pi-subagents/test/unit/child-runtime-config.test.ts +90 -0
  302. package/dist/extensions/pi-subagents/test/unit/{pi-args-permission-system.test.ts → child-tool-plan-permission-system.test.ts} +48 -86
  303. package/dist/extensions/pi-subagents/test/unit/child-tool-plan.test.ts +33 -0
  304. package/dist/extensions/pi-subagents/test/unit/compaction-resume.test.ts +18 -18
  305. package/dist/extensions/pi-subagents/test/unit/completion-evidence.test.ts +9 -9
  306. package/dist/extensions/pi-subagents/test/unit/completion-guard.test.ts +8 -7
  307. package/dist/extensions/pi-subagents/test/unit/control-channel.test.ts +225 -65
  308. package/dist/extensions/pi-subagents/test/unit/extension-bindings.test.ts +17 -22
  309. package/dist/extensions/pi-subagents/test/unit/fleet-status.test.ts +11 -1
  310. package/dist/extensions/pi-subagents/test/unit/fleet.test.ts +47 -3
  311. package/dist/extensions/pi-subagents/test/unit/foreign-workflow-steering.test.ts +74 -0
  312. package/dist/extensions/pi-subagents/test/unit/fork-cache-key.test.ts +23 -29
  313. package/dist/extensions/pi-subagents/test/unit/host-peer-runtime-imports.test.ts +96 -4
  314. package/dist/extensions/pi-subagents/test/unit/host-step-status.test.ts +4 -4
  315. package/dist/extensions/pi-subagents/test/unit/index-child-registration.test.ts +116 -55
  316. package/dist/extensions/pi-subagents/test/unit/index-segment.test.ts +58 -1
  317. package/dist/extensions/pi-subagents/test/unit/llm-intent-arbiter.test.ts +104 -3
  318. package/dist/extensions/pi-subagents/test/unit/mission-lifecycle.test.ts +10 -1
  319. package/dist/extensions/pi-subagents/test/unit/mission-store.test.ts +31 -1
  320. package/dist/extensions/pi-subagents/test/unit/model-exclusions.test.ts +102 -51
  321. package/dist/extensions/pi-subagents/test/unit/model-fallback.test.ts +196 -6
  322. package/dist/extensions/pi-subagents/test/unit/native-supervisor-channel.test.ts +181 -38
  323. package/dist/extensions/pi-subagents/test/unit/nested-control.test.ts +62 -70
  324. package/dist/extensions/pi-subagents/test/unit/nested-events.test.ts +58 -53
  325. package/dist/extensions/pi-subagents/test/unit/notify-diagnostics.test.ts +42 -0
  326. package/dist/extensions/pi-subagents/test/unit/notify.test.ts +84 -0
  327. package/dist/extensions/pi-subagents/test/unit/orca-progress-tabs.test.ts +13 -5
  328. package/dist/extensions/pi-subagents/test/unit/package-manifest.test.ts +21 -5
  329. package/dist/extensions/pi-subagents/test/unit/parallel-handoff.test.ts +5 -4
  330. package/dist/extensions/pi-subagents/test/unit/permissions.test.ts +2 -6
  331. package/dist/extensions/pi-subagents/test/unit/pi-coding-agent-dir.test.ts +28 -2
  332. package/dist/extensions/pi-subagents/test/unit/pi-web-session-liveness.test.ts +209 -0
  333. package/dist/extensions/pi-subagents/test/unit/preflight.test.ts +38 -1
  334. package/dist/extensions/pi-subagents/test/unit/prompt-audit-optional-peers.test.ts +43 -0
  335. package/dist/extensions/pi-subagents/test/unit/public-execution.test.ts +24 -2
  336. package/dist/extensions/pi-subagents/test/unit/readonly-drain-observation.test.ts +174 -0
  337. package/dist/extensions/pi-subagents/test/unit/readonly-model-continuation.test.ts +94 -0
  338. package/dist/extensions/pi-subagents/test/unit/readonly-session-evidence.test.ts +1329 -0
  339. package/dist/extensions/pi-subagents/test/unit/recursion-guard.test.ts +29 -80
  340. package/dist/extensions/pi-subagents/test/unit/render-helpers.test.ts +11 -8
  341. package/dist/extensions/pi-subagents/test/unit/result-files.test.ts +2 -2
  342. package/dist/extensions/pi-subagents/test/unit/retained-nested-route-tracker.test.ts +175 -0
  343. package/dist/extensions/pi-subagents/test/unit/rpc.test.ts +38 -12
  344. package/dist/extensions/pi-subagents/test/unit/run-fanout-budget.test.ts +2 -5
  345. package/dist/extensions/pi-subagents/test/unit/run-status.test.ts +89 -1
  346. package/dist/extensions/pi-subagents/test/unit/runtime-acknowledged-extensions.test.ts +2 -16
  347. package/dist/extensions/pi-subagents/test/unit/scheduled-runs.test.ts +27 -3
  348. package/dist/extensions/pi-subagents/test/unit/scheduled-supervisor-demand.test.ts +215 -0
  349. package/dist/extensions/pi-subagents/test/unit/schemas.test.ts +15 -11
  350. package/dist/extensions/pi-subagents/test/unit/scripted-workflow.test.ts +237 -1
  351. package/dist/extensions/pi-subagents/test/unit/steering-action.test.ts +2 -5
  352. package/dist/extensions/pi-subagents/test/unit/streamed-progress-bounds.test.ts +2 -2
  353. package/dist/extensions/pi-subagents/test/unit/subagent-guide.test.ts +14 -1
  354. package/dist/extensions/pi-subagents/test/unit/subagent-prompt-runtime.test.ts +130 -739
  355. package/dist/extensions/pi-subagents/test/unit/supervisor-ask-registration.test.ts +682 -0
  356. package/dist/extensions/pi-subagents/test/unit/supervisor-ui.test.ts +137 -0
  357. package/dist/extensions/pi-subagents/test/unit/tool-budget.test.ts +1 -11
  358. package/dist/extensions/pi-subagents/test/unit/tool-description.test.ts +23 -3
  359. package/dist/extensions/pi-subagents/test/unit/wait-completions.test.ts +8 -1
  360. package/dist/extensions/pi-subagents/test/unit/watchdog-tool-actions.test.ts +19 -1
  361. package/dist/extensions/pi-subagents/test/unit/workflow-chat-progress.test.ts +72 -4
  362. package/dist/extensions/pi-subagents/test/unit/workflow-checklist.test.ts +17 -3
  363. package/dist/extensions/pi-subagents/test/unit/workflow-child-summary.test.ts +34 -0
  364. package/dist/extensions/pi-subagents/test/unit/workflow-detach-reconcile.test.ts +12 -2
  365. package/dist/extensions/pi-subagents/test/unit/workflow-launch-params.test.ts +46 -6
  366. package/dist/extensions/pi-subagents/test/unit/workflow-receipt.test.ts +3 -3
  367. package/dist/extensions/pi-subagents/test/unit/workflow-resources.test.ts +133 -1
  368. package/dist/extensions/pi-subagents/test/unit/workflow-resume-hint.test.ts +53 -2
  369. package/dist/extensions/pi-subagents/test/unit/worktree-cleanup-plan.test.ts +222 -14
  370. package/dist/extensions/pi-subagents/test/unit/worktree.test.ts +526 -85
  371. package/dist/extensions/pi-web-agent/src/backends/config.ts +1 -0
  372. package/dist/extensions/pi-web-agent/src/backends/settings-reader.ts +5 -3
  373. package/dist/extensions/pi-web-agent/src/search/tokenin.ts +7 -3
  374. package/dist/extensions/pi-web-agent/src/types.ts +1 -1
  375. package/dist/extensions/pi-zentui/README.md +17 -0
  376. package/dist/extensions/pi-zentui/assets/screenshots/footer-status-hyperlink.png +0 -0
  377. package/dist/extensions/pi-zentui/docs/configuration.md +71 -2
  378. package/dist/extensions/pi-zentui/extensions/zentui/config.ts +11 -0
  379. package/dist/extensions/pi-zentui/extensions/zentui/editor-transfer.ts +14 -0
  380. package/dist/extensions/pi-zentui/extensions/zentui/extension-status.ts +29 -13
  381. package/dist/extensions/pi-zentui/extensions/zentui/footer-layout.ts +5 -4
  382. package/dist/extensions/pi-zentui/extensions/zentui/footer-text.ts +11 -0
  383. package/dist/extensions/pi-zentui/extensions/zentui/footer.ts +11 -10
  384. package/dist/extensions/pi-zentui/extensions/zentui/index.ts +77 -3
  385. package/dist/extensions/pi-zentui/extensions/zentui/presets.ts +77 -0
  386. package/dist/extensions/pi-zentui/extensions/zentui/settings-command.ts +103 -2
  387. package/dist/extensions/pi-zentui/extensions/zentui/working-line-extension-segments.ts +115 -0
  388. package/dist/extensions/pi-zentui/extensions/zentui/working-line.ts +87 -5
  389. package/dist/extensions/pi-zentui/package-lock.json +277 -517
  390. package/dist/extensions/pi-zentui/package.json +7 -4
  391. package/dist/extensions/pi-zentui/test/config-presets.test.ts +238 -0
  392. package/dist/extensions/pi-zentui/test/editor-transfer.test.ts +24 -1
  393. package/dist/extensions/pi-zentui/test/extension-compliance.test.ts +570 -2
  394. package/dist/extensions/pi-zentui/test/extension-status.test.ts +90 -0
  395. package/dist/extensions/pi-zentui/test/footer-hyperlink.test.ts +243 -0
  396. package/dist/extensions/pi-zentui/test/package-contents.mjs +1 -0
  397. package/dist/extensions/pi-zentui/test/presets.test.ts +121 -0
  398. package/dist/extensions/pi-zentui/test/settings-command.test.ts +205 -1
  399. package/dist/extensions/pi-zentui/test/working-line-extension-segments.test.ts +139 -0
  400. package/dist/extensions/pi-zentui/test/working-line-lifecycle.integration.test.ts +237 -3
  401. package/dist/extensions/pi-zentui/test/working-line.test.ts +94 -2
  402. package/dist/index.d.ts +1 -1
  403. package/dist/main.js +4 -1
  404. package/dist/modes/interactive/chat-viewport.d.ts +19 -0
  405. package/dist/modes/interactive/chat-viewport.js +27 -0
  406. package/dist/modes/interactive/components/assistant-message.d.ts +6 -2
  407. package/dist/modes/interactive/components/assistant-message.js +30 -13
  408. package/dist/modes/interactive/components/custom-editor.d.ts +10 -1
  409. package/dist/modes/interactive/components/custom-editor.js +39 -1
  410. package/dist/modes/interactive/components/first-time-setup.js +1 -1
  411. package/dist/modes/interactive/components/index.d.ts +1 -1
  412. package/dist/modes/interactive/components/markdown-transform.d.ts +2 -0
  413. package/dist/modes/interactive/components/markdown-transform.js +18 -0
  414. package/dist/modes/interactive/components/model-selector.js +19 -17
  415. package/dist/modes/interactive/components/scoped-models-selector.js +21 -23
  416. package/dist/modes/interactive/components/settings-selector.d.ts +7 -1
  417. package/dist/modes/interactive/components/settings-selector.js +128 -20
  418. package/dist/modes/interactive/components/settings-submenu.d.ts +71 -0
  419. package/dist/modes/interactive/components/settings-submenu.js +164 -0
  420. package/dist/modes/interactive/components/status-indicator.d.ts +3 -1
  421. package/dist/modes/interactive/components/status-indicator.js +10 -3
  422. package/dist/modes/interactive/components/thinking-selector.d.ts +15 -3
  423. package/dist/modes/interactive/components/thinking-selector.js +75 -18
  424. package/dist/modes/interactive/components/tool-execution.d.ts +21 -4
  425. package/dist/modes/interactive/components/tool-execution.js +35 -33
  426. package/dist/modes/interactive/components/trust-selector.js +2 -2
  427. package/dist/modes/interactive/interactive-mode.d.ts +13 -15
  428. package/dist/modes/interactive/interactive-mode.js +144 -80
  429. package/dist/modes/interactive/session-share.d.ts +15 -0
  430. package/dist/modes/interactive/session-share.js +183 -0
  431. package/dist/modes/interactive/theme/dark.json +2 -1
  432. package/dist/modes/interactive/theme/light.json +2 -1
  433. package/dist/modes/interactive/theme/theme-controller.d.ts +1 -0
  434. package/dist/modes/interactive/theme/theme-controller.js +5 -0
  435. package/dist/modes/interactive/theme/theme-json.d.ts +83 -0
  436. package/dist/modes/interactive/theme/theme-json.js +129 -0
  437. package/dist/modes/interactive/theme/theme-schema.json +9 -1
  438. package/dist/modes/interactive/theme/theme.d.ts +14 -5
  439. package/dist/modes/interactive/theme/theme.js +18 -119
  440. package/dist/modes/interactive/tui-renderer.d.ts +20 -0
  441. package/dist/modes/interactive/tui-renderer.js +65 -0
  442. package/dist/utils/exif-orientation.js +2 -3
  443. package/dist/utils/management-http.d.ts +24 -0
  444. package/dist/utils/management-http.js +53 -0
  445. package/dist/utils/text.d.ts +7 -0
  446. package/dist/utils/text.js +8 -0
  447. package/dist/utils/tools-manager.d.ts +1 -0
  448. package/dist/utils/tools-manager.js +43 -21
  449. package/docs/docs.json +0 -4
  450. package/package.json +4 -4
  451. package/dist/extensions/pi-subagents/src/runs/shared/child-protocol.ts +0 -415
  452. package/dist/extensions/pi-subagents/src/runs/shared/pi-args.ts +0 -1059
  453. package/dist/extensions/pi-subagents/src/runs/shared/subagent-startup-retry.ts +0 -116
  454. package/dist/extensions/pi-subagents/src/shared/post-exit-stdio-guard.ts +0 -85
  455. package/dist/extensions/pi-subagents/test/e2e/real-session-subagent.test.ts +0 -224
  456. package/dist/extensions/pi-subagents/test/integration/async-execution.test.ts +0 -6986
  457. package/dist/extensions/pi-subagents/test/support/mock-pi-script.mjs +0 -447
  458. package/dist/extensions/pi-subagents/test/support/real-session-child-cli.mjs +0 -185
  459. package/dist/extensions/pi-subagents/test/support/real-session-runner.ts +0 -311
  460. package/dist/extensions/pi-subagents/test/unit/capability-ceiling-pi-args.test.ts +0 -84
  461. package/dist/extensions/pi-subagents/test/unit/child-protocol.test.ts +0 -202
  462. package/dist/extensions/pi-subagents/test/unit/close-grace-timer.test.ts +0 -101
  463. package/dist/extensions/pi-subagents/test/unit/pi-args.test.ts +0 -2347
  464. package/dist/extensions/pi-subagents/test/unit/subagent-startup-retry.test.ts +0 -104
  465. package/dist/extensions/pi-subagents/test/unit/windows-hide-spawn.test.ts +0 -49
  466. package/dist/skills/imagegen-frontend-mobile/SKILL.md +0 -1465
  467. package/dist/skills/imagegen-frontend-web/SKILL.md +0 -987
  468. package/dist/skills/implanger/SKILL.md +0 -70
  469. package/dist/skills/output/SKILL.md +0 -49
  470. package/dist/skills/planger/SKILL.md +0 -167
  471. package/dist/skills/workflow/SKILL.md +0 -95
  472. package/docs/workflows.md +0 -18
  473. /package/dist/bun/{register-bedrock.d.ts → runtime-setup.d.ts} +0 -0
@@ -193,11 +193,19 @@ test("malformed optional observer metadata cannot break child execution", { skip
193
193
  env: { ...process.env, ORCA_TEST_CAPTURE: capture },
194
194
  } as never);
195
195
  assert.ok(tab);
196
- tab.finish("completed");
197
- await waitForFile(capture);
196
+ await tab.finish("completed");
197
+ // Capture precedes the watchdog's final manifest/queue writes; wait for its close.
198
+ await tab.creationSettled;
198
199
  const args = JSON.parse(fs.readFileSync(capture, "utf-8")) as string[];
199
200
  assert.equal(args[args.indexOf("--title") + 1], "subagents · subagent · 1");
200
- removeProgressFiles("run-0-");
201
+ const manifestDir = path.join(dir, ".pi-subagents", "views", "orca");
202
+ const [manifestName] = fs.readdirSync(manifestDir);
203
+ const manifest = JSON.parse(fs.readFileSync(path.join(manifestDir, manifestName!), "utf-8"));
204
+ assert.equal(manifest.state, "open");
205
+ const viewer = args[args.indexOf("--command") + 1]!;
206
+ assert.match(await captureCommand(viewer, dir), /completed/);
207
+ assert.equal(fs.existsSync(manifest.logPath), false);
208
+ assert.equal(fs.existsSync(manifest.logPath.replace(/\.log$/, ".done")), false);
201
209
  });
202
210
 
203
211
  test("disabled Orca progress tabs do not invoke Orca", async () => {
@@ -272,7 +280,7 @@ test("enabled tabs use a worktree sequence and successful Pi sessions get cleanu
272
280
  assert.match(text, /done output/);
273
281
  const quotedSessionFile = `'${fs.realpathSync(sessionFile).replace(/'/g, `'"'"'`)}'`;
274
282
  assert.ok(text.includes(`completed. To remove the Pi session for this run, run rm -- ${quotedSessionFile}`));
275
- assert.doesNotMatch(text, /find ~\/\.selesai[\\/]agent\/sessions/);
283
+ assert.doesNotMatch(text, /find ~\/\.selesai\/agent\/sessions/);
276
284
 
277
285
  const nestedCwd = path.join(dir, "packages", "app");
278
286
  fs.mkdirSync(nestedCwd, { recursive: true });
@@ -542,4 +550,4 @@ test("mirror output truncates at a finite byte bound", { skip: process.platform
542
550
  const text = fs.readFileSync(log, "utf-8");
543
551
  assert.match(text, /progress mirror truncated at 1048576 bytes/);
544
552
  assert.doesNotMatch(text, /must be dropped/);
545
- });
553
+ });
@@ -37,6 +37,17 @@ test("the root entrypoint exposes the runtime error flag to TypeScript consumers
37
37
  fs.writeFileSync(path.join(consumerRoot, "consumer.ts"), `
38
38
  import "pi-subagents";
39
39
  import type { AgentToolResult } from "@earendil-works/pi-agent-core";
40
+ import { registerWorkflowResource, type RegisterWorkflowResourceInput, type WorkflowResourceDefinition, type WorkflowResourceRegistration } from "pi-subagents/workflow-resources";
41
+
42
+ const definition: WorkflowResourceDefinition = {
43
+ name: "consumer.check", version: 1,
44
+ resolve: (args) => typeof args.task === "string"
45
+ ? { script: "return 1;", hostCommands: [{ key: "check", command: "node --version" }] }
46
+ : { error: "task required" },
47
+ };
48
+ const input: RegisterWorkflowResourceInput = { sessionId: "consumer", definition };
49
+ const registration: WorkflowResourceRegistration = registerWorkflowResource(input);
50
+ registration.dispose();
40
51
 
41
52
  const result: AgentToolResult<undefined> = {
42
53
  content: [],
@@ -60,6 +71,7 @@ void result.isError;
60
71
  baseUrl: consumerRoot,
61
72
  paths: {
62
73
  "pi-subagents": [path.join(projectRoot, "index.ts")],
74
+ "pi-subagents/workflow-resources": [path.join(projectRoot, "src/api/workflow-resources.ts")],
63
75
  "@earendil-works/pi-agent-core": [path.join(projectRoot, "node_modules", "@earendil-works", "pi-agent-core", "dist", "index.d.ts")],
64
76
  },
65
77
  },
@@ -108,11 +120,12 @@ test("published extension APIs use supported package entrypoints", async () => {
108
120
  "./external-job-provider": "./src/api/external-job-provider.ts",
109
121
  "./external-runs": "./src/api/external-runs.ts",
110
122
  "./capability-ceiling": "./src/api/capability-ceiling.ts",
123
+ "./workflow-resources": "./src/api/workflow-resources.ts",
111
124
  "./delegation": "./src/api/delegation.ts",
112
125
  "./preflight": "./src/api/preflight.ts",
113
126
  "./control-channel": "./src/api/control-channel.ts",
114
127
  "./intercom-bridge": "./src/api/intercom-bridge.ts",
115
- "./pi-args": "./src/api/pi-args.ts",
128
+ "./child-tool-plan": "./src/api/child-tool-plan.ts",
116
129
  "./shared-types": "./src/api/shared-types.ts",
117
130
  "./project-panes": "./src/api/project-panes.ts",
118
131
  });
@@ -134,6 +147,9 @@ test("published extension APIs use supported package entrypoints", async () => {
134
147
  assert.equal(typeof externalRuns.snapshotExternalRuns, "function");
135
148
  assert.equal(typeof externalRuns.unregisterExternalRun, "function");
136
149
  const capability = await import("pi-subagents/capability-ceiling");
150
+ const workflowResources = await import("pi-subagents/workflow-resources");
151
+ assert.deepEqual(Object.keys(workflowResources), ["registerWorkflowResource"]);
152
+ assert.equal(typeof workflowResources.registerWorkflowResource, "function");
137
153
  assert.equal(capability.SUBAGENT_CAPABILITY_CEILING_VERSION, 1);
138
154
  assert.equal(capability.SUBAGENT_CAPABILITY_CEILING_REGISTRY_KEY, "pi-subagents.capability-ceiling.v1");
139
155
  const delegation = await import("pi-subagents/delegation");
@@ -145,9 +161,9 @@ test("published extension APIs use supported package entrypoints", async () => {
145
161
  assert.equal(typeof controlChannel.requestAsyncStop, "function");
146
162
  const intercomBridge = await import("pi-subagents/intercom-bridge");
147
163
  assert.equal(typeof intercomBridge.resolveIntercomSessionTarget, "function");
148
- const piArgs = await import("pi-subagents/pi-args");
149
- assert.equal(typeof piArgs.resolvePiLaunchToolPlan, "function");
150
- assert.equal("buildPiArgs" in piArgs, false);
164
+ const childToolPlan = await import("pi-subagents/child-tool-plan");
165
+ assert.equal(typeof childToolPlan.resolvePiLaunchToolPlan, "function");
166
+ assert.deepEqual(Object.keys(childToolPlan).sort(), ["resolvePiLaunchToolPlan"]);
151
167
  const sharedTypes = await import("pi-subagents/shared-types");
152
168
  assert.equal(typeof sharedTypes.wrapForkTask, "function");
153
169
  assert.equal(typeof sharedTypes.DEFAULT_FORK_PREAMBLE, "string");
@@ -238,4 +254,4 @@ test("Pi package resolution stays export-map safe", () => {
238
254
  assert.equal(piPackageJsonSubpathPattern.test(source), false, `${file} should not resolve unexported package.json subpaths`);
239
255
  assert.equal(cjsPiPackageResolutionPattern.test(source), false, `${file} should not use CommonJS resolution for ESM-only Pi packages`);
240
256
  }
241
- });
257
+ });
@@ -11,7 +11,6 @@ import {
11
11
  recordParallelHandoffSupersession,
12
12
  resolveParallelHandoffChild,
13
13
  writeParallelHandoffGroup,
14
- writePendingParallelHandoff,
15
14
  } from "../../src/runs/shared/parallel-handoff.ts";
16
15
  import type { ParallelHandoffManifest } from "../../src/shared/types.ts";
17
16
  import type { WorktreeCleanupReport, WorktreeDiff, WorktreeSetup } from "../../src/runs/shared/worktree.ts";
@@ -56,7 +55,8 @@ describe("parallel handoff", () => {
56
55
  const dir = fs.mkdtempSync(path.join(os.tmpdir(), "pi-parallel-handoff-pending-"));
57
56
  try {
58
57
  const manifestPath = path.join(dir, "handoff.json");
59
- const reference = writePendingParallelHandoff({
58
+ const reference = writeParallelHandoffGroup({
59
+ diffs: [], results: [],
60
60
  manifestPath,
61
61
  runId: "run-pending",
62
62
  mode: "parallel",
@@ -416,7 +416,8 @@ describe("parallel handoff", () => {
416
416
  const dir = fs.mkdtempSync(path.join(os.tmpdir(), "pi-parallel-handoff-merge-unknown-"));
417
417
  try {
418
418
  const manifestPath = path.join(dir, "handoff.json");
419
- writePendingParallelHandoff({
419
+ writeParallelHandoffGroup({
420
+ diffs: [], results: [],
420
421
  manifestPath,
421
422
  runId: "lane-unknown",
422
423
  mode: "single",
@@ -560,4 +561,4 @@ describe("parallel handoff", () => {
560
561
  fs.rmSync(dir, { recursive: true, force: true });
561
562
  }
562
563
  });
563
- });
564
+ });
@@ -1,8 +1,6 @@
1
1
  import assert from "node:assert/strict";
2
2
  import { describe, it } from "node:test";
3
3
  import {
4
- decodePermissionRules,
5
- encodePermissionRules,
6
4
  permissionArgsPreview,
7
5
  permissionDecision,
8
6
  resolvePermissionRules,
@@ -31,9 +29,7 @@ describe("native child permissions", () => {
31
29
  assert.throws(() => validatePermissionConfig({ rules: { write: "sometimes" } }), /allow, ask, or deny/);
32
30
  });
33
31
 
34
- it("round-trips only explicit non-allow rules and redacts bounded previews", () => {
35
- const encoded = encodePermissionRules({ write: "ask" });
36
- assert.deepEqual(decodePermissionRules(encoded), { write: "ask" });
32
+ it("redacts bounded argument previews", () => {
37
33
  const preview = permissionArgsPreview({ token: "secret-value", content: `Bearer abcdefghijklmnop ${"x".repeat(3000)}` });
38
34
  assert.doesNotMatch(preview, /secret-value|abcdefghijklmnop/);
39
35
  assert.ok(Buffer.byteLength(preview) <= 2048);
@@ -43,4 +39,4 @@ describe("native child permissions", () => {
43
39
  assert.doesNotMatch(multibytePreview, /�/);
44
40
  assert.match(multibytePreview, /…$/);
45
41
  });
46
- });
42
+ });
@@ -158,7 +158,7 @@ Inspect env.
158
158
  assert.equal(fs.existsSync(path.join(agentDir, "agents", `${createdName}.md`)), true);
159
159
  });
160
160
 
161
- it("ignores nested .selesai and sync-backups agent definitions", () => {
161
+ it("ignores nested .pi and sync-backups agent definitions", () => {
162
162
  const userAgentsDir = path.join(agentDir, "agents");
163
163
  const rootAgentPath = path.join(userAgentsDir, "root-agent.md");
164
164
  writeFile(rootAgentPath, `---
@@ -292,6 +292,32 @@ Package skill content.
292
292
  assert.throws(() => updateConfig((config) => config), /config\.defaultSubagentContext must be "fresh" or "fork"/);
293
293
  });
294
294
 
295
+ it("loads exact model response aliases and preserves them during config updates", () => {
296
+ const configPath = path.join(agentDir, "extensions", "subagent", "config.json");
297
+ const modelResponseAliases = {
298
+ "databricks-bedrock/ias-claude-opus-5": ["claude-opus-5", "exact/Response:high"],
299
+ "gateway/owner/model": [],
300
+ };
301
+ writeFile(configPath, JSON.stringify({ modelResponseAliases }));
302
+ assert.deepEqual(loadConfig().modelResponseAliases, modelResponseAliases);
303
+ updateConfig((config) => ({ ...config, asyncByDefault: false }));
304
+ assert.deepEqual(loadConfig(), { modelResponseAliases, asyncByDefault: false });
305
+ writeFile(configPath, JSON.stringify({ modelResponseAliases: {} }));
306
+ assert.deepEqual(loadConfig().modelResponseAliases, {});
307
+ });
308
+
309
+ it("fails config load for malformed model response aliases with useful diagnostics", () => {
310
+ const configPath = path.join(agentDir, "extensions", "subagent", "config.json");
311
+ for (const modelResponseAliases of [null, [], "alias", { "": [] }, { model: [] }, { "/model": [] }, { "provider/ ": [] }, { " /model": [] }]) {
312
+ writeFile(configPath, JSON.stringify({ modelResponseAliases }));
313
+ assert.throws(() => loadConfig(), /config\.modelResponseAliases.*(?:JSON object|provider\/model ID)/);
314
+ }
315
+ for (const aliases of [null, "response", [""], [" "], [1], ["valid", false]]) {
316
+ writeFile(configPath, JSON.stringify({ modelResponseAliases: { "provider/model": aliases } }));
317
+ assert.throws(() => loadConfig(), /config\.modelResponseAliases\["provider\/model"\].*array of non-empty response ID strings/);
318
+ }
319
+ });
320
+
295
321
  it("loads and applies model exclusion TTL config", () => {
296
322
  const configPath = path.join(agentDir, "extensions", "subagent", "config.json");
297
323
  const exclusionPath = path.join(tempDir, "model-exclusions.json");
@@ -458,4 +484,4 @@ Package skill content.
458
484
  assert.equal(bridge.extensionDir, "native:pi-subagents-supervisor-channel");
459
485
  assert.match(bridge.instruction, /Native bridge for main/);
460
486
  });
461
- });
487
+ });
@@ -0,0 +1,209 @@
1
+ import assert from "node:assert/strict";
2
+ import * as fs from "node:fs";
3
+ import * as path from "node:path";
4
+ import { afterEach, describe, it } from "node:test";
5
+ import {
6
+ hasLiveSubagentWork,
7
+ PI_WEB_SESSION_LIVENESS_REGISTRY_KEY,
8
+ registerPiWebSessionLiveness,
9
+ retainLiveForegroundNestedRoute,
10
+ } from "../../src/integrations/pi-web-session-liveness.ts";
11
+ import { createNestedRoute, writeNestedEvent } from "../../src/runs/shared/nested-events.ts";
12
+ import { removeForegroundControlIfIdle } from "../../src/runs/foreground/subagent-executor.ts";
13
+ import type { SubagentState } from "../../src/shared/types.ts";
14
+
15
+ function clearRegistry(): void {
16
+ delete (globalThis as Record<PropertyKey, unknown>)[Symbol.for(PI_WEB_SESSION_LIVENESS_REGISTRY_KEY)];
17
+ }
18
+
19
+ const routeRoots: string[] = [];
20
+
21
+ afterEach(() => {
22
+ clearRegistry();
23
+ for (const root of routeRoots.splice(0)) fs.rmSync(root, { recursive: true, force: true });
24
+ });
25
+
26
+ function nestedRoute(rootRunId: string) {
27
+ const route = createNestedRoute(rootRunId);
28
+ routeRoots.push(path.dirname(route.eventSink));
29
+ return route;
30
+ }
31
+
32
+ function writeNestedState(route: ReturnType<typeof nestedRoute>, state: "running" | "complete", ts: number): void {
33
+ writeNestedEvent(route, {
34
+ type: state === "running" ? "subagent.nested.updated" : "subagent.nested.completed",
35
+ ts,
36
+ parentRunId: route.rootRunId,
37
+ parentStepIndex: 0,
38
+ child: {
39
+ id: "nested-child",
40
+ parentRunId: route.rootRunId,
41
+ parentStepIndex: 0,
42
+ depth: 1,
43
+ path: [{ runId: route.rootRunId, stepIndex: 0 }],
44
+ state,
45
+ agent: "worker",
46
+ lastUpdate: ts,
47
+ },
48
+ });
49
+ }
50
+
51
+ function makeState(): Parameters<typeof hasLiveSubagentWork>[0] {
52
+ return {
53
+ asyncJobs: new Map(),
54
+ foregroundControls: new Map(),
55
+ };
56
+ }
57
+
58
+ describe("pi-web session liveness integration", () => {
59
+ it("reports only queued or running async jobs as live", () => {
60
+ const state = makeState();
61
+ state.asyncJobs.set("retained", { status: "complete" } as never);
62
+ assert.equal(hasLiveSubagentWork(state), false);
63
+
64
+ state.asyncJobs.set("queued", { status: "queued" } as never);
65
+ assert.equal(hasLiveSubagentWork(state), true);
66
+ state.asyncJobs.delete("queued");
67
+
68
+ state.asyncJobs.set("running", { status: "running" } as never);
69
+ assert.equal(hasLiveSubagentWork(state), true);
70
+ });
71
+
72
+ it("keeps a terminal parent live while a nested descendant is active", () => {
73
+ const state = makeState();
74
+ const nestedChild = { state: "running" };
75
+ state.asyncJobs.set("parent", {
76
+ status: "complete",
77
+ nestedChildren: [{ state: "complete", children: [nestedChild] }],
78
+ } as never);
79
+ assert.equal(hasLiveSubagentWork(state), true);
80
+
81
+ nestedChild.state = "complete";
82
+ assert.equal(hasLiveSubagentWork(state), false);
83
+ });
84
+
85
+ it("reports foreground scheduling or active children as live", () => {
86
+ const state = makeState();
87
+ state.foregroundControls.set("settled", { schedulingOwners: 0, activeChildren: new Map() } as never);
88
+ assert.equal(hasLiveSubagentWork(state), false);
89
+
90
+ state.foregroundControls.set("scheduling", { schedulingOwners: 1, activeChildren: new Map() } as never);
91
+ assert.equal(hasLiveSubagentWork(state), true);
92
+ state.foregroundControls.delete("scheduling");
93
+
94
+ state.foregroundControls.set("child", { schedulingOwners: 0, activeChildren: new Map([[0, {}]]) } as never);
95
+ assert.equal(hasLiveSubagentWork(state), true);
96
+ });
97
+
98
+ it("retains a foreground nested route until its async descendant finishes", () => {
99
+ const state = makeState();
100
+ const route = nestedRoute("foreground-root");
101
+ writeNestedState(route, "running", 100);
102
+
103
+ assert.equal(retainLiveForegroundNestedRoute(state, route), true);
104
+ assert.equal(state.retainedForegroundNestedRoutes?.has(route.rootRunId), true);
105
+ assert.equal(hasLiveSubagentWork(state), true);
106
+
107
+ writeNestedState(route, "complete", 200);
108
+ assert.equal(hasLiveSubagentWork(state), true, "the synchronous probe reads only its cached projection");
109
+ });
110
+
111
+ it("does not retain foreground nested routes without a host registration", () => {
112
+ const state = makeState() as SubagentState;
113
+ const route = nestedRoute("unregistered-foreground-root");
114
+ writeNestedState(route, "running", 100);
115
+ state.foregroundControls.set(route.rootRunId, {
116
+ runId: route.rootRunId,
117
+ mode: "single",
118
+ startedAt: 1,
119
+ updatedAt: 1,
120
+ schedulingOwners: 0,
121
+ activeChildren: new Map(),
122
+ nestedRoute: route,
123
+ });
124
+
125
+ const liveness = registerPiWebSessionLiveness({ sessionId: "session-a", isActive: () => true });
126
+ assert.equal(liveness.registered, false);
127
+ assert.equal(removeForegroundControlIfIdle(state, route.rootRunId), true);
128
+ assert.equal(state.retainedForegroundNestedRoutes, undefined);
129
+ });
130
+
131
+ it("transfers a live nested route before removing its settled foreground control", () => {
132
+ const state = makeState() as SubagentState;
133
+ const route = nestedRoute("settled-foreground-root");
134
+ writeNestedState(route, "running", 100);
135
+ state.foregroundControls.set(route.rootRunId, {
136
+ runId: route.rootRunId,
137
+ mode: "single",
138
+ startedAt: 1,
139
+ updatedAt: 1,
140
+ schedulingOwners: 0,
141
+ activeChildren: new Map(),
142
+ nestedRoute: route,
143
+ });
144
+ let tracked: string | undefined;
145
+
146
+ assert.equal(removeForegroundControlIfIdle(state, route.rootRunId, (rootRunId) => { tracked = rootRunId; }), true);
147
+ assert.equal(state.foregroundControls.has(route.rootRunId), false);
148
+ assert.equal(state.retainedForegroundNestedRoutes?.has(route.rootRunId), true);
149
+ assert.equal(tracked, route.rootRunId);
150
+ });
151
+
152
+ it("does not retain foreground routes without live descendants", () => {
153
+ const state = makeState();
154
+ const route = nestedRoute("terminal-foreground-root");
155
+ writeNestedState(route, "complete", 100);
156
+
157
+ assert.equal(retainLiveForegroundNestedRoute(state, route), false);
158
+ assert.equal(state.retainedForegroundNestedRoutes, undefined);
159
+ });
160
+
161
+ it("is a no-op outside pi-web or with an incompatible protocol", () => {
162
+ const releaseWithoutHost = registerPiWebSessionLiveness({
163
+ sessionId: "session-a",
164
+ isActive: () => true,
165
+ });
166
+ assert.equal(releaseWithoutHost.registered, false);
167
+ releaseWithoutHost.release();
168
+ let registered = false;
169
+ (globalThis as Record<PropertyKey, unknown>)[Symbol.for(PI_WEB_SESSION_LIVENESS_REGISTRY_KEY)] = {
170
+ version: 2,
171
+ register() {
172
+ registered = true;
173
+ return () => {};
174
+ },
175
+ };
176
+ const incompatible = registerPiWebSessionLiveness({ sessionId: "session-a", isActive: () => true });
177
+ assert.equal(incompatible.registered, false);
178
+ assert.equal(registered, false);
179
+ });
180
+
181
+ it("registers exact session aliases and returns the host release function", () => {
182
+ let provider: { name: string; sessionId: string; sessionFile?: string; isActive(): boolean } | undefined;
183
+ let released = 0;
184
+ (globalThis as Record<PropertyKey, unknown>)[Symbol.for(PI_WEB_SESSION_LIVENESS_REGISTRY_KEY)] = {
185
+ version: 1,
186
+ register(value: typeof provider) {
187
+ provider = value;
188
+ return () => { released += 1; };
189
+ },
190
+ };
191
+
192
+ let active = true;
193
+ const release = registerPiWebSessionLiveness({
194
+ sessionId: "session-a",
195
+ sessionFile: "/tmp/session-a.jsonl",
196
+ isActive: () => active,
197
+ });
198
+ assert.equal(release.registered, true);
199
+ assert.equal(provider?.name, "pi-subagents");
200
+ assert.equal(provider?.sessionId, "session-a");
201
+ assert.equal(provider?.sessionFile, "/tmp/session-a.jsonl");
202
+ assert.equal(provider?.isActive(), true);
203
+ active = false;
204
+ assert.equal(provider?.isActive(), false);
205
+
206
+ release.release();
207
+ assert.equal(released, 1);
208
+ });
209
+ });
@@ -157,6 +157,43 @@ Project prompt.
157
157
  }
158
158
  });
159
159
 
160
+ it("projects concurrent children under distinct run-id roots for an explicit sessionDir", async () => {
161
+ const cwd = path.join(tempDir, "repo-session-dir-keying");
162
+ fs.mkdirSync(cwd, { recursive: true });
163
+ writeAgent(path.join(cwd, ".selesai", "agents", "worker.md"), `---\nname: worker\ndescription: Project worker\n---\nWorker.\n`);
164
+ const sessionDir = path.join(tempDir, "caller-sessions");
165
+ const runIds = ["run-123", "run-456"];
166
+
167
+ const projected = await Promise.all(runIds.map((runId) => resolveSubagentLaunchContract({
168
+ agent: "worker",
169
+ cwd,
170
+ task: "Inspect the repo",
171
+ runId,
172
+ sessionDir,
173
+ })));
174
+ assert.ok(projected.every((result) => result.ok));
175
+ for (const [index, result] of projected.entries()) {
176
+ if (!result.ok) continue;
177
+ const runId = runIds[index]!;
178
+ assert.equal(result.contract.roots.sessionFile, path.join(sessionDir, runId, "run-0", "session.jsonl"));
179
+ assert.equal(result.contract.roots.sessionDir, path.join(sessionDir, runId, "run-0"));
180
+ assert.equal(result.contract.roots.sessionRoot, path.join(sessionDir, runId));
181
+ }
182
+ assert.notEqual(projected[0]!.contract?.roots.sessionFile, projected[1]!.contract?.roots.sessionFile);
183
+
184
+ const withoutRunId = await resolveSubagentLaunchContract({
185
+ agent: "worker",
186
+ cwd,
187
+ task: "Inspect the repo",
188
+ sessionDir,
189
+ });
190
+ assert.equal(withoutRunId.ok, true);
191
+ if (withoutRunId.ok) {
192
+ assert.equal(withoutRunId.contract.roots.sessionFile, path.join(sessionDir, "preflight", "run-0", "session.jsonl"));
193
+ assert.equal(withoutRunId.contract.roots.sessionDir, path.join(sessionDir, "preflight", "run-0"));
194
+ }
195
+ });
196
+
160
197
  it("binds canonical extension metadata into public preflight provenance", async () => {
161
198
  const cwd = path.join(tempDir, "bindings-repo");
162
199
  fs.mkdirSync(cwd, { recursive: true });
@@ -975,4 +1012,4 @@ Project prompt.
975
1012
  assert.equal(result.code, "denied_required_tool");
976
1013
  assert.match(result.message, /Unresolved MCP direct-tool selectors: rt__wiki\/read_wiki_structure\./);
977
1014
  });
978
- });
1015
+ });
@@ -0,0 +1,43 @@
1
+ import assert from "node:assert/strict";
2
+ import { mkdtemp, mkdir, readFile, rm, writeFile } from "node:fs/promises";
3
+ import { tmpdir } from "node:os";
4
+ import { dirname, join } from "node:path";
5
+ import test from "node:test";
6
+ import { fileURLToPath, pathToFileURL } from "node:url";
7
+
8
+ const repositoryRoot = fileURLToPath(new URL("../..", import.meta.url));
9
+
10
+ test("ordinary prompt audit works without optional Pi peers", async () => {
11
+ const isolatedRoot = await mkdtemp(join(tmpdir(), "pi-subagents-prompt-audit-"));
12
+ const promptAuditPath = join(isolatedRoot, "src/runs/foreground/prompt-audit.ts");
13
+ const streamOptionsPath = join(isolatedRoot, "src/shared/agent-stream-options.ts");
14
+
15
+ try {
16
+ await mkdir(dirname(promptAuditPath), { recursive: true });
17
+ await mkdir(dirname(streamOptionsPath), { recursive: true });
18
+ await writeFile(
19
+ promptAuditPath,
20
+ await readFile(join(repositoryRoot, "src/runs/foreground/prompt-audit.ts"), "utf8"),
21
+ );
22
+ await writeFile(
23
+ streamOptionsPath,
24
+ await readFile(join(repositoryRoot, "src/shared/agent-stream-options.ts"), "utf8"),
25
+ );
26
+
27
+ const promptAudit = await import(pathToFileURL(promptAuditPath).href);
28
+ const control = {};
29
+ promptAudit.registerLivePromptAudit(control, 0, "authored", "before authored after");
30
+ assert.deepEqual(promptAudit.getLivePromptAudit(control, 0), {
31
+ authoredTask: "authored",
32
+ runtimeAdditions: "before\n\nafter",
33
+ finalEffectivePrompt: "before authored after",
34
+ });
35
+
36
+ promptAudit.updateLiveEffectivePrompt(control, 0, "next authored tail");
37
+ assert.equal(promptAudit.getLivePromptAudit(control, 0)?.runtimeAdditions, "next\n\ntail");
38
+ promptAudit.removeLivePromptAudit(control, 0);
39
+ assert.equal(promptAudit.getLivePromptAudit(control, 0), undefined);
40
+ } finally {
41
+ await rm(isolatedRoot, { recursive: true, force: true });
42
+ }
43
+ });
@@ -26,11 +26,12 @@ describe("public subagent execution normalization", () => {
26
26
  output: true,
27
27
  },
28
28
  });
29
- assert.deepEqual(normalizePublicSubagentExecution({ agent: "worker", async: true }), {
29
+ assert.deepEqual(normalizePublicSubagentExecution({ agent: "worker", async: true, baseRef: "@/foo" }), {
30
30
  ok: true,
31
31
  params: {
32
32
  agent: "worker",
33
33
  async: true,
34
+ baseRef: "@/foo",
34
35
  output: true,
35
36
  },
36
37
  });
@@ -69,6 +70,27 @@ describe("public subagent execution normalization", () => {
69
70
  );
70
71
  });
71
72
 
73
+ it("rejects unsafe base refs at the public boundary", () => {
74
+ for (const baseRef of ["refs/heads/unsafe..ref", "branch name", "HEAD^{tree}", "@", "a".repeat(40), "a".repeat(64), 42]) {
75
+ const result = normalizePublicSubagentExecution({ agent: "worker", baseRef });
76
+ assert.equal(result.ok, false, String(baseRef));
77
+ if (!result.ok) assert.match(result.error, /baseRef.*HEAD.*named ref.*40\/64-character commit IDs.*revision expressions.*unsupported/);
78
+ }
79
+ });
80
+
81
+ it("rejects base refs on management actions that do not consume them", () => {
82
+ const result = normalizePublicSubagentExecution({ action: "list", baseRef: "refs/heads/release" });
83
+ assert.equal(result.ok, false);
84
+ if (!result.ok) assert.match(result.error, /baseRef is only supported/);
85
+ });
86
+
87
+ it("accepts base refs on resume because resume consumes them", () => {
88
+ assert.deepEqual(normalizePublicSubagentExecution({ action: " resume ", id: "run-1", message: "Continue", baseRef: "refs/heads/release" }), {
89
+ ok: true,
90
+ params: { action: "resume", id: "run-1", message: "Continue", baseRef: "refs/heads/release" },
91
+ });
92
+ });
93
+
72
94
  it("rejects workflowScript with workflowScriptPath", () => {
73
95
  const result = normalizePublicSubagentExecution({ workflowScript: "return 1", workflowScriptPath: "workflow.js" });
74
96
  assert.equal(result.ok, false);
@@ -179,4 +201,4 @@ describe("public subagent execution normalization", () => {
179
201
  assert.equal(normalizePublicSubagentExecution(params).ok, false, JSON.stringify(params));
180
202
  }
181
203
  });
182
- });
204
+ });