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
@@ -0,0 +1,225 @@
1
+ 'use strict';
2
+
3
+ // Newline-delimited JSON (ND-JSON) stdio transport — the ACP primitive (D-1, D-5).
4
+ //
5
+ // One JSON object per line over a child process's stdin/stdout. It is deliberately NOT a
6
+ // PTY: a PTY echoes input back and rewrites "\n" as "\r\n", which corrupts JSON-RPC
7
+ // framing. stdout carries the protocol only; stderr is line-split into `onStderrLine` so
8
+ // the caller can keep a bounded diagnostic tail without polluting the protocol stream.
9
+ //
10
+ // Extracted from lib/codex-app-server-client.js's spawnCodexTransport (WP-1 of
11
+ // docs/deepseek-harness-acp-agent-2026-10-28.html §6.1); that function is now a thin
12
+ // wrapper over this one so both the Codex app-server client and the ACP client share
13
+ // exactly one framing implementation.
14
+ //
15
+ // Decoding uses StringDecoder('utf8') so a multi-byte character split across two chunks
16
+ // is reassembled instead of becoming U+FFFD. A partial trailing line waits for more data.
17
+
18
+ const { spawn: defaultSpawn } = require('child_process');
19
+ const { StringDecoder } = require('string_decoder');
20
+
21
+ /**
22
+ * @param {object} opts
23
+ * @param {string} opts.command
24
+ * @param {string[]} [opts.args=[]]
25
+ * @param {string} [opts.cwd]
26
+ * @param {NodeJS.ProcessEnv} [opts.env]
27
+ * @param {Function} [opts.spawnFn=require('child_process').spawn]
28
+ * @param {(line: string) => void} [opts.onStderrLine] // default: no-op; called once per complete stderr line
29
+ * @returns {{ write(json: string): boolean, onLine(cb: (line: string) => void): void,
30
+ * onExit(cb: (info: {code: number|null, signal: string|null, error?: Error}) => void): void,
31
+ * endInput(): void, kill(signal?: string): void, pid: number|undefined, _child: object }}
32
+ */
33
+ function spawnNdjsonTransport(opts = {}) {
34
+ const {
35
+ command,
36
+ args = [],
37
+ cwd,
38
+ env,
39
+ spawnFn = defaultSpawn,
40
+ onStderrLine = () => {},
41
+ } = opts;
42
+
43
+ let child = null;
44
+ let spawnFailure = null;
45
+ try {
46
+ child = spawnFn(command, args, { stdio: ['pipe', 'pipe', 'pipe'], cwd, env });
47
+ } catch (error) {
48
+ // A spawnFn that throws synchronously (rather than emitting 'error') is reported
49
+ // through the same onExit channel, asynchronously so a caller can subscribe first.
50
+ spawnFailure = error;
51
+ child = null;
52
+ }
53
+
54
+ const stdoutDecoder = new StringDecoder('utf8');
55
+ const stderrDecoder = new StringDecoder('utf8');
56
+ let stdoutBuf = '';
57
+ let stderrBuf = '';
58
+ let lineCb = null;
59
+ const queuedLines = [];
60
+ let exitInfo = null;
61
+ let exitCbs = [];
62
+ let stdinClosed = false;
63
+ let stdinErrored = false;
64
+
65
+ function emitLine(line) {
66
+ if (lineCb) lineCb(line);
67
+ else queuedLines.push(line);
68
+ }
69
+
70
+ function stripCr(line) {
71
+ return line.endsWith('\r') ? line.slice(0, -1) : line;
72
+ }
73
+
74
+ function drainStdout() {
75
+ let nl;
76
+ while ((nl = stdoutBuf.indexOf('\n')) >= 0) {
77
+ const line = stripCr(stdoutBuf.slice(0, nl));
78
+ stdoutBuf = stdoutBuf.slice(nl + 1);
79
+ if (line.trim() === '') continue;
80
+ emitLine(line);
81
+ }
82
+ }
83
+
84
+ function drainStderr() {
85
+ let nl;
86
+ while ((nl = stderrBuf.indexOf('\n')) >= 0) {
87
+ const line = stripCr(stderrBuf.slice(0, nl));
88
+ stderrBuf = stderrBuf.slice(nl + 1);
89
+ try {
90
+ onStderrLine(line);
91
+ } catch (error) {
92
+ // expected: a broken stderr observer must never stop the stderr pump.
93
+ void error;
94
+ }
95
+ }
96
+ }
97
+
98
+ function fireExit(info) {
99
+ if (exitInfo) return;
100
+ exitInfo = info;
101
+ const cbs = exitCbs;
102
+ exitCbs = [];
103
+ for (const cb of cbs) {
104
+ try {
105
+ cb(info);
106
+ } catch (error) {
107
+ // expected: one exit observer must not prevent the others from running.
108
+ void error;
109
+ }
110
+ }
111
+ }
112
+
113
+ if (child) {
114
+ if (child.stdout && typeof child.stdout.on === 'function') {
115
+ child.stdout.on('data', (chunk) => {
116
+ stdoutBuf += stdoutDecoder.write(chunk);
117
+ drainStdout();
118
+ });
119
+ child.stdout.on('end', () => {
120
+ stdoutBuf += stdoutDecoder.end();
121
+ const tail = stripCr(stdoutBuf);
122
+ stdoutBuf = '';
123
+ if (tail.trim() !== '') emitLine(tail);
124
+ });
125
+ }
126
+ if (child.stderr && typeof child.stderr.on === 'function') {
127
+ child.stderr.on('data', (chunk) => {
128
+ stderrBuf += stderrDecoder.write(chunk);
129
+ drainStderr();
130
+ });
131
+ child.stderr.on('end', () => {
132
+ stderrBuf += stderrDecoder.end();
133
+ const tail = stripCr(stderrBuf);
134
+ stderrBuf = '';
135
+ if (tail.trim() !== '') {
136
+ try {
137
+ onStderrLine(tail);
138
+ } catch (error) {
139
+ // expected: a broken stderr observer must never stop the stderr pump.
140
+ void error;
141
+ }
142
+ }
143
+ });
144
+ }
145
+ // A child that dies mid-write makes stdin emit EPIPE; without a listener that is an
146
+ // uncaught exception that takes the whole process down.
147
+ if (child.stdin && typeof child.stdin.on === 'function') {
148
+ child.stdin.on('error', () => {
149
+ stdinErrored = true;
150
+ });
151
+ }
152
+ // 'close', not 'exit': Node emits 'exit' as soon as the process is gone, while stdout
153
+ // may still hold buffered data — the final response line of the turn (e.g. the
154
+ // session/close reply) would then be delivered after the caller was already told the
155
+ // child died, and the client would reject that request with acp_child_exited even
156
+ // though its answer was in flight. 'close' fires once every stdio stream has closed and
157
+ // carries the same (code, signal). A spawn failure emits 'error' (handled below) and is
158
+ // followed by 'close'; fireExit is idempotent, so the second call is a no-op.
159
+ child.on('close', (code, signal) => {
160
+ fireExit({ code: code == null ? null : code, signal: signal == null ? null : signal });
161
+ });
162
+ child.on('error', (error) => {
163
+ fireExit({ code: null, signal: null, error });
164
+ });
165
+ } else if (spawnFailure) {
166
+ queueMicrotask(() => fireExit({ code: null, signal: null, error: spawnFailure }));
167
+ }
168
+
169
+ function write(json) {
170
+ if (!child || !child.stdin || exitInfo || stdinClosed || stdinErrored) return false;
171
+ try {
172
+ return child.stdin.write(`${json}\n`);
173
+ } catch (error) {
174
+ // expected: writing to a child that already exited raises EPIPE; report it as false.
175
+ void error;
176
+ return false;
177
+ }
178
+ }
179
+
180
+ function onLine(cb) {
181
+ lineCb = cb;
182
+ while (queuedLines.length) cb(queuedLines.shift());
183
+ }
184
+
185
+ function onExit(cb) {
186
+ if (exitInfo) {
187
+ cb(exitInfo);
188
+ return;
189
+ }
190
+ exitCbs.push(cb);
191
+ }
192
+
193
+ function endInput() {
194
+ if (!child || !child.stdin || exitInfo || stdinClosed) return;
195
+ stdinClosed = true;
196
+ try {
197
+ child.stdin.end();
198
+ } catch (error) {
199
+ // expected: ending an already-closed stdin is a no-op.
200
+ void error;
201
+ }
202
+ }
203
+
204
+ function kill(signal = 'SIGTERM') {
205
+ if (!child || exitInfo || typeof child.kill !== 'function') return;
206
+ try {
207
+ child.kill(signal);
208
+ } catch (error) {
209
+ // expected: a child that already exited cannot be signalled.
210
+ void error;
211
+ }
212
+ }
213
+
214
+ return {
215
+ write,
216
+ onLine,
217
+ onExit,
218
+ endInput,
219
+ kill,
220
+ pid: child ? child.pid : undefined,
221
+ _child: child,
222
+ };
223
+ }
224
+
225
+ module.exports = { spawnNdjsonTransport };
@@ -21,7 +21,14 @@
21
21
  // would have (`manager.hosts`, `manager._adoptedHostRedials`,
22
22
  // `manager._adoptedHostRedialAttempts`, `manager._terminatingAdoptedRedials`,
23
23
  // `manager._serverBootId`, `manager._routeAdoptedFrame`, `manager._unregister`,
24
- // `manager._removeHostRecordAsync`, `manager.logger`).
24
+ // `manager._removeHostRecordAsync`, `manager.logger`, `manager.hostRecordForId`,
25
+ // `manager.hostCompatibility`, `manager.emit`).
26
+
27
+ // WP-3a: the exit event carries `hostPidAliveAtDeclare` -- the manager's own
28
+ // observation of whether the host process was still alive when the host was
29
+ // declared dead. Borrowed from lib/host-registry.js so there is exactly one
30
+ // liveness probe in the codebase, never a re-implementation.
31
+ const { isProcessAlive } = require('./host-registry');
25
32
 
26
33
  function _sleep(ms) {
27
34
  return new Promise((resolve) => {
@@ -49,24 +56,53 @@ const ADOPT_REDIAL_STABLE_MS = 5000;
49
56
 
50
57
  // Review round 1, fix (b) + reused by the dial-failure `.catch()` below: the
51
58
  // SAME terminal path a dead host's own close would otherwise have taken.
59
+ //
60
+ // WP-3a (live-defer-wake-adopted-host-death design, R-6/R-7): "declaring the
61
+ // host dead" used to synthesize the exits immediately and never stop the host
62
+ // process. If the host was only UNREACHABLE (CTM overloaded, dial ladder
63
+ // exhausted) it is still running an agent on the same transcript while the
64
+ // session is respawned with --resume -- two writers, one transcript. Repo
65
+ // policy is "evacuate first, revive second, never keep" (see the header of
66
+ // lib/host-health-revive.js), so the host is stopped through an INJECTED
67
+ // collaborator (`manager.retireDeadHost`, wired by server.js) BEFORE any exit
68
+ // is emitted, and the evidence travels on the exit event itself. Still
69
+ // synchronous from the caller's point of view: returns true the moment the
70
+ // adapters are unregistered, with the exits emitted once the retire settles.
52
71
  function _declareHostDead(manager, hostId, attemptNumber) {
53
72
  if (manager.isRecoveryProtectedHost?.(hostId)) return false;
54
73
  manager._adoptedHostRedialAttempts.delete(hostId);
55
- manager.logger.warn?.(`[session-host-registry] adopted-host redial exhausted hostId=${hostId} after ${attemptNumber} attempts -- declaring host dead`);
74
+ // WP-3a: resolve the record BEFORE unregistering anything -- hostRecordForId()
75
+ // iterates manager.hosts, so once the loop below has unregistered the last
76
+ // adapter there is no record left to hand the retire collaborator.
77
+ const record = manager.hostRecordForId?.(hostId) || null;
78
+ const hostPidAliveAtDeclare = !!(record && isProcessAlive(record.pid));
79
+ manager.logger.warn?.(`[session-host-registry] adopted-host redial exhausted hostId=${hostId} after ${attemptNumber} attempts -- declaring host dead pidAlive=${hostPidAliveAtDeclare}`);
80
+ const victims = [];
56
81
  for (const [sessionId, adapter] of manager.hosts) {
57
82
  if (adapter._hostId !== hostId || !adapter._adopted || adapter.closed) continue;
58
83
  adapter.closed = true;
59
84
  manager._unregister(sessionId, adapter);
60
- adapter._emitExitOnce({ exitCode: 1, signal: null, hostClosed: true, reason: 'adopted-redial-exhausted' });
85
+ victims.push(adapter);
61
86
  }
62
- manager._removeHostRecordAsync(hostId);
63
- // D-8 (stale-pty-host-evacuation design): a dead host leaves no retry behind --
64
- // without its compat entry handoffStale() returns null and never re-arms a
65
- // stale retry for a process that is already gone.
66
- manager.hostCompatibility?.delete(hostId);
67
- // I6 (host-readiness design): announce the death so the primary's readiness
68
- // ledger forgets this hostId -- the ONE terminal path for an adopted host.
69
- manager.emit?.('host-exit', { hostId, kind: 'adopted' });
87
+ Promise.resolve(manager.retireDeadHost ? manager.retireDeadHost(record) : false)
88
+ .catch((err) => { // REPORT: a failed retire is logged and the exits still fire (hostRetired:false)
89
+ manager.logger.warn?.(`[session-host-registry] retire dead host ${hostId} failed: ${err?.message || err}`);
90
+ return false;
91
+ })
92
+ .then((retired) => {
93
+ for (const adapter of victims) {
94
+ adapter._emitExitOnce({ exitCode: 1, signal: null, hostClosed: true, reason: 'adopted-redial-exhausted', hostRetired: retired === true, hostPidAliveAtDeclare });
95
+ }
96
+ manager._removeHostRecordAsync(hostId);
97
+ // D-8 (stale-pty-host-evacuation design): a dead host leaves no retry behind --
98
+ // without its compat entry handoffStale() returns null and never re-arms a
99
+ // stale retry for a process that is already gone.
100
+ manager.hostCompatibility?.delete(hostId);
101
+ // I6 (host-readiness design): announce the death so the primary's readiness
102
+ // ledger forgets this hostId -- the ONE terminal path for an adopted host.
103
+ manager.emit?.('host-exit', { hostId, kind: 'adopted' });
104
+ });
105
+ return true;
70
106
  }
71
107
 
72
108
  // Single-flight re-dial for an adopted host's write connection -- called from
@@ -0,0 +1,123 @@
1
+ 'use strict';
2
+
3
+ // WP-2 of docs/launch-environment-host-carried-adoption-2026-10-26.html (§5 D-3/D-4/D-7, §6).
4
+ //
5
+ // ONE pure converter: the launch environment an adopted session keeps is DERIVED from the host-carried
6
+ // record (adapter.launchEnvironment, WP-1), never frozen from a stamp a previous CTM wrote. The record
7
+ // is the authority -- it holds the bytes the child actually received -- so the spawn receipt's
8
+ // `sourceEnvironmentReference` is cross-checked (reported as `mismatch`), never allowed to override it.
9
+ //
10
+ // An adapter with NO record was spawned by a pre-design host (or restored from a manifest one wrote):
11
+ // that is rule 1, converted on read by the stated rule below (§5 D-4). The four legacy rows are the
12
+ // whole reason 'unknown' is no longer assignable at adoption: every adopted session leaves this module
13
+ // with one of captured / captured-empty / unavailable. 'unknown' stays reserved for sessions whose
14
+ // `_launchEnvOverrides` field CTM itself never wrote (API attach, lib/coding-session-generation-runtime.js;
15
+ // named out of scope in §11) -- it is never produced here.
16
+ //
17
+ // The returned `overrides` is a NEW frozen object (the adapter's already-sanitized modelStorageRoots
18
+ // plus the record's values); the caller may hand it to a session, never mutate it.
19
+
20
+ const { LAUNCH_ENV_RULE, LAUNCH_ENV_STATES, captureLaunchEnvironment } = require('./launch-environment');
21
+
22
+ // The two values lib/model-execution-recipe-metadata.js accepts for `sourceEnvironmentReference`, i.e. the
23
+ // spawn receipt's own reading of the private environment. They are the receipt half of the cross-check.
24
+ const REFERENCE_CAPTURED = 'private-owner-required';
25
+ const REFERENCE_CAPTURED_EMPTY = 'captured-empty';
26
+
27
+ // The launch environment is private only for a LEAD harness: a worker's environment is not CTM's to
28
+ // reinterpret, and a shell/walle session is not a lead at all (§5 D-4).
29
+ const LEAD_AGENT_TYPES = Object.freeze(['claude', 'codex']);
30
+
31
+ // The sources, one per row R1..R6 of §6 -- exported data so a caller (or the gate's sentence map, WP-3)
32
+ // never re-spells them.
33
+ const ADOPTION_SOURCES = Object.freeze(['host-record', 'host-record-unavailable', 'legacy-recipe',
34
+ 'legacy-reinterpreted', 'legacy-worker', 'legacy-no-receipt']);
35
+
36
+ /** A record is trusted only as a well-formed observation in the launch-environment vocabulary with a rule
37
+ * this reader knows (1..LAUNCH_ENV_RULE); anything else (a tampered record, a rule newer than this code)
38
+ * has no record at all and the legacy rows decide. Never throws: it only reads own data properties. */
39
+ function validRecord(value) {
40
+ if (!value || typeof value !== 'object' || Array.isArray(value)) return null;
41
+ if (!Number.isInteger(value.rule) || value.rule < 1 || value.rule > LAUNCH_ENV_RULE) return null;
42
+ if (!LAUNCH_ENV_STATES.includes(value.state)) return null;
43
+ if (value.state === 'unavailable') {
44
+ if (typeof value.reason !== 'string' || !value.reason || value.values !== null) return null;
45
+ return { rule: value.rule, state: 'unavailable', values: null, reason: value.reason };
46
+ }
47
+ if (value.reason !== null) return null;
48
+ // The values are re-bounded by the rule-0 primitive: a record whose declared state no longer agrees
49
+ // with a re-capture is not a record.
50
+ const recaptured = captureLaunchEnvironment(value.values);
51
+ if (recaptured.state !== value.state) return null;
52
+ return { rule: value.rule, state: value.state, values: recaptured.values, reason: null };
53
+ }
54
+
55
+ /** The receipt half of the cross-check: under the record's rule a captured set is private-owner-required
56
+ * and an empty one is captured-empty, so a receipt that says otherwise disagrees with the bytes the child
57
+ * received. Absent/blank receipts carry no claim (an older CTM wrote none) and never disagree. */
58
+ function receiptMismatch(reference, recordState) {
59
+ if (typeof reference !== 'string' || !reference) return null;
60
+ const expected = recordState === 'captured' ? REFERENCE_CAPTURED : REFERENCE_CAPTURED_EMPTY;
61
+ if (reference === expected) return null;
62
+ return Object.freeze({ receipt: reference, record: recordState });
63
+ }
64
+
65
+ /**
66
+ * The launch environment of an adopted session, derived row by row (§6; first match wins).
67
+ *
68
+ * R1 record && state in {captured, captured-empty} -> the record's values over the host storage roots
69
+ * R2 record && state === 'unavailable' -> roots only, the record's own reason
70
+ * R3 !record && receipt === 'captured-empty' -> captured-empty (rule 1: the receipt proves it)
71
+ * R4 !record && receipt === 'private-owner-required' && a lead harness (not a worker)
72
+ * -> captured-empty: under rule 1 the only lead-reachable
73
+ * private keys were the projected HOME/CODEX_HOME/TMPDIR
74
+ * R5 !record && receipt === 'private-owner-required' -> unavailable/'legacy_worker_private_env'
75
+ * R6 otherwise -> unavailable/'legacy_no_receipt'
76
+ *
77
+ * @param {object} input
78
+ * @param {Readonly<Record>|undefined|null} input.launchEnvironment the host record, or undefined (legacy)
79
+ * @param {object|undefined|null} input.modelStorageRoots the adapter's sanitized storage roots
80
+ * @param {object|null|undefined} input.recipe the adopted (validated) execution recipe, or null
81
+ * @param {string|null|undefined} input.agentRole `session.agentRole` after _stampWorkerMarkers; 'worker'
82
+ * is a worker
83
+ * @param {string|null|undefined} input.agentType 'claude' | 'codex' | 'shell' | 'walle'
84
+ * @returns {{overrides: Readonly<object>, state: 'captured'|'captured-empty'|'unavailable', reason:
85
+ * string|null, source: string, fromRule: 1|2, mismatch: Readonly<{receipt: string, record:
86
+ * string}>|null}} — frozen; `state` is never 'unknown'
87
+ */
88
+ function deriveAdoptedLaunchEnvironment({ launchEnvironment, modelStorageRoots, recipe, agentRole, agentType } = {}) {
89
+ const roots = modelStorageRoots && typeof modelStorageRoots === 'object' && !Array.isArray(modelStorageRoots)
90
+ ? modelStorageRoots : {};
91
+ const overridesOf = (values) => Object.freeze({ ...roots, ...(values || {}) });
92
+ const record = validRecord(launchEnvironment);
93
+ const reference = recipe && typeof recipe === 'object' ? recipe.sourceEnvironmentReference : null;
94
+ // R1: the record holds the bytes the child received; the receipt is only cross-checked against it.
95
+ if (record && record.state !== 'unavailable') {
96
+ return Object.freeze({ overrides: overridesOf(record.values), state: record.state, reason: null,
97
+ source: 'host-record', fromRule: record.rule, mismatch: receiptMismatch(reference, record.state) });
98
+ }
99
+ // R2: the host itself could not capture this session's environment; its reason is carried verbatim.
100
+ if (record) {
101
+ return Object.freeze({ overrides: overridesOf(null), state: 'unavailable', reason: record.reason,
102
+ source: 'host-record-unavailable', fromRule: record.rule, mismatch: null });
103
+ }
104
+ // R3..R6: no record -- rule 1, reinterpreted by what the receipt says the source environment was.
105
+ if (reference === REFERENCE_CAPTURED_EMPTY) {
106
+ return Object.freeze({ overrides: overridesOf(null), state: 'captured-empty', reason: null,
107
+ source: 'legacy-recipe', fromRule: 1, mismatch: null });
108
+ }
109
+ if (reference === REFERENCE_CAPTURED && agentRole !== 'worker' && LEAD_AGENT_TYPES.includes(agentType)) {
110
+ return Object.freeze({ overrides: overridesOf(null), state: 'captured-empty', reason: null,
111
+ source: 'legacy-reinterpreted', fromRule: 1, mismatch: null });
112
+ }
113
+ if (reference === REFERENCE_CAPTURED) {
114
+ return Object.freeze({ overrides: overridesOf(null), state: 'unavailable',
115
+ reason: 'legacy_worker_private_env', source: 'legacy-worker', fromRule: 1, mismatch: null });
116
+ }
117
+ return Object.freeze({ overrides: overridesOf(null), state: 'unavailable', reason: 'legacy_no_receipt',
118
+ source: 'legacy-no-receipt', fromRule: 1, mismatch: null });
119
+ }
120
+
121
+ // LAUNCH_ENV_RULE is re-exported because the adoption block (server.js) stamps it on the launch-env-adopted
122
+ // diagnostic; it is imported above from the launch-environment primitive, never re-defined here.
123
+ module.exports = { deriveAdoptedLaunchEnvironment, ADOPTION_SOURCES, LAUNCH_ENV_RULE };
@@ -6,7 +6,6 @@
6
6
 
7
7
  const path = require('path');
8
8
  const autoUpdate = require('./agent-auto-update');
9
- const { codexQualification } = require('./codex-harness-qualification');
10
9
  const { DEFAULT_AGENT_IDS } = require('./agent-definitions');
11
10
  const { refreshOutdatedHooks } = require('./agent-hooks-boot-prune');
12
11
  const hooksInstaller = require('./agent-hooks-installer');
@@ -44,8 +43,6 @@ function createAgentAutoUpdateRuntime({
44
43
  startJob: (agent) => agentVersionService.startUpgradeJob(agent, { ...versionOptions(), trigger: 'auto' }),
45
44
  hasRunningJob: (agent) => agentVersionService.listUpgradeJobs().jobs.some((j) => j.agent === agent && j.status === 'running'),
46
45
  liveSessionAgents: () => autoUpdate.liveAgentIds(sessions, isLive),
47
- // WP-2 (D-6): only Codex is gated by the qualified-version table; every other agent is untouched.
48
- qualificationFor: (agent, v) => (agent === 'codex' ? codexQualification(v) : null),
49
46
  isEnabled,
50
47
  readAttempts: async () => (await stateFile.read()).attempts,
51
48
  writeAttempts: (attempts) => stateFile.update((state) => ({ ...state, attempts })),
@@ -16,10 +16,6 @@ const LIVE_SENSITIVE_MODES = new Set(['npm-global', 'homebrew', 'homebrew-cask']
16
16
  function createAutoUpdater({
17
17
  getStatus, startJob, hasRunningJob, liveSessionAgents, isEnabled,
18
18
  readAttempts, writeAttempts, report, log,
19
- // WP-2 (D-6): the caller's qualified-version table reader, `(agent, version) => ({ state } | null)`.
20
- // Optional: a caller that passes nothing keeps the pre-WP-2 chain exactly (no automatic version is
21
- // ever deferred for qualification).
22
- qualificationFor = null,
23
19
  setTimeoutImpl = setTimeout, clearTimeoutImpl = clearTimeout,
24
20
  now = Date.now,
25
21
  }) {
@@ -46,9 +42,6 @@ function createAutoUpdater({
46
42
  const attempts = (await readAttempts()) || {};
47
43
  const prior = attempts[agent];
48
44
  if (prior && prior.version === row.latestVersion) action = 'already_attempted';
49
- // WP-2 (D-6): never start an automatic upgrade to a version outside the qualified table.
50
- // The attempts file is untouched (no attempt was made) and a user click still upgrades (P-4).
51
- else if (qualificationFor && qualificationFor(agent, row.latestVersion)?.state === 'unqualified') action = 'deferred_unqualified';
52
45
  else if (LIVE_SENSITIVE_MODES.has(row.upgradeMode) && liveSessionAgents().has(agent)) action = 'deferred_live_sessions';
53
46
  else if (hasRunningJob(agent)) action = 'job_running';
54
47
  else {
@@ -126,18 +119,38 @@ function createStateFile(filePath) {
126
119
  return { read, write, update };
127
120
  }
128
121
 
122
+ /** The agent definition a session record belongs to, or null. Shared by liveAgentIds/liveSessionsFor. */
123
+ function _sessionAgentDefinition(session) {
124
+ const bin = path.basename(String(session.cmd || '').trim().split(/\s+/)[0] || '');
125
+ return definitionForCli(bin) || definitionForCli(session.type) || null;
126
+ }
127
+
129
128
  /** Agent ids (keys of AGENT_DEFINITIONS) that have a live session, from an iterable of session records. */
130
129
  function liveAgentIds(sessionMap, isLive) {
131
130
  const out = new Set();
132
131
  for (const session of sessionMap.values()) {
133
132
  if (!session || !isLive(session)) continue;
134
- const bin = path.basename(String(session.cmd || '').trim().split(/\s+/)[0] || '');
135
- const def = definitionForCli(bin) || definitionForCli(session.type);
133
+ const def = _sessionAgentDefinition(session);
136
134
  if (def) out.add(def.id);
137
135
  }
138
136
  return out;
139
137
  }
140
138
 
139
+ /**
140
+ * WP-4 (D-9): the live sessions of ONE agent, as `[{ id, title, agent }]`, derived exactly like
141
+ * liveAgentIds above. The user-click upgrade path names them before it replaces a running install.
142
+ */
143
+ function liveSessionsFor(sessionMap, isLive, agentId) {
144
+ const out = [];
145
+ for (const [id, session] of sessionMap.entries()) {
146
+ if (!session || !isLive(session)) continue;
147
+ const def = _sessionAgentDefinition(session);
148
+ if (!def || def.id !== agentId) continue;
149
+ out.push({ id: String(session.id || id), title: session.title || session.label || '', agent: def.id });
150
+ }
151
+ return out;
152
+ }
153
+
141
154
  /** Record how an automatic job ended in the attempts file (no-op when no attempt matches). */
142
155
  async function recordJobOutcome(file, job) {
143
156
  if (!job || job.trigger !== 'auto') return;
@@ -150,5 +163,8 @@ async function recordJobOutcome(file, job) {
150
163
 
151
164
  module.exports = {
152
165
  TICK_MS, FIRST_TICK_MS,
153
- createAutoUpdater, createStateFile, liveAgentIds, recordJobOutcome,
166
+ // WP-4 (S-13): exported so the user-click upgrade path (lib/agent-version-service.js) shares the
167
+ // tick's predicate instead of re-deriving it. Behaviour is unchanged; createAutoUpdater reads it.
168
+ LIVE_SENSITIVE_MODES,
169
+ createAutoUpdater, createStateFile, liveAgentIds, liveSessionsFor, recordJobOutcome,
154
170
  };