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
@@ -172,7 +172,9 @@ function machineChipPresentation(row) {
172
172
  const title = unreachable
173
173
  ? `Runs on ${name} — unreachable (showing its last known state)`
174
174
  : `Runs on ${name}`;
175
- return { name, health: facts.health, unreachable, title, label: (unreachable ? '⚠ ' : '◈ ') + name };
175
+ // `machine` is the member's instance id — the same id the trust file and the pending/grant rows
176
+ // key on, so a click on the chip can name the exact card on the Machines page (AC-4a).
177
+ return { machine: facts.machine, name, health: facts.health, unreachable, title, label: (unreachable ? '⚠ ' : '◈ ') + name };
176
178
  }
177
179
 
178
180
  // HTML twin, for the row templates that build markup as strings.
@@ -183,6 +185,7 @@ function machineChipHtml(row) {
183
185
  const id = _machineRowId(row);
184
186
  return `<span class="${classes}" title="${escHtml(view.title)}" aria-label="${escHtml(view.title)}"`
185
187
  + (id ? ` data-session-id="${escHtml(id)}"` : '')
188
+ + ` data-machine-id="${escHtml(view.machine)}"`
186
189
  + ` data-machine-name="${escHtml(view.name)}" data-machine-health="${escHtml(view.health)}">${escHtml(view.label)}</span>`;
187
190
  }
188
191
 
