create-walle 0.10.2 → 0.10.3

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 (488) hide show
  1. package/README.md +3 -1
  2. package/lib/release-schema.json +2 -2
  3. package/lib/runtime-closure-policy.json +8 -7
  4. package/package.json +1 -1
  5. package/template/coding-task-manager/api-prompts.js +45 -7
  6. package/template/coding-task-manager/bin/claude-hook.js +55 -1
  7. package/template/coding-task-manager/bin/ctm-relay-client.js +35 -12
  8. package/template/coding-task-manager/bin/land.js +2069 -0
  9. package/template/coding-task-manager/bin/memory-census.js +4 -2
  10. package/template/coding-task-manager/bin/memory-sync-verify.js +151 -0
  11. package/template/coding-task-manager/bin/probe-refusal-scope.js +530 -0
  12. package/template/coding-task-manager/db.js +156 -32
  13. package/template/coding-task-manager/lib/acp/acp-client.js +383 -0
  14. package/template/coding-task-manager/lib/acp/dsh-context-truth.js +176 -0
  15. package/template/coding-task-manager/lib/acp/dsh-launch-model.js +302 -0
  16. package/template/coding-task-manager/lib/acp/dsh-mcp-servers.js +194 -0
  17. package/template/coding-task-manager/lib/acp/dsh-prompt-lane.js +616 -0
  18. package/template/coding-task-manager/lib/acp/dsh-route-patch.js +308 -0
  19. package/template/coding-task-manager/lib/acp/dsh-session-runtime.js +522 -0
  20. package/template/coding-task-manager/lib/acp/dsh-transcript.js +395 -0
  21. package/template/coding-task-manager/lib/acp/dsh-usage-log.js +162 -0
  22. package/template/coding-task-manager/lib/acp/ndjson-stdio-transport.js +225 -0
  23. package/template/coding-task-manager/lib/adopted-host-redial.js +47 -11
  24. package/template/coding-task-manager/lib/adopted-launch-environment.js +123 -0
  25. package/template/coding-task-manager/lib/agent-auto-update-runtime.js +0 -3
  26. package/template/coding-task-manager/lib/agent-auto-update.js +26 -10
  27. package/template/coding-task-manager/lib/agent-bundle/build.js +657 -0
  28. package/template/coding-task-manager/lib/agent-bundle/codex-install.js +558 -0
  29. package/template/coding-task-manager/lib/agent-bundle/drift.js +120 -0
  30. package/template/coding-task-manager/lib/agent-bundle/gc.js +522 -0
  31. package/template/coding-task-manager/lib/agent-bundle/inventory.js +346 -0
  32. package/template/coding-task-manager/lib/agent-bundle/push.js +717 -0
  33. package/template/coding-task-manager/lib/agent-bundle/skill-transfer.js +724 -0
  34. package/template/coding-task-manager/lib/agent-bundle/spawn.js +119 -0
  35. package/template/coding-task-manager/lib/agent-bundle/store.js +568 -0
  36. package/template/coding-task-manager/lib/agent-capabilities.js +142 -12
  37. package/template/coding-task-manager/lib/agent-cli-cache.js +30 -5
  38. package/template/coding-task-manager/lib/agent-definitions.js +19 -0
  39. package/template/coding-task-manager/lib/agent-hooks-codex-toml.js +28 -16
  40. package/template/coding-task-manager/lib/agent-hooks-codex-workspace.js +9 -1
  41. package/template/coding-task-manager/lib/agent-hooks-installer.js +23 -8
  42. package/template/coding-task-manager/lib/agent-hooks-prune.js +37 -11
  43. package/template/coding-task-manager/lib/agent-hooks-shim.js +105 -0
  44. package/template/coding-task-manager/lib/agent-presets.js +84 -1
  45. package/template/coding-task-manager/lib/agent-upgrade-jobs.js +12 -1
  46. package/template/coding-task-manager/lib/agent-version-service.js +74 -11
  47. package/template/coding-task-manager/lib/all-sessions-query.js +6 -2
  48. package/template/coding-task-manager/lib/api/agent-bundles.js +436 -0
  49. package/template/coding-task-manager/lib/api/backup-retention.js +83 -0
  50. package/template/coding-task-manager/lib/api/conversation-sync-routes.js +124 -0
  51. package/template/coding-task-manager/lib/api/diagnostics.js +549 -69
  52. package/template/coding-task-manager/lib/api/fleet.js +118 -0
  53. package/template/coding-task-manager/lib/api/hub-bridge.js +243 -0
  54. package/template/coding-task-manager/lib/api/ingress.js +9 -1
  55. package/template/coding-task-manager/lib/api/landing.js +403 -0
  56. package/template/coding-task-manager/lib/api/machines.js +691 -2
  57. package/template/coding-task-manager/lib/api/memory-sync-routes.js +335 -0
  58. package/template/coding-task-manager/lib/api/misc-ops.js +8 -3
  59. package/template/coding-task-manager/lib/api/remote-sessions.js +1326 -0
  60. package/template/coding-task-manager/lib/api/session-attach.js +623 -0
  61. package/template/coding-task-manager/lib/api/session-messages.js +1384 -0
  62. package/template/coding-task-manager/lib/api/sessions.js +77 -51
  63. package/template/coding-task-manager/lib/api/setup-network.js +544 -16
  64. package/template/coding-task-manager/lib/api/setup-wizard-handlers.js +884 -0
  65. package/template/coding-task-manager/lib/api/setup.js +829 -10
  66. package/template/coding-task-manager/lib/api/walle-bridge.js +9 -1
  67. package/template/coding-task-manager/lib/attachment-reconciler-wiring.js +5 -2
  68. package/template/coding-task-manager/lib/auth-rate-limit.js +23 -0
  69. package/template/coding-task-manager/lib/auth-rules.js +292 -21
  70. package/template/coding-task-manager/lib/background-stop.js +369 -0
  71. package/template/coding-task-manager/lib/best-of-attempts.js +4 -1
  72. package/template/coding-task-manager/lib/best-of-launch-plan.js +52 -0
  73. package/template/coding-task-manager/lib/box-keep-awake.js +89 -0
  74. package/template/coding-task-manager/lib/broadcast-reason-stats.js +152 -0
  75. package/template/coding-task-manager/lib/broadcast-serialize.js +5 -0
  76. package/template/coding-task-manager/lib/build-info.js +4 -2
  77. package/template/coding-task-manager/lib/claude-model-truth.js +13 -2
  78. package/template/coding-task-manager/lib/claude-transcript-terminal-renderer.js +17 -13
  79. package/template/coding-task-manager/lib/client-diag-handler.js +64 -2
  80. package/template/coding-task-manager/lib/codex-app-server-client.js +14 -16
  81. package/template/coding-task-manager/lib/codex-configuration-history.js +55 -0
  82. package/template/coding-task-manager/lib/codex-harness-qualification.js +43 -20
  83. package/template/coding-task-manager/lib/codex-rollout-history.js +743 -0
  84. package/template/coding-task-manager/lib/coding-agent-models.js +27 -12
  85. package/template/coding-task-manager/lib/coding-cli-skill-installer.js +44 -14
  86. package/template/coding-task-manager/lib/coding-session-model-adapters.js +43 -2
  87. package/template/coding-task-manager/lib/coding-session-model-owner.js +1 -1
  88. package/template/coding-task-manager/lib/coding-session-model-public.js +7 -1
  89. package/template/coding-task-manager/lib/coding-session-model-runtime.js +23 -4
  90. package/template/coding-task-manager/lib/coding-session-model-scan.js +31 -0
  91. package/template/coding-task-manager/lib/coding-session-model-state.js +7 -0
  92. package/template/coding-task-manager/lib/conversation-freshness-diagnostics.js +280 -0
  93. package/template/coding-task-manager/lib/conversation-item-clock.js +261 -0
  94. package/template/coding-task-manager/lib/conversation-source-registry.js +5 -0
  95. package/template/coding-task-manager/lib/conversation-store-v2.js +44 -0
  96. package/template/coding-task-manager/lib/conversation-sync.js +355 -0
  97. package/template/coding-task-manager/lib/create/resolve-launch-params.js +96 -12
  98. package/template/coding-task-manager/lib/create/worker-role-profile.js +4 -4
  99. package/template/coding-task-manager/lib/create-intent-lease.js +51 -0
  100. package/template/coding-task-manager/lib/ctm-session-context-api.js +97 -6
  101. package/template/coding-task-manager/lib/db-domain-tables.js +1 -0
  102. package/template/coding-task-manager/lib/db-domains.js +1 -0
  103. package/template/coding-task-manager/lib/db-owner-dispatch-probe.js +32 -0
  104. package/template/coding-task-manager/lib/db-owner-request-counts.js +178 -0
  105. package/template/coding-task-manager/lib/db-owner-worker-client.js +68 -14
  106. package/template/coding-task-manager/lib/db-schema-source-files.js +5 -0
  107. package/template/coding-task-manager/lib/deferred-restore-attempt.js +6 -2
  108. package/template/coding-task-manager/lib/feature-manifest.js +4 -0
  109. package/template/coding-task-manager/lib/fleet-conversation-route.js +97 -0
  110. package/template/coding-task-manager/lib/fleet-fanout.js +78 -0
  111. package/template/coding-task-manager/lib/fleet-hub.js +762 -0
  112. package/template/coding-task-manager/lib/fleet-origin-follower.js +252 -0
  113. package/template/coding-task-manager/lib/fleet-resolver-effects.js +147 -0
  114. package/template/coding-task-manager/lib/fleet-resolver-tick.js +148 -0
  115. package/template/coding-task-manager/lib/fleet-resolver.js +454 -0
  116. package/template/coding-task-manager/lib/fleet-session-list-routes.js +114 -0
  117. package/template/coding-task-manager/lib/fleet-session-lists.js +672 -0
  118. package/template/coding-task-manager/lib/fleet-update.js +798 -0
  119. package/template/coding-task-manager/lib/fs-watcher-root-watch.js +141 -0
  120. package/template/coding-task-manager/lib/fs-watcher.js +58 -42
  121. package/template/coding-task-manager/lib/harness-history-transition.js +50 -9
  122. package/template/coding-task-manager/lib/headless-term-service.js +84 -8
  123. package/template/coding-task-manager/lib/hermetic-agent-launch-guard.js +10 -0
  124. package/template/coding-task-manager/lib/history-transition-read-op.js +175 -8
  125. package/template/coding-task-manager/lib/host-cpu-categories.js +310 -0
  126. package/template/coding-task-manager/lib/host-fseventsd-sampler.js +399 -0
  127. package/template/coding-task-manager/lib/host-handoff.js +16 -19
  128. package/template/coding-task-manager/lib/host-stats.js +150 -3
  129. package/template/coding-task-manager/lib/hosted-sync-worker.js +43 -320
  130. package/template/coding-task-manager/lib/hub-bridge-access.js +798 -0
  131. package/template/coding-task-manager/lib/hub-bridge-box.js +409 -0
  132. package/template/coding-task-manager/lib/hub-bridge-mcp.js +380 -0
  133. package/template/coding-task-manager/lib/hub-bridge-mesh.js +313 -0
  134. package/template/coding-task-manager/lib/hub-bridge-ops.js +721 -0
  135. package/template/coding-task-manager/lib/hub-bridge.js +398 -0
  136. package/template/coding-task-manager/lib/idle-notify.js +491 -0
  137. package/template/coding-task-manager/lib/instance-id-ownership-manifest.js +8 -0
  138. package/template/coding-task-manager/lib/instance-manifest.js +5 -1
  139. package/template/coding-task-manager/lib/instance-sync-status.js +18 -8
  140. package/template/coding-task-manager/lib/landing/agent-rule.txt +1 -0
  141. package/template/coding-task-manager/lib/landing/batch-runner.js +366 -0
  142. package/template/coding-task-manager/lib/landing/config.js +536 -0
  143. package/template/coding-task-manager/lib/landing/ctm-view.js +256 -0
  144. package/template/coding-task-manager/lib/landing/gate.js +360 -0
  145. package/template/coding-task-manager/lib/landing/git.js +344 -0
  146. package/template/coding-task-manager/lib/landing/lease.js +247 -0
  147. package/template/coding-task-manager/lib/landing/merge-delta.js +380 -0
  148. package/template/coding-task-manager/lib/landing/proof.js +223 -0
  149. package/template/coding-task-manager/lib/landing/queue.js +998 -0
  150. package/template/coding-task-manager/lib/landing/radar.js +489 -0
  151. package/template/coding-task-manager/lib/landing/resolve-cli.js +424 -0
  152. package/template/coding-task-manager/lib/landing/state.js +263 -0
  153. package/template/coding-task-manager/lib/landing/stop.js +49 -0
  154. package/template/coding-task-manager/lib/landing/sync-cli.js +475 -0
  155. package/template/coding-task-manager/lib/landing/sync.js +456 -0
  156. package/template/coding-task-manager/lib/landing/train.js +885 -0
  157. package/template/coding-task-manager/lib/landing/window.js +57 -0
  158. package/template/coding-task-manager/lib/launch-environment.js +121 -0
  159. package/template/coding-task-manager/lib/launch-model-override.js +36 -10
  160. package/template/coding-task-manager/lib/launch-plan-pool.js +2 -1
  161. package/template/coding-task-manager/lib/launch-plan-warm-cache.js +6 -0
  162. package/template/coding-task-manager/lib/lead-model-observer.js +57 -1
  163. package/template/coding-task-manager/lib/lead-model-options.js +160 -3
  164. package/template/coding-task-manager/lib/lead-model-restore-reconciliation.js +106 -24
  165. package/template/coding-task-manager/lib/lead-model-switch-runtime.js +352 -68
  166. package/template/coding-task-manager/lib/lead-model-switch.js +114 -10
  167. package/template/coding-task-manager/lib/lead-model-transition-runtime.js +14 -2
  168. package/template/coding-task-manager/lib/lead-model-transition-store.js +24 -6
  169. package/template/coding-task-manager/lib/lead-route-preflight.js +179 -0
  170. package/template/coding-task-manager/lib/lead-switch-history-mode.js +110 -0
  171. package/template/coding-task-manager/lib/lead-wire-agent.js +7 -0
  172. package/template/coding-task-manager/lib/lifecycle-wake-experiment.js +9 -2
  173. package/template/coding-task-manager/lib/live-defer-announce.js +45 -0
  174. package/template/coding-task-manager/lib/machine-registry.js +750 -5
  175. package/template/coding-task-manager/lib/macos-capabilities.js +32 -15
  176. package/template/coding-task-manager/lib/main-thread-lint-exemptions.json +433 -53
  177. package/template/coding-task-manager/lib/mainloop-observability.js +14 -9
  178. package/template/coding-task-manager/lib/media-draft-owner.js +16 -3
  179. package/template/coding-task-manager/lib/memory-join.js +337 -0
  180. package/template/coding-task-manager/lib/memory-sync-verify.js +393 -0
  181. package/template/coding-task-manager/lib/memory-sync.js +565 -0
  182. package/template/coding-task-manager/lib/migrations/v57-delegate-pref-mirror-opencode.js +68 -0
  183. package/template/coding-task-manager/lib/migrations/v58-subagent-launch-native-subagents.js +42 -0
  184. package/template/coding-task-manager/lib/migrations/v59-coding-session-model-state-dsh.js +73 -0
  185. package/template/coding-task-manager/lib/migrations/v60-delegate-pref-mirror-dsh.js +78 -0
  186. package/template/coding-task-manager/lib/migrations/v61-conversation-item-clock.js +71 -0
  187. package/template/coding-task-manager/lib/model-availability.js +727 -0
  188. package/template/coding-task-manager/lib/model-execution-recipe-metadata.js +4 -6
  189. package/template/coding-task-manager/lib/model-host-receipt.js +6 -3
  190. package/template/coding-task-manager/lib/model-id-rule.js +19 -0
  191. package/template/coding-task-manager/lib/model-proxy/anthropic-face.js +4 -0
  192. package/template/coding-task-manager/lib/model-proxy/auto-mode-review.js +110 -23
  193. package/template/coding-task-manager/lib/model-proxy/chat-response-translators.js +3 -0
  194. package/template/coding-task-manager/lib/model-proxy/generation-probe.js +60 -17
  195. package/template/coding-task-manager/lib/model-proxy/historical-tool-declarations.js +37 -0
  196. package/template/coding-task-manager/lib/model-proxy/lead-request-validation.js +1 -0
  197. package/template/coding-task-manager/lib/model-proxy/lead-token-admin.js +130 -0
  198. package/template/coding-task-manager/lib/model-proxy/refusal-scope.js +151 -0
  199. package/template/coding-task-manager/lib/model-proxy/request-budget-store.js +11 -2
  200. package/template/coding-task-manager/lib/model-proxy/tokens.js +69 -5
  201. package/template/coding-task-manager/lib/model-proxy/upstream-outcome.js +9 -0
  202. package/template/coding-task-manager/lib/native-agent-model-args.js +25 -22
  203. package/template/coding-task-manager/lib/native-history-control.js +6 -4
  204. package/template/coding-task-manager/lib/native-lead-settings-client.js +44 -4
  205. package/template/coding-task-manager/lib/oauth-proxy-supervisor.js +173 -36
  206. package/template/coding-task-manager/lib/online-backup-worker-client.js +2 -0
  207. package/template/coding-task-manager/lib/opencode-cli.js +480 -0
  208. package/template/coding-task-manager/lib/opencode-launch-model.js +471 -0
  209. package/template/coding-task-manager/lib/opencode-v1-plugin/model-carrier.mjs +35 -0
  210. package/template/coding-task-manager/lib/opencode-v2-plugin/server.js +118 -0
  211. package/template/coding-task-manager/lib/owner-action-manifest-data.json +1 -1
  212. package/template/coding-task-manager/lib/park-composer-draft.js +54 -0
  213. package/template/coding-task-manager/lib/park-fresh-relaunch.js +41 -10
  214. package/template/coding-task-manager/lib/perf-phase-trace.js +72 -0
  215. package/template/coding-task-manager/lib/perf-summary.js +7 -0
  216. package/template/coding-task-manager/lib/perf-tracker.js +63 -2
  217. package/template/coding-task-manager/lib/project-config.js +7 -0
  218. package/template/coding-task-manager/lib/prompt-purge-v2.js +52 -1
  219. package/template/coding-task-manager/lib/provider-login-broker.js +72 -15
  220. package/template/coding-task-manager/lib/provider-login-tab.js +10 -2
  221. package/template/coding-task-manager/lib/read-pool-client.js +89 -2
  222. package/template/coding-task-manager/lib/read-pool-worker-handle.js +29 -4
  223. package/template/coding-task-manager/lib/recent-catalog-query.js +15 -0
  224. package/template/coding-task-manager/lib/recent-session-catalog-response.js +67 -10
  225. package/template/coding-task-manager/lib/recovery-evidence.js +26 -11
  226. package/template/coding-task-manager/lib/relay-client.js +57 -3
  227. package/template/coding-task-manager/lib/relink-audit.js +34 -5
  228. package/template/coding-task-manager/lib/remote-machine-catalog.js +321 -26
  229. package/template/coding-task-manager/lib/remote-machine-create.js +576 -36
  230. package/template/coding-task-manager/lib/remote-machine-link.js +546 -59
  231. package/template/coding-task-manager/lib/remote-machine-proxy.js +143 -9
  232. package/template/coding-task-manager/lib/remote-session-forward.js +65 -7
  233. package/template/coding-task-manager/lib/remote-terminal-target.js +9 -2
  234. package/template/coding-task-manager/lib/restart-guard.js +18 -6
  235. package/template/coding-task-manager/lib/restore-seed-modes.js +87 -0
  236. package/template/coding-task-manager/lib/restored-scrollback-hydration-runtime.js +22 -2
  237. package/template/coding-task-manager/lib/resume-admission.js +17 -3
  238. package/template/coding-task-manager/lib/review-repo-registry.js +58 -19
  239. package/template/coding-task-manager/lib/root-delivery-runtime.js +2 -2
  240. package/template/coding-task-manager/lib/root-prompt-flow.js +1 -1
  241. package/template/coding-task-manager/lib/runtime-contract.js +3 -1
  242. package/template/coding-task-manager/lib/schema-indexes.js +1 -0
  243. package/template/coding-task-manager/lib/session-context-locator.js +742 -0
  244. package/template/coding-task-manager/lib/session-create/attachment.js +2 -2
  245. package/template/coding-task-manager/lib/session-create/create-phases.js +118 -0
  246. package/template/coding-task-manager/lib/session-create/delegate-worker.js +86 -16
  247. package/template/coding-task-manager/lib/session-create/dsh-session.js +930 -0
  248. package/template/coding-task-manager/lib/session-create/lead-route-launch.js +186 -13
  249. package/template/coding-task-manager/lib/session-create/native-lead-lifetime.js +55 -3
  250. package/template/coding-task-manager/lib/session-create/opencode-lead-provider.js +50 -0
  251. package/template/coding-task-manager/lib/session-create/prepared.js +162 -38
  252. package/template/coding-task-manager/lib/session-create/provider-process.js +160 -28
  253. package/template/coding-task-manager/lib/session-create/response.js +7 -7
  254. package/template/coding-task-manager/lib/session-create/structured-session.js +27 -0
  255. package/template/coding-task-manager/lib/session-create/subagent-pick-table.js +3 -1
  256. package/template/coding-task-manager/lib/session-create/subagent-pick.js +458 -9
  257. package/template/coding-task-manager/lib/session-create/transcript.js +1 -1
  258. package/template/coding-task-manager/lib/session-create/worker-budget-setup.js +21 -2
  259. package/template/coding-task-manager/lib/session-create/worker-continuation.js +7 -1
  260. package/template/coding-task-manager/lib/session-create/worker-launch-sandbox.js +39 -10
  261. package/template/coding-task-manager/lib/session-create/worker-observability.js +2 -2
  262. package/template/coding-task-manager/lib/session-empty.js +13 -10
  263. package/template/coding-task-manager/lib/session-host-manager.js +60 -0
  264. package/template/coding-task-manager/lib/session-jobs.js +3 -1
  265. package/template/coding-task-manager/lib/session-lifecycle.js +10 -4
  266. package/template/coding-task-manager/lib/session-model-action-preconditions.js +6 -2
  267. package/template/coding-task-manager/lib/session-model-intent-contract.js +11 -8
  268. package/template/coding-task-manager/lib/session-park.js +738 -0
  269. package/template/coding-task-manager/lib/session-path-grant.js +13 -4
  270. package/template/coding-task-manager/lib/session-status-ledger.js +106 -4
  271. package/template/coding-task-manager/lib/session-transport.js +17 -0
  272. package/template/coding-task-manager/lib/session-workspace-projection.js +54 -5
  273. package/template/coding-task-manager/lib/session-workspace-tracking-runtime.js +213 -1
  274. package/template/coding-task-manager/lib/skill-autocomplete-query.js +120 -3
  275. package/template/coding-task-manager/lib/skill-autocomplete.js +15 -1
  276. package/template/coding-task-manager/lib/sqlite-file-set.js +39 -0
  277. package/template/coding-task-manager/lib/standup-search-adapter.js +16 -2
  278. package/template/coding-task-manager/lib/state-sync/client-ledger.js +12 -0
  279. package/template/coding-task-manager/lib/state-sync/frame-emitter.js +319 -100
  280. package/template/coding-task-manager/lib/storage/coding-session-model-store.js +4 -1
  281. package/template/coding-task-manager/lib/storage/delegate-pref-mirror-store.js +32 -9
  282. package/template/coding-task-manager/lib/structured-session-boot-sweep.js +235 -0
  283. package/template/coding-task-manager/lib/submission-ack.js +90 -2
  284. package/template/coding-task-manager/lib/systemd-scope.js +115 -0
  285. package/template/coding-task-manager/lib/telemetry-receiver.js +39 -0
  286. package/template/coding-task-manager/lib/terminal-attach-geometry.js +985 -0
  287. package/template/coding-task-manager/lib/terminal-bootstrap.js +30 -0
  288. package/template/coding-task-manager/lib/terminal-draft-operation.js +357 -0
  289. package/template/coding-task-manager/lib/terminal-input-admission.js +17 -1
  290. package/template/coding-task-manager/lib/terminal-input-prepared.js +563 -0
  291. package/template/coding-task-manager/lib/transcript-cache-temps.js +171 -0
  292. package/template/coding-task-manager/lib/transcript-frame-cache.js +8 -3
  293. package/template/coding-task-manager/lib/transcript-source.js +36 -4
  294. package/template/coding-task-manager/lib/transcript-store.js +9 -0
  295. package/template/coding-task-manager/lib/typing-interaction-trace.js +106 -3
  296. package/template/coding-task-manager/lib/usage-ledger/backfill.js +40 -5
  297. package/template/coding-task-manager/lib/usage-ledger/client.js +4 -1
  298. package/template/coding-task-manager/lib/usage-ledger/dsh-parse.js +152 -0
  299. package/template/coding-task-manager/lib/usage-ledger/dsh-read.js +73 -0
  300. package/template/coding-task-manager/lib/usage-ledger/ingest.js +34 -6
  301. package/template/coding-task-manager/lib/usage-ledger/live.js +35 -8
  302. package/template/coding-task-manager/lib/usage-ledger/read.js +29 -20
  303. package/template/coding-task-manager/lib/usage-ledger/schema.js +61 -1
  304. package/template/coding-task-manager/lib/usage-ledger/task-coordinator.js +4 -2
  305. package/template/coding-task-manager/lib/wake-skip-reasons.js +1 -0
  306. package/template/coding-task-manager/lib/walle/turn.js +1 -1
  307. package/template/coding-task-manager/lib/walle-history-serve.js +838 -0
  308. package/template/coding-task-manager/lib/walle-kill-authority.js +2 -2
  309. package/template/coding-task-manager/lib/walle-log-rotation.js +164 -1
  310. package/template/coding-task-manager/lib/walle-mcp-auto-config.js +56 -2
  311. package/template/coding-task-manager/lib/walle-row-history.js +495 -0
  312. package/template/coding-task-manager/lib/walle-supervisor.js +33 -14
  313. package/template/coding-task-manager/lib/watch-worker-client.js +203 -0
  314. package/template/coding-task-manager/lib/worker-terminal-output.js +5 -2
  315. package/template/coding-task-manager/lib/ws/hub-bridge.js +35 -0
  316. package/template/coding-task-manager/lib/ws/lifecycle.js +6 -11
  317. package/template/coding-task-manager/lib/ws/misc.js +1 -1
  318. package/template/coding-task-manager/lib/ws/state-sync.js +106 -4
  319. package/template/coding-task-manager/lib/ws/terminal-attach.js +91 -0
  320. package/template/coding-task-manager/oauth-proxy.js +112 -115
  321. package/template/coding-task-manager/package-lock.json +10 -94
  322. package/template/coding-task-manager/package.json +4 -3
  323. package/template/coding-task-manager/protocol/message-table.json +10 -0
  324. package/template/coding-task-manager/protocol/messages.js +10 -0
  325. package/template/coding-task-manager/protocol/ws-schema.json +20 -0
  326. package/template/coding-task-manager/protocol/ws-schema.md +2 -0
  327. package/template/coding-task-manager/public/css/app.css +170 -0
  328. package/template/coding-task-manager/public/css/walle-session.css +4 -0
  329. package/template/coding-task-manager/public/index.html +473 -243
  330. package/template/coding-task-manager/public/js/agent-command.js +86 -0
  331. package/template/coding-task-manager/public/js/app/backups-panel.js +111 -5
  332. package/template/coding-task-manager/public/js/app/coding-agent-upgrade.js +103 -4
  333. package/template/coding-task-manager/public/js/app/machines-page.js +1328 -8
  334. package/template/coding-task-manager/public/js/app/models-tab.js +113 -38
  335. package/template/coding-task-manager/public/js/app/restart-banner.js +53 -0
  336. package/template/coding-task-manager/public/js/app/worktrees-panel.js +184 -2
  337. package/template/coding-task-manager/public/js/background-work.js +196 -27
  338. package/template/coding-task-manager/public/js/coding-session-model-presentation.js +138 -10
  339. package/template/coding-task-manager/public/js/core/active-session-groups.js +179 -0
  340. package/template/coding-task-manager/public/js/core/pending-create.js +238 -0
  341. package/template/coding-task-manager/public/js/core/recent-machine-source.js +228 -0
  342. package/template/coding-task-manager/public/js/core/session-commands.js +180 -14
  343. package/template/coding-task-manager/public/js/dashboard-client-function-order.json +8 -0
  344. package/template/coding-task-manager/public/js/document-review-links.js +9 -1
  345. package/template/coding-task-manager/public/js/file-resolution-client.js +52 -1
  346. package/template/coding-task-manager/public/js/history-app-seam.js +22 -2
  347. package/template/coding-task-manager/public/js/machine-pool-shared.js +558 -3
  348. package/template/coding-task-manager/public/js/message-renderer.js +4 -3
  349. package/template/coding-task-manager/public/js/model-picker.js +3 -1
  350. package/template/coding-task-manager/public/js/native-subagent-review.js +15 -2
  351. package/template/coding-task-manager/public/js/new-session-agent-grid.js +346 -0
  352. package/template/coding-task-manager/public/js/pasted-content.js +236 -0
  353. package/template/coding-task-manager/public/js/pe-private-content-lifetime.js +39 -7
  354. package/template/coding-task-manager/public/js/private-model-lifetime.js +6 -2
  355. package/template/coding-task-manager/public/js/prompts.js +11 -10
  356. package/template/coding-task-manager/public/js/protocol.js +10 -0
  357. package/template/coding-task-manager/public/js/restart-banner-policy.js +29 -1
  358. package/template/coding-task-manager/public/js/session-model-picker.js +447 -57
  359. package/template/coding-task-manager/public/js/session-search-utils.js +18 -2
  360. package/template/coding-task-manager/public/js/session-usage-view.js +2 -1
  361. package/template/coding-task-manager/public/js/session-workspace-tracking.js +51 -1
  362. package/template/coding-task-manager/public/js/state-sync-client.js +10 -1
  363. package/template/coding-task-manager/public/js/stream-view.js +6 -5
  364. package/template/coding-task-manager/public/js/terminal/conv-only-session.js +287 -0
  365. package/template/coding-task-manager/public/js/terminal/runtime-09.js +2 -0
  366. package/template/coding-task-manager/public/js/terminal/runtime-10.js +5 -5
  367. package/template/coding-task-manager/public/js/terminal/runtime-12.js +8 -1
  368. package/template/coding-task-manager/public/js/terminal/runtime-16.js +4 -0
  369. package/template/coding-task-manager/public/js/terminal/runtime-20.js +1 -1
  370. package/template/coding-task-manager/public/js/terminal-attachment-draft.js +67 -13
  371. package/template/coding-task-manager/public/js/terminal-image-orchestration.js +52 -6
  372. package/template/coding-task-manager/public/js/terminal-wheel.js +23 -3
  373. package/template/coding-task-manager/public/js/walle/chat-conversation.js +4 -4
  374. package/template/coding-task-manager/public/js/walle.js +6 -0
  375. package/template/coding-task-manager/public/js/ws/live-dispatch.js +10 -0
  376. package/template/coding-task-manager/public/m/app.css +140 -0
  377. package/template/coding-task-manager/public/m/app.js +507 -68
  378. package/template/coding-task-manager/public/m/index.html +17 -0
  379. package/template/coding-task-manager/public/m/machines.js +838 -4
  380. package/template/coding-task-manager/public/m/private-api.js +31 -1
  381. package/template/coding-task-manager/public/usage.html +1 -0
  382. package/template/coding-task-manager/scripts/dev-route-fixture/synthetic-route-upstream.js +104 -0
  383. package/template/coding-task-manager/scripts/dev-route-fixture.js +339 -0
  384. package/template/coding-task-manager/scripts/opencode-lead-route-probe.js +195 -0
  385. package/template/coding-task-manager/scripts/opencode-v2-contract-probe/fake-anthropic.js +168 -0
  386. package/template/coding-task-manager/scripts/opencode-v2-contract-probe/probe-plugin/server.js +95 -0
  387. package/template/coding-task-manager/scripts/opencode-v2-contract-probe.js +673 -0
  388. package/template/coding-task-manager/server.js +1950 -11679
  389. package/template/coding-task-manager/session-integrity.js +64 -4
  390. package/template/coding-task-manager/workers/db-owner-worker.js +19 -2
  391. package/template/coding-task-manager/workers/online-backup-worker.js +1 -0
  392. package/template/coding-task-manager/workers/read-pool-model-collector.js +51 -3
  393. package/template/coding-task-manager/workers/read-pool-worker.js +76 -6
  394. package/template/coding-task-manager/workers/session-host-pool-process.js +6 -6
  395. package/template/coding-task-manager/workers/session-host-process.js +5 -5
  396. package/template/coding-task-manager/workers/watch-worker.js +105 -0
  397. package/template/coding-task-manager/workers/worktree-worker.js +168 -33
  398. package/template/ctm-relay/lib/protocol.js +14 -1
  399. package/template/package-lock.json +2 -2
  400. package/template/package.json +1 -1
  401. package/template/shared/backup-retention.js +82 -0
  402. package/template/shared/conversation-admission.js +2 -0
  403. package/template/shared/conversation-provenance.js +3 -7
  404. package/template/shared/conversation-storage-v2-contract.js +5 -0
  405. package/template/shared/linked-worktree.js +51 -0
  406. package/template/shared/macos-fda-target.js +57 -0
  407. package/template/shared/orphan-parents.js +55 -0
  408. package/template/shared/release-schema.json +2 -2
  409. package/template/shared/storage/contract.js +3 -0
  410. package/template/wall-e/adapters/imessage.js +12 -0
  411. package/template/wall-e/agent.js +71 -4
  412. package/template/wall-e/api-walle.js +21 -1
  413. package/template/wall-e/bin/train-gemma-e4b-tooluse.js +2 -2
  414. package/template/wall-e/bin/walle-mcp-stdio.js +5 -5
  415. package/template/wall-e/brain/brain-join.js +859 -0
  416. package/template/wall-e/brain/brain-sync-membership.js +20 -0
  417. package/template/wall-e/brain/brain-sync-store.js +131 -77
  418. package/template/wall-e/brain/brain-sync-v2-schema.js +203 -0
  419. package/template/wall-e/brain/brain-sync-v2.js +578 -0
  420. package/template/wall-e/brain/delegate-model-prefs-store.js +13 -4
  421. package/template/wall-e/brain/deterministic-id.js +51 -0
  422. package/template/wall-e/brain/memories.js +2 -2
  423. package/template/wall-e/brain/migrations.js +40 -6
  424. package/template/wall-e/brain/model-identity-migration.js +1 -1
  425. package/template/wall-e/brain/owner-call-whitelist.js +23 -7
  426. package/template/wall-e/brain/schema.js +45 -85
  427. package/template/wall-e/brain.js +171 -35
  428. package/template/wall-e/chat.js +3 -3
  429. package/template/wall-e/coding/agent-shell-env.js +7 -2
  430. package/template/wall-e/coding/prompt-bundle.js +66 -21
  431. package/template/wall-e/config/main-loop-exemptions.json +2 -2
  432. package/template/wall-e/http/admin-api.js +37 -0
  433. package/template/wall-e/http/gws-api.js +4 -0
  434. package/template/wall-e/http/helper-rules-api.js +7 -1
  435. package/template/wall-e/http/model-admin.js +8 -1
  436. package/template/wall-e/http/model-delegate-pref-admin.js +3 -3
  437. package/template/wall-e/http/model-proxy-providers.js +174 -1
  438. package/template/wall-e/http/model-route-health.js +157 -0
  439. package/template/wall-e/http/sync-api.js +278 -464
  440. package/template/wall-e/jobs/job-runner.js +28 -1
  441. package/template/wall-e/lib/brain-owner-op-priority.js +9 -1
  442. package/template/wall-e/lib/ctm-data-dir.js +26 -0
  443. package/template/wall-e/lib/derivation-home.js +147 -0
  444. package/template/wall-e/lib/helper-rules/evaluate.js +50 -9
  445. package/template/wall-e/lib/helper-rules/grade.js +51 -8
  446. package/template/wall-e/lib/helper-rules/lead-call-hook.js +38 -5
  447. package/template/wall-e/lib/helper-rules/store.js +4 -2
  448. package/template/wall-e/lib/landing-mcp-tools.js +170 -0
  449. package/template/wall-e/lib/mcp-client-config.js +133 -14
  450. package/template/wall-e/lib/mcp-gateway-migrate.js +28 -64
  451. package/template/wall-e/lib/mcp-integration.js +58 -13
  452. package/template/wall-e/lib/parent-death.js +7 -1
  453. package/template/wall-e/lib/scheduler-worker-jobs.js +6 -4
  454. package/template/wall-e/llm/delegate-lead-prefs.js +16 -1
  455. package/template/wall-e/llm/delegate-vendor-default.js +12 -5
  456. package/template/wall-e/llm/model-roles.js +1 -1
  457. package/template/wall-e/llm/native-delegate-selection.js +56 -8
  458. package/template/wall-e/llm/worker-delegate-args.js +72 -7
  459. package/template/wall-e/llm/worker-mcp-routing.js +66 -17
  460. package/template/wall-e/loops/brain-custom-writes.js +19 -0
  461. package/template/wall-e/loops/ingest.js +17 -1
  462. package/template/wall-e/loops/think.js +19 -4
  463. package/template/wall-e/mcp-contract.js +222 -6
  464. package/template/wall-e/mcp-protocol-contract.js +40 -5
  465. package/template/wall-e/mcp-server.js +128 -29
  466. package/template/wall-e/mcp-worker-schemas.js +5 -5
  467. package/template/wall-e/memory/ctm-context-client.js +85 -0
  468. package/template/wall-e/memory/ctm-session-context.js +9 -3
  469. package/template/wall-e/memory/hub-bridge-client.js +388 -0
  470. package/template/wall-e/memory/replica-origin.js +56 -0
  471. package/template/wall-e/memory/session-pool.js +135 -0
  472. package/template/wall-e/runtime/live-capabilities.js +8 -3
  473. package/template/wall-e/server.js +4 -2
  474. package/template/wall-e/shared/release-schema.json +2 -2
  475. package/template/wall-e/shared/sqlite-file-set.js +39 -0
  476. package/template/wall-e/shared/storage/contract.js +3 -0
  477. package/template/wall-e/skills/_templates/delegate-worker/VERSION +1 -1
  478. package/template/wall-e/skills/_templates/delegate-worker/released-sha256.json +7 -1
  479. package/template/wall-e/skills/_templates/delegate-worker/templates/claude/SKILL.md +4 -4
  480. package/template/wall-e/skills/_templates/delegate-worker/templates/codex/SKILL.md +6 -6
  481. package/template/wall-e/skills/_templates/fleet-sync/VERSION +1 -0
  482. package/template/wall-e/skills/_templates/fleet-sync/released-sha256.json +16 -0
  483. package/template/wall-e/skills/_templates/fleet-sync/templates/claude/SKILL.md +64 -0
  484. package/template/wall-e/skills/_templates/fleet-sync/templates/codex/SKILL.md +64 -0
  485. package/template/wall-e/tools/chrome-automation.js +6 -0
  486. package/template/wall-e/training/setup-cuda-train-env.sh +2 -2
  487. package/template/wall-e/workers/brain-owner-worker.js +18 -4
  488. package/template/wall-e/workers/mcp-gateway-process.js +5 -5
@@ -21,9 +21,14 @@ const { validateDeferredRestoreAttempt } = require('../deferred-restore-attempt'
21
21
  const { getPrivateSourceRecoveryEnvironment, capturePrivateSourceEnvironment,
22
22
  hasCapturedEmptySourceEnvironmentRestore } = require('../lead-model-restore-reconciliation');
23
23
  const { modelStorageRootsFromEnv, privateOverridesFromEnv } = require('../host-handoff');
24
+ // WP-1 (D-2): the host-carried launch-environment record is built by the ONE capture function (§5 D-1).
25
+ const { captureLaunchEnvironment } = require('../launch-environment');
24
26
  // WP-0b: the rollback launch capture (moved out of this file, same spawn point) -- see
25
27
  // lib/session-create/provider-launch-context.js for the field-by-field contract.
26
28
  const { buildModelTransitionLaunchContext } = require('./provider-launch-context');
29
+ // WP-4 (D-7/D-8, §6.4): the hub's agent-skill bundle, applied to the SPAWN argv/env only.
30
+ const { applyAgentBundleToSpawn, resolveSpawnBundleForSession } = require('../agent-bundle/spawn');
31
+ const { treeHex } = require('../agent-bundle/drift'); // WP-3 D-11/S-5: the spawn result names the tree it applied
27
32
  const codexNativeProviderGate = require('./codex-native-provider-gate');
28
33
  const MAX_CODEX_CONFIG_BYTES = 1024 * 1024;
29
34
 
@@ -117,12 +122,19 @@ function explicitClaudeSessionId(args) {
117
122
  return unique.length === 1 ? unique[0] : unique.length === 0 ? null : '';
118
123
  }
119
124
 
120
- function launchProviderThreadId({ agent, launchPlan, claudeResumeId, injectedSessionId, args }) {
125
+ // R-2 (docs/opencode-v2-model-switch-standalone-plugin-2026-10-30.html §5.1): the OpenCode v2 session id
126
+ // resolve-launch-params minted, carried in the `_launchParams` bag server.js forwards.
127
+ function injectedOpencodeSessionId(state) {
128
+ const value = state?._injectedOpencodeSessionId || state?._launchParams?._injectedOpencodeSessionId;
129
+ return typeof value === 'string' && value.length > 0 ? value : null;
130
+ }
131
+
132
+ function launchProviderThreadId({ agent, launchPlan, claudeResumeId, injectedSessionId, injectedOpencodeId, args }) {
121
133
  const resume = launchPlan?.resume || {};
122
134
  const explicit = agent === 'claude' ? explicitClaudeSessionId(args) : null;
123
135
  if (explicit === '') return null;
124
136
  const candidates = [resume.providerResumeId, resume.providerResumeID, resume.sessionId, resume.agentSessionId,
125
- claudeResumeId, injectedSessionId, explicit,
137
+ claudeResumeId, injectedSessionId, injectedOpencodeId, explicit,
126
138
  extractResumeTarget(agent, args)?.sessionId].filter((value) => typeof value === 'string' && value.length > 0);
127
139
  const unique = [...new Set(candidates)];
128
140
  return unique.length === 1 ? unique[0] : null;
@@ -202,6 +214,7 @@ async function prepareProviderSession(state) {
202
214
  } = _getDeps();
203
215
  const { args, cmd, createAgentType, cwd, env, id, msg, preparedLaunchPlan, restoreSeedSnapshot, ws, signal,
204
216
  claudeResumeId, _injectedSessionId } = state;
217
+ const _injectedOpencodeSessionId = injectedOpencodeSessionId(state);
205
218
  const transitionSignal = Object.hasOwn(state, 'transitionSignal')
206
219
  ? (state.transitionSignal || null) : (msg?._transitionSignal || null);
207
220
  // WP-0b (docs/session-model-authority-and-display-2026-10-15.html §9 S3, AC-0d): a provider
@@ -225,7 +238,7 @@ async function prepareProviderSession(state) {
225
238
  return { handled: true, result: null };
226
239
  }
227
240
  const resolvedProviderThreadId = launchProviderThreadId({ agent: createAgentType, launchPlan: preparedLaunchPlan,
228
- claudeResumeId, injectedSessionId: _injectedSessionId, args });
241
+ claudeResumeId, injectedSessionId: _injectedSessionId, injectedOpencodeId: _injectedOpencodeSessionId, args });
229
242
  const subagentOwnerContext = {
230
243
  processGeneration: modelProcessGeneration,
231
244
  harness: createAgentType === 'codex' ? 'codex-cli' : 'claude-code',
@@ -238,8 +251,8 @@ async function prepareProviderSession(state) {
238
251
  if (!msg._isRestore || msg._leadModelTransition
239
252
  || sourceRecoveryEnvironment.ctmSessionId !== id
240
253
  || sourceRecoveryEnvironment.agent !== createAgentType
241
- || sourceRecoveryEnvironment.providerThreadId !== providerThreadId
242
- || sourceRecoveryEnvironment.modelId !== msg._launchModelOverride
254
+ || (sourceRecoveryEnvironment.providerThreadId !== providerThreadId && !(sourceRecoveryEnvironment.freshRelaunch === true && providerThreadId === ''))
255
+ || sourceRecoveryEnvironment.modelId !== String(msg._launchModelOverride || '')
243
256
  || sourceRecoveryEnvironment.routeId !== routeId) {
244
257
  recordSessionDiagnostic?.(id, 'source-recovery-environment-rejected', { reason: 'source_owner_mismatch' });
245
258
  return { handled: false, providerState: null };
@@ -293,6 +306,7 @@ async function prepareProviderSession(state) {
293
306
  ? await _prepareRestoredScrollbackSeed(id, restoreSeedData, {
294
307
  recordedSeamRow: Number.isFinite(restoreSeedSnapshot?.archiveSeamRow)
295
308
  ? restoreSeedSnapshot.archiveSeamRow : null,
309
+ seedRows: restoreSeedSnapshot?.rows, // the snapshot's rows, not the new session's
296
310
  })
297
311
  : null;
298
312
  } catch (error) {
@@ -313,8 +327,11 @@ async function prepareProviderSession(state) {
313
327
  // session has a persisted lead route runs its CLI against CTM's model proxy. Never for a worker
314
328
  // (own route path) and never for a non claude/codex agent. The target comes from the switch's own
315
329
  // msg._launchLeadRoute when present (object, or null = explicitly native), else the DB row.
330
+ // WP-2 (opencode-model-selection round 2 §5 R-3): an OpenCode LEAD rides the SAME preparation --
331
+ // same token, ownership, persistence, revocation -- only its last step (the OPENCODE_CONFIG_CONTENT
332
+ // provider patch merged below) differs, exactly as Codex's `-c` block already does.
316
333
  let leadRoute = null;
317
- if (msg.agentRole !== 'worker' && (createAgentType === 'claude' || createAgentType === 'codex')) {
334
+ if (msg.agentRole !== 'worker' && (createAgentType === 'claude' || createAgentType === 'codex' || createAgentType === 'opencode')) {
318
335
  let target = null;
319
336
  let readFailed = false;
320
337
  if (Object.hasOwn(msg, '_launchLeadRoute')) {
@@ -512,9 +529,12 @@ async function prepareProviderSession(state) {
512
529
  }
513
530
  // default-subagent-model-delegate-pick-2026-10-13.html §5 D-1..D-3/D-9/D-12: a Claude/Codex LEAD
514
531
  // launch reads the Wall-E delegate pick and applies a native/inherit pick to THIS spawn's env/argv
515
- // only. The RESOLVER comes through the deps getter (never a require fallback): when it is absent
516
- // (every existing test harness) nothing happens -- no Wall-E read, zero change (D-1), and unit
517
- // tests stay off the live Wall-E. The PURE planner is required lazily inside that guard.
532
+ // only. S-19 (opencode-lead-and-delegate-model-selection-2026-10-28.html §8 WP-4) adds the OpenCode
533
+ // lead to that same gate: its pick is projected into OPENCODE_CONFIG_CONTENT instead of subagent env
534
+ // vars (see subagent-pick.opencodeLaunchProjection). The RESOLVER comes through the deps getter
535
+ // (never a require fallback): when it is absent (every existing test harness) nothing happens -- no
536
+ // Wall-E read, zero change (D-1), and unit tests stay off the live Wall-E. The PURE planner is
537
+ // required lazily inside that guard.
518
538
  let subagentPick = null;
519
539
  let subagentPlan = null;
520
540
  let appliedSubagentPick = null;
@@ -532,7 +552,8 @@ async function prepareProviderSession(state) {
532
552
  // through the private runtime state so the PRE-SPAWN rechecks (after every late transform) can still
533
553
  // refuse an attempt that went stale while the launch plan ran.
534
554
  let nativeLaunchGenerationFence = null;
535
- if (msg.agentRole !== 'worker' && (createAgentType === 'claude' || createAgentType === 'codex')) {
555
+ if (msg.agentRole !== 'worker'
556
+ && (createAgentType === 'claude' || createAgentType === 'codex' || createAgentType === 'opencode')) {
536
557
  const resolvePick = _getDeps().resolveSubagentPick;
537
558
  if (typeof resolvePick === 'function') {
538
559
  try {
@@ -608,15 +629,42 @@ async function prepareProviderSession(state) {
608
629
  }
609
630
  }
610
631
  }
611
- if (subagentPick && (subagentPick.kind === 'native' || subagentPick.kind === 'inherit')) {
612
- const { planSubagentLaunch } = require('./subagent-pick');
613
- subagentPlan = planSubagentLaunch(subagentPick, { agent: createAgentType, leadRoute, dataDir: getDataDir() });
632
+ // WP-1 (codex-native-subagent-pick-enforcement-2026-10-28.html D-2/D-3/D-4): an unservable Codex pick is
633
+ // planned too -- the plan carries the deny prefix (roleFile null) and the fact is recorded on the pick.
634
+ let codexVersion = '';
635
+ if (subagentPick && (subagentPick.kind === 'native' || subagentPick.kind === 'inherit'
636
+ || subagentPick.kind === 'unservable')) {
637
+ const { planSubagentLaunch, nativeSubagentsDenied } = require('./subagent-pick');
638
+ // WP-1b: the deny prefix needs a config key only Codex >= 0.163.0 knows, so probe the binary
639
+ // this launch spawns -- and ONLY for a denied pick (no extra spawn everywhere else). A
640
+ // throwing or empty probe reads as unknown: no deny, never a blocked launch.
641
+ if (nativeSubagentsDenied(subagentPick)) {
642
+ try {
643
+ const probeVersion = _getDeps().probeCodexVersion || require('../harness-model-profile')._probeVersion;
644
+ codexVersion = String(await probeVersion(cmd, signal) || '');
645
+ } catch (error) {
646
+ /* HANDLE: a failed probe is unknown -> baseline launch (D-1), never a refusal. */
647
+ recordSessionDiagnostic?.(id, 'subagent-pick-version-probe-failed', { detail: String((error && error.message) || error).slice(0, 200) });
648
+ }
649
+ }
650
+ // §5 R-10: an OpenCode pick is projected into inline runtime config, so the planner needs the
651
+ // launch env's CURRENT OPENCODE_CONFIG_CONTENT to merge over rather than replace. Nothing else
652
+ // reads it -- a claude/codex plan ignores the option entirely.
653
+ subagentPlan = planSubagentLaunch(subagentPick, { agent: createAgentType, leadRoute, dataDir: getDataDir(), codexVersion,
654
+ existingConfigContent: env && env.OPENCODE_CONFIG_CONTENT });
655
+ if (subagentPlan && subagentPlan.nativeSubagents) {
656
+ subagentPick = { ...subagentPick, nativeSubagents: subagentPlan.nativeSubagents };
657
+ }
614
658
  }
615
659
  if (typeof recordSessionDiagnostic === 'function') {
616
660
  if (subagentPick && subagentPick.kind === 'none' && subagentPick.reason === 'read_failed') {
617
661
  recordSessionDiagnostic(id, 'subagent-pick-read-failed', { detail: subagentPick.detail });
618
662
  } else if (subagentPick && subagentPick.kind === 'unservable') {
619
- recordSessionDiagnostic(id, 'subagent-pick-unservable', { reason: subagentPick.reason });
663
+ recordSessionDiagnostic(id, 'subagent-pick-unservable', {
664
+ reason: subagentPick.reason,
665
+ nativeSubagents: subagentPlan ? subagentPlan.nativeSubagents : '',
666
+ codexVersion,
667
+ });
620
668
  }
621
669
  }
622
670
  if (subagentPlan && subagentPlan.roleFile) {
@@ -675,6 +723,12 @@ async function prepareProviderSession(state) {
675
723
  }
676
724
  }
677
725
 
726
+ // WP-4 (§5 D-6/D-7/D-8, §6.4): the hub's bundle, read while we are still async (the spawn tail is
727
+ // synchronous). Resolved per spawn, so a restore picks up the CURRENT tree (AC-4d); never persisted.
728
+ const spawnBundle = createAgentType === 'claude'
729
+ ? await resolveSpawnBundleForSession(id, { report: (event, details) => recordSessionDiagnostic?.(id, event, details) })
730
+ : null;
731
+
678
732
  const providerStateInput = {
679
733
  ...state,
680
734
  // Carry only the already-validated private capability across the async preparation boundary.
@@ -693,7 +747,7 @@ async function prepareProviderSession(state) {
693
747
  restoreSeedPrepared,
694
748
  args: runtime?.ready ? runtime.args : args,
695
749
  codexApprovalProxyOwnsApprovals: runtime?.ready === true && runtime.mode === 'canary',
696
- appliedSubagentPick,
750
+ appliedSubagentPick, spawnBundle,
697
751
  };
698
752
  let providerState;
699
753
  try {
@@ -727,8 +781,10 @@ function isLiveForCwdConflict(s) {
727
781
  function createProviderSession(state) {
728
782
  const { sessionInputAuthority } = _getDeps();
729
783
  const { CODEX_RESUME_CWD_GUARD_ENABLED, RESUME_FIRSTBYTE_MS, RESUME_LIFECYCLE_V2_ENABLED, _armResumeHardCeiling, _attentionMarkerMs, _detachOwnerMutation, _enforceLifecycleCap, _fireResumeFirstByteWatchdog, _fireResumeLoadingSafetyTimeout, _isAgentWorktreePath, _markRestoreInterruptionWaiting, _markRestoredHeadlessSeedApplied, _perfTracker, _prepareScrollbackForSession, _providerIdFromCmd, _reportWorkerIpc, _resumeAttemptTracker, _resumeLifecycleCoordinator, _resumeLoadingAgentEnabled, _resumeLoadingMaxMs, _resumeLoadingServerCore, _retireResumeGenerationLocalState, _sessionMcpProfileSetting, _sessionStream, _setSessionAttentionFields, _spawnSessionPty, _providerRunningHoldMsForSession, _stateSyncCreateSubscriptionOptions, _resyncViewingForSession, _stripAgentWorktreePath, _subscribeStateSyncClient, _useSessionHostProcessForPty, _viewerArbitration, _wsSend, broadcastSessionList, claudeProjectDirForCwd, codexConfigGuard, codexPaths, createPtyStartupReservation, createSessionWithStartupTaskWithRetry, crypto, dbModule, detectAgentType, encodeClaudeProjectEntry, encodeProjectEntry, execFileCb, headlessWorker, normalizeAgentType, parseSessionStartMs, path, recordSessionDiagnostic, resolveResumeGeneration, restoreRuntime, seedClaudeModel, serverConfig, sessionEvents, sessionHostManager, sessionRegistry, statusHooks, telemetry } = _getDeps();
730
- const { _approvalHookEnabled, _approvalHookToken, _codexResumeCwdToHeal, _handleCreateStartedAt, _injectedSessionId, claudeResumeId, cmd, codexApprovalProxyOwnsApprovals, cols, createAgentType, cwd, env, existingTitle, hasExplicitClientTitle, id, isResumeLaunch, label, leadRoute, modelProcessGeneration: capturedModelProcessGeneration, nativeLeadTokenOwnership, nativeLeadLifetimeCapture: capturedNativeLifetime, nativeLeadOwnerRow: capturedNativeOwnerRow, nativeLaunchGenerationFence: capturedNativeGenerationFence, model_id, model_provider, msg, nativeConfigReceipt, preparedLaunchPlan, ptyStartupAttempt, restoreLaunchFence, restoreSeedPrepared, restoreSeedSnapshot, rows, sourceRecoveryEnvironment, subagentPick, appliedSubagentPick, subagentPlan, title, ws } = state;
784
+ const { _approvalHookEnabled, _approvalHookToken, _codexResumeCwdToHeal, _handleCreateStartedAt, _injectedSessionId, claudeResumeId, cmd, codexApprovalProxyOwnsApprovals, cols, createAgentType, cwd, env, existingTitle, hasExplicitClientTitle, id, isResumeLaunch, label, leadRoute, modelProcessGeneration: capturedModelProcessGeneration, nativeLeadTokenOwnership, nativeLeadLifetimeCapture: capturedNativeLifetime, nativeLeadOwnerRow: capturedNativeOwnerRow, nativeLaunchGenerationFence: capturedNativeGenerationFence, model_id, model_provider, msg, nativeConfigReceipt, preparedLaunchPlan, ptyStartupAttempt, restoreLaunchFence, restoreSeedPrepared, restoreSeedSnapshot, rows, sourceRecoveryEnvironment, subagentPick, appliedSubagentPick, subagentPlan, spawnBundle, title, ws } = state;
731
785
  const preparedLeadTokenOwner = leadRoute?.ownership || leadRoute?.preparedPlan?.ownership || nativeLeadTokenOwnership || null;
786
+ // R-2: never `_injectedSessionId` — the Claude-only JSONL/project-dir side effects below key on it.
787
+ const _injectedOpencodeSessionId = injectedOpencodeSessionId(state);
732
788
  // §6.6 item 11 / §6.12: an EXACT captured native owner has exactly ONE cleanup obligation — the
733
789
  // private lifetime record owns both phases of it (the exact token/row revoke AND the files), and the
734
790
  // module decides whether the files may go (an UNCONSUMED attempt) or must be retained until a real
@@ -822,11 +878,11 @@ function createProviderSession(state) {
822
878
  }
823
879
  }
824
880
 
825
- // Lead-model switch (picker design D-7): the one-shot model override reaches THIS spawn's argv
826
- // only. `args` (what session.args and startup_tasks get below) never carries it; a later
827
- // restore replays the session's stored pin (the WP-3 block below), not the one-shot override.
881
+ // Lead-model switch (picker design D-7): the one-shot model override reaches THIS spawn's argv only
882
+ // (`args`/startup_tasks never carry it; a later restore replays the stored pin, WP-3). The OpenCode
883
+ // line rides along so a 2.x relaunch drops `--model` (its target is the inline config + plugin, R-4).
828
884
  const launchOverride = msg._isRestore === true
829
- ? applyLaunchModelOverride({ agentType: normalizeAgentType(createAgentType), args, model: msg._launchModelOverride })
885
+ ? applyLaunchModelOverride({ agentType: normalizeAgentType(createAgentType), args, model: msg._launchModelOverride, ...(normalizeAgentType(createAgentType) === 'opencode' ? { line: require('../opencode-cli').peekOpencodeLine() } : {}) })
830
886
  : { args, applied: false, reason: 'none' };
831
887
  if (msg._launchModelOverride) recordSessionDiagnostic(id, 'lead-model-launch-override', { applied: launchOverride.applied, reason: launchOverride.reason, agent: createAgentType });
832
888
 
@@ -882,10 +938,15 @@ function createProviderSession(state) {
882
938
  // receives them (`launchEnvOverrides` below).
883
939
  const trustedCapturedEmptySourceEnvironment = msg._isRestore === true
884
940
  && hasCapturedEmptySourceEnvironmentRestore(msg);
885
- const sourceOverrideCapture = capturePrivateSourceEnvironment(sourceRecoveryEnvironment
941
+ // The ONE input both the spawn receipt and the host-carried record are built from (WP-1 §6 S-3).
942
+ const privateSourceEnv = sourceRecoveryEnvironment
886
943
  ? privateOverridesFromEnv(sourceRecoveryEnvironment.environment)
887
944
  : trustedCapturedEmptySourceEnvironment ? {}
888
- : privateOverridesFromEnv(msg.env && typeof msg.env === 'object' ? msg.env : {}));
945
+ : privateOverridesFromEnv(msg.env && typeof msg.env === 'object' ? msg.env : {});
946
+ const sourceOverrideCapture = capturePrivateSourceEnvironment(privateSourceEnv);
947
+ // WP-1 (S-3, §6): the SAME input drives the host-carried record, so the record's state/reason can never
948
+ // drift from the spawn receipt's `sourceEnvironmentReference` below.
949
+ const launchEnvironmentRecord = captureLaunchEnvironment(privateSourceEnv);
889
950
  const sourceEnvironmentReference = trustedCapturedEmptySourceEnvironment ? 'captured-empty'
890
951
  : sourceOverrideCapture.state === 'captured'
891
952
  ? (Object.keys(sourceOverrideCapture.values || {}).length === 0 ? 'captured-empty' : 'private-owner-required')
@@ -909,7 +970,8 @@ function createProviderSession(state) {
909
970
  const executionRecipe = modelExecutionRecipeForSpawn({ sessionId: id, processGeneration: modelProcessGeneration,
910
971
  agent: createAgentType, launchPlan: preparedLaunchPlan, leadRoute, transition: msg._leadModelTransition || null,
911
972
  sourceEnvironmentReference, nativeConfigReceipt, providerThreadId: launchProviderThreadId({ agent: createAgentType,
912
- launchPlan: preparedLaunchPlan, claudeResumeId, injectedSessionId: _injectedSessionId, args: launchArgs }) });
973
+ launchPlan: preparedLaunchPlan, claudeResumeId, injectedSessionId: _injectedSessionId,
974
+ injectedOpencodeId: _injectedOpencodeSessionId, args: launchArgs }) });
913
975
  let spawnEnv = { ...applyModelExecutionRecipeToSpawnEnv(leadApplied.spawnEnv, executionRecipe,
914
976
  { sessionId: id, processGeneration: modelProcessGeneration }), CTM_MODEL_PROCESS_GENERATION: String(modelProcessGeneration) };
915
977
  // default-subagent-model-delegate-pick-2026-10-13.html §5 D-2/D-3/D-9: apply this session's
@@ -918,6 +980,73 @@ function createProviderSession(state) {
918
980
  const pickApplied = _applySubagentPickToSpawn({ launchArgs, spawnEnv, plan: subagentPlan });
919
981
  launchArgs = pickApplied.launchArgs;
920
982
  spawnEnv = pickApplied.spawnEnv;
983
+ // WP-5 (§5 R-6/§9 S-21, opencode-lead-and-delegate-model-selection-2026-10-28.html §8): an
984
+ // OpenCode LEAD gets the Wall-E MCP server INLINE, for THIS spawn only -- CTM never writes
985
+ // OpenCode's own config (~/.config/opencode/*). The entry comes through the deps getter
986
+ // (opencodeWalleMcp); absent (every existing test harness) means byte-identical behaviour. It is
987
+ // merged AFTER the subagent pick so it never replaces the pick's `agent.*.model` config -- both
988
+ // ride the same OPENCODE_CONFIG_CONTENT document (subagent-pick.opencodeWalleMcpProjection).
989
+ // A throw from the dep is REPORTED and the launch proceeds without it.
990
+ if (msg.agentRole !== 'worker' && createAgentType === 'opencode') {
991
+ const opencodeWalleMcp = _getDeps().opencodeWalleMcp;
992
+ if (typeof opencodeWalleMcp === 'function') {
993
+ let walleMcpEntry = null;
994
+ try {
995
+ walleMcpEntry = opencodeWalleMcp();
996
+ } catch (error) {
997
+ recordSessionDiagnostic?.(id, 'opencode-walle-mcp-failed', { message: String((error && error.message) || error).slice(0, 200) });
998
+ }
999
+ if (walleMcpEntry) {
1000
+ const { opencodeWalleMcpProjection } = require('./subagent-pick');
1001
+ const content = opencodeWalleMcpProjection({
1002
+ existingConfigContent: spawnEnv.OPENCODE_CONFIG_CONTENT,
1003
+ walleMcp: walleMcpEntry,
1004
+ });
1005
+ if (content !== null) spawnEnv = { ...spawnEnv, OPENCODE_CONFIG_CONTENT: content };
1006
+ }
1007
+ }
1008
+ }
1009
+ // WP-2 (opencode-model-selection round 2 §5 R-3/R-6, §6.2): an OpenCode ROUTED lead's `ctm-lead`
1010
+ // provider entry is merged into the SAME OPENCODE_CONFIG_CONTENT blob its subagent pick (:942) and
1011
+ // Wall-E MCP server (:951-973) ride. It is merged LAST -- after BOTH -- because the pick's
1012
+ // projection REPLACES the value (`{...spawnEnv, OPENCODE_CONFIG_CONTENT: <its own>}`), so only here
1013
+ // is the document final. One writer, one blob: provider['ctm-lead'] + agent.general/explore +
1014
+ // mcp['wall-e'] together (AC-2b), with the token appearing only as {env:CTM_LEAD_TOKEN} (AC-2c).
1015
+ // The `delete spawnEnv.ANTHROPIC_API_KEY` behaviour stays in _applyLeadRouteToSpawn, unchanged.
1016
+ if (createAgentType === 'opencode' && leadRoute && leadRoute.configPatch) {
1017
+ const { opencodeLeadRouteProjection } = require('./subagent-pick');
1018
+ const content = opencodeLeadRouteProjection({
1019
+ existingConfigContent: spawnEnv.OPENCODE_CONFIG_CONTENT,
1020
+ configPatch: leadRoute.configPatch,
1021
+ });
1022
+ if (content !== null) spawnEnv = { ...spawnEnv, OPENCODE_CONFIG_CONTENT: content };
1023
+ }
1024
+ // WP-5 (R-9, §6.7): a prompted OpenCode 1.x tab's switch relaunch carries the model carrier; a no-op otherwise.
1025
+ const v1CarrierEnv = require('./subagent-pick').opencodeV1CarrierEnv({
1026
+ agentType: createAgentType, isRestore: msg._isRestore === true, agentRole: msg.agentRole,
1027
+ line: require('../opencode-cli').peekOpencodeLine(), nativeModel: msg._launchModelOverride,
1028
+ launchLeadRoute: msg._launchLeadRoute, launchArgs, spawnEnv,
1029
+ });
1030
+ if (v1CarrierEnv !== spawnEnv) {
1031
+ spawnEnv = v1CarrierEnv;
1032
+ recordSessionDiagnostic?.(id, 'opencode-v1-model-carrier', { target: spawnEnv.CTM_OPENCODE_SWITCH_MODEL, session_id: spawnEnv.CTM_OPENCODE_SWITCH_SESSION });
1033
+ }
1034
+ // WP-2 (R-3, §6.2) + WP-4 (R-4): every OpenCode 2.x LEAD launch carries the CTM status plugin inline; on a restore that same entry also carries `switch_model` (the switch). No-op otherwise.
1035
+ const v2PluginEnv = require('./subagent-pick').opencodeV2PluginEnv({
1036
+ agentType: createAgentType, isRestore: msg._isRestore === true, agentRole: msg.agentRole,
1037
+ line: require('../opencode-cli').peekOpencodeLine(), nativeModel: msg._launchModelOverride,
1038
+ launchLeadRoute: msg._launchLeadRoute, launchArgs, spawnEnv,
1039
+ });
1040
+ if (v2PluginEnv !== spawnEnv) {
1041
+ spawnEnv = v2PluginEnv;
1042
+ recordSessionDiagnostic?.(id, 'opencode-v2-plugin', { session_id: require('./subagent-pick').opencodeResumeSessionId(launchArgs), switch_model: require('./subagent-pick').opencodeV2SwitchModelOf(v2PluginEnv) });
1043
+ }
1044
+ // WP-4 (D-7/D-8, §6.4): applied to THIS spawn's argv/env only — `args`/state env keep their
1045
+ // originals (AC-4c), and the pre-spawn fence below still runs after it.
1046
+ const bundleApplied = applyAgentBundleToSpawn({ launchArgs, spawnEnv, agentType: createAgentType, bundle: spawnBundle });
1047
+ launchArgs = bundleApplied.launchArgs;
1048
+ spawnEnv = bundleApplied.spawnEnv;
1049
+ if (bundleApplied.applied) recordSessionDiagnostic?.(id, 'agent-bundle-applied', { treeHash: spawnBundle.treeHash, hubPeerId: spawnBundle.hubPeerId });
921
1050
  if (leadRoute && typeof recordSessionDiagnostic === 'function') {
922
1051
  const token = String(leadRoute.token || '');
923
1052
  recordSessionDiagnostic(id, 'lead-route-launch', { agent: createAgentType, route_id: leadRoute.alias, model: leadRoute.model, token_suffix: token.slice(-4) });
@@ -978,7 +1107,7 @@ function createProviderSession(state) {
978
1107
  cols,
979
1108
  rows,
980
1109
  cwd,
981
- env: spawnEnv,
1110
+ env: spawnEnv, launchEnvironment: launchEnvironmentRecord,
982
1111
  initialHeadlessData: restoreSeedForHeadless || undefined,
983
1112
  initialHeadlessSeedAligned: restoreSeedPrepared?.seedAligned === true,
984
1113
  initialHeadlessForwardDriftSeamRow: restoreSeedPrepared?.forwardDriftSeamRow,
@@ -1198,6 +1327,8 @@ function createProviderSession(state) {
1198
1327
  // -- native, inherit or routed -- is env-only and none/unservable applies nothing, so
1199
1328
  // those persist null rather than claiming a native-role effort.
1200
1329
  effort: appliedNativeEffort(appliedSubagentPick),
1330
+ // WP-1 (D-4, v58): what THIS spawn did about native sub-agents; the plan is the authority ('' = known not denied).
1331
+ nativeSubagents: subagentPlan ? subagentPlan.nativeSubagents : '',
1201
1332
  routeId: appliedSubagentPick.routeId || '', processGeneration: modelProcessGeneration,
1202
1333
  harness: executionRecipe?.harness || (createAgentType === 'codex' ? 'codex-cli' : 'claude-code'),
1203
1334
  providerThreadId: executionRecipe?.providerThreadId ?? null,
@@ -1340,7 +1471,7 @@ function createProviderSession(state) {
1340
1471
  if (session._wakeStartedAt) {
1341
1472
  session._wakePhases = { ...(session._wakePhases || {}), ptyStartedAt: Date.now() };
1342
1473
  }
1343
- broadcastSessionList(true);
1474
+ broadcastSessionList(true, { reason: 'pty-started' });
1344
1475
  });
1345
1476
  }
1346
1477
  // The creator was already subscribed atomically by subscribeOnCreate() at function entry
@@ -1360,7 +1491,7 @@ function createProviderSession(state) {
1360
1491
  setImmediate(() => { _enforceLifecycleCap().catch(error => {
1361
1492
  console.warn(`[lifecycle] create-cap-enforcement failed id=${String(id).slice(0, 8)} error=${error.message}`);
1362
1493
  }); });
1363
- telemetry.track('ctm_session', { type: cmd.includes('claude') ? 'claude' : cmd.includes('codex') ? 'codex' : 'shell' });
1494
+ telemetry.track('ctm_session', { type: ({ claude: 'claude', codex: 'codex' })[detectAgentType(cmd)] || 'shell' });
1364
1495
 
1365
1496
  // With --session-id injected, the JSONL path is known before Claude even starts
1366
1497
  // writing. Link the session stream eagerly so the ring buffer / conversation
@@ -1392,9 +1523,10 @@ function createProviderSession(state) {
1392
1523
  let startupPersistence = Promise.resolve(true);
1393
1524
  if (!msg._isRestore) {
1394
1525
  const sessionAgentType = detectAgentType(cmd) || 'unknown';
1526
+ // R-2: an OpenCode 2.x create persists its minted id (at most one of the three is set).
1395
1527
  const initialAgentSessionId = sessionAgentType === 'codex'
1396
1528
  ? ''
1397
- : (claudeResumeId || _injectedSessionId || '');
1529
+ : (claudeResumeId || _injectedSessionId || _injectedOpencodeSessionId || '');
1398
1530
  // WP-R7: msg here is preparedMsg (handleCreatePrepared spreads it verbatim into
1399
1531
  // handleCreate), so a client-supplied `mcp_profile` on the WS create message survives
1400
1532
  // to this point unmodified. Normalizes through the same function the launch-plan
@@ -1478,7 +1610,7 @@ function createProviderSession(state) {
1478
1610
  // db-owner preparation owns cleanup for both new and restored sessionRegistry.
1479
1611
  deferInspect: true,
1480
1612
  });
1481
- return { ...state, branch, ptyProcess, session, startupPersistence, args };
1613
+ return { ...state, branch, ptyProcess, session, startupPersistence, args, agentBundleTreeHash: treeHex(spawnBundle?.treeHash) }; // WP-3/D-11: the tree THIS spawn applied (hex; null = no tree)
1482
1614
  }
1483
1615
 
1484
1616
  module.exports = { configure, createProviderSession, prepareProviderSession, isLiveForCwdConflict,
@@ -1219,7 +1219,7 @@ function installResponseRuntime(runtime) {
1219
1219
  console.log(` ✗ Restart failed: ${e.message}`);
1220
1220
  // Startup task was already in DB from original create — leave it for
1221
1221
  // manual restart or next CTM boot
1222
- runtime.broadcastSessionList(true);
1222
+ runtime.broadcastSessionList(true, { reason: 'resume-restart-failed' });
1223
1223
  }
1224
1224
  }, delay);
1225
1225
  return;
@@ -1245,9 +1245,8 @@ function installResponseRuntime(runtime) {
1245
1245
  agentType,
1246
1246
  }, 'response-defer');
1247
1247
  }
1248
- // Keep the CTM identity and startup recipe as a deferred placeholder. Retiring the startup
1249
- // task here would make retry impossible. Failed resume mirrors also stay provisional so they
1250
- // cannot replace the known-good seed with startup noise.
1248
+ // Keep the CTM identity and startup recipe as a deferred placeholder. Retiring the startup task here would make
1249
+ // retry impossible. Failed resume mirrors also stay provisional so they cannot replace the known-good seed with startup noise.
1251
1250
  runAfterExitDrain(() => {
1252
1251
  runtime.session._ptyExitLifecycle.stage = 'defer-finalizing';
1253
1252
  flushExitTailBuffers();
@@ -1281,7 +1280,8 @@ function installResponseRuntime(runtime) {
1281
1280
  cleanAutoApprovalBuffer(runtime.id);
1282
1281
  cleanIdleNotify(runtime.id);
1283
1282
  try { statusHooks.unregisterSession(runtime.id); } catch (error) { void error; }
1284
- runtime.broadcastSessionList(true);
1283
+ runtime._announceLiveDefer(runtime.session, runtime.id, 'crash-defer'); // WP-2 (R-3): the open tab learns of the live defer
1284
+ runtime.broadcastSessionList(true, { reason: 'session-crash-defer' });
1285
1285
  });
1286
1286
  return;
1287
1287
  }
@@ -1310,7 +1310,7 @@ function installResponseRuntime(runtime) {
1310
1310
  cleanIdleNotify(runtime.id);
1311
1311
  try { statusHooks.unregisterSession(runtime.id); } catch (e) { void e; /* non-fatal */ }
1312
1312
  if (_sessionStream && runtime.session._claudeSessionId) _sessionStream.removeSession(runtime.session._claudeSessionId);
1313
- runtime.broadcastSessionList(true);
1313
+ runtime.broadcastSessionList(true, { reason: 'session-exit' });
1314
1314
 
1315
1315
  // Fresh-cache the conversation rows immediately on exit,
1316
1316
  // so the review page serves from DB without waiting for the background scan.
@@ -1494,7 +1494,7 @@ function finalizeProviderSession(runtime, state) {
1494
1494
  Promise.resolve(startupPersistence).then(sendCreated, sendCreated);
1495
1495
  }
1496
1496
  }
1497
- broadcastSessionList(true);
1497
+ broadcastSessionList(true, { reason: 'session-create' });
1498
1498
  }
1499
1499
 
1500
1500
  module.exports = { installResponseRuntime, finalizeProviderSession, _revokeWorkerTokenOnCreatePathExit, scheduleExitedSessionRetire, RETIRE_EXITED_SESSION_DELAY_MS };
@@ -0,0 +1,27 @@
1
+ 'use strict';
2
+
3
+ // WP-2 (docs/deepseek-harness-acp-agent-2026-10-28.html §5 D-17, §9 S-11; §8 WP-2 row).
4
+ //
5
+ // The ONE pre-PTY create dispatcher: a create request that is not backed by a terminal goes to the
6
+ // strategy that owns it. Today those are the Wall-E transcript session and the DeepSeek Harness ACP
7
+ // session (lib/session-create/dsh-session.js); a strategy returns `false` to decline, and a `true`
8
+ // means "handled" (a session row was created, or the failure frame was already sent).
9
+ //
10
+ // server.js's `handleCreate` calls this at the exact line it used to call the Wall-E strategy, so the
11
+ // dispatcher costs no line budget (D-17). The Wall-E strategy keeps its own `configure` call in
12
+ // server.js and is reached here through the shared module instance, so this file only has to wire the
13
+ // strategy that has no other owner.
14
+
15
+ const transcript = require('./transcript');
16
+ const dshSession = require('./dsh-session');
17
+
18
+ function configure(getDeps) {
19
+ if (typeof getDeps !== 'function') throw new TypeError('session-create structured requires a dependency getter');
20
+ dshSession.configure(getDeps);
21
+ }
22
+
23
+ async function createStructuredSession(state) {
24
+ return (await transcript.createWalleSession(state)) || (await dshSession.createDshSession(state));
25
+ }
26
+
27
+ module.exports = { configure, createStructuredSession };
@@ -350,7 +350,9 @@ async function _runPass() {
350
350
  return;
351
351
  }
352
352
  const leads = live.map((s) => {
353
- if (!s || (s.agent !== 'claude' && s.agent !== 'codex')) return null;
353
+ // WP-14 (§9b W-4): 'dsh' joins the lead agents the delegate-pick table serves. A dsh lead's pick
354
+ // is routed-only (D-24), so its row is read and reported exactly like a claude/codex lead's.
355
+ if (!s || (s.agent !== 'claude' && s.agent !== 'codex' && s.agent !== 'dsh')) return null;
354
356
  const owner = _ownerContext(s);
355
357
  return owner ? { ...s, owner, mutationEpoch: _mutationEpochs.get(s.id) || 0 } : null;
356
358
  }).filter(Boolean);