@selesai/code 0.13.16 → 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 (467) hide show
  1. package/CHANGELOG.md +30 -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/pi-hermes-memory/CHANGELOG.md +18 -0
  65. package/dist/extensions/pi-hermes-memory/README.md +16 -12
  66. package/dist/extensions/pi-hermes-memory/docs/ROADMAP.md +1 -1
  67. package/dist/extensions/pi-hermes-memory/package-lock.json +587 -62
  68. package/dist/extensions/pi-hermes-memory/package.json +4 -4
  69. package/dist/extensions/pi-hermes-memory/src/config.ts +32 -0
  70. package/dist/extensions/pi-hermes-memory/src/constants.ts +12 -2
  71. package/dist/extensions/pi-hermes-memory/src/handlers/background-review.ts +109 -51
  72. package/dist/extensions/pi-hermes-memory/src/handlers/index-sessions.ts +9 -3
  73. package/dist/extensions/pi-hermes-memory/src/handlers/review-memory-ops.ts +257 -98
  74. package/dist/extensions/pi-hermes-memory/src/handlers/session-backfill.ts +9 -2
  75. package/dist/extensions/pi-hermes-memory/src/handlers/sync-markdown-memories.ts +5 -0
  76. package/dist/extensions/pi-hermes-memory/src/index.ts +22 -2
  77. package/dist/extensions/pi-hermes-memory/src/paths.ts +1 -1
  78. package/dist/extensions/pi-hermes-memory/src/store/db.ts +6 -0
  79. package/dist/extensions/pi-hermes-memory/src/store/fts-query.ts +58 -1
  80. package/dist/extensions/pi-hermes-memory/src/store/memory-store.ts +60 -8
  81. package/dist/extensions/pi-hermes-memory/src/store/session-indexer.ts +169 -7
  82. package/dist/extensions/pi-hermes-memory/src/store/session-search.ts +7 -21
  83. package/dist/extensions/pi-hermes-memory/src/store/sqlite-memory-store.ts +134 -15
  84. package/dist/extensions/pi-hermes-memory/src/tools/memory-search-tool.ts +4 -2
  85. package/dist/extensions/pi-hermes-memory/src/tools/memory-tool.ts +24 -9
  86. package/dist/extensions/pi-hermes-memory/src/types.ts +11 -0
  87. package/dist/extensions/pi-hermes-memory/tests/config.test.ts +42 -0
  88. package/dist/extensions/pi-hermes-memory/tests/handlers/background-review.test.ts +159 -3
  89. package/dist/extensions/pi-hermes-memory/tests/handlers/review-memory-ops.test.ts +452 -0
  90. package/dist/extensions/pi-hermes-memory/tests/handlers/session-backfill.test.ts +39 -0
  91. package/dist/extensions/pi-hermes-memory/tests/integration/corruption-recovery-integration.test.ts +91 -0
  92. package/dist/extensions/pi-hermes-memory/tests/store/db.test.ts +29 -0
  93. package/dist/extensions/pi-hermes-memory/tests/store/fts-query.test.ts +116 -0
  94. package/dist/extensions/pi-hermes-memory/tests/store/memory-store.test.ts +163 -0
  95. package/dist/extensions/pi-hermes-memory/tests/store/session-indexer.test.ts +233 -0
  96. package/dist/extensions/pi-hermes-memory/tests/store/session-search.test.ts +12 -0
  97. package/dist/extensions/pi-hermes-memory/tests/store/sqlite-memory-store.test.ts +175 -0
  98. package/dist/extensions/pi-hermes-memory/tests/store/sqlite-native.test.ts +2 -2
  99. package/dist/extensions/pi-hermes-memory/tests/tools/memory-search-tool.test.ts +22 -0
  100. package/dist/extensions/pi-hermes-memory/tests/tools/memory-tool.test.ts +37 -1
  101. package/dist/extensions/pi-intercom/CHANGELOG.md +13 -0
  102. package/dist/extensions/pi-intercom/README.md +16 -2
  103. package/dist/extensions/pi-intercom/broker/spawn.test.ts +19 -2
  104. package/dist/extensions/pi-intercom/broker/spawn.ts +4 -4
  105. package/dist/extensions/pi-intercom/index.ts +1 -1
  106. package/dist/extensions/pi-intercom/intercom.integration.test.ts +121 -2
  107. package/dist/extensions/pi-intercom/package.json +1 -1
  108. package/dist/extensions/pi-intercom/project-agent.test.ts +1 -1
  109. package/dist/extensions/pi-intercom/project-agent.ts +1 -6
  110. package/dist/extensions/pi-intercom/skills/pi-intercom/SKILL.md +7 -6
  111. package/dist/extensions/pi-rewind-hook/index.test.ts +7 -0
  112. package/dist/extensions/pi-subagents/.github/workflows/test.yml +36 -4
  113. package/dist/extensions/pi-subagents/CHANGELOG.md +120 -0
  114. package/dist/extensions/pi-subagents/README.md +3 -3
  115. package/dist/extensions/pi-subagents/agents/researcher.md +23 -13
  116. package/dist/extensions/pi-subagents/agents/reviewer.md +1 -1
  117. package/dist/extensions/pi-subagents/agents/scout.md +1 -1
  118. package/dist/extensions/pi-subagents/docs/agents.md +32 -16
  119. package/dist/extensions/pi-subagents/docs/configuration.md +41 -15
  120. package/dist/extensions/pi-subagents/docs/extension-api.md +109 -6
  121. package/dist/extensions/pi-subagents/docs/missions.md +2 -0
  122. package/dist/extensions/pi-subagents/docs/models.md +58 -1
  123. package/dist/extensions/pi-subagents/docs/observability.md +50 -12
  124. package/dist/extensions/pi-subagents/docs/tool-reference.md +17 -10
  125. package/dist/extensions/pi-subagents/docs/watchdog.md +1 -1
  126. package/dist/extensions/pi-subagents/docs/workflows.md +26 -9
  127. package/dist/extensions/pi-subagents/package-lock.json +747 -177
  128. package/dist/extensions/pi-subagents/package.json +6 -4
  129. package/dist/extensions/pi-subagents/runner-server-preload.mjs +13 -0
  130. package/dist/extensions/pi-subagents/skills/pi-subagents/SKILL.md +2 -1
  131. package/dist/extensions/pi-subagents/skills/pi-subagents/references/constraints-and-recipes.md +1 -1
  132. package/dist/extensions/pi-subagents/skills/pi-subagents/references/execution-controls.md +21 -4
  133. package/dist/extensions/pi-subagents/skills/pi-subagents/references/management-authoring-rpc.md +2 -1
  134. package/dist/extensions/pi-subagents/skills/pi-subagents/references/multi-lane-orchestration.md +2 -0
  135. package/dist/extensions/pi-subagents/src/agents/advertised-agent-prompt.ts +63 -0
  136. package/dist/extensions/pi-subagents/src/agents/agent-management.ts +61 -16
  137. package/dist/extensions/pi-subagents/src/agents/agent-serializer.ts +2 -0
  138. package/dist/extensions/pi-subagents/src/agents/agents.ts +8 -0
  139. package/dist/extensions/pi-subagents/src/api/capability-ceiling.ts +0 -1
  140. package/dist/extensions/pi-subagents/src/api/{pi-args.ts → child-tool-plan.ts} +1 -1
  141. package/dist/extensions/pi-subagents/src/api/preflight.ts +7 -4
  142. package/dist/extensions/pi-subagents/src/api/shared-types.ts +2 -2
  143. package/dist/extensions/pi-subagents/src/api/workflow-resources.ts +6 -0
  144. package/dist/extensions/pi-subagents/src/extension/config.ts +4 -2
  145. package/dist/extensions/pi-subagents/src/extension/doctor.ts +2 -10
  146. package/dist/extensions/pi-subagents/src/extension/fanout-child.ts +9 -11
  147. package/dist/extensions/pi-subagents/src/extension/index.ts +99 -10
  148. package/dist/extensions/pi-subagents/src/extension/public-execution.ts +13 -0
  149. package/dist/extensions/pi-subagents/src/extension/rpc.ts +7 -23
  150. package/dist/extensions/pi-subagents/src/extension/schemas.ts +11 -8
  151. package/dist/extensions/pi-subagents/src/extension/tool-description.ts +25 -7
  152. package/dist/extensions/pi-subagents/src/integrations/pi-web-session-liveness.ts +73 -0
  153. package/dist/extensions/pi-subagents/src/intercom/native-supervisor-channel.ts +228 -136
  154. package/dist/extensions/pi-subagents/src/intercom/supervisor-ui.ts +244 -0
  155. package/dist/extensions/pi-subagents/src/missions/workflow-state.ts +37 -16
  156. package/dist/extensions/pi-subagents/src/runs/background/active-async-capacity.ts +18 -18
  157. package/dist/extensions/pi-subagents/src/runs/background/async-execution.ts +51 -25
  158. package/dist/extensions/pi-subagents/src/runs/background/async-job-tracker.ts +46 -3
  159. package/dist/extensions/pi-subagents/src/runs/background/async-resume.ts +14 -3
  160. package/dist/extensions/pi-subagents/src/runs/background/async-retention.ts +9 -0
  161. package/dist/extensions/pi-subagents/src/runs/background/async-status-snapshot.ts +10 -12
  162. package/dist/extensions/pi-subagents/src/runs/background/async-status.ts +18 -15
  163. package/dist/extensions/pi-subagents/src/runs/background/auto-drain.ts +40 -29
  164. package/dist/extensions/pi-subagents/src/runs/background/chain-root-attachment.ts +8 -0
  165. package/dist/extensions/pi-subagents/src/runs/background/control-channel.ts +79 -247
  166. package/dist/extensions/pi-subagents/src/runs/background/notify.ts +88 -12
  167. package/dist/extensions/pi-subagents/src/runs/background/owned-process-tree.ts +6 -6
  168. package/dist/extensions/pi-subagents/src/runs/background/process-terminal.ts +24 -24
  169. package/dist/extensions/pi-subagents/src/runs/background/retained-nested-route-tracker.ts +96 -0
  170. package/dist/extensions/pi-subagents/src/runs/background/run-child-session.ts +642 -0
  171. package/dist/extensions/pi-subagents/src/runs/background/run-status.ts +75 -6
  172. package/dist/extensions/pi-subagents/src/runs/background/runner-aliases.ts +163 -0
  173. package/dist/extensions/pi-subagents/src/runs/background/runner-child-launch.ts +86 -0
  174. package/dist/extensions/pi-subagents/src/runs/background/runner-child-sessions.ts +31 -0
  175. package/dist/extensions/pi-subagents/src/runs/background/scheduled-runs.ts +18 -4
  176. package/dist/extensions/pi-subagents/src/runs/background/stale-run-reconciler.ts +3 -1
  177. package/dist/extensions/pi-subagents/src/runs/background/subagent-runner.ts +597 -1092
  178. package/dist/extensions/pi-subagents/src/runs/background/subagent-wait.ts +3 -0
  179. package/dist/extensions/pi-subagents/src/runs/background/wait-completions.ts +4 -0
  180. package/dist/extensions/pi-subagents/src/runs/foreground/async-steering-action.ts +20 -17
  181. package/dist/extensions/pi-subagents/src/runs/foreground/execution.ts +296 -394
  182. package/dist/extensions/pi-subagents/src/runs/foreground/foreground-control.ts +4 -0
  183. package/dist/extensions/pi-subagents/src/runs/foreground/foreground-history.ts +3 -1
  184. package/dist/extensions/pi-subagents/src/runs/foreground/prompt-audit.ts +9 -5
  185. package/dist/extensions/pi-subagents/src/runs/foreground/subagent-executor.ts +630 -283
  186. package/dist/extensions/pi-subagents/src/runs/foreground/workflow-detach-reconcile.ts +8 -5
  187. package/dist/extensions/pi-subagents/src/runs/foreground/workflow-foreground-steering.ts +78 -98
  188. package/dist/extensions/pi-subagents/src/runs/shared/abort-recovery.ts +3 -3
  189. package/dist/extensions/pi-subagents/src/runs/shared/acceptance.ts +16 -3
  190. package/dist/extensions/pi-subagents/src/runs/shared/agent-contract.ts +1 -1
  191. package/dist/extensions/pi-subagents/src/runs/shared/async-status-projection.ts +47 -47
  192. package/dist/extensions/pi-subagents/src/runs/shared/capability-ceiling.ts +1 -2
  193. package/dist/extensions/pi-subagents/src/runs/shared/child-hooks.ts +174 -0
  194. package/dist/extensions/pi-subagents/src/runs/shared/child-identity.ts +14 -3
  195. package/dist/extensions/pi-subagents/src/runs/shared/child-launch.ts +319 -0
  196. package/dist/extensions/pi-subagents/src/runs/shared/child-lifecycle.ts +25 -0
  197. package/dist/extensions/pi-subagents/src/runs/shared/child-runtime-config.ts +126 -0
  198. package/dist/extensions/pi-subagents/src/runs/shared/child-session.ts +373 -0
  199. package/dist/extensions/pi-subagents/src/runs/shared/child-tool-plan.ts +530 -0
  200. package/dist/extensions/pi-subagents/src/runs/shared/completion-evidence.ts +2 -2
  201. package/dist/extensions/pi-subagents/src/runs/shared/completion-guard.ts +2 -1
  202. package/dist/extensions/pi-subagents/src/runs/shared/external-cli-preflight.ts +16 -0
  203. package/dist/extensions/pi-subagents/src/runs/shared/host-step-status.ts +11 -11
  204. package/dist/extensions/pi-subagents/src/runs/shared/llm-intent-arbiter.ts +30 -20
  205. package/dist/extensions/pi-subagents/src/runs/shared/mcp-direct-tool-allowlist.ts +5 -4
  206. package/dist/extensions/pi-subagents/src/runs/shared/model-exclusions.ts +84 -15
  207. package/dist/extensions/pi-subagents/src/runs/shared/model-fallback.ts +88 -12
  208. package/dist/extensions/pi-subagents/src/runs/shared/nested-events.ts +37 -53
  209. package/dist/extensions/pi-subagents/src/runs/shared/nested-path.ts +1 -1
  210. package/dist/extensions/pi-subagents/src/runs/shared/orca-progress-tabs.ts +18 -7
  211. package/dist/extensions/pi-subagents/src/runs/shared/parallel-handoff.ts +57 -12
  212. package/dist/extensions/pi-subagents/src/runs/shared/parallel-utils.ts +3 -4
  213. package/dist/extensions/pi-subagents/src/runs/shared/permissions.ts +0 -11
  214. package/dist/extensions/pi-subagents/src/runs/shared/process-signal.ts +4 -1
  215. package/dist/extensions/pi-subagents/src/runs/shared/readonly-drain-observation.ts +42 -0
  216. package/dist/extensions/pi-subagents/src/runs/shared/readonly-model-continuation.ts +69 -0
  217. package/dist/extensions/pi-subagents/src/runs/shared/readonly-session-evidence.ts +307 -0
  218. package/dist/extensions/pi-subagents/src/runs/shared/run-fanout-budget.ts +8 -21
  219. package/dist/extensions/pi-subagents/src/runs/shared/runtime-acknowledged-extensions.ts +3 -30
  220. package/dist/extensions/pi-subagents/src/runs/shared/structured-output.ts +17 -4
  221. package/dist/extensions/pi-subagents/src/runs/shared/subagent-control.ts +2 -0
  222. package/dist/extensions/pi-subagents/src/runs/shared/subagent-prompt-runtime.ts +99 -386
  223. package/dist/extensions/pi-subagents/src/runs/shared/tool-availability.ts +18 -62
  224. package/dist/extensions/pi-subagents/src/runs/shared/tool-budget.ts +0 -14
  225. package/dist/extensions/pi-subagents/src/runs/shared/worktree-cleanup-plan.ts +31 -9
  226. package/dist/extensions/pi-subagents/src/runs/shared/worktree-setup-command.ts +190 -0
  227. package/dist/extensions/pi-subagents/src/runs/shared/worktree.ts +506 -226
  228. package/dist/extensions/pi-subagents/src/shared/child-session-name.ts +1 -1
  229. package/dist/extensions/pi-subagents/src/shared/jsonl-writer.ts +11 -0
  230. package/dist/extensions/pi-subagents/src/shared/model-response-aliases.ts +13 -0
  231. package/dist/extensions/pi-subagents/src/shared/thinking-ceiling.ts +0 -6
  232. package/dist/extensions/pi-subagents/src/shared/types.ts +145 -89
  233. package/dist/extensions/pi-subagents/src/shared/utils.ts +13 -6
  234. package/dist/extensions/pi-subagents/src/shared/watch-strategy.ts +2 -0
  235. package/dist/extensions/pi-subagents/src/shared/workflow-child-permit.ts +18 -13
  236. package/dist/extensions/pi-subagents/src/slash/slash-commands.ts +0 -6
  237. package/dist/extensions/pi-subagents/src/tui/fleet-status.ts +1 -1
  238. package/dist/extensions/pi-subagents/src/tui/fleet.ts +11 -6
  239. package/dist/extensions/pi-subagents/src/tui/render.ts +277 -46
  240. package/dist/extensions/pi-subagents/src/watchdog/child-status.ts +0 -1
  241. package/dist/extensions/pi-subagents/src/watchdog/register-child.ts +12 -12
  242. package/dist/extensions/pi-subagents/src/workflows/chat-progress.ts +3 -3
  243. package/dist/extensions/pi-subagents/src/workflows/scripted-workflow.ts +116 -15
  244. package/dist/extensions/pi-subagents/src/workflows/workflow-checklist.ts +15 -18
  245. package/dist/extensions/pi-subagents/src/workflows/workflow-child-summary.ts +57 -8
  246. package/dist/extensions/pi-subagents/src/workflows/workflow-preflight.ts +19 -19
  247. package/dist/extensions/pi-subagents/src/workflows/workflow-receipt.ts +3 -3
  248. package/dist/extensions/pi-subagents/src/workflows/workflow-resources.ts +97 -22
  249. package/dist/extensions/pi-subagents/src/workflows/workflow-settlement.ts +3 -0
  250. package/dist/extensions/pi-subagents/test/integration/acceptance-file-report.test.ts +336 -21
  251. package/dist/extensions/pi-subagents/test/integration/async-execution.part-1.test.ts +1181 -0
  252. package/dist/extensions/pi-subagents/test/integration/async-execution.part-2.test.ts +2240 -0
  253. package/dist/extensions/pi-subagents/test/integration/async-execution.part-3.test.ts +2268 -0
  254. package/dist/extensions/pi-subagents/test/integration/async-execution.part-4.test.ts +1512 -0
  255. package/dist/extensions/pi-subagents/test/integration/async-job-tracker.test.ts +231 -16
  256. package/dist/extensions/pi-subagents/test/integration/error-handling.test.ts +4 -18
  257. package/dist/extensions/pi-subagents/test/integration/foreign-workflow-steering.test.ts +95 -0
  258. package/dist/extensions/pi-subagents/test/integration/fork-context-execution.test.ts +9 -15
  259. package/dist/extensions/pi-subagents/test/integration/in-process-child.test.ts +374 -0
  260. package/dist/extensions/pi-subagents/test/integration/intercom-result-delivery.test.ts +20 -10
  261. package/dist/extensions/pi-subagents/test/integration/orca-progress-tabs.test.ts +18 -6
  262. package/dist/extensions/pi-subagents/test/integration/recovered-assistant-error.test.ts +151 -0
  263. package/dist/extensions/pi-subagents/test/integration/render-fork-badge.test.ts +42 -1
  264. package/dist/extensions/pi-subagents/test/integration/render-widget.test.ts +150 -25
  265. package/dist/extensions/pi-subagents/test/integration/result-publication.test.ts +354 -0
  266. package/dist/extensions/pi-subagents/test/integration/shared-cwd-terminal-evidence.test.ts +117 -0
  267. package/dist/extensions/pi-subagents/test/integration/single-execution.part-1.test.ts +3678 -0
  268. package/dist/extensions/pi-subagents/test/integration/{single-execution.test.ts → single-execution.part-2.test.ts} +500 -4207
  269. package/dist/extensions/pi-subagents/test/integration/slash-commands.test.ts +1 -2
  270. package/dist/extensions/pi-subagents/test/integration/workflow-result-publication.test.ts +127 -0
  271. package/dist/extensions/pi-subagents/test/integration/workflow-steer-inbox.test.ts +365 -0
  272. package/dist/extensions/pi-subagents/test/smoke/pi085-child.ts +31 -0
  273. package/dist/extensions/pi-subagents/test/smoke/pi085-clean-install.mjs +74 -0
  274. package/dist/extensions/pi-subagents/test/smoke/pi085-extension.ts +16 -0
  275. package/dist/extensions/pi-subagents/test/support/async-execution-fixture.ts +699 -0
  276. package/dist/extensions/pi-subagents/test/support/fake-child-session.ts +418 -0
  277. package/dist/extensions/pi-subagents/test/support/foreign-workflow-steer-host.mjs +13 -0
  278. package/dist/extensions/pi-subagents/test/support/mock-pi.ts +30 -76
  279. package/dist/extensions/pi-subagents/test/support/notify-diagnostics-fixture.ts +84 -0
  280. package/dist/extensions/pi-subagents/test/support/result-publication-capacity-preload.mjs +70 -0
  281. package/dist/extensions/pi-subagents/test/support/runner-child-session-factory.ts +17 -0
  282. package/dist/extensions/pi-subagents/test/support/single-execution-fixture.ts +390 -0
  283. package/dist/extensions/pi-subagents/test/unit/acceptance-compaction.test.ts +120 -0
  284. package/dist/extensions/pi-subagents/test/unit/acceptance.test.ts +24 -3
  285. package/dist/extensions/pi-subagents/test/unit/advertised-agent-prompt.test.ts +87 -0
  286. package/dist/extensions/pi-subagents/test/unit/advertised-agent-refresh.test.ts +163 -0
  287. package/dist/extensions/pi-subagents/test/unit/agent-frontmatter.test.ts +70 -31
  288. package/dist/extensions/pi-subagents/test/unit/agent-management.test.ts +78 -3
  289. package/dist/extensions/pi-subagents/test/unit/agent-overrides.test.ts +2 -8
  290. package/dist/extensions/pi-subagents/test/unit/async-execution.test.ts +1 -1
  291. package/dist/extensions/pi-subagents/test/unit/async-interrupt-action.test.ts +73 -66
  292. package/dist/extensions/pi-subagents/test/unit/async-recovery-descriptor.test.ts +51 -1
  293. package/dist/extensions/pi-subagents/test/unit/async-retention.test.ts +49 -1
  294. package/dist/extensions/pi-subagents/test/unit/async-spawn-preload.test.ts +103 -0
  295. package/dist/extensions/pi-subagents/test/unit/async-status-projection.test.ts +3 -3
  296. package/dist/extensions/pi-subagents/test/unit/capability-ceiling-agent-allowlist.test.ts +9 -8
  297. package/dist/extensions/pi-subagents/test/unit/capability-ceiling.test.ts +10 -7
  298. package/dist/extensions/pi-subagents/test/unit/chain-root-attachment.test.ts +48 -6
  299. package/dist/extensions/pi-subagents/test/unit/child-runtime-config.test.ts +90 -0
  300. package/dist/extensions/pi-subagents/test/unit/{pi-args-permission-system.test.ts → child-tool-plan-permission-system.test.ts} +48 -86
  301. package/dist/extensions/pi-subagents/test/unit/child-tool-plan.test.ts +33 -0
  302. package/dist/extensions/pi-subagents/test/unit/compaction-resume.test.ts +18 -18
  303. package/dist/extensions/pi-subagents/test/unit/completion-evidence.test.ts +9 -9
  304. package/dist/extensions/pi-subagents/test/unit/completion-guard.test.ts +8 -7
  305. package/dist/extensions/pi-subagents/test/unit/control-channel.test.ts +225 -65
  306. package/dist/extensions/pi-subagents/test/unit/extension-bindings.test.ts +17 -22
  307. package/dist/extensions/pi-subagents/test/unit/fleet-status.test.ts +11 -1
  308. package/dist/extensions/pi-subagents/test/unit/fleet.test.ts +47 -3
  309. package/dist/extensions/pi-subagents/test/unit/foreign-workflow-steering.test.ts +74 -0
  310. package/dist/extensions/pi-subagents/test/unit/fork-cache-key.test.ts +23 -29
  311. package/dist/extensions/pi-subagents/test/unit/host-peer-runtime-imports.test.ts +96 -4
  312. package/dist/extensions/pi-subagents/test/unit/host-step-status.test.ts +4 -4
  313. package/dist/extensions/pi-subagents/test/unit/index-child-registration.test.ts +116 -55
  314. package/dist/extensions/pi-subagents/test/unit/index-segment.test.ts +58 -1
  315. package/dist/extensions/pi-subagents/test/unit/llm-intent-arbiter.test.ts +104 -3
  316. package/dist/extensions/pi-subagents/test/unit/mission-lifecycle.test.ts +10 -1
  317. package/dist/extensions/pi-subagents/test/unit/mission-store.test.ts +31 -1
  318. package/dist/extensions/pi-subagents/test/unit/model-exclusions.test.ts +102 -51
  319. package/dist/extensions/pi-subagents/test/unit/model-fallback.test.ts +196 -6
  320. package/dist/extensions/pi-subagents/test/unit/native-supervisor-channel.test.ts +181 -38
  321. package/dist/extensions/pi-subagents/test/unit/nested-control.test.ts +62 -70
  322. package/dist/extensions/pi-subagents/test/unit/nested-events.test.ts +58 -53
  323. package/dist/extensions/pi-subagents/test/unit/notify-diagnostics.test.ts +42 -0
  324. package/dist/extensions/pi-subagents/test/unit/notify.test.ts +84 -0
  325. package/dist/extensions/pi-subagents/test/unit/orca-progress-tabs.test.ts +13 -5
  326. package/dist/extensions/pi-subagents/test/unit/package-manifest.test.ts +21 -5
  327. package/dist/extensions/pi-subagents/test/unit/parallel-handoff.test.ts +5 -4
  328. package/dist/extensions/pi-subagents/test/unit/permissions.test.ts +2 -6
  329. package/dist/extensions/pi-subagents/test/unit/pi-coding-agent-dir.test.ts +28 -2
  330. package/dist/extensions/pi-subagents/test/unit/pi-web-session-liveness.test.ts +209 -0
  331. package/dist/extensions/pi-subagents/test/unit/preflight.test.ts +38 -1
  332. package/dist/extensions/pi-subagents/test/unit/prompt-audit-optional-peers.test.ts +43 -0
  333. package/dist/extensions/pi-subagents/test/unit/public-execution.test.ts +24 -2
  334. package/dist/extensions/pi-subagents/test/unit/readonly-drain-observation.test.ts +174 -0
  335. package/dist/extensions/pi-subagents/test/unit/readonly-model-continuation.test.ts +94 -0
  336. package/dist/extensions/pi-subagents/test/unit/readonly-session-evidence.test.ts +1329 -0
  337. package/dist/extensions/pi-subagents/test/unit/recursion-guard.test.ts +29 -80
  338. package/dist/extensions/pi-subagents/test/unit/render-helpers.test.ts +11 -8
  339. package/dist/extensions/pi-subagents/test/unit/result-files.test.ts +2 -2
  340. package/dist/extensions/pi-subagents/test/unit/retained-nested-route-tracker.test.ts +175 -0
  341. package/dist/extensions/pi-subagents/test/unit/rpc.test.ts +38 -12
  342. package/dist/extensions/pi-subagents/test/unit/run-fanout-budget.test.ts +2 -5
  343. package/dist/extensions/pi-subagents/test/unit/run-status.test.ts +89 -1
  344. package/dist/extensions/pi-subagents/test/unit/runtime-acknowledged-extensions.test.ts +2 -16
  345. package/dist/extensions/pi-subagents/test/unit/scheduled-runs.test.ts +27 -3
  346. package/dist/extensions/pi-subagents/test/unit/scheduled-supervisor-demand.test.ts +215 -0
  347. package/dist/extensions/pi-subagents/test/unit/schemas.test.ts +15 -11
  348. package/dist/extensions/pi-subagents/test/unit/scripted-workflow.test.ts +237 -1
  349. package/dist/extensions/pi-subagents/test/unit/steering-action.test.ts +2 -5
  350. package/dist/extensions/pi-subagents/test/unit/streamed-progress-bounds.test.ts +2 -2
  351. package/dist/extensions/pi-subagents/test/unit/subagent-guide.test.ts +14 -1
  352. package/dist/extensions/pi-subagents/test/unit/subagent-prompt-runtime.test.ts +130 -739
  353. package/dist/extensions/pi-subagents/test/unit/supervisor-ask-registration.test.ts +682 -0
  354. package/dist/extensions/pi-subagents/test/unit/supervisor-ui.test.ts +137 -0
  355. package/dist/extensions/pi-subagents/test/unit/tool-budget.test.ts +1 -11
  356. package/dist/extensions/pi-subagents/test/unit/tool-description.test.ts +23 -3
  357. package/dist/extensions/pi-subagents/test/unit/wait-completions.test.ts +8 -1
  358. package/dist/extensions/pi-subagents/test/unit/watchdog-tool-actions.test.ts +19 -1
  359. package/dist/extensions/pi-subagents/test/unit/workflow-chat-progress.test.ts +72 -4
  360. package/dist/extensions/pi-subagents/test/unit/workflow-checklist.test.ts +17 -3
  361. package/dist/extensions/pi-subagents/test/unit/workflow-child-summary.test.ts +34 -0
  362. package/dist/extensions/pi-subagents/test/unit/workflow-detach-reconcile.test.ts +12 -2
  363. package/dist/extensions/pi-subagents/test/unit/workflow-launch-params.test.ts +46 -6
  364. package/dist/extensions/pi-subagents/test/unit/workflow-receipt.test.ts +3 -3
  365. package/dist/extensions/pi-subagents/test/unit/workflow-resources.test.ts +133 -1
  366. package/dist/extensions/pi-subagents/test/unit/workflow-resume-hint.test.ts +53 -2
  367. package/dist/extensions/pi-subagents/test/unit/worktree-cleanup-plan.test.ts +222 -14
  368. package/dist/extensions/pi-subagents/test/unit/worktree.test.ts +526 -85
  369. package/dist/extensions/pi-zentui/README.md +17 -0
  370. package/dist/extensions/pi-zentui/assets/screenshots/footer-status-hyperlink.png +0 -0
  371. package/dist/extensions/pi-zentui/docs/configuration.md +71 -2
  372. package/dist/extensions/pi-zentui/extensions/zentui/config.ts +11 -0
  373. package/dist/extensions/pi-zentui/extensions/zentui/editor-transfer.ts +14 -0
  374. package/dist/extensions/pi-zentui/extensions/zentui/extension-status.ts +29 -13
  375. package/dist/extensions/pi-zentui/extensions/zentui/footer-layout.ts +5 -4
  376. package/dist/extensions/pi-zentui/extensions/zentui/footer-text.ts +11 -0
  377. package/dist/extensions/pi-zentui/extensions/zentui/footer.ts +11 -10
  378. package/dist/extensions/pi-zentui/extensions/zentui/index.ts +77 -3
  379. package/dist/extensions/pi-zentui/extensions/zentui/presets.ts +77 -0
  380. package/dist/extensions/pi-zentui/extensions/zentui/settings-command.ts +103 -2
  381. package/dist/extensions/pi-zentui/extensions/zentui/working-line-extension-segments.ts +115 -0
  382. package/dist/extensions/pi-zentui/extensions/zentui/working-line.ts +87 -5
  383. package/dist/extensions/pi-zentui/package-lock.json +277 -517
  384. package/dist/extensions/pi-zentui/package.json +7 -4
  385. package/dist/extensions/pi-zentui/test/config-presets.test.ts +238 -0
  386. package/dist/extensions/pi-zentui/test/editor-transfer.test.ts +24 -1
  387. package/dist/extensions/pi-zentui/test/extension-compliance.test.ts +570 -2
  388. package/dist/extensions/pi-zentui/test/extension-status.test.ts +90 -0
  389. package/dist/extensions/pi-zentui/test/footer-hyperlink.test.ts +243 -0
  390. package/dist/extensions/pi-zentui/test/package-contents.mjs +1 -0
  391. package/dist/extensions/pi-zentui/test/presets.test.ts +121 -0
  392. package/dist/extensions/pi-zentui/test/settings-command.test.ts +205 -1
  393. package/dist/extensions/pi-zentui/test/working-line-extension-segments.test.ts +139 -0
  394. package/dist/extensions/pi-zentui/test/working-line-lifecycle.integration.test.ts +237 -3
  395. package/dist/extensions/pi-zentui/test/working-line.test.ts +94 -2
  396. package/dist/index.d.ts +1 -1
  397. package/dist/main.js +4 -1
  398. package/dist/modes/interactive/chat-viewport.d.ts +19 -0
  399. package/dist/modes/interactive/chat-viewport.js +27 -0
  400. package/dist/modes/interactive/components/assistant-message.d.ts +6 -2
  401. package/dist/modes/interactive/components/assistant-message.js +30 -13
  402. package/dist/modes/interactive/components/custom-editor.d.ts +10 -1
  403. package/dist/modes/interactive/components/custom-editor.js +39 -1
  404. package/dist/modes/interactive/components/first-time-setup.js +1 -1
  405. package/dist/modes/interactive/components/index.d.ts +1 -1
  406. package/dist/modes/interactive/components/markdown-transform.d.ts +2 -0
  407. package/dist/modes/interactive/components/markdown-transform.js +18 -0
  408. package/dist/modes/interactive/components/model-selector.js +19 -17
  409. package/dist/modes/interactive/components/scoped-models-selector.js +21 -23
  410. package/dist/modes/interactive/components/settings-selector.d.ts +7 -1
  411. package/dist/modes/interactive/components/settings-selector.js +128 -20
  412. package/dist/modes/interactive/components/settings-submenu.d.ts +71 -0
  413. package/dist/modes/interactive/components/settings-submenu.js +164 -0
  414. package/dist/modes/interactive/components/status-indicator.d.ts +3 -1
  415. package/dist/modes/interactive/components/status-indicator.js +10 -3
  416. package/dist/modes/interactive/components/thinking-selector.d.ts +15 -3
  417. package/dist/modes/interactive/components/thinking-selector.js +75 -18
  418. package/dist/modes/interactive/components/tool-execution.d.ts +21 -4
  419. package/dist/modes/interactive/components/tool-execution.js +35 -33
  420. package/dist/modes/interactive/components/trust-selector.js +2 -2
  421. package/dist/modes/interactive/interactive-mode.d.ts +13 -15
  422. package/dist/modes/interactive/interactive-mode.js +144 -80
  423. package/dist/modes/interactive/session-share.d.ts +15 -0
  424. package/dist/modes/interactive/session-share.js +183 -0
  425. package/dist/modes/interactive/theme/dark.json +2 -1
  426. package/dist/modes/interactive/theme/light.json +2 -1
  427. package/dist/modes/interactive/theme/theme-controller.d.ts +1 -0
  428. package/dist/modes/interactive/theme/theme-controller.js +5 -0
  429. package/dist/modes/interactive/theme/theme-json.d.ts +83 -0
  430. package/dist/modes/interactive/theme/theme-json.js +129 -0
  431. package/dist/modes/interactive/theme/theme-schema.json +9 -1
  432. package/dist/modes/interactive/theme/theme.d.ts +14 -5
  433. package/dist/modes/interactive/theme/theme.js +18 -119
  434. package/dist/modes/interactive/tui-renderer.d.ts +20 -0
  435. package/dist/modes/interactive/tui-renderer.js +65 -0
  436. package/dist/utils/exif-orientation.js +2 -3
  437. package/dist/utils/management-http.d.ts +24 -0
  438. package/dist/utils/management-http.js +53 -0
  439. package/dist/utils/text.d.ts +7 -0
  440. package/dist/utils/text.js +8 -0
  441. package/dist/utils/tools-manager.d.ts +1 -0
  442. package/dist/utils/tools-manager.js +43 -21
  443. package/docs/docs.json +0 -4
  444. package/package.json +4 -4
  445. package/dist/extensions/pi-subagents/src/runs/shared/child-protocol.ts +0 -415
  446. package/dist/extensions/pi-subagents/src/runs/shared/pi-args.ts +0 -1059
  447. package/dist/extensions/pi-subagents/src/runs/shared/subagent-startup-retry.ts +0 -116
  448. package/dist/extensions/pi-subagents/src/shared/post-exit-stdio-guard.ts +0 -85
  449. package/dist/extensions/pi-subagents/test/e2e/real-session-subagent.test.ts +0 -224
  450. package/dist/extensions/pi-subagents/test/integration/async-execution.test.ts +0 -6986
  451. package/dist/extensions/pi-subagents/test/support/mock-pi-script.mjs +0 -447
  452. package/dist/extensions/pi-subagents/test/support/real-session-child-cli.mjs +0 -185
  453. package/dist/extensions/pi-subagents/test/support/real-session-runner.ts +0 -311
  454. package/dist/extensions/pi-subagents/test/unit/capability-ceiling-pi-args.test.ts +0 -84
  455. package/dist/extensions/pi-subagents/test/unit/child-protocol.test.ts +0 -202
  456. package/dist/extensions/pi-subagents/test/unit/close-grace-timer.test.ts +0 -101
  457. package/dist/extensions/pi-subagents/test/unit/pi-args.test.ts +0 -2347
  458. package/dist/extensions/pi-subagents/test/unit/subagent-startup-retry.test.ts +0 -104
  459. package/dist/extensions/pi-subagents/test/unit/windows-hide-spawn.test.ts +0 -49
  460. package/dist/skills/imagegen-frontend-mobile/SKILL.md +0 -1465
  461. package/dist/skills/imagegen-frontend-web/SKILL.md +0 -987
  462. package/dist/skills/implanger/SKILL.md +0 -70
  463. package/dist/skills/output/SKILL.md +0 -49
  464. package/dist/skills/planger/SKILL.md +0 -167
  465. package/dist/skills/workflow/SKILL.md +0 -95
  466. package/docs/workflows.md +0 -18
  467. /package/dist/bun/{register-bedrock.d.ts → runtime-setup.d.ts} +0 -0
@@ -0,0 +1,307 @@
1
+ /** Internal, opt-in factory evidence. No runner enables continuation through this module. */
2
+ import { createHash } from "node:crypto";
3
+ import { lstatSync, readFileSync } from "node:fs";
4
+ import { resolve } from "node:path";
5
+ import { isDeepStrictEqual } from "node:util";
6
+ import type { AgentSession, SessionEntry, SessionHeader } from "@selesai/code";
7
+ import type { ChildSession, ChildSessionLaunch, PiCodingAgentModule } from "./child-session.ts";
8
+ import { captureReadonlyChildDrain, isReadonlyChildHookProfile, isReadonlyChildSessionReporting, observeReadonlyChildHookDrain } from "./child-hooks.ts";
9
+
10
+ type Runtime = Awaited<ReturnType<PiCodingAgentModule["ModelRuntime"]["create"]>>;
11
+ type Model = NonNullable<AgentSession["model"]>;
12
+
13
+ export interface SettledReadonlyEvidence {
14
+ readonly sessionFile: string;
15
+ readonly sessionId: string;
16
+ readonly leafId: string;
17
+ readonly provider: string;
18
+ readonly model: string;
19
+ readonly api: string;
20
+ readonly status: 429;
21
+ /** Complete active context, not the host's attempt-only event projection. */
22
+ readonly contextJson: string;
23
+ readonly completedToolResults: number;
24
+ readonly fileDigest: string;
25
+ }
26
+
27
+ const requested = new WeakMap<ChildSessionLaunch, SettledReadonlyEvidence | null>();
28
+ const receipts = new WeakMap<ChildSession, SettledReadonlyEvidence>();
29
+ // Opaque configured-provider continuity, never an implementation-origin attestation.
30
+ const providers = new WeakMap<SettledReadonlyEvidence, object>();
31
+
32
+ /** Internal integration seam: opt in before factory creation. Ordinary launches do no evidence I/O. */
33
+ export function requestReadonlySessionEvidence(launch: ChildSessionLaunch, expected?: SettledReadonlyEvidence): void {
34
+ requested.set(launch, expected ?? null);
35
+ }
36
+
37
+ /** Only the default factory can produce a receipt; duck-typed fake child properties are ignored. */
38
+ export function getReadonlySessionEvidence(child: ChildSession): SettledReadonlyEvidence | undefined {
39
+ return receipts.get(child);
40
+ }
41
+
42
+ function digest(bytes: string): string {
43
+ return createHash("sha256").update(bytes).digest("hex");
44
+ }
45
+
46
+ function absent(file: string): boolean {
47
+ try { lstatSync(file); return false; }
48
+ catch (error) { return (error as NodeJS.ErrnoException).code === "ENOENT"; }
49
+ }
50
+
51
+ function sameStored(disk: unknown, live: unknown): boolean {
52
+ // The SDK keeps optional undefined fields in memory which JSONL intentionally omits.
53
+ return isDeepStrictEqual(disk, JSON.parse(JSON.stringify(live)));
54
+ }
55
+
56
+ /** Must run before opening a retained file. Never repairs, truncates, or creates it. */
57
+ export function validateReadonlySessionCheckpoint(evidence: SettledReadonlyEvidence): boolean {
58
+ if (!providers.has(evidence)) return false;
59
+ try { return digest(readFileSync(evidence.sessionFile, "utf8")) === evidence.fileDigest; }
60
+ catch { return false; }
61
+ }
62
+
63
+ function readHistory(file: string): { header: SessionHeader; entries: SessionEntry[]; bytes: string } {
64
+ const bytes = readFileSync(file, "utf8");
65
+ if (!bytes.endsWith("\n")) throw new Error("Incomplete session file");
66
+ const rows = bytes.slice(0, -1).split("\n").map((line) => JSON.parse(line));
67
+ const [header, ...entries] = rows;
68
+ if (header?.type !== "session" || header.version !== 3 || typeof header.id !== "string" || !header.id || typeof header.cwd !== "string" || !entries.length) throw new Error("Unsupported session header");
69
+ const ids = new Set<string>();
70
+ for (const entry of entries) {
71
+ if (!entry || typeof entry.id !== "string" || !entry.id || ids.has(entry.id) || typeof entry.type !== "string" || typeof entry.timestamp !== "string" || (entry.parentId !== null && !ids.has(entry.parentId))) throw new Error("Broken session chain");
72
+ ids.add(entry.id);
73
+ }
74
+ return { header, entries, bytes };
75
+ }
76
+
77
+ function activeMessages(branch: SessionEntry[]): AgentSession["messages"] {
78
+ const messages = branch.flatMap((entry) => {
79
+ if (entry.type === "message") return [entry.message];
80
+ // Compaction/branch summaries and custom context need their own proof; do not reconstruct them.
81
+ if (!["model_change", "thinking_level_change", "session_info", "label"].includes(entry.type)) throw new Error("Unsupported active context");
82
+ return [];
83
+ });
84
+ // Snapshot the persisted representation, not mutable SDK message references.
85
+ return JSON.parse(JSON.stringify(messages));
86
+ }
87
+
88
+ function completedResults(messages: AgentSession["messages"]): number {
89
+ const pending = new Map<string, string>();
90
+ const seen = new Set<string>();
91
+ let completed = 0;
92
+ for (const message of messages) {
93
+ if (message.role === "toolResult") {
94
+ if (typeof message.toolCallId !== "string" || !pending.has(message.toolCallId) || pending.get(message.toolCallId) !== message.toolName || !Array.isArray(message.content)) throw new Error("Unmatched tool result");
95
+ pending.delete(message.toolCallId);
96
+ if (!message.isError && message.content.length) completed++;
97
+ } else {
98
+ if (pending.size) throw new Error("Unresolved tool call");
99
+ if (message.role === "assistant") {
100
+ if (!Array.isArray(message.content)) throw new Error("Invalid assistant content");
101
+ for (const block of message.content) {
102
+ if (block.type !== "toolCall") continue;
103
+ if (!block.id || typeof block.id !== "string" || seen.has(block.id) || !["read", "ls"].includes(block.name)) throw new Error("Uncertified tool call");
104
+ seen.add(block.id);
105
+ pending.set(block.id, block.name);
106
+ }
107
+ } else if (message.role !== "user") throw new Error("Unsupported context message");
108
+ }
109
+ }
110
+ if (pending.size) throw new Error("Unresolved tool call");
111
+ return completed;
112
+ }
113
+
114
+ function eligibleLaunch(launch: ChildSessionLaunch): boolean {
115
+ const r = launch.runtime;
116
+ return launch.ambientExtensions === false && !launch.extensionPaths.length
117
+ && isReadonlyChildSessionReporting(launch)
118
+ && (!launch.hooks.length || (launch.storage.kind === "file" && isReadonlyChildHookProfile(launch.hooks, r)))
119
+ && launch.tools !== undefined && launch.tools.every((tool) => tool === "read" || tool === "ls")
120
+ && !r.toolBudget && !r.permissions && !r.childWatchdog && !r.watchdogStatus && !r.structuredOutput
121
+ && !r.waitTool.enabled && !r.fanoutChild && !r.fast && !r.nestedRoute && !r.nestedParent && !r.runFanoutBudget
122
+ && !r.supervisorChannelDir && !r.mcpDirectTools?.length;
123
+ }
124
+
125
+ export interface ReadonlyEvidenceObserver {
126
+ start(): void;
127
+ settled(): void;
128
+ invalidate(): void;
129
+ beforeShutdown(): void;
130
+ finish(child: ChildSession): void;
131
+ }
132
+
133
+ /** Called only on the explicit opt-in path, before SessionManager.open can permissively repair input. */
134
+ export function prepareReadonlySessionEvidence(launch: ChildSessionLaunch): { loadingHooks(enabled: boolean): void; beforeOpen(): void; opened(manager: AgentSession["sessionManager"]): void; observe(pi: PiCodingAgentModule, runtime: Runtime, session: AgentSession): ReadonlyEvidenceObserver | undefined } | undefined {
135
+ if (!requested.has(launch)) return undefined;
136
+ const expected = requested.get(launch);
137
+ requested.delete(launch);
138
+ const deny = (): undefined => {
139
+ if (expected) throw new Error("Unsupported read-only continuation session");
140
+ return undefined;
141
+ };
142
+ const checkExpected = (): void => {
143
+ if (expected && (launch.storage.kind !== "file" || resolve(launch.storage.sessionFile) !== expected.sessionFile || !validateReadonlySessionCheckpoint(expected))) throw new Error("Read-only continuation checkpoint changed");
144
+ };
145
+ checkExpected();
146
+ if (!eligibleLaunch(launch) || launch.storage.kind !== "file") return deny();
147
+ const file = resolve(launch.storage.sessionFile);
148
+ // Only an initially absent *assigned exact file* may use SDK initialization.
149
+ // Empty files, dangling symlinks, inaccessible and corrupt inputs are not fresh.
150
+ let fresh = !expected && absent(file);
151
+ let initialHeader: SessionHeader | undefined;
152
+ try { if (!fresh) initialHeader = readHistory(file).header; }
153
+ catch { return deny(); }
154
+ const beforeOpen = (): void => {
155
+ checkExpected();
156
+ if (fresh) fresh = absent(file);
157
+ };
158
+ const opened = (manager: AgentSession["sessionManager"]): void => {
159
+ if (fresh && manager.getSessionFile() === file && manager.getEntries().length === 0 && manager.getLeafId() === null) {
160
+ // Capture the real SDK-generated identity immediately after open, before hooks.
161
+ initialHeader = JSON.parse(JSON.stringify(manager.getHeader()));
162
+ }
163
+ };
164
+ const observe = (pi: PiCodingAgentModule, runtime: Runtime, session: AgentSession): ReadonlyEvidenceObserver | undefined => {
165
+ const drainSettled = captureReadonlyChildDrain(launch.hooks);
166
+ // A deliberately tested capability floor, not an attestation of installed code origin.
167
+ if (!initialHeader || pi.VERSION !== "0.85.1" || !session.model || !session.agent.streamFunction) return deny();
168
+ const header = initialHeader;
169
+ const model = { ...session.model };
170
+ const provider = runtime.getProvider(model.provider);
171
+ if (expected && provider !== providers.get(expected)) return deny();
172
+ // Coverage is namespace/API plus the observed POST topology below, not builtin provider origin.
173
+ const supported = (m: Model): boolean => m.provider === "baseten" && m.api === "openai-completions"
174
+ && runtime.getProvider(m.provider) === provider
175
+ && !runtime.getRegisteredNativeProvider(m.provider) && !runtime.getRegisteredProviderConfig(m.provider);
176
+ const allowed = launch.tools!.filter((name) => !launch.excludeTools?.includes(name)).sort();
177
+ const toolsMatch = (): boolean => {
178
+ const tools = session.getAllTools();
179
+ return isDeepStrictEqual(session.getActiveToolNames().sort(), allowed)
180
+ && isDeepStrictEqual(tools.map((tool) => tool.name).sort(), allowed)
181
+ && tools.every((tool) => tool.sourceInfo?.source === "builtin");
182
+ };
183
+ const idle = (): boolean => session.isIdle && !session.isRetrying && !session.agent.hasQueuedMessages()
184
+ && session.agent.state.pendingToolCalls.size === 0 && !session.hasPendingBashMessages;
185
+ const continuity = (): boolean => eligibleLaunch(launch) && toolsMatch() && session.model !== undefined
186
+ && session.model.id === model.id && session.model.provider === model.provider && session.model.api === model.api && supported(session.model);
187
+ const history = () => {
188
+ const disk = readHistory(file);
189
+ const manager = session.sessionManager;
190
+ const leaf = manager.getLeafId();
191
+ if (session.sessionFile !== file || session.sessionId !== header.id || !leaf || leaf !== disk.entries.at(-1)?.id
192
+ || !isDeepStrictEqual(disk.header, header) || !sameStored(disk.header, manager.getHeader())
193
+ || !sameStored(disk.entries, manager.getEntries())) throw new Error("Session checkpoint mismatch");
194
+ // The disk chain and live entries already agree; use the SDK's raw branch walk.
195
+ const messages = activeMessages(manager.getBranch());
196
+ if (!sameStored(messages, session.messages)) throw new Error("Incomplete active context");
197
+ return { ...disk, messages, leaf, completed: completedResults(messages) };
198
+ };
199
+ const startingHistory = () => {
200
+ // SDK defers persistence until its first assistant response. This exception
201
+ // is for the empty source baseline only; settlement always reads strict disk history.
202
+ if (fresh && absent(file)) {
203
+ const manager = session.sessionManager;
204
+ if (session.sessionFile !== file || session.sessionId !== header.id || !sameStored(header, manager.getHeader())
205
+ || session.messages.length
206
+ || manager.getEntries().some((entry) => !["model_change", "thinking_level_change", "session_info", "label"].includes(entry.type))) throw new Error("Fresh session initialization changed");
207
+ return { messages: [] as AgentSession["messages"], completed: 0 };
208
+ }
209
+ return history();
210
+ };
211
+ if (!provider || !eligibleLaunch(launch) || !supported(model) || !toolsMatch() || !idle()) return deny();
212
+ try {
213
+ const restored = startingHistory();
214
+ if (expected && (model.provider !== expected.provider || JSON.stringify(restored.messages) !== expected.contextJson)) throw new Error("Restored continuation context changed");
215
+ } catch (error) {
216
+ if (expected) throw error;
217
+ return undefined;
218
+ }
219
+ let invalid = false;
220
+ let phase: "new" | "running" | "settled" = "new";
221
+ let owner: ChildSession | undefined;
222
+ let baseline = 0;
223
+ let before: AgentSession["messages"] = [];
224
+ let inFlight = 0;
225
+ type Invocation = { status?: number; pending: number; ambiguous: boolean; result?: Awaited<ReturnType<Awaited<ReturnType<typeof session.agent.streamFunction>>["result"]>> };
226
+ let latest: Invocation | undefined;
227
+ const original = session.agent.streamFunction;
228
+ const wrapped: typeof original = async (m, context, options) => {
229
+ const invocation: Invocation = { pending: 0, ambiguous: false };
230
+ latest = invocation;
231
+ if (inFlight++ || phase !== "running" || !eligibleLaunch(launch) || !supported(m) || m.id !== model.id || !toolsMatch()) invalid = true;
232
+ if (expected && (!continuity() || session.agent.streamFunction !== wrapped)) invalid = true;
233
+ // The repository's older agent-core types omit this documented 0.85.1 request option.
234
+ const transport = (options as (typeof options & { fetch?: typeof fetch }))?.fetch ?? globalThis.fetch;
235
+ const observedFetch: typeof fetch = async (...args) => {
236
+ invocation.status = undefined; // Starting even a rejected retry invalidates any earlier 429.
237
+ if (invocation.pending++ || invocation.result) invocation.ambiguous = true;
238
+ try {
239
+ try {
240
+ const [input, init] = args;
241
+ const url = new URL(input instanceof Request ? input.url : String(input));
242
+ // Only the tested completions POST topology. Radius /messages and auxiliary requests deny.
243
+ if (init?.method !== "POST" || !url.pathname.endsWith("/chat/completions") || typeof init.body !== "string") invocation.ambiguous = true;
244
+ } catch { invocation.ambiguous = true; }
245
+ const response = await transport(...args);
246
+ invocation.status = response.status;
247
+ return response;
248
+ } catch (error) {
249
+ invocation.status = undefined;
250
+ throw error;
251
+ } finally { invocation.pending--; }
252
+ };
253
+ try {
254
+ // Guarded continuations must veto known changes before entering configured SDK dispatch.
255
+ if (expected && invalid) throw new Error("Read-only continuation changed before dispatch");
256
+ const stream = await original.call(session.agent, m, context, { ...options, fetch: observedFetch });
257
+ // Observe result without consuming or replacing the event stream.
258
+ void stream.result().then((result) => {
259
+ invocation.result = result;
260
+ inFlight--;
261
+ }, () => { invalid = true; inFlight--; });
262
+ return stream;
263
+ } catch (error) { invalid = true; inFlight--; throw error; }
264
+ };
265
+ session.agent.streamFunction = wrapped;
266
+ return {
267
+ start() {
268
+ if (owner) receipts.delete(owner);
269
+ if (phase !== "new" || !idle()) invalid = true;
270
+ if (expected && (!continuity() || session.agent.streamFunction !== wrapped)) invalid = true;
271
+ phase = "running";
272
+ latest = undefined;
273
+ try {
274
+ const h = startingHistory(); baseline = h.completed; before = h.messages;
275
+ if (expected && JSON.stringify(h.messages) !== expected.contextJson) invalid = true;
276
+ } catch { invalid = true; }
277
+ if (expected && invalid) throw new Error("Read-only continuation changed before prompt");
278
+ },
279
+ settled() { phase = "settled"; },
280
+ invalidate() { invalid = true; if (owner) receipts.delete(owner); },
281
+ beforeShutdown() {
282
+ // Only the identity-certified prompt runtime may finalize owned acknowledgements.
283
+ if (!launch.hooks.length || !continuity()) invalid = true;
284
+ },
285
+ finish(child) {
286
+ owner = child;
287
+ if (!drainSettled()) return;
288
+ if (invalid || child.detached || child.shutDown || phase !== "settled" || inFlight || !eligibleLaunch(launch) || !idle() || !supported(model) || !toolsMatch() || session.agent.streamFunction !== wrapped
289
+ || session.model?.id !== model.id || session.model.provider !== model.provider || session.model.api !== model.api) return;
290
+ const invocation = latest;
291
+ const terminal = invocation?.result;
292
+ if (!invocation || invocation.ambiguous || invocation.pending || invocation.status !== 429 || terminal?.stopReason !== "error"
293
+ || terminal.content.length || terminal.provider !== model.provider || terminal.model !== model.id || terminal.api !== model.api) return;
294
+ try {
295
+ const h = history();
296
+ if (h.completed <= baseline || !isDeepStrictEqual(h.messages.slice(0, before.length), before) || !sameStored(h.messages.at(-1), terminal)) return;
297
+ const receipt: SettledReadonlyEvidence = Object.freeze({ sessionFile: file, sessionId: session.sessionId, leafId: h.leaf,
298
+ provider: model.provider, model: model.id, api: model.api, status: 429, contextJson: JSON.stringify(h.messages),
299
+ completedToolResults: h.completed, fileDigest: digest(h.bytes) });
300
+ providers.set(receipt, provider);
301
+ receipts.set(child, receipt);
302
+ } catch { /* Strict checkpoint failures only deny evidence; never repair storage. */ }
303
+ },
304
+ };
305
+ };
306
+ return { beforeOpen, opened, observe, loadingHooks: (enabled) => observeReadonlyChildHookDrain(launch.hooks, enabled, file) };
307
+ }
@@ -9,17 +9,16 @@ import {
9
9
  type RunFanoutRejection,
10
10
  } from "../../shared/types.ts";
11
11
 
12
- export const RUN_FANOUT_BUDGET_ENV = "SELESAI_SUBAGENT_RUN_FANOUT_BUDGET";
13
12
  const RUN_FANOUT_ROOT = path.join(TEMP_ROOT_DIR, "run-fanout-budgets");
14
13
 
15
- interface ManifestV1 {
14
+ interface FanoutBudgetManifest {
16
15
  version: 1;
17
16
  rootRunId: string;
18
17
  limit: number;
19
18
  createdAt: number;
20
19
  }
21
20
 
22
- interface ClaimV1 {
21
+ interface FanoutBudgetClaim {
23
22
  version: 1;
24
23
  claimId: string;
25
24
  path: string;
@@ -42,16 +41,16 @@ function safeRootRunId(rootRunId: string): string {
42
41
  return rootRunId.replace(/[^A-Za-z0-9._-]/g, "_").slice(0, 120) || randomUUID();
43
42
  }
44
43
 
45
- function parseManifest(value: unknown): ManifestV1 | undefined {
44
+ function parseManifest(value: unknown): FanoutBudgetManifest | undefined {
46
45
  if (!value || typeof value !== "object" || Array.isArray(value)) return undefined;
47
- const manifest = value as Partial<ManifestV1>;
46
+ const manifest = value as Partial<FanoutBudgetManifest>;
48
47
  if (manifest.version !== 1 || typeof manifest.rootRunId !== "string" || !manifest.rootRunId
49
48
  || !Number.isInteger(manifest.limit) || (manifest.limit ?? 0) <= 0
50
49
  || typeof manifest.createdAt !== "number" || !Number.isFinite(manifest.createdAt)) return undefined;
51
- return manifest as ManifestV1;
50
+ return manifest as FanoutBudgetManifest;
52
51
  }
53
52
 
54
- function readManifest(directory: string): ManifestV1 {
53
+ function readManifest(directory: string): FanoutBudgetManifest {
55
54
  let parsed: unknown;
56
55
  try {
57
56
  parsed = JSON.parse(fs.readFileSync(path.join(directory, "manifest.json"), "utf-8"));
@@ -85,7 +84,7 @@ export function createRunFanoutBudget(rootRunId: string, limit: number): RunFano
85
84
  do directory = path.join(RUN_FANOUT_ROOT, `${safeRootRunId(rootRunId)}-${randomUUID()}`);
86
85
  while (fs.existsSync(directory));
87
86
  fs.mkdirSync(path.join(directory, "claims"), { recursive: true, mode: 0o700 });
88
- const manifest: ManifestV1 = { version: 1, rootRunId, limit, createdAt: Date.now() };
87
+ const manifest: FanoutBudgetManifest = { version: 1, rootRunId, limit, createdAt: Date.now() };
89
88
  fs.writeFileSync(path.join(directory, "manifest.json"), `${JSON.stringify(manifest)}\n`, { mode: 0o600, flag: "wx" });
90
89
  return { version: 1, rootRunId, directory, limit };
91
90
  }
@@ -124,18 +123,6 @@ export function readRunFanoutBudgetDescriptor(asyncDir: string | undefined): Run
124
123
  }
125
124
  }
126
125
 
127
- export function encodeRunFanoutBudgetDescriptor(descriptor: RunFanoutBudgetDescriptor): string {
128
- return Buffer.from(JSON.stringify(validateRunFanoutBudgetDescriptor(descriptor)), "utf-8").toString("base64url");
129
- }
130
-
131
- export function decodeRunFanoutBudgetDescriptor(encoded: string | undefined): RunFanoutBudgetDescriptor | undefined {
132
- if (!encoded) return undefined;
133
- try {
134
- return validateRunFanoutBudgetDescriptor(JSON.parse(Buffer.from(encoded, "base64url").toString("utf-8")));
135
- } catch (error) {
136
- throw new Error(`Invalid inherited run fan-out budget: ${error instanceof Error ? error.message : String(error)}`);
137
- }
138
- }
139
126
 
140
127
  interface AdmissionLockOwner {
141
128
  pid: number;
@@ -243,7 +230,7 @@ function commitRunFanoutBatch<T>(descriptor: RunFanoutBudgetDescriptor, paths: s
243
230
  const fd = fs.openSync(slotPath, "wx", 0o600);
244
231
  created.push(slotPath);
245
232
  try {
246
- const claim: ClaimV1 = { version: 1, claimId: randomUUID(), path: claimPath, claimedAt: Date.now() };
233
+ const claim: FanoutBudgetClaim = { version: 1, claimId: randomUUID(), path: claimPath, claimedAt: Date.now() };
247
234
  fs.writeFileSync(fd, `${JSON.stringify(claim)}\n`, "utf-8");
248
235
  } finally { fs.closeSync(fd); }
249
236
  break;
@@ -1,13 +1,8 @@
1
- import * as fs from "node:fs";
2
- import * as path from "node:path";
3
- import type { RuntimeAcknowledgedChildExtensionsV1 } from "../../shared/types.ts";
1
+ import type { RuntimeAcknowledgedChildExtensions } from "../../shared/types.ts";
4
2
 
5
3
  export const RUNTIME_EXTENSION_ACK_EVENT = "subagent:acknowledge-extension";
6
- export const RUNTIME_EXTENSION_ACK_PATH_ENV = "SELESAI_SUBAGENT_RUNTIME_ACKNOWLEDGED_EXTENSIONS";
7
4
  export const MAX_RUNTIME_ACKNOWLEDGED_EXTENSION_IDS = 32;
8
5
  export const MAX_RUNTIME_ACKNOWLEDGED_EXTENSION_ID_LENGTH = 128;
9
- // Generous bound for a valid capture (32 ids x 128 chars plus envelope); larger files are child misbehavior.
10
- export const MAX_RUNTIME_ACKNOWLEDGED_EXTENSION_FILE_BYTES = 64 * 1024;
11
6
 
12
7
  export function isRuntimeAcknowledgedExtensionId(value: unknown): value is string {
13
8
  return typeof value === "string"
@@ -19,7 +14,7 @@ export function isRuntimeAcknowledgedExtensionId(value: unknown): value is strin
19
14
  && !value.includes("\\");
20
15
  }
21
16
 
22
- export function projectRuntimeAcknowledgedExtensions(ids: Iterable<unknown>): RuntimeAcknowledgedChildExtensionsV1 | undefined {
17
+ export function projectRuntimeAcknowledgedExtensions(ids: Iterable<unknown>): RuntimeAcknowledgedChildExtensions | undefined {
23
18
  const unique: string[] = [];
24
19
  const seen = new Set<string>();
25
20
  for (const id of ids) {
@@ -36,7 +31,7 @@ export function projectRuntimeAcknowledgedExtensions(ids: Iterable<unknown>): Ru
36
31
  };
37
32
  }
38
33
 
39
- export function sanitizeRuntimeAcknowledgedExtensions(value: unknown): RuntimeAcknowledgedChildExtensionsV1 | undefined {
34
+ export function sanitizeRuntimeAcknowledgedExtensions(value: unknown): RuntimeAcknowledgedChildExtensions | undefined {
40
35
  if (!value || typeof value !== "object") return undefined;
41
36
  const raw = value as Record<string, unknown>;
42
37
  if (raw.version !== 1 || raw.source !== "child-runtime" || !Array.isArray(raw.ids)) return undefined;
@@ -47,25 +42,3 @@ export function sanitizeRuntimeAcknowledgedExtensions(value: unknown): RuntimeAc
47
42
  : 0;
48
43
  return { ...projected, omitted: projected.omitted + omitted };
49
44
  }
50
-
51
- export function readRuntimeAcknowledgedExtensions(filePath: string | undefined): RuntimeAcknowledgedChildExtensionsV1 | undefined {
52
- if (!filePath) return undefined;
53
- try {
54
- if (fs.statSync(filePath).size > MAX_RUNTIME_ACKNOWLEDGED_EXTENSION_FILE_BYTES) return undefined;
55
- const parsed = JSON.parse(fs.readFileSync(filePath, "utf-8")) as unknown;
56
- return sanitizeRuntimeAcknowledgedExtensions(parsed);
57
- } catch {
58
- return undefined;
59
- }
60
- }
61
-
62
- export function writeRuntimeAcknowledgedExtensions(filePath: string, ids: Iterable<unknown>): void {
63
- const projection = projectRuntimeAcknowledgedExtensions(ids);
64
- try {
65
- fs.mkdirSync(path.dirname(filePath), { recursive: true });
66
- if (projection) fs.writeFileSync(filePath, JSON.stringify(projection), { mode: 0o600 });
67
- else fs.rmSync(filePath, { force: true });
68
- } catch {
69
- // Runtime acknowledgement is best-effort observability only.
70
- }
71
- }
@@ -7,10 +7,6 @@ import { SELESAI_CODING_AGENT_PACKAGE_ROOT_ENV } from "../../shared/utils.ts";
7
7
  import type { JsonSchemaObject } from "../../shared/types.ts";
8
8
  import type { ResolvedAcceptanceReportMode } from "./acceptance.ts";
9
9
 
10
- export const STRUCTURED_OUTPUT_SCHEMA_ENV = "SELESAI_SUBAGENT_STRUCTURED_OUTPUT_SCHEMA";
11
- export const STRUCTURED_OUTPUT_CAPTURE_ENV = "SELESAI_SUBAGENT_STRUCTURED_OUTPUT_CAPTURE";
12
- export const STRUCTURED_OUTPUT_ACCEPTANCE_CAPTURE_ENV = "SELESAI_SUBAGENT_STRUCTURED_OUTPUT_ACCEPTANCE_CAPTURE";
13
- export const STRUCTURED_OUTPUT_ACCEPTANCE_REQUIRED_ENV = "SELESAI_SUBAGENT_STRUCTURED_OUTPUT_ACCEPTANCE_REQUIRED";
14
10
  export const MISSING_STRUCTURED_OUTPUT_CALL_ERROR = "Missing structured_output call; this step has outputSchema and must finish by calling structured_output.";
15
11
  export const MISSING_STRUCTURED_ACCEPTANCE_REPORT_ERROR = "Missing acceptanceReport in structured_output call; acceptance.report is \"on\".";
16
12
 
@@ -200,6 +196,23 @@ export function readStructuredOutputAcceptanceReport(runtime: StructuredOutputRu
200
196
  }
201
197
  }
202
198
 
199
+ /**
200
+ * Capture callback that persists the structured output (and acceptance report)
201
+ * to the runtime's files, for hosts that read the value back from disk.
202
+ */
203
+ export function createStructuredOutputFileCapture(runtime: StructuredOutputRuntime): (value: unknown, acceptanceReport: unknown | undefined) => void {
204
+ return (value, acceptanceReport) => {
205
+ fs.mkdirSync(path.dirname(runtime.outputPath), { recursive: true });
206
+ if (runtime.acceptanceReportPath && acceptanceReport !== undefined) {
207
+ fs.mkdirSync(path.dirname(runtime.acceptanceReportPath), { recursive: true });
208
+ fs.writeFileSync(runtime.acceptanceReportPath, JSON.stringify(acceptanceReport), { mode: 0o600 });
209
+ } else if (runtime.acceptanceReportPath && fs.existsSync(runtime.acceptanceReportPath)) {
210
+ fs.unlinkSync(runtime.acceptanceReportPath);
211
+ }
212
+ fs.writeFileSync(runtime.outputPath, JSON.stringify(value), { mode: 0o600 });
213
+ };
214
+ }
215
+
203
216
  export function clearStructuredOutputCaptures(runtime: StructuredOutputRuntime): string | undefined {
204
217
  let cleanupError: string | undefined;
205
218
  for (const filePath of [runtime.outputPath, runtime.acceptanceReportPath]) {
@@ -138,6 +138,7 @@ export function buildControlEvent(input: {
138
138
  tokens?: number;
139
139
  toolCount?: number;
140
140
  currentTool?: string;
141
+ toolCallId?: string;
141
142
  currentToolDurationMs?: number;
142
143
  currentPath?: string;
143
144
  elapsedMs?: number;
@@ -170,6 +171,7 @@ export function buildControlEvent(input: {
170
171
  ...(input.tokens !== undefined ? { tokens: input.tokens } : {}),
171
172
  ...(input.toolCount !== undefined ? { toolCount: input.toolCount } : {}),
172
173
  ...(input.currentTool ? { currentTool: input.currentTool } : {}),
174
+ ...(input.toolCallId ? { toolCallId: input.toolCallId } : {}),
173
175
  ...(input.currentToolDurationMs !== undefined ? { currentToolDurationMs: input.currentToolDurationMs } : {}),
174
176
  ...(input.currentPath ? { currentPath: input.currentPath } : {}),
175
177
  ...(elapsedMs !== undefined ? { elapsedMs } : {}),