@@ -195,6 +198,7 @@ function machineSessionChipNode(row, sessionId) {
195
198
  chip.textContent = view.label;
196
199
  chip.title = view.title;
197
200
  chip.setAttribute('aria-label', view.title);
201
+ chip.dataset.machineId = view.machine;
198
202
  chip.dataset.machineName = view.name;
199
203
  chip.dataset.machineHealth = view.health;
200
204
  const id = String(sessionId || _machineRowId(row) || '');
@@ -604,13 +608,23 @@ function createSession() {
604
608
  var wantCreateCwd = (!!_nsPathPickerState.createCwd && _nsPathPickerState.createCwd === _normCwd) || _typedMissing;
605
609
 
606
610
  function _doCreate(finalCwd) {
611
+ // WP-1 (D-1): the client mints the create id, so the box's late `created` (or its row in a later
612
+ // sessions list) can be matched back to THIS click even when the hub answers with an error first.
613
+ // The id comes from PendingCreate.newId(), never from `crypto` directly: crypto.randomUUID is
614
+ // secure-context only (a hub over plain http on a LAN address has no such function), and a page
615
+ // that loads this file without pending-create.js simply sends today's id-less frame.
616
+ var _pc = (typeof PendingCreate === 'object' && PendingCreate) || null;
607
617
  var msg = { type: 'create', cwd: finalCwd, label: label || undefined, mcp_profile: mcpProfile };
618
+ if (_pc) msg.id = _pc.newId();
608
619
  if (machine) msg.machine = machine;
609
620
  if (wantCreateCwd && !useWorktree && finalCwd) msg.createCwd = true;
610
621
  // Spawn the PTY at the terminal's real size so the agent's first paint
611
622
  // matches the final height (no 120x30→fit reflow that strands Codex's cursor).
612
- var dims = _estimateNewSessionTermDims();
613
- if (dims) { msg.cols = dims.cols; msg.rows = dims.rows; }
623
+ // WP-7 (S-53): a conv-only agent has no PTY, so it sends no cols/rows at all.
624
+ if (agentType !== 'dsh') {
625
+ var dims = _estimateNewSessionTermDims();
626
+ if (dims) { msg.cols = dims.cols; msg.rows = dims.rows; }
627
+ }
614
628
 
615
629
  if (agentType === 'claude') {
616
630
  msg.cmd = 'claude';
@@ -630,10 +644,31 @@ function createSession() {
630
644
  } else if (agentType === 'cursor') {
631
645
  msg.cmd = 'cursor-agent';
632
646
  msg.args = [];
647
+ } else if (agentType === 'dsh') {
648
+ // WP-7 (S-53, D-11): conv-only ACP agent. `dsh` is the command word the server detects
649
+ // (lib/agent-capabilities.js detectAgentType). OQ-4: the card's Model select contributes the
650
+ // route — absent/'' means "Auto (DeepSeek on Portkey)" and no routeAlias is sent at all.
651
+ msg.cmd = 'dsh';
652
+ msg.agentType = 'dsh';
653
+ msg.args = [];
654
+ var dshPick = (window.NewSessionAgentGrid && typeof window.NewSessionAgentGrid.dshRoutePick === 'function')
655
+ ? window.NewSessionAgentGrid.dshRoutePick() : null;
656
+ if (dshPick && dshPick.routeAlias) {
657
+ msg.routeAlias = dshPick.routeAlias;
658
+ if (dshPick.model) msg.model = dshPick.model;
659
+ }
633
660
  } else if (agentType === 'shell') {
634
661
  // default shell
635
662
  }
636
663
 
664
+ // WP-1 (D-7, §6.4): register the pending create BEFORE the frame leaves, so a `create-accepted`,
665
+ // a `created`, an `error` or a sessions list that lands before this line still finds the entry.
666
+ if (_pc) {
667
+ _pc.begin({
668
+ id: msg.id, machine: machine || '', machineName: machineSelectionName(),
669
+ label: label, activeTabAtClick: state.activeTab,
670
+ });
671
+ }
637
672
  send(msg);
638
673
  closeModal('new-session-modal');
639
674
  }
@@ -665,7 +700,9 @@ function createSession() {
665
700
  })
666
701
  .then(function(d) {
667
702
  if (d.error) {
668
- toast(d.error, { type: 'error', title: 'Worktree creation failed' });
703
+ // D-5: a box mid-update says so instead of leaving the user with a bare failure.
704
+ var updatingText = typeof machineUpdatingToastText === 'function' ? machineUpdatingToastText(d.box_updating) : '';
705
+ toast(updatingText || d.error, { type: 'error', title: 'Worktree creation failed' });
669
706
  if (createBtn) { createBtn.disabled = false; createBtn.textContent = 'Create'; }
670
707
  return;
671
708
  }
@@ -678,7 +715,9 @@ function createSession() {
678
715
  _doCreate(d.path || cwd);
679
716
  })
680
717
  .catch(function(e) {
681
- toast('Worktree error: ' + e.message, { type: 'error' });
718
+ // D-5: `_wtCreateWithProgress` carries the hub's `box_updating` on the thrown error.
719
+ var updatingText = typeof machineUpdatingToastText === 'function' ? machineUpdatingToastText(e && e.box_updating) : '';
720
+ toast(updatingText || ('Worktree error: ' + e.message), { type: 'error' });
682
721
  if (createBtn) { createBtn.disabled = false; createBtn.textContent = 'Create'; }
683
722
  });
684
723
  } else {
@@ -758,6 +797,7 @@ function closeSpecialTab(tabId) {
758
797
  if (tabId === 'review') {
759
798
  if (typeof _cancelReviewCatchUp === 'function') _cancelReviewCatchUp();
760
799
  state.reviewingSessionId = null;
800
+ state.reviewMachine = '';
761
801
  savePref('reviewing_session', null);
762
802
  document.querySelectorAll('.recent-item.reviewing').forEach(el => el.classList.remove('reviewing'));
763
803
  // Phase 3: stop receiving live updates for the no-longer-reviewed session.
@@ -815,7 +855,13 @@ async function resumeSession(sessionId, cwd, label) {
815
855
  alert('This provider does not support session resume yet.');
816
856
  return;
817
857
  }
818
- const resumeCwd = await _resolveResumeCwdBeforeCreate(cwd, agentType, label, resumeId);
858
+ // WP-2 (§5 D-7): a stamped Recent row is resumed ON its box. The cwd pre-check must ask the same
859
+ // box (the hub-local worktree check would consult the wrong filesystem), and the create carries
860
+ // `machine` so the server forwards it. An unstamped row keeps today's message byte for byte.
861
+ const machine = String(recent?.machine || '').trim();
862
+ const resumeCwd = machine
863
+ ? await _resolveMachineResumeCwdBeforeCreate(cwd, machine, label)
864
+ : await _resolveResumeCwdBeforeCreate(cwd, agentType, label, resumeId);
819
865
  if (resumeCwd === null) return;
820
866
  send({
821
867
  type: 'create',
@@ -824,9 +870,32 @@ async function resumeSession(sessionId, cwd, label) {
824
870
  args: resumeSpec.args,
825
871
  cwd: resumeCwd || undefined,
826
872
  label: label.replace(/^Resume:\s*/i, '').slice(0, 60),
873
+ ...(machine ? { machine } : {}),
827
874
  });
828
875
  }
829
876
 
877
+ // WP-2 (§5 D-7, §4 `POST /api/path-status` — already proxied with ?machine=). The machine twin of
878
+ // _resolveResumeCwdBeforeCreate: it asks the BOX whether the resume cwd still exists there. A probe
879
+ // that cannot answer never blocks the resume — the create itself reports the real error.
880
+ async function _resolveMachineResumeCwdBeforeCreate(cwd, machine, label) {
881
+ if (!cwd) return cwd;
882
+ try {
883
+ const r = await fetch('/api/path-status?machine=' + encodeURIComponent(machine), {
884
+ method: 'POST',
885
+ headers: { 'Content-Type': 'application/json' },
886
+ body: JSON.stringify({ paths: [cwd] }),
887
+ });
888
+ if (!r.ok) return cwd;
889
+ let d = null;
890
+ try { d = await r.json(); } catch { /* expected: a probe body that is not JSON leaves the verdict unknown */ }
891
+ const row = Array.isArray(d?.paths) ? d.paths.find(p => p && p.path === cwd) : null;
892
+ if (row && row.directory === false) {
893
+ toast('"' + (label || 'This session').replace(/^Resume:\s*/i, '') + '" was created in a folder that no longer exists on that computer.', { type: 'warning', duration: 7000, key: 'resume-machine-cwd-missing' });
894
+ }
895
+ } catch { /* expected: a probe failure must never block the resume the user asked for */ }
896
+ return cwd;
897
+ }
898
+
830
899
  function resumeWalleSession(sessionId, cwd, label, chatSessionId) {
831
900
  if (state.sessions.has(sessionId)) {
832
901
  activateTab(sessionId);
@@ -888,6 +957,10 @@ async function reviewSession(sessionId, projectEntry, title, sessionData, opts)
888
957
  // Track which review is in flight so stale fetches are discarded
889
958
  const reviewRequestId = (state._reviewRequestCounter = (state._reviewRequestCounter || 0) + 1);
890
959
  state.reviewingSessionId = sessionId;
960
+ // WP-1 (§5 D-6, docs/recent-sessions-follow-computer-filter-2026-10-31.html): a stamped Recent row's
961
+ // transcript lives on that box, so every review page request carries its machine (resolved by
962
+ // _reviewMessagesUrl). '' for a hub/Local row, which keeps its URL byte-identical.
963
+ state.reviewMachine = String(sessionData?.machine || '').trim();
891
964
  _cancelReviewCatchUp();
892
965
 
893
966
  // Persist for restore after CTM restart
@@ -1052,8 +1125,11 @@ function closeSessionPalette() {
1052
1125
  // `renderedAt` is the clock the last card render judged D-12 staleness against, so a re-render
1053
1126
  // (a popover pick) cannot move the numbers under the user; `pickerMachine` is the D-1 row picked
1054
1127
  // from the popover, kept for THIS modal session only.
1128
+ // `localKeysState` is the D-6 three-state read of THIS Mac's project list: 'idle' (never asked),
1129
+ // 'loading', 'ok' (the map is the truth) and 'failed'. A failure is never a latch — the next modal
1130
+ // open retries — and it is never reported as "no checkout" (see nsMachineAfterProjectsLoaded).
1055
1131
  const _nsMachineState = {
1056
- machines: [], localRepoKeyPath: null, localKeysRequested: false, localCwd: '',
1132
+ machines: [], localRepoKeyPath: null, localKeysState: 'idle', localCwd: '',
1057
1133
  renderedAt: 0, pickerMachine: '',
1058
1134
  };
1059
1135
 
@@ -1457,6 +1533,8 @@ function _selectMachineCard(value) {
1457
1533
  });
1458
1534
  }
1459
1535
  _nsMachineSetHint(next ? 'Sessions will spawn on ' + machineSelectionName() + ' — pick a folder on that box.' : '');
1536
+ // WP-13b (D-15): the agent grid's dsh card depends on the picked machine's own agent presence.
1537
+ if (window.NewSessionAgentGrid && typeof window.NewSessionAgentGrid.refresh === 'function') window.NewSessionAgentGrid.refresh();
1460
1538
  // S-13: host-path truth belongs to exactly one machine. Re-run the picker reset on every
1461
1539
  // change — it rebinds the host probe (which now carries ?machine=) and forgets the previous
1462
1540
  // machine's project list — so a box answer can never land on a local path field.
@@ -1468,6 +1546,7 @@ function _selectMachineCard(value) {
1468
1546
  if (typeof _nsPathPickerState !== 'undefined') {
1469
1547
  _nsPathPickerState.machine = next;
1470
1548
  _nsPathPickerState.projectsLoaded = false;
1549
+ _nsPathPickerState.projectsError = false;
1471
1550
  _nsPathPickerState.projects = [];
1472
1551
  }
1473
1552
  _nsPathReset(next ? '' : (typeof getLastSessionCwd === 'function' ? getLastSessionCwd() : ''));
@@ -1508,33 +1587,67 @@ function localProjectKeyFor(cwd, keyPath) {
1508
1587
 
1509
1588
  // Local gitRemoteKey -> path, so the same-repo prefill is a plain key equality against the
1510
1589
  // box's own /api/projects rows. Normalization stays server-side (§6.5).
1590
+ //
1591
+ // D-6: the read is THREE-state, not a latch. Only 'loading'/'ok' short-circuit — 'idle' and
1592
+ // 'failed' both retry, so one timed-out /api/projects (the 10-30 hub read) cannot leave the map
1593
+ // null for the page's lifetime and make the picker claim a checkout is missing.
1511
1594
  function loadLocalRepoKeys() {
1512
- if (_nsMachineState.localKeysRequested) return;
1513
- _nsMachineState.localKeysRequested = true;
1595
+ const keysState = _nsMachineState.localKeysState;
1596
+ if (keysState === 'loading' || keysState === 'ok') return;
1597
+ _nsMachineState.localKeysState = 'loading';
1514
1598
  const token = (typeof state !== 'undefined' && state.token) || '';
1515
1599
  fetch('/api/projects?token=' + encodeURIComponent(token))
1516
1600
  .then(function(r) { return r.ok ? r.json() : null; })
1517
1601
  .then(function(rows) {
1602
+ if (!Array.isArray(rows)) {
1603
+ // A non-OK answer is a failed read, never an empty project list.
1604
+ _nsMachineState.localKeysState = 'failed';
1605
+ return;
1606
+ }
1518
1607
  const map = Object.create(null);
1519
- (Array.isArray(rows) ? rows : []).forEach(function(row) {
1608
+ rows.forEach(function(row) {
1520
1609
  if (row && row.path && row.gitRemoteKey) map[String(row.gitRemoteKey)] = row.path;
1521
1610
  });
1522
1611
  _nsMachineState.localRepoKeyPath = map;
1612
+ _nsMachineState.localKeysState = 'ok';
1613
+ })
1614
+ .catch(function() {
1615
+ // expected: without the local key list the picker browses — and the next open retries.
1616
+ _nsMachineState.localKeysState = 'failed';
1523
1617
  })
1524
- .catch(function() { /* expected: without the local key list the picker simply browses */ });
1618
+ .then(_nsMachineRecheckAfterLocalKeys);
1619
+ }
1620
+
1621
+ // The box's rows may have arrived while this Mac's list was still loading; judge them now.
1622
+ function _nsMachineRecheckAfterLocalKeys() {
1623
+ if (!machineSelection() || typeof _nsPathPickerState === 'undefined') return;
1624
+ if (_nsPathPickerState.projectsLoaded || _nsPathPickerState.projectsError) nsMachineAfterProjectsLoaded(_nsPathPickerState);
1525
1625
  }
1526
1626
 
1527
- // Called by _nsPathLoadProjects once the SELECTED machine's projects answer arrives.
1627
+ // D-6: the three-state hint. `ok` + no equal key is today's "No checkout…" copy; `ok` + a match is
1628
+ // today's prefill. Anything else (this Mac's list unread, or the box's own read failed) is UNKNOWN,
1629
+ // never "no checkout" — the box may well carry the checkout and the user must still be able to pick.
1528
1630
  function nsMachineAfterProjectsLoaded(pickerState) {
1529
1631
  const machine = machineSelection();
1530
1632
  if (!machine) return false;
1633
+ const input = document.getElementById('ns-cwd');
1634
+ if (!input) return false;
1635
+ // Still reading this Mac's list: say nothing final yet — the read's completion re-runs this check.
1636
+ // (A failed BOX read is already final, whatever this Mac's read is doing.)
1637
+ if (!(pickerState && pickerState.projectsError)
1638
+ && (_nsMachineState.localKeysState === 'loading' || _nsMachineState.localKeysState === 'idle')) {
1639
+ _nsMachineSetHint('Checking project lists…');
1640
+ return false;
1641
+ }
1642
+ if (_nsMachineState.localKeysState !== 'ok' || !!(pickerState && pickerState.projectsError)) {
1643
+ _nsMachineSetHint("Couldn't read the project lists right now — pick the folder on " + machineSelectionName() + '.', true);
1644
+ return false;
1645
+ }
1531
1646
  const rows = (pickerState && Array.isArray(pickerState.projects)) ? pickerState.projects : [];
1532
1647
  const localKey = localProjectKeyFor(_nsMachineState.localCwd, _nsMachineState.localRepoKeyPath);
1533
1648
  const match = localKey ? rows.find(function(row) {
1534
1649
  return row && row.path && String(row.gitRemoteKey || '') === localKey;
1535
1650
  }) : null;
1536
- const input = document.getElementById('ns-cwd');
1537
- if (!input) return false;
1538
1651
  if (!match) {
1539
1652
  _nsMachineSetHint('No checkout on ' + machineSelectionName() + " carries this project's git remote — browse to a folder on that box.", true);
1540
1653
  return false;
@@ -1550,6 +1663,15 @@ function nsMachineAfterProjectsLoaded(pickerState) {
1550
1663
  return true;
1551
1664
  }
1552
1665
 
1666
+ // WP-4 (D-5/§6.5 client half): a 502 whose body carries `box_updating` is not a broken box — it is
1667
+ // the box restarting onto `to`. Naming the sha (its first 12 chars) turns "worktree error" into an
1668
+ // instruction. '' when the body carries no update, so the caller keeps its own copy.
1669
+ function machineUpdatingToastText(boxUpdating) {
1670
+ const to = String((boxUpdating && boxUpdating.to) || '');
1671
+ if (!to) return '';
1672
+ return machineSelectionName() + ' is restarting to apply update ' + to.slice(0, 12) + ' — try again in a minute.';
1673
+ }
1674
+
1553
1675
  // Opened with the modal, so the machine list is fresh every time. A hub-less (older) server
1554
1676
  // answers 404 and the modal stays exactly as it was (AC-5a).
1555
1677
  function loadNewSessionMachines() {
@@ -1598,3 +1720,47 @@ function resumeBlockedOpenOnMachineAction(msg, actions, s) {
1598
1720
  actions.appendChild(btn);
1599
1721
  return true;
1600
1722
  }
1723
+
1724
+ // ── WP-4 (docs/remote-session-hub-bridge-2026-10-30.html R-13, §8 AC-4a) ────────────────────────────
1725
+ // The machine chip is a CONTROL, not decoration: clicking a `.machine-chip` (the sidebar row or the
1726
+ // tab chrome) opens the Machines page with that machine's card scrolled into view and briefly
1727
+ // highlighted. The handler is registered in the CAPTURE phase and stops propagation, so the row it
1728
+ // sits in never also activates its session (the row's own click would switch tabs).
1729
+ function machineChipMachineId(chip) {
1730
+ if (!chip) return '';
1731
+ const dataset = chip.dataset || {};
1732
+ return String(dataset.machineId || dataset.machineName || '').trim();
1733
+ }
1734
+
1735
+ /** Open the Machines page at one machine. navTo routes through showMachinesPanel's reveal hook. */
1736
+ function machineChipOpen(machineId, machineName) {
1737
+ const id = String(machineId || '');
1738
+ const name = String(machineName || '');
1739
+ if (typeof navTo === 'function') {
1740
+ navTo('machines', { revealMachine: id, revealMachineName: name });
1741
+ return true;
1742
+ }
1743
+ // No navTo (a unit slice): the reveal itself is machines-page.js's single implementation.
1744
+ return typeof machinesPageRevealCard === 'function' ? machinesPageRevealCard(id, name) : false;
1745
+ }
1746
+
1747
+ /** Capture-phase delegated click: the chip wins, the row's own activation never runs. */
1748
+ function machineChipClick(event) {
1749
+ if (!event) return false;
1750
+ const target = event.target;
1751
+ const chip = target && typeof target.closest === 'function' ? target.closest('.machine-chip') : null;
1752
+ if (!chip) return false;
1753
+ if (typeof event.stopPropagation === 'function') event.stopPropagation();
1754
+ if (typeof event.preventDefault === 'function') event.preventDefault();
1755
+ const dataset = chip.dataset || {};
1756
+ return machineChipOpen(machineChipMachineId(chip), String(dataset.machineName || ''));
1757
+ }
1758
+
1759
+ function bindMachineChipClickThrough(doc) {
1760
+ const target = doc || (typeof document !== 'undefined' ? document : null);
1761
+ if (!target || typeof target.addEventListener !== 'function') return false;
1762
+ target.addEventListener('click', machineChipClick, true);
1763
+ return true;
1764
+ }
1765
+
1766
+ bindMachineChipClickThrough();
@@ -1381,6 +1381,9 @@
1381
1381
  "isActiveProjectCollapsed",
1382
1382
  "persistActiveProjectCollapsedKeys",
1383
1383
  "toggleActiveProjectGroup",
1384
+ "setActiveComputerFilter",
1385
+ "syncActiveComputerFilterChips",
1386
+ "syncActiveComputerMenu",
1384
1387
  "activeListSessionCount",
1385
1388
  "activeListCanCollapse",
1386
1389
  "activeListMinVisibleLimit",
@@ -1392,6 +1395,11 @@
1392
1395
  "updateActiveListExpansionFromDividerDrag",
1393
1396
  "updateActiveListDividerAffordance",
1394
1397
  "tabOrderSortCmp",
1398
+ "landingEtaText",
1399
+ "landingQueueText",
1400
+ "landingChipText",
1401
+ "landingBadgeParts",
1402
+ "landingBadgeHtml",
1395
1403
  "worktreeAttentionBadge",
1396
1404
  "branchDisplayParts",
1397
1405
  "branchDisplayTitle",
@@ -610,7 +610,15 @@ function _terminalGestureWasSelection(term) {
610
610
  const sel = (typeof window !== 'undefined' && typeof window.getSelection === 'function')
611
611
  ? window.getSelection()
612
612
  : null;
613
- return !!(sel && typeof sel.toString === 'function' && sel.toString().length > 0);
613
+ if (!(sel && typeof sel.toString === 'function' && sel.toString().length > 0)) return false;
614
+ // Inside the terminal, xterm's own selection (checked above) is the truth. A native DOM selection
615
+ // can remain over the terminal's row spans independently of term.clearSelection(). Such a
616
+ // mirror must not block activation when xterm has no selection (the Linux link-click incident,
617
+ // design nightly-linux-host-portability-2026-10-27). A range that reaches outside the terminal
618
+ // is still a real page selection.
619
+ const host = term && term.element;
620
+ const inside = (node) => !!(node && host && typeof host.contains === 'function' && host.contains(node));
621
+ return !(inside(sel.anchorNode) && inside(sel.focusNode));
614
622
  }
615
623
 
616
624
  // xterm's documented hover contract: the element must live inside Terminal.element and
@@ -36,10 +36,15 @@
36
36
  return { kind: 'error', message };
37
37
  }
38
38
 
39
+ // D-4: a lone modifier press is not "typing elsewhere" — it must not dismiss the panel.
40
+ const LONE_MODIFIER_KEYS = new Set(['Shift', 'Control', 'Alt', 'Meta', 'CapsLock']);
41
+
39
42
  function create(opts) {
40
43
  const options = opts || {};
41
44
  const counts = Object.create(null);
42
45
  let last = null;
46
+ // D-7: at most one panel is open; opening a new one dismisses the open one first.
47
+ let activeDismiss = null;
43
48
 
44
49
  function loadedAssetEpoch() {
45
50
  const script = Array.from(document.scripts).find((item) => /\/file-resolution-client\.js(?:\?|$)/.test(item.src || ''));
@@ -69,8 +74,14 @@
69
74
 
70
75
  function dialogFor(outcome) {
71
76
  return new Promise((resolve) => {
77
+ // D-7: one panel at a time. Dismiss the open one (exactly a Close) before building.
78
+ if (activeDismiss) activeDismiss();
72
79
  const dialog = document.createElement('dialog');
73
80
  dialog.className = 'ctm-file-menu ctm-file-resolution-dialog';
81
+ // D-9: a non-modal dialog sits at its static position, and the phone shell does not load
82
+ // reviews.css, so the top-left placement the user already sees is set inline.
83
+ dialog.style.cssText = 'position:fixed;top:12px;left:12px;right:auto;bottom:auto;margin:0;'
84
+ + 'z-index:100050;max-width:min(420px, calc(100vw - 24px))';
74
85
  const heading = document.createElement('strong');
75
86
  heading.textContent = outcome.kind === 'ambiguous' ? 'Choose the file'
76
87
  : outcome.kind === 'incomplete' ? 'File search incomplete' : 'Link details';
@@ -79,11 +90,37 @@
79
90
  message.textContent = outcome.message || 'File resolution failed';
80
91
  dialog.appendChild(message);
81
92
 
93
+ let done = false;
94
+ // D-8: finish runs once; it removes both document listeners, clears activeDismiss if it
95
+ // is its own, closes and removes the dialog, then resolves.
82
96
  const finish = (value) => {
97
+ if (done) return;
98
+ done = true;
99
+ document.removeEventListener('pointerdown', onPointerDown, true);
100
+ document.removeEventListener('keydown', onKeyDown, true);
101
+ if (activeDismiss === dismiss) activeDismiss = null;
83
102
  if (dialog.open && typeof dialog.close === 'function') dialog.close();
84
103
  dialog.remove();
85
104
  resolve(value);
86
105
  };
106
+ const dismiss = () => finish(null);
107
+ // D-3: a press outside is a Close and is never swallowed — the press still reaches target.
108
+ function onPointerDown(event) {
109
+ if (!dialog.contains(event.target)) finish(null);
110
+ }
111
+ // D-4/D-5: Escape closes and is consumed; any other non-modifier key outside is a Close
112
+ // that is not consumed, so the keystroke still lands where the user was typing.
113
+ function onKeyDown(event) {
114
+ if (event.key === 'Escape') {
115
+ event.preventDefault();
116
+ event.stopPropagation();
117
+ finish(null);
118
+ return;
119
+ }
120
+ if (event.isComposing) return;
121
+ if (LONE_MODIFIER_KEYS.has(event.key)) return;
122
+ if (!dialog.contains(event.target)) finish(null);
123
+ }
87
124
  if (outcome.kind === 'ambiguous') {
88
125
  for (const candidate of (outcome.candidates || []).slice(0, 20)) {
89
126
  const button = document.createElement('button');
@@ -112,8 +149,22 @@
112
149
  dialog.appendChild(close);
113
150
  dialog.addEventListener('cancel', (event) => { event.preventDefault(); finish(null); });
114
151
  document.body.appendChild(dialog);
115
- if (typeof dialog.showModal === 'function') dialog.showModal();
152
+ // D-1: non-modal — the page stays interactive. D-2: record who had focus, then give it back.
153
+ const prev = document.activeElement;
154
+ if (typeof dialog.show === 'function') dialog.show();
116
155
  else dialog.setAttribute('open', '');
156
+ if (dialog.contains(document.activeElement)) {
157
+ const inside = document.activeElement;
158
+ if (prev && typeof Element !== 'undefined' && prev instanceof Element
159
+ && prev !== document.body && prev.isConnected) {
160
+ prev.focus({ preventScroll: true });
161
+ } else if (inside && typeof inside.blur === 'function') {
162
+ inside.blur();
163
+ }
164
+ }
165
+ activeDismiss = dismiss;
166
+ document.addEventListener('pointerdown', onPointerDown, true);
167
+ document.addEventListener('keydown', onKeyDown, true);
117
168
  });
118
169
  }
119
170
 
@@ -870,6 +870,23 @@
870
870
  }
871
871
  return session.agentType || (session.meta && session.meta.agentType) || '';
872
872
  }
873
+ // WP-1 (wheel-reader-only-where-history-exists-2026-10-28 §5 D-3): the continuous reader can only
874
+ // serve a provider the server has a reader source for -- claude (JSONL window) or codex (rollout
875
+ // lanes), i.e. `historyReader: 'transcript'` in index.html's CLIENT_AGENT_CAPABILITIES, read through its
876
+ // _clientAgentCaps/_clientAgentTypeForSession globals. Every other provider (opencode, gemini, walle,
877
+ // cursor, shell) is 'none': its wheel-up forwards the SGR report to the app instead of opening a
878
+ // reader that exits at once with source-missing. The ONE implementation -- index.html calls it as
879
+ // HistoryAppSeam.historyReader (index.html sits at its hard size ceiling); the claude/codex fallback
880
+ // is for node unit tests, where those globals are absent.
881
+ function historyReader(session) {
882
+ const g = typeof globalThis !== 'undefined' ? globalThis : {};
883
+ if (typeof g._clientAgentCaps === 'function' && typeof g._clientAgentTypeForSession === 'function') {
884
+ return g._clientAgentCaps(g._clientAgentTypeForSession(session)).historyReader === 'transcript';
885
+ }
886
+ if (!session) return false;
887
+ const kind = liveAgentKind(session);
888
+ return kind === 'codex' || kind === 'claude';
889
+ }
873
890
  function prefetchContinuousPage(c, opts) {
874
891
  if (!c || c.active || c._continuousPrefetchInFlight) return false;
875
892
  const ttlMs = Number(opts && opts.ttlMs) > 0 ? Number(opts.ttlMs) : PREFETCH_TTL_MS;
@@ -901,13 +918,16 @@
901
918
  agentKind: liveAgentKind(session),
902
919
  hasScrollback: Number(buf.baseY) > 0,
903
920
  readerOpen: !!c.active,
921
+ historyReader: historyReader(session),
904
922
  }), {
905
923
  terminalMouseState: StateSync.terminalMouseState,
906
924
  terminalWheelRoute: StateSync.terminalWheelRoute,
907
925
  });
908
926
  // `deltaY: -1` above: this probe asks "would a wheel-UP open the reader?" -- a proven mouse OR
909
927
  // a Codex alt-screen tab (D-4, codexAltReaderUp) answers yes.
910
- if (!decision.isAlt || decision.parkedInLocalScrollback || !(decision.mouseActive || decision.codexAltReaderUp)) return false;
928
+ // WP-1: a provider with no reader source never prefetches -- its wheel-up forwards to the app.
929
+ if (!decision.historyReader || !decision.isAlt || decision.parkedInLocalScrollback
930
+ || !(decision.mouseActive || decision.codexAltReaderUp)) return false;
911
931
  key = liveSeqKey(session);
912
932
  } catch {
913
933
  // expected: unreadable live terminal/session facts fail closed before any prefetch state mutation
@@ -1441,7 +1461,7 @@
1441
1461
  prefetchNextSegment, enterAboveApp, exitToApp, showBoundaryChip, applyTranscriptWindowBody,
1442
1462
  onTranscriptScroll, fetchTranscriptPage, loadOlderTranscriptWindow, loadNewerTranscriptWindow,
1443
1463
  renderTranscript, resetContinuous, readRenderDiagnostics,
1444
- enterContinuous, prefetchContinuousPage, rejoin, epochChanged, joinDiag,
1464
+ enterContinuous, prefetchContinuousPage, rejoin, epochChanged, joinDiag, historyReader,
1445
1465
  exitContinuous,
1446
1466
  // WP-3 (D-8/D-9): the fetch-ahead scheduler's window onto the page fetcher's retry bookkeeping.
1447
1467
  planPageFetch, pageRetryPending, hasFailedPage, clearFailedPage, dropPageRetries, abortTranscriptPage,