create-walle 0.10.1 → 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 (681) hide show
  1. package/README.md +7 -1
  2. package/lib/owner-write-safety.js +135 -0
  3. package/lib/public-runtime.js +13 -5
  4. package/lib/release-schema.json +3 -2
  5. package/lib/runtime-closure-policy.json +11 -8
  6. package/package.json +1 -1
  7. package/template/bin/deps-doctor.js +1 -1
  8. package/template/bin/node-bin.sh +11 -0
  9. package/template/coding-task-manager/api-prompts.js +55 -29
  10. package/template/coding-task-manager/bin/claude-hook.js +62 -4
  11. package/template/coding-task-manager/bin/claude-table-parity.js +307 -0
  12. package/template/coding-task-manager/bin/conversation-storage-auto-migration-lib.js +16 -1
  13. package/template/coding-task-manager/bin/conversation-storage-generation-evidence.js +9 -2
  14. package/template/coding-task-manager/bin/conversation-storage-service-entry-lib.js +16 -1
  15. package/template/coding-task-manager/bin/conversation-storage-walle-owner.js +247 -0
  16. package/template/coding-task-manager/bin/ctm-machine-pair.js +160 -0
  17. package/template/coding-task-manager/bin/ctm-relay-client.js +35 -12
  18. package/template/coding-task-manager/bin/land.js +2069 -0
  19. package/template/coding-task-manager/bin/lead-wait-census.js +1348 -0
  20. package/template/coding-task-manager/bin/memory-census.js +4 -2
  21. package/template/coding-task-manager/bin/memory-sync-verify.js +151 -0
  22. package/template/coding-task-manager/bin/probe-refusal-scope.js +530 -0
  23. package/template/coding-task-manager/bin/repair-foreign-clone.js +564 -0
  24. package/template/coding-task-manager/bin/repair-resume-echo-titles.js +248 -0
  25. package/template/coding-task-manager/bin/write-lock-bench.js +111 -0
  26. package/template/coding-task-manager/db.js +860 -317
  27. package/template/coding-task-manager/git-utils.js +44 -0
  28. package/template/coding-task-manager/lib/acp/acp-client.js +383 -0
  29. package/template/coding-task-manager/lib/acp/dsh-context-truth.js +176 -0
  30. package/template/coding-task-manager/lib/acp/dsh-launch-model.js +302 -0
  31. package/template/coding-task-manager/lib/acp/dsh-mcp-servers.js +194 -0
  32. package/template/coding-task-manager/lib/acp/dsh-prompt-lane.js +616 -0
  33. package/template/coding-task-manager/lib/acp/dsh-route-patch.js +308 -0
  34. package/template/coding-task-manager/lib/acp/dsh-session-runtime.js +522 -0
  35. package/template/coding-task-manager/lib/acp/dsh-transcript.js +395 -0
  36. package/template/coding-task-manager/lib/acp/dsh-usage-log.js +162 -0
  37. package/template/coding-task-manager/lib/acp/ndjson-stdio-transport.js +225 -0
  38. package/template/coding-task-manager/lib/adopted-host-redial.js +47 -7
  39. package/template/coding-task-manager/lib/adopted-launch-environment.js +123 -0
  40. package/template/coding-task-manager/lib/agent-auto-update-runtime.js +0 -3
  41. package/template/coding-task-manager/lib/agent-auto-update.js +26 -10
  42. package/template/coding-task-manager/lib/agent-bundle/build.js +657 -0
  43. package/template/coding-task-manager/lib/agent-bundle/codex-install.js +558 -0
  44. package/template/coding-task-manager/lib/agent-bundle/drift.js +120 -0
  45. package/template/coding-task-manager/lib/agent-bundle/gc.js +522 -0
  46. package/template/coding-task-manager/lib/agent-bundle/inventory.js +346 -0
  47. package/template/coding-task-manager/lib/agent-bundle/push.js +717 -0
  48. package/template/coding-task-manager/lib/agent-bundle/skill-transfer.js +724 -0
  49. package/template/coding-task-manager/lib/agent-bundle/spawn.js +119 -0
  50. package/template/coding-task-manager/lib/agent-bundle/store.js +568 -0
  51. package/template/coding-task-manager/lib/agent-capabilities.js +142 -12
  52. package/template/coding-task-manager/lib/agent-cli-cache.js +30 -5
  53. package/template/coding-task-manager/lib/agent-definitions.js +19 -0
  54. package/template/coding-task-manager/lib/agent-hooks-codex-toml.js +28 -16
  55. package/template/coding-task-manager/lib/agent-hooks-codex-workspace.js +9 -1
  56. package/template/coding-task-manager/lib/agent-hooks-installer.js +23 -8
  57. package/template/coding-task-manager/lib/agent-hooks-prune.js +37 -11
  58. package/template/coding-task-manager/lib/agent-hooks-shim.js +105 -0
  59. package/template/coding-task-manager/lib/agent-presets.js +99 -1
  60. package/template/coding-task-manager/lib/agent-title-apply.js +88 -0
  61. package/template/coding-task-manager/lib/agent-title-backfill-read.js +92 -0
  62. package/template/coding-task-manager/lib/agent-upgrade-jobs.js +12 -1
  63. package/template/coding-task-manager/lib/agent-version-service.js +74 -11
  64. package/template/coding-task-manager/lib/all-sessions-query.js +6 -2
  65. package/template/coding-task-manager/lib/api/agent-bundles.js +436 -0
  66. package/template/coding-task-manager/lib/api/backup-retention.js +83 -0
  67. package/template/coding-task-manager/lib/api/conversation-sync-routes.js +124 -0
  68. package/template/coding-task-manager/lib/api/diagnostics.js +549 -69
  69. package/template/coding-task-manager/lib/api/fleet.js +118 -0
  70. package/template/coding-task-manager/lib/api/host-stats.js +98 -0
  71. package/template/coding-task-manager/lib/api/hub-bridge.js +243 -0
  72. package/template/coding-task-manager/lib/api/ingress.js +43 -12
  73. package/template/coding-task-manager/lib/api/landing.js +403 -0
  74. package/template/coding-task-manager/lib/api/machine-pairing.js +285 -0
  75. package/template/coding-task-manager/lib/api/machine-pool.js +307 -0
  76. package/template/coding-task-manager/lib/api/machines.js +1150 -0
  77. package/template/coding-task-manager/lib/api/memory-sync-routes.js +335 -0
  78. package/template/coding-task-manager/lib/api/misc-ops.js +25 -5
  79. package/template/coding-task-manager/lib/api/providers.js +53 -6
  80. package/template/coding-task-manager/lib/api/remote-sessions.js +1326 -0
  81. package/template/coding-task-manager/lib/api/resume-from-store.js +25 -0
  82. package/template/coding-task-manager/lib/api/session-attach.js +623 -0
  83. package/template/coding-task-manager/lib/api/session-messages.js +1384 -0
  84. package/template/coding-task-manager/lib/api/sessions.js +237 -59
  85. package/template/coding-task-manager/lib/api/setup-network.js +544 -16
  86. package/template/coding-task-manager/lib/api/setup-wizard-handlers.js +884 -0
  87. package/template/coding-task-manager/lib/api/setup.js +829 -10
  88. package/template/coding-task-manager/lib/api/transcript-history.js +17 -4
  89. package/template/coding-task-manager/lib/api/walle-bridge.js +9 -1
  90. package/template/coding-task-manager/lib/api/worktrees.js +38 -37
  91. package/template/coding-task-manager/lib/approval-drift.js +16 -1
  92. package/template/coding-task-manager/lib/approval-logical-frame.js +5 -1
  93. package/template/coding-task-manager/lib/approval-scope.js +68 -4
  94. package/template/coding-task-manager/lib/attachment-reconciler-wiring.js +5 -2
  95. package/template/coding-task-manager/lib/auth-context.js +32 -2
  96. package/template/coding-task-manager/lib/auth-rate-limit.js +64 -1
  97. package/template/coding-task-manager/lib/auth-rules.js +474 -62
  98. package/template/coding-task-manager/lib/background-stop.js +369 -0
  99. package/template/coding-task-manager/lib/best-of-attempts.js +4 -1
  100. package/template/coding-task-manager/lib/best-of-launch-plan.js +52 -0
  101. package/template/coding-task-manager/lib/box-keep-awake.js +89 -0
  102. package/template/coding-task-manager/lib/broadcast-reason-stats.js +152 -0
  103. package/template/coding-task-manager/lib/broadcast-serialize.js +7 -1
  104. package/template/coding-task-manager/lib/browser-session-broker.js +9 -1
  105. package/template/coding-task-manager/lib/browser-use-adapter.js +33 -2
  106. package/template/coding-task-manager/lib/build-info.js +4 -2
  107. package/template/coding-task-manager/lib/claude-markdown-ansi.js +27 -85
  108. package/template/coding-task-manager/lib/claude-model-truth.js +13 -2
  109. package/template/coding-task-manager/lib/claude-session-title.js +6 -30
  110. package/template/coding-task-manager/lib/claude-table-layout.js +322 -0
  111. package/template/coding-task-manager/lib/claude-transcript-terminal-renderer.js +17 -13
  112. package/template/coding-task-manager/lib/client-diag-handler.js +69 -2
  113. package/template/coding-task-manager/lib/codex-app-server-client.js +14 -16
  114. package/template/coding-task-manager/lib/codex-config-guard.js +33 -3
  115. package/template/coding-task-manager/lib/codex-configuration-history.js +55 -0
  116. package/template/coding-task-manager/lib/codex-harness-qualification.js +55 -20
  117. package/template/coding-task-manager/lib/codex-launch-health.js +29 -2
  118. package/template/coding-task-manager/lib/codex-link-preparation.js +9 -8
  119. package/template/coding-task-manager/lib/codex-paths.js +2 -1
  120. package/template/coding-task-manager/lib/codex-rollout-history.js +743 -0
  121. package/template/coding-task-manager/lib/coding-agent-models.js +48 -42
  122. package/template/coding-task-manager/lib/coding-cli-skill-installer.js +44 -14
  123. package/template/coding-task-manager/lib/coding-session-model-adapters.js +70 -4
  124. package/template/coding-task-manager/lib/coding-session-model-owner.js +1 -1
  125. package/template/coding-task-manager/lib/coding-session-model-projection.js +5 -0
  126. package/template/coding-task-manager/lib/coding-session-model-public.js +7 -1
  127. package/template/coding-task-manager/lib/coding-session-model-runtime.js +24 -6
  128. package/template/coding-task-manager/lib/coding-session-model-scan.js +31 -0
  129. package/template/coding-task-manager/lib/coding-session-model-state.js +17 -0
  130. package/template/coding-task-manager/lib/coding-session-model-sync-state.js +0 -1
  131. package/template/coding-task-manager/lib/conversation-freshness-diagnostics.js +280 -0
  132. package/template/coding-task-manager/lib/conversation-import/cursor-guard-owner.js +10 -0
  133. package/template/coding-task-manager/lib/conversation-item-clock.js +261 -0
  134. package/template/coding-task-manager/lib/conversation-source-registry.js +5 -0
  135. package/template/coding-task-manager/lib/conversation-store-v2.js +44 -0
  136. package/template/coding-task-manager/lib/conversation-sync.js +355 -0
  137. package/template/coding-task-manager/lib/create/resolve-launch-params.js +104 -13
  138. package/template/coding-task-manager/lib/create/worker-role-profile.js +4 -4
  139. package/template/coding-task-manager/lib/create-intent-lease.js +51 -0
  140. package/template/coding-task-manager/lib/ctm-boot-lifecycle.js +17 -1
  141. package/template/coding-task-manager/lib/ctm-session-context-api.js +97 -6
  142. package/template/coding-task-manager/lib/db-domain-tables.js +8 -0
  143. package/template/coding-task-manager/lib/db-domains.js +22 -2
  144. package/template/coding-task-manager/lib/db-owner-dispatch-probe.js +32 -0
  145. package/template/coding-task-manager/lib/db-owner-op-registry.js +7 -0
  146. package/template/coding-task-manager/lib/db-owner-request-counts.js +178 -0
  147. package/template/coding-task-manager/lib/db-owner-worker-client.js +68 -14
  148. package/template/coding-task-manager/lib/db-schema-source-files.js +6 -0
  149. package/template/coding-task-manager/lib/deferred-restore-attempt.js +6 -2
  150. package/template/coding-task-manager/lib/feature-manifest.js +5 -1
  151. package/template/coding-task-manager/lib/fleet-conversation-route.js +97 -0
  152. package/template/coding-task-manager/lib/fleet-fanout.js +78 -0
  153. package/template/coding-task-manager/lib/fleet-hub.js +762 -0
  154. package/template/coding-task-manager/lib/fleet-origin-follower.js +252 -0
  155. package/template/coding-task-manager/lib/fleet-resolver-effects.js +147 -0
  156. package/template/coding-task-manager/lib/fleet-resolver-tick.js +148 -0
  157. package/template/coding-task-manager/lib/fleet-resolver.js +454 -0
  158. package/template/coding-task-manager/lib/fleet-session-list-routes.js +114 -0
  159. package/template/coding-task-manager/lib/fleet-session-lists.js +672 -0
  160. package/template/coding-task-manager/lib/fleet-update.js +798 -0
  161. package/template/coding-task-manager/lib/fs-watcher-root-watch.js +141 -0
  162. package/template/coding-task-manager/lib/fs-watcher.js +61 -44
  163. package/template/coding-task-manager/lib/harness-history-transition.js +52 -11
  164. package/template/coding-task-manager/lib/headless-inflight-ops.js +203 -0
  165. package/template/coding-task-manager/lib/headless-missing-reply.js +42 -0
  166. package/template/coding-task-manager/lib/headless-term-service.js +139 -25
  167. package/template/coding-task-manager/lib/hermetic-agent-launch-guard.js +10 -0
  168. package/template/coding-task-manager/lib/history-transition-read-op.js +175 -8
  169. package/template/coding-task-manager/lib/host-control-dial.js +167 -0
  170. package/template/coding-task-manager/lib/host-cpu-categories.js +310 -0
  171. package/template/coding-task-manager/lib/host-fseventsd-sampler.js +399 -0
  172. package/template/coding-task-manager/lib/host-handoff-orchestrator.js +16 -2
  173. package/template/coding-task-manager/lib/host-handoff.js +50 -15
  174. package/template/coding-task-manager/lib/host-health-ledger.js +164 -12
  175. package/template/coding-task-manager/lib/host-self-truth-watchdog.js +4 -0
  176. package/template/coding-task-manager/lib/host-stats.js +475 -0
  177. package/template/coding-task-manager/lib/host-threadpool-evacuation.js +160 -0
  178. package/template/coding-task-manager/lib/host-threadpool-monitor.js +14 -1
  179. package/template/coding-task-manager/lib/hosted-input-dispatch.js +203 -0
  180. package/template/coding-task-manager/lib/hosted-sync-worker.js +141 -310
  181. package/template/coding-task-manager/lib/hub-bridge-access.js +798 -0
  182. package/template/coding-task-manager/lib/hub-bridge-box.js +409 -0
  183. package/template/coding-task-manager/lib/hub-bridge-mcp.js +380 -0
  184. package/template/coding-task-manager/lib/hub-bridge-mesh.js +313 -0
  185. package/template/coding-task-manager/lib/hub-bridge-ops.js +721 -0
  186. package/template/coding-task-manager/lib/hub-bridge.js +398 -0
  187. package/template/coding-task-manager/lib/idle-notify.js +491 -0
  188. package/template/coding-task-manager/lib/instance-id-ownership-manifest.js +12 -0
  189. package/template/coding-task-manager/lib/instance-manifest-runtime.js +3 -0
  190. package/template/coding-task-manager/lib/instance-manifest.js +18 -2
  191. package/template/coding-task-manager/lib/instance-sync-status.js +33 -8
  192. package/template/coding-task-manager/lib/landing/agent-rule.txt +1 -0
  193. package/template/coding-task-manager/lib/landing/batch-runner.js +366 -0
  194. package/template/coding-task-manager/lib/landing/config.js +536 -0
  195. package/template/coding-task-manager/lib/landing/ctm-view.js +256 -0
  196. package/template/coding-task-manager/lib/landing/gate.js +360 -0
  197. package/template/coding-task-manager/lib/landing/git.js +344 -0
  198. package/template/coding-task-manager/lib/landing/lease.js +247 -0
  199. package/template/coding-task-manager/lib/landing/merge-delta.js +380 -0
  200. package/template/coding-task-manager/lib/landing/proof.js +223 -0
  201. package/template/coding-task-manager/lib/landing/queue.js +998 -0
  202. package/template/coding-task-manager/lib/landing/radar.js +489 -0
  203. package/template/coding-task-manager/lib/landing/resolve-cli.js +424 -0
  204. package/template/coding-task-manager/lib/landing/state.js +263 -0
  205. package/template/coding-task-manager/lib/landing/stop.js +49 -0
  206. package/template/coding-task-manager/lib/landing/sync-cli.js +475 -0
  207. package/template/coding-task-manager/lib/landing/sync.js +456 -0
  208. package/template/coding-task-manager/lib/landing/train.js +885 -0
  209. package/template/coding-task-manager/lib/landing/window.js +57 -0
  210. package/template/coding-task-manager/lib/launch-environment.js +121 -0
  211. package/template/coding-task-manager/lib/launch-model-override.js +193 -8
  212. package/template/coding-task-manager/lib/launch-plan-pool.js +2 -1
  213. package/template/coding-task-manager/lib/launch-plan-warm-cache.js +6 -0
  214. package/template/coding-task-manager/lib/launch-plan-worker.js +59 -2
  215. package/template/coding-task-manager/lib/lead-model-observer.js +57 -1
  216. package/template/coding-task-manager/lib/lead-model-options.js +160 -3
  217. package/template/coding-task-manager/lib/lead-model-restore-reconciliation.js +106 -24
  218. package/template/coding-task-manager/lib/lead-model-switch-runtime.js +409 -72
  219. package/template/coding-task-manager/lib/lead-model-switch.js +115 -10
  220. package/template/coding-task-manager/lib/lead-model-transition-runtime.js +14 -2
  221. package/template/coding-task-manager/lib/lead-model-transition-store.js +85 -9
  222. package/template/coding-task-manager/lib/lead-route-preflight.js +179 -0
  223. package/template/coding-task-manager/lib/lead-switch-history-mode.js +110 -0
  224. package/template/coding-task-manager/lib/lead-wire-agent.js +7 -0
  225. package/template/coding-task-manager/lib/legacy-draft-cancellation-recovery.js +111 -0
  226. package/template/coding-task-manager/lib/lifecycle-wake-experiment.js +9 -2
  227. package/template/coding-task-manager/lib/live-defer-announce.js +45 -0
  228. package/template/coding-task-manager/lib/login-tripwire.js +1 -0
  229. package/template/coding-task-manager/lib/machine-pairing.js +238 -0
  230. package/template/coding-task-manager/lib/machine-pool.js +409 -0
  231. package/template/coding-task-manager/lib/machine-registry.js +1494 -0
  232. package/template/coding-task-manager/lib/machine-self.js +66 -0
  233. package/template/coding-task-manager/lib/macos-capabilities.js +32 -15
  234. package/template/coding-task-manager/lib/main-thread-lint-exemptions.json +485 -57
  235. package/template/coding-task-manager/lib/mainloop-observability.js +14 -9
  236. package/template/coding-task-manager/lib/media-draft-owner.js +16 -3
  237. package/template/coding-task-manager/lib/media-journal-control-reader.js +473 -0
  238. package/template/coding-task-manager/lib/media-journal.js +84 -27
  239. package/template/coding-task-manager/lib/media-store-options.js +43 -15
  240. package/template/coding-task-manager/lib/memory-join.js +337 -0
  241. package/template/coding-task-manager/lib/memory-sync-verify.js +393 -0
  242. package/template/coding-task-manager/lib/memory-sync.js +565 -0
  243. package/template/coding-task-manager/lib/migrations/v56-host-samples-and-machine-pool.js +76 -0
  244. package/template/coding-task-manager/lib/migrations/v57-delegate-pref-mirror-opencode.js +68 -0
  245. package/template/coding-task-manager/lib/migrations/v58-subagent-launch-native-subagents.js +42 -0
  246. package/template/coding-task-manager/lib/migrations/v59-coding-session-model-state-dsh.js +73 -0
  247. package/template/coding-task-manager/lib/migrations/v60-delegate-pref-mirror-dsh.js +78 -0
  248. package/template/coding-task-manager/lib/migrations/v61-conversation-item-clock.js +71 -0
  249. package/template/coding-task-manager/lib/mirror-feed-sanitize.js +12 -3
  250. package/template/coding-task-manager/lib/model-availability.js +727 -0
  251. package/template/coding-task-manager/lib/model-execution-recipe-metadata.js +4 -6
  252. package/template/coding-task-manager/lib/model-host-receipt.js +6 -3
  253. package/template/coding-task-manager/lib/model-id-rule.js +19 -0
  254. package/template/coding-task-manager/lib/model-proxy/anthropic-face.js +8 -0
  255. package/template/coding-task-manager/lib/model-proxy/auto-mode-review.js +110 -23
  256. package/template/coding-task-manager/lib/model-proxy/chat-response-translators.js +6 -0
  257. package/template/coding-task-manager/lib/model-proxy/generation-probe.js +60 -17
  258. package/template/coding-task-manager/lib/model-proxy/handoff.js +494 -0
  259. package/template/coding-task-manager/lib/model-proxy/historical-tool-declarations.js +37 -0
  260. package/template/coding-task-manager/lib/model-proxy/lead-request-validation.js +1 -0
  261. package/template/coding-task-manager/lib/model-proxy/lead-token-admin.js +130 -0
  262. package/template/coding-task-manager/lib/model-proxy/lead-worker-picks.js +25 -0
  263. package/template/coding-task-manager/lib/model-proxy/native-lead-listener.js +61 -7
  264. package/template/coding-task-manager/lib/model-proxy/proxy-cli.js +200 -0
  265. package/template/coding-task-manager/lib/model-proxy/proxy-instance-record.js +257 -0
  266. package/template/coding-task-manager/lib/model-proxy/refusal-scope.js +151 -0
  267. package/template/coding-task-manager/lib/model-proxy/request-budget-store.js +11 -2
  268. package/template/coding-task-manager/lib/model-proxy/stream-accounting.js +205 -0
  269. package/template/coding-task-manager/lib/model-proxy/tokens.js +147 -5
  270. package/template/coding-task-manager/lib/model-proxy/upstream-outcome.js +18 -0
  271. package/template/coding-task-manager/lib/native-agent-model-args.js +25 -22
  272. package/template/coding-task-manager/lib/native-history-control.js +7 -5
  273. package/template/coding-task-manager/lib/native-lead-settings-client.js +46 -5
  274. package/template/coding-task-manager/lib/native-lead-tls.js +18 -4
  275. package/template/coding-task-manager/lib/oauth-proxy-supervisor.js +776 -75
  276. package/template/coding-task-manager/lib/online-backup-worker-client.js +2 -0
  277. package/template/coding-task-manager/lib/opencode-cli.js +480 -0
  278. package/template/coding-task-manager/lib/opencode-launch-model.js +471 -0
  279. package/template/coding-task-manager/lib/opencode-v1-plugin/model-carrier.mjs +35 -0
  280. package/template/coding-task-manager/lib/opencode-v2-plugin/server.js +118 -0
  281. package/template/coding-task-manager/lib/owner-action-manifest-data.json +15 -1
  282. package/template/coding-task-manager/lib/painted-row-recorder.js +9 -1
  283. package/template/coding-task-manager/lib/park-composer-draft.js +54 -0
  284. package/template/coding-task-manager/lib/park-fresh-relaunch.js +41 -10
  285. package/template/coding-task-manager/lib/perf-phase-trace.js +72 -0
  286. package/template/coding-task-manager/lib/perf-summary.js +7 -0
  287. package/template/coding-task-manager/lib/perf-tracker.js +63 -2
  288. package/template/coding-task-manager/lib/project-config.js +7 -0
  289. package/template/coding-task-manager/lib/prompt-purge-v2.js +52 -1
  290. package/template/coding-task-manager/lib/prompt-submission-contract.js +21 -1
  291. package/template/coding-task-manager/lib/provider-login-broker.js +264 -24
  292. package/template/coding-task-manager/lib/provider-login-capture.js +153 -0
  293. package/template/coding-task-manager/lib/provider-login-tab.js +10 -2
  294. package/template/coding-task-manager/lib/queue-draft-status-overlay.js +36 -0
  295. package/template/coding-task-manager/lib/raw-codex-history-window.js +5 -3
  296. package/template/coding-task-manager/lib/read-pool-client.js +94 -4
  297. package/template/coding-task-manager/lib/read-pool-op-registry.js +10 -1
  298. package/template/coding-task-manager/lib/read-pool-worker-handle.js +29 -4
  299. package/template/coding-task-manager/lib/recent-catalog-query.js +41 -0
  300. package/template/coding-task-manager/lib/recent-session-catalog-response.js +76 -10
  301. package/template/coding-task-manager/lib/recovery-evidence.js +26 -11
  302. package/template/coding-task-manager/lib/relay-client.js +57 -3
  303. package/template/coding-task-manager/lib/relink-audit.js +34 -5
  304. package/template/coding-task-manager/lib/remote-command-context.js +12 -0
  305. package/template/coding-task-manager/lib/remote-command-runtime.js +13 -1
  306. package/template/coding-task-manager/lib/remote-machine-catalog.js +1357 -0
  307. package/template/coding-task-manager/lib/remote-machine-create.js +1233 -0
  308. package/template/coding-task-manager/lib/remote-machine-link.js +1426 -0
  309. package/template/coding-task-manager/lib/remote-machine-proxy.js +654 -0
  310. package/template/coding-task-manager/lib/remote-session-forward.js +364 -0
  311. package/template/coding-task-manager/lib/remote-submission-status.js +6 -0
  312. package/template/coding-task-manager/lib/remote-terminal-target.js +9 -2
  313. package/template/coding-task-manager/lib/restart-guard.js +18 -6
  314. package/template/coding-task-manager/lib/restart-outcome-truth.js +20 -3
  315. package/template/coding-task-manager/lib/restart-preflight.js +9 -2
  316. package/template/coding-task-manager/lib/restore-backoff-gate.js +10 -2
  317. package/template/coding-task-manager/lib/restore-prepare-retry.js +12 -5
  318. package/template/coding-task-manager/lib/restore-resume-batch.js +22 -1
  319. package/template/coding-task-manager/lib/restore-seed-modes.js +87 -0
  320. package/template/coding-task-manager/lib/restored-scrollback-hydration-runtime.js +22 -2
  321. package/template/coding-task-manager/lib/resume-admission.js +17 -3
  322. package/template/coding-task-manager/lib/resume-blocked-wire.js +62 -1
  323. package/template/coding-task-manager/lib/resume-cwd.js +13 -0
  324. package/template/coding-task-manager/lib/resume-from-store.js +12 -1
  325. package/template/coding-task-manager/lib/resume-origin-facts.js +38 -1
  326. package/template/coding-task-manager/lib/resume-preflight.js +21 -16
  327. package/template/coding-task-manager/lib/review-repo-admission.js +39 -6
  328. package/template/coding-task-manager/lib/review-repo-registry.js +74 -18
  329. package/template/coding-task-manager/lib/root-delivery-runtime.js +74 -17
  330. package/template/coding-task-manager/lib/root-delivery-selection.js +37 -1
  331. package/template/coding-task-manager/lib/root-prompt-admission.js +33 -2
  332. package/template/coding-task-manager/lib/root-prompt-flow.js +168 -34
  333. package/template/coding-task-manager/lib/runtime-contract.js +3 -1
  334. package/template/coding-task-manager/lib/schema-indexes.js +1 -0
  335. package/template/coding-task-manager/lib/scrollback-archive-store.js +7 -4
  336. package/template/coding-task-manager/lib/session-analysis-memory.js +2 -0
  337. package/template/coding-task-manager/lib/session-context-locator.js +742 -0
  338. package/template/coding-task-manager/lib/session-create/attachment.js +2 -2
  339. package/template/coding-task-manager/lib/session-create/codex-native-provider-gate.js +218 -0
  340. package/template/coding-task-manager/lib/session-create/codex-resume-exit-classify.js +52 -0
  341. package/template/coding-task-manager/lib/session-create/create-phases.js +118 -0
  342. package/template/coding-task-manager/lib/session-create/delegate-worker.js +179 -20
  343. package/template/coding-task-manager/lib/session-create/dsh-session.js +930 -0
  344. package/template/coding-task-manager/lib/session-create/identity.js +20 -1
  345. package/template/coding-task-manager/lib/session-create/lead-route-launch.js +186 -13
  346. package/template/coding-task-manager/lib/session-create/native-lead-lifetime.js +55 -3
  347. package/template/coding-task-manager/lib/session-create/opencode-lead-provider.js +50 -0
  348. package/template/coding-task-manager/lib/session-create/prepared.js +201 -9
  349. package/template/coding-task-manager/lib/session-create/provider-launch-context.js +77 -0
  350. package/template/coding-task-manager/lib/session-create/provider-process.js +193 -64
  351. package/template/coding-task-manager/lib/session-create/response.js +37 -19
  352. package/template/coding-task-manager/lib/session-create/structured-session.js +27 -0
  353. package/template/coding-task-manager/lib/session-create/subagent-pick-table.js +3 -1
  354. package/template/coding-task-manager/lib/session-create/subagent-pick.js +458 -9
  355. package/template/coding-task-manager/lib/session-create/transcript.js +14 -5
  356. package/template/coding-task-manager/lib/session-create/worker-budget-setup.js +21 -2
  357. package/template/coding-task-manager/lib/session-create/worker-continuation.js +50 -2
  358. package/template/coding-task-manager/lib/session-create/worker-launch-sandbox.js +39 -10
  359. package/template/coding-task-manager/lib/session-create/worker-notices.js +94 -5
  360. package/template/coding-task-manager/lib/session-create/worker-observability.js +101 -9
  361. package/template/coding-task-manager/lib/session-create/worker-stop.js +11 -3
  362. package/template/coding-task-manager/lib/session-create/worker-wait-watcher.js +315 -0
  363. package/template/coding-task-manager/lib/session-empty.js +13 -10
  364. package/template/coding-task-manager/lib/session-geometry-authority-handler.js +10 -1
  365. package/template/coding-task-manager/lib/session-host-manager.js +212 -206
  366. package/template/coding-task-manager/lib/session-jobs.js +20 -10
  367. package/template/coding-task-manager/lib/session-lifecycle.js +28 -4
  368. package/template/coding-task-manager/lib/session-model-action-preconditions.js +15 -2
  369. package/template/coding-task-manager/lib/session-model-intent-contract.js +11 -8
  370. package/template/coding-task-manager/lib/session-park.js +738 -0
  371. package/template/coding-task-manager/lib/session-path-grant.js +13 -4
  372. package/template/coding-task-manager/lib/session-resource-sampler.js +19 -9
  373. package/template/coding-task-manager/lib/session-standup.js +67 -4
  374. package/template/coding-task-manager/lib/session-status-ledger.js +147 -6
  375. package/template/coding-task-manager/lib/session-status-runtime.js +45 -1
  376. package/template/coding-task-manager/lib/session-title-mirror.js +25 -57
  377. package/template/coding-task-manager/lib/session-transcript-trash.js +8 -1
  378. package/template/coding-task-manager/lib/session-transport.js +17 -0
  379. package/template/coding-task-manager/lib/session-workspace-projection.js +54 -5
  380. package/template/coding-task-manager/lib/session-workspace-tracking-runtime.js +213 -1
  381. package/template/coding-task-manager/lib/skill-autocomplete-query.js +120 -3
  382. package/template/coding-task-manager/lib/skill-autocomplete.js +15 -1
  383. package/template/coding-task-manager/lib/sqlite-file-set.js +39 -0
  384. package/template/coding-task-manager/lib/standup-search-adapter.js +16 -2
  385. package/template/coding-task-manager/lib/startup-pointer-write.js +57 -0
  386. package/template/coding-task-manager/lib/state-sync/client-ledger.js +12 -0
  387. package/template/coding-task-manager/lib/state-sync/frame-emitter.js +319 -100
  388. package/template/coding-task-manager/lib/state-sync/painted-frame-field.js +11 -0
  389. package/template/coding-task-manager/lib/storage/coding-session-model-store.js +25 -23
  390. package/template/coding-task-manager/lib/storage/delegate-pref-mirror-store.js +32 -9
  391. package/template/coding-task-manager/lib/structured-session-boot-sweep.js +235 -0
  392. package/template/coding-task-manager/lib/submission-ack.js +90 -2
  393. package/template/coding-task-manager/lib/surviving-owner-bootstrap.js +7 -2
  394. package/template/coding-task-manager/lib/surviving-owner-recovery.js +2 -1
  395. package/template/coding-task-manager/lib/systemd-scope.js +115 -0
  396. package/template/coding-task-manager/lib/telemetry-receiver.js +39 -0
  397. package/template/coding-task-manager/lib/terminal-attach-geometry.js +985 -0
  398. package/template/coding-task-manager/lib/terminal-bootstrap.js +30 -0
  399. package/template/coding-task-manager/lib/terminal-draft-http-status.js +25 -0
  400. package/template/coding-task-manager/lib/terminal-draft-operation.js +357 -0
  401. package/template/coding-task-manager/lib/terminal-input-admission.js +17 -1
  402. package/template/coding-task-manager/lib/terminal-input-prepared.js +563 -0
  403. package/template/coding-task-manager/lib/transcript-archiver.js +229 -229
  404. package/template/coding-task-manager/lib/transcript-cache-temps.js +171 -0
  405. package/template/coding-task-manager/lib/transcript-frame-cache.js +20 -5
  406. package/template/coding-task-manager/lib/transcript-guard-job.js +55 -4
  407. package/template/coding-task-manager/lib/transcript-link.js +77 -0
  408. package/template/coding-task-manager/lib/transcript-manifest-store.js +8 -4
  409. package/template/coding-task-manager/lib/transcript-source.js +44 -7
  410. package/template/coding-task-manager/lib/transcript-store.js +49 -0
  411. package/template/coding-task-manager/lib/tunnel-lane-governor.js +6 -3
  412. package/template/coding-task-manager/lib/typing-interaction-trace.js +198 -3
  413. package/template/coding-task-manager/lib/typing-worker-stages.js +60 -0
  414. package/template/coding-task-manager/lib/usage-ledger/backfill.js +40 -5
  415. package/template/coding-task-manager/lib/usage-ledger/client.js +4 -1
  416. package/template/coding-task-manager/lib/usage-ledger/dsh-parse.js +152 -0
  417. package/template/coding-task-manager/lib/usage-ledger/dsh-read.js +73 -0
  418. package/template/coding-task-manager/lib/usage-ledger/ingest.js +34 -6
  419. package/template/coding-task-manager/lib/usage-ledger/live.js +35 -8
  420. package/template/coding-task-manager/lib/usage-ledger/read.js +29 -20
  421. package/template/coding-task-manager/lib/usage-ledger/schema.js +61 -1
  422. package/template/coding-task-manager/lib/usage-ledger/task-coordinator.js +4 -2
  423. package/template/coding-task-manager/lib/visible-revision-watchdog.js +8 -12
  424. package/template/coding-task-manager/lib/wake-skip-reasons.js +47 -0
  425. package/template/coding-task-manager/lib/walle/turn.js +1 -1
  426. package/template/coding-task-manager/lib/walle-history-serve.js +838 -0
  427. package/template/coding-task-manager/lib/walle-kill-authority.js +2 -2
  428. package/template/coding-task-manager/lib/walle-log-rotation.js +164 -1
  429. package/template/coding-task-manager/lib/walle-mcp-auto-config.js +56 -2
  430. package/template/coding-task-manager/lib/walle-row-history.js +495 -0
  431. package/template/coding-task-manager/lib/walle-supervisor.js +130 -27
  432. package/template/coding-task-manager/lib/watch-worker-client.js +203 -0
  433. package/template/coding-task-manager/lib/worker-failure-classify.js +13 -1
  434. package/template/coding-task-manager/lib/worker-terminal-output.js +5 -2
  435. package/template/coding-task-manager/lib/ws/hub-bridge.js +35 -0
  436. package/template/coding-task-manager/lib/ws/lifecycle.js +6 -11
  437. package/template/coding-task-manager/lib/ws/misc.js +1 -1
  438. package/template/coding-task-manager/lib/ws/state-sync.js +125 -6
  439. package/template/coding-task-manager/lib/ws/terminal-attach.js +123 -1
  440. package/template/coding-task-manager/lib/ws-router.js +68 -1
  441. package/template/coding-task-manager/lib/ws-send-admission.js +22 -4
  442. package/template/coding-task-manager/oauth-proxy.js +211 -170
  443. package/template/coding-task-manager/package-lock.json +34 -94
  444. package/template/coding-task-manager/package.json +7 -3
  445. package/template/coding-task-manager/protocol/message-table.json +10 -0
  446. package/template/coding-task-manager/protocol/messages.js +10 -0
  447. package/template/coding-task-manager/protocol/ws-schema.json +20 -0
  448. package/template/coding-task-manager/protocol/ws-schema.md +2 -0
  449. package/template/coding-task-manager/providers/codex-mcp-extract.js +121 -19
  450. package/template/coding-task-manager/providers/codex-mcp.js +14 -5
  451. package/template/coding-task-manager/public/css/app.css +449 -1
  452. package/template/coding-task-manager/public/css/reviews.css +4 -0
  453. package/template/coding-task-manager/public/css/walle-session.css +4 -0
  454. package/template/coding-task-manager/public/index.html +766 -465
  455. package/template/coding-task-manager/public/js/agent-command.js +86 -0
  456. package/template/coding-task-manager/public/js/app/backups-panel.js +111 -5
  457. package/template/coding-task-manager/public/js/app/coding-agent-upgrade.js +103 -4
  458. package/template/coding-task-manager/public/js/app/machines-page.js +2572 -0
  459. package/template/coding-task-manager/public/js/app/models-tab.js +658 -73
  460. package/template/coding-task-manager/public/js/app/restart-banner.js +53 -0
  461. package/template/coding-task-manager/public/js/app/worktrees-panel.js +191 -7
  462. package/template/coding-task-manager/public/js/background-work.js +203 -28
  463. package/template/coding-task-manager/public/js/coding-session-model-presentation.js +181 -13
  464. package/template/coding-task-manager/public/js/core/active-session-groups.js +179 -0
  465. package/template/coding-task-manager/public/js/core/pending-create.js +238 -0
  466. package/template/coding-task-manager/public/js/core/recent-machine-source.js +228 -0
  467. package/template/coding-task-manager/public/js/core/session-commands.js +847 -5
  468. package/template/coding-task-manager/public/js/core/session-selectors.js +5 -1
  469. package/template/coding-task-manager/public/js/dashboard-client-function-order.json +8 -0
  470. package/template/coding-task-manager/public/js/document-review-links.js +9 -1
  471. package/template/coding-task-manager/public/js/file-resolution-client.js +52 -1
  472. package/template/coding-task-manager/public/js/history-app-seam.js +48 -4
  473. package/template/coding-task-manager/public/js/history-painted-rows.js +17 -2
  474. package/template/coding-task-manager/public/js/history-reader-park.js +13 -1
  475. package/template/coding-task-manager/public/js/history-scroller.js +187 -9
  476. package/template/coding-task-manager/public/js/history-transcript-pages.js +5 -5
  477. package/template/coding-task-manager/public/js/machine-pool-shared.js +991 -0
  478. package/template/coding-task-manager/public/js/message-renderer.js +4 -3
  479. package/template/coding-task-manager/public/js/model-picker.js +3 -1
  480. package/template/coding-task-manager/public/js/native-subagent-review.js +15 -2
  481. package/template/coding-task-manager/public/js/new-session-agent-grid.js +346 -0
  482. package/template/coding-task-manager/public/js/pasted-content.js +236 -0
  483. package/template/coding-task-manager/public/js/pe-private-content-lifetime.js +39 -7
  484. package/template/coding-task-manager/public/js/private-model-lifetime.js +6 -2
  485. package/template/coding-task-manager/public/js/private-state-scope.js +31 -3
  486. package/template/coding-task-manager/public/js/prompt-submission-client.js +173 -8
  487. package/template/coding-task-manager/public/js/prompt-submission-tray.js +281 -0
  488. package/template/coding-task-manager/public/js/prompts.js +11 -10
  489. package/template/coding-task-manager/public/js/protocol.js +10 -0
  490. package/template/coding-task-manager/public/js/queue-panel-submission-reconcile.js +174 -1
  491. package/template/coding-task-manager/public/js/restart-banner-policy.js +29 -1
  492. package/template/coding-task-manager/public/js/reviews.js +7 -3
  493. package/template/coding-task-manager/public/js/root-draft-lifetime.js +139 -2
  494. package/template/coding-task-manager/public/js/root-queue-builder-lifetime.js +16 -0
  495. package/template/coding-task-manager/public/js/row-join.js +4 -2
  496. package/template/coding-task-manager/public/js/session-model-picker.js +447 -57
  497. package/template/coding-task-manager/public/js/session-search-utils.js +64 -21
  498. package/template/coding-task-manager/public/js/session-usage-view.js +2 -1
  499. package/template/coding-task-manager/public/js/session-workspace-tracking.js +51 -1
  500. package/template/coding-task-manager/public/js/state-sync-client.js +14 -1
  501. package/template/coding-task-manager/public/js/stream-view.js +6 -5
  502. package/template/coding-task-manager/public/js/terminal/conv-only-session.js +287 -0
  503. package/template/coding-task-manager/public/js/terminal/runtime-02.js +16 -7
  504. package/template/coding-task-manager/public/js/terminal/runtime-03.js +41 -0
  505. package/template/coding-task-manager/public/js/terminal/runtime-04.js +41 -4
  506. package/template/coding-task-manager/public/js/terminal/runtime-09.js +2 -0
  507. package/template/coding-task-manager/public/js/terminal/runtime-10.js +5 -5
  508. package/template/coding-task-manager/public/js/terminal/runtime-12.js +60 -3
  509. package/template/coding-task-manager/public/js/terminal/runtime-16.js +16 -12
  510. package/template/coding-task-manager/public/js/terminal/runtime-18.js +14 -0
  511. package/template/coding-task-manager/public/js/terminal/runtime-19.js +8 -4
  512. package/template/coding-task-manager/public/js/terminal/runtime-20.js +211 -74
  513. package/template/coding-task-manager/public/js/terminal/runtime-21.js +19 -6
  514. package/template/coding-task-manager/public/js/terminal/runtime-22.js +86 -0
  515. package/template/coding-task-manager/public/js/terminal-attachment-draft.js +67 -13
  516. package/template/coding-task-manager/public/js/terminal-history-viewport.js +1 -1
  517. package/template/coding-task-manager/public/js/terminal-image-orchestration.js +52 -6
  518. package/template/coding-task-manager/public/js/terminal-wheel.js +62 -5
  519. package/template/coding-task-manager/public/js/walle/chat-conversation.js +15 -7
  520. package/template/coding-task-manager/public/js/walle-session.js +30 -7
  521. package/template/coding-task-manager/public/js/walle.js +6 -0
  522. package/template/coding-task-manager/public/js/ws/live-dispatch.js +10 -0
  523. package/template/coding-task-manager/public/m/app.css +366 -8
  524. package/template/coding-task-manager/public/m/app.js +1006 -74
  525. package/template/coding-task-manager/public/m/index.html +55 -1
  526. package/template/coding-task-manager/public/m/machines.js +2147 -0
  527. package/template/coding-task-manager/public/m/pool-failover.js +391 -0
  528. package/template/coding-task-manager/public/m/private-api.js +31 -1
  529. package/template/coding-task-manager/public/m/private-queue-actions.js +26 -7
  530. package/template/coding-task-manager/public/m/sw.js +5 -0
  531. package/template/coding-task-manager/public/usage.html +1 -0
  532. package/template/coding-task-manager/queue-engine.js +13 -0
  533. package/template/coding-task-manager/scripts/dev-route-fixture/synthetic-route-upstream.js +104 -0
  534. package/template/coding-task-manager/scripts/dev-route-fixture.js +339 -0
  535. package/template/coding-task-manager/scripts/opencode-lead-route-probe.js +195 -0
  536. package/template/coding-task-manager/scripts/opencode-v2-contract-probe/fake-anthropic.js +168 -0
  537. package/template/coding-task-manager/scripts/opencode-v2-contract-probe/probe-plugin/server.js +95 -0
  538. package/template/coding-task-manager/scripts/opencode-v2-contract-probe.js +673 -0
  539. package/template/coding-task-manager/server/approvals.js +5 -6
  540. package/template/coding-task-manager/server/boot.js +136 -17
  541. package/template/coding-task-manager/server.js +2819 -11885
  542. package/template/coding-task-manager/session-integrity.js +71 -13
  543. package/template/coding-task-manager/workers/db-owner-worker.js +72 -9
  544. package/template/coding-task-manager/workers/online-backup-worker.js +1 -0
  545. package/template/coding-task-manager/workers/read-pool-model-collector.js +51 -3
  546. package/template/coding-task-manager/workers/read-pool-worker.js +93 -12
  547. package/template/coding-task-manager/workers/session-host-pool-process.js +24 -10
  548. package/template/coding-task-manager/workers/session-host-process.js +19 -8
  549. package/template/coding-task-manager/workers/transcript-archive-worker.js +1 -1
  550. package/template/coding-task-manager/workers/watch-worker.js +105 -0
  551. package/template/coding-task-manager/workers/worktree-worker.js +202 -33
  552. package/template/ctm-relay/lib/protocol.js +14 -1
  553. package/template/package-lock.json +2 -2
  554. package/template/package.json +1 -1
  555. package/template/scripts/conversation-storage-v2-migration.js +78 -11
  556. package/template/shared/backup-retention.js +82 -0
  557. package/template/shared/conversation-admission.js +2 -0
  558. package/template/shared/conversation-provenance.js +3 -7
  559. package/template/shared/conversation-storage-v2-contract.js +47 -6
  560. package/template/shared/fixtures/worker-status-payloads.json +392 -0
  561. package/template/shared/git-remote-key.js +83 -0
  562. package/template/shared/host-identity.js +98 -2
  563. package/template/shared/linked-worktree.js +51 -0
  564. package/template/shared/macos-fda-target.js +57 -0
  565. package/template/shared/orphan-parents.js +55 -0
  566. package/template/shared/owner-write-safety.js +135 -0
  567. package/template/shared/public-runtime.js +13 -5
  568. package/template/shared/release-schema.json +3 -2
  569. package/template/shared/report-citations.js +14 -0
  570. package/template/shared/sqlite-write-lock.js +361 -223
  571. package/template/shared/storage/contract.js +38 -3
  572. package/template/wall-e/adapters/imessage.js +12 -0
  573. package/template/wall-e/agent.js +92 -4
  574. package/template/wall-e/api-walle.js +26 -1
  575. package/template/wall-e/bin/brain-purge-legacy-ctm.js +3 -2
  576. package/template/wall-e/bin/train-gemma-e4b-tooluse.js +2 -2
  577. package/template/wall-e/bin/walle-mcp-stdio.js +14 -8
  578. package/template/wall-e/brain/brain-join.js +859 -0
  579. package/template/wall-e/brain/brain-sync-membership.js +20 -0
  580. package/template/wall-e/brain/brain-sync-store.js +131 -77
  581. package/template/wall-e/brain/brain-sync-v2-schema.js +203 -0
  582. package/template/wall-e/brain/brain-sync-v2.js +578 -0
  583. package/template/wall-e/brain/delegate-model-prefs-store.js +13 -4
  584. package/template/wall-e/brain/deterministic-id.js +51 -0
  585. package/template/wall-e/brain/helper-rules-schema.js +129 -0
  586. package/template/wall-e/brain/memories.js +2 -2
  587. package/template/wall-e/brain/migrations.js +91 -28
  588. package/template/wall-e/brain/model-deployment-facts.js +31 -1
  589. package/template/wall-e/brain/model-identity-migration.js +1 -1
  590. package/template/wall-e/brain/owner-call-whitelist.js +39 -7
  591. package/template/wall-e/brain/schema-ensures.js +22 -0
  592. package/template/wall-e/brain/schema.js +45 -85
  593. package/template/wall-e/brain.js +172 -36
  594. package/template/wall-e/chat.js +3 -3
  595. package/template/wall-e/coding/agent-shell-env.js +7 -2
  596. package/template/wall-e/coding/journal-dispatcher.js +51 -0
  597. package/template/wall-e/coding/prompt-bundle.js +66 -21
  598. package/template/wall-e/coding/session-journal.js +28 -40
  599. package/template/wall-e/coding-orchestrator.js +23 -26
  600. package/template/wall-e/config/main-loop-exemptions.json +2 -2
  601. package/template/wall-e/http/admin-api.js +37 -0
  602. package/template/wall-e/http/auth.js +18 -1
  603. package/template/wall-e/http/blog-views-api.js +318 -0
  604. package/template/wall-e/http/gws-api.js +4 -0
  605. package/template/wall-e/http/helper-rules-api.js +327 -0
  606. package/template/wall-e/http/model-admin.js +8 -1
  607. package/template/wall-e/http/model-delegate-pref-admin.js +3 -3
  608. package/template/wall-e/http/model-proxy-providers.js +177 -2
  609. package/template/wall-e/http/model-route-health.js +157 -0
  610. package/template/wall-e/http/sync-api.js +278 -464
  611. package/template/wall-e/http/telemetry-api.js +12 -0
  612. package/template/wall-e/jobs/job-runner.js +28 -1
  613. package/template/wall-e/lib/blog-view-policy.js +88 -0
  614. package/template/wall-e/lib/blog-view-store.js +169 -0
  615. package/template/wall-e/lib/brain-owner-op-priority.js +9 -1
  616. package/template/wall-e/lib/client-config-lock.js +2 -1
  617. package/template/wall-e/lib/coding-journal-writer-child-client.js +67 -18
  618. package/template/wall-e/lib/ctm-data-dir.js +26 -0
  619. package/template/wall-e/lib/derivation-home.js +147 -0
  620. package/template/wall-e/lib/error-kinds.js +10 -1
  621. package/template/wall-e/lib/feature-manifest.js +1 -1
  622. package/template/wall-e/lib/helper-rules/cell-state.js +123 -0
  623. package/template/wall-e/lib/helper-rules/evaluate.js +398 -0
  624. package/template/wall-e/lib/helper-rules/explore-rubric.md +12 -0
  625. package/template/wall-e/lib/helper-rules/grade.js +320 -0
  626. package/template/wall-e/lib/helper-rules/label.js +247 -0
  627. package/template/wall-e/lib/helper-rules/lead-call-hook.js +555 -0
  628. package/template/wall-e/lib/helper-rules/store.js +669 -0
  629. package/template/wall-e/lib/landing-mcp-tools.js +170 -0
  630. package/template/wall-e/lib/mcp-client-config.js +133 -14
  631. package/template/wall-e/lib/mcp-gateway-migrate.js +28 -64
  632. package/template/wall-e/lib/mcp-integration.js +63 -19
  633. package/template/wall-e/lib/parent-death.js +7 -1
  634. package/template/wall-e/lib/runtime-worker-pool.js +1 -0
  635. package/template/wall-e/lib/scheduler-worker-jobs.js +12 -4
  636. package/template/wall-e/lib/telemetry-db-schema.js +37 -0
  637. package/template/wall-e/lib/telemetry-process-client.js +76 -1
  638. package/template/wall-e/llm/default-fallback.js +4 -0
  639. package/template/wall-e/llm/delegate-lead-prefs.js +16 -1
  640. package/template/wall-e/llm/delegate-vendor-default.js +12 -5
  641. package/template/wall-e/llm/model-catalog.js +13 -4
  642. package/template/wall-e/llm/model-roles.js +7 -1
  643. package/template/wall-e/llm/native-delegate-selection.js +56 -8
  644. package/template/wall-e/llm/portkey-http.js +150 -0
  645. package/template/wall-e/llm/portkey-sync.js +15 -145
  646. package/template/wall-e/llm/worker-delegate-args.js +72 -7
  647. package/template/wall-e/llm/worker-mcp-routing.js +117 -7
  648. package/template/wall-e/llm/worker-route.js +43 -1
  649. package/template/wall-e/loops/brain-custom-writes.js +64 -0
  650. package/template/wall-e/loops/ingest.js +17 -1
  651. package/template/wall-e/loops/think.js +19 -4
  652. package/template/wall-e/mcp-contract.js +222 -6
  653. package/template/wall-e/mcp-protocol-contract.js +77 -2
  654. package/template/wall-e/mcp-server.js +141 -31
  655. package/template/wall-e/mcp-worker-schemas.js +25 -7
  656. package/template/wall-e/memory/ctm-context-client.js +110 -5
  657. package/template/wall-e/memory/ctm-session-context.js +9 -3
  658. package/template/wall-e/memory/hub-bridge-client.js +388 -0
  659. package/template/wall-e/memory/replica-origin.js +56 -0
  660. package/template/wall-e/memory/session-pool.js +135 -0
  661. package/template/wall-e/runtime/live-capabilities.js +8 -3
  662. package/template/wall-e/server.js +4 -2
  663. package/template/wall-e/shared/release-schema.json +3 -2
  664. package/template/wall-e/shared/sqlite-file-set.js +39 -0
  665. package/template/wall-e/shared/sqlite-write-lock.js +361 -223
  666. package/template/wall-e/shared/storage/contract.js +38 -3
  667. package/template/wall-e/skills/_templates/delegate-worker/VERSION +1 -1
  668. package/template/wall-e/skills/_templates/delegate-worker/released-sha256.json +13 -1
  669. package/template/wall-e/skills/_templates/delegate-worker/templates/claude/SKILL.md +11 -6
  670. package/template/wall-e/skills/_templates/delegate-worker/templates/codex/SKILL.md +13 -8
  671. package/template/wall-e/skills/_templates/fleet-sync/VERSION +1 -0
  672. package/template/wall-e/skills/_templates/fleet-sync/released-sha256.json +16 -0
  673. package/template/wall-e/skills/_templates/fleet-sync/templates/claude/SKILL.md +64 -0
  674. package/template/wall-e/skills/_templates/fleet-sync/templates/codex/SKILL.md +64 -0
  675. package/template/wall-e/tools/chrome-automation.js +6 -0
  676. package/template/wall-e/tools/local-tools.js +6 -4
  677. package/template/wall-e/training/setup-cuda-train-env.sh +2 -2
  678. package/template/wall-e/workers/brain-owner-worker.js +27 -4
  679. package/template/wall-e/workers/coding-journal-writer-child.js +8 -1
  680. package/template/wall-e/workers/mcp-gateway-process.js +5 -5
  681. package/template/wall-e/workers/telemetry-worker.js +8 -0
@@ -0,0 +1,721 @@
1
+ 'use strict';
2
+
3
+ // WP-1/WP-3 (docs/remote-session-hub-bridge-2026-10-30.html §5 R-3/R-12, §6.4, §8 WP-1/WP-3;
4
+ // docs/cross-machine-session-context-2026-10-31.html §5 R-3/R-5/R-8, §6.3, §8 WP-3): the HUB-side
5
+ // READ ops a box asks for over the WP-0 lane (lib/hub-bridge.js `handleRequest`).
6
+ //
7
+ // session.context resolve ONE session id ANYWHERE in the pool and answer with it — the hub order
8
+ // of lib/session-context-locator.js (local -> directory owner -> parallel probe),
9
+ // minus the calling machine, which already read locally.
10
+ // session.read the same resolution, projected for a reader (R-9): role/at/kind/text only.
11
+ //
12
+ // R-3: the resolver is lib/session-context-locator.js; its LOCAL leg is INJECTED
13
+ // (`deps.readSessionContext`) and in production is the SAME off-thread read-pool runner
14
+ // `/api/ctm/session-memory/context` uses, so a full session-context read (multiple FTS/LIKE scans +
15
+ // a JSON.parse of matched conversations) never runs on the hub's main loop for a remote caller.
16
+ // R-12: an optional `machine` target is ACCEPTED AND IGNORED here — target selection is WP-5's.
17
+ //
18
+ // Every refusal is a NAMED code (`session_ref_invalid`, `session_on_caller`, `session_not_found`,
19
+ // `session_read_unavailable`) carried on the thrown error's `code`, which lib/hub-bridge.js maps into
20
+ // the error frame. The old `session_on_other_machine` is GONE (WP-3): a session that lives on another
21
+ // machine is now forwarded to, not refused.
22
+
23
+ // The SAME identity parser the search box uses (a hub link's `#session=<id>` / `review=<id>` / bare
24
+ // uuid), so a ref that the UI accepts is a ref this op accepts — including URL-encoded variants.
25
+ const SessionSearchUtils = require('../public/js/session-search-utils');
26
+
27
+ const childProcess = require('node:child_process');
28
+ const fs = require('node:fs');
29
+ const os = require('node:os');
30
+ const path = require('node:path');
31
+
32
+ const DEFAULT_MAX_MESSAGES = 40;
33
+ const MAX_MESSAGES = 200;
34
+ // WP-3 (§6.3, R-8): the byte ceiling a session read asks the resolver for — HALF the bridge lane's
35
+ // own 1 MiB RESULT_MAX_BYTES (lib/hub-bridge.js), so an answer can never be truncated in flight.
36
+ const SESSION_CONTEXT_BYTE_LIMIT = 512 * 1024;
37
+ // WP-4 (§6.3): the pool-search args a box may ask for. `limit` is the RESULT-ROW budget the hub
38
+ // merges into; the deadline bounds the off-thread read the hub runs on the caller's behalf.
39
+ const SESSION_SEARCH_DEFAULT_LIMIT = 10;
40
+ const SESSION_SEARCH_MAX_LIMIT = 50;
41
+ const SESSION_SEARCH_TIMEOUT_MS = 20000;
42
+
43
+ // WP-2 (docs/remote-session-hub-bridge-2026-10-30.html §5 R-4/R-8, §6.4, §8 WP-2): the host ops a
44
+ // GRANTED box session asks the hub to run — `fs.read`, `fs.list` (tier `read`) and `exec` (tier
45
+ // `exec`). R-8 bounds them the same way the lane bounds everything: <= 1 MiB of file, <= 2000
46
+ // directory entries, <= 16 KiB of command, <= 256 KiB of each output stream, <= 120 s of wall clock.
47
+ // Deliberately NO command denylist (design anti-goal): the boundary is the user's GRANT, not a
48
+ // string filter.
49
+ const FS_READ_CAP_BYTES = 1024 * 1024;
50
+ const FS_READ_DEFAULT_LIMIT = 2000;
51
+ const FS_READ_MAX_LIMIT = 2000;
52
+ const FS_LIST_MAX_ENTRIES = 2000;
53
+ const EXEC_MAX_COMMAND_BYTES = 16 * 1024;
54
+ const EXEC_DEFAULT_TIMEOUT_MS = 30000;
55
+ const EXEC_MAX_TIMEOUT_MS = 120000;
56
+ const EXEC_OUTPUT_CAP_BYTES = 256 * 1024;
57
+ const EXEC_KILL_GRACE_MS = 1000;
58
+ // A box-requested command runs as the hub USER, not as the hub's CTM: CTM's own runtime env (the
59
+ // peer token, the Wall-E bearer, CTM_PORT/CTM_DATA_DIR that would make a nested `ctm`/`land` call
60
+ // speak as this server) is not handed to it. The user's login shell (`-lc`) still sets up PATH etc.
61
+ const EXEC_ENV_DROP_RE = /^(CTM_|WALLE_|WALL_E_)/;
62
+
63
+ /** process.env minus CTM's own runtime keys (EXEC_ENV_DROP_RE). Pure. */
64
+ function execChildEnv(parentEnv = process.env) {
65
+ const out = {};
66
+ for (const [key, value] of Object.entries(parentEnv || {})) {
67
+ if (!EXEC_ENV_DROP_RE.test(key)) out[key] = value;
68
+ }
69
+ return out;
70
+ }
71
+
72
+ /** Clamp a possibly-junk numeric arg into [min, max] with `fallback` for a non-number. */
73
+ function clampInt(value, fallback, min, max) {
74
+ const n = Number(value);
75
+ if (!Number.isFinite(n)) return fallback;
76
+ return Math.min(max, Math.max(min, Math.trunc(n)));
77
+ }
78
+
79
+ /** `*` / `?` name glob -> predicate, or null for "match everything". Deliberately not a path glob. */
80
+ function compileNameGlob(glob) {
81
+ const raw = String(glob == null ? '' : glob);
82
+ if (!raw) return null;
83
+ const escaped = raw.replace(/[.+^${}()|[\]\\]/g, '\\$&').replace(/\*/g, '.*').replace(/\?/g, '.');
84
+ const re = new RegExp(`^${escaped}$`);
85
+ return (name) => re.test(name);
86
+ }
87
+
88
+ /** dirent -> the wire's three-value type, then its size (lstat for a link, so a dangling one still works). */
89
+ async function _entrySize(fullPath, dirent) {
90
+ try {
91
+ const stat = dirent.isSymbolicLink() ? await fs.promises.lstat(fullPath) : await fs.promises.stat(fullPath);
92
+ return Number(stat.size) || 0;
93
+ } catch {
94
+ // REPORT via 0: an entry that vanished or is unreadable between readdir and stat keeps its row.
95
+ return 0;
96
+ }
97
+ }
98
+
99
+
100
+ /** A refusal as the lane speaks it: the code rides the error, never the message. */
101
+ function _namedError(code, message) {
102
+ return Object.assign(new Error(message), { code });
103
+ }
104
+
105
+ /**
106
+ * Clamp `max_messages`: default 40, hard max 200 (§6.4). A missing/blank/non-numeric value is the
107
+ * default; a numeric value is truncated to a whole number and pinned into [1, 200].
108
+ */
109
+ function clampMaxMessages(value) {
110
+ if (value === undefined || value === null || value === '') return DEFAULT_MAX_MESSAGES;
111
+ const n = Number(value);
112
+ if (!Number.isFinite(n)) return DEFAULT_MAX_MESSAGES;
113
+ return Math.min(MAX_MESSAGES, Math.max(1, Math.trunc(n)));
114
+ }
115
+
116
+ /**
117
+ * The byte count of a message whose payload was NOT persisted (an over-cap envelope carries
118
+ * `payload.raw_bytes` — wall-e/memory/session-context-page.js `oversizedEnvelope`; the paged/
119
+ * grouped variants carry `raw_bytes_at_least`). 0 when the envelope has neither, so the box
120
+ * always reads a number.
121
+ */
122
+ function omittedByteCount(message) {
123
+ const payload = message && typeof message.payload === 'object' && message.payload ? message.payload : {};
124
+ for (const key of ['raw_bytes', 'raw_bytes_at_least']) {
125
+ const raw = payload[key];
126
+ if (raw === undefined || raw === null) continue;
127
+ const n = Number(raw);
128
+ if (Number.isFinite(n) && n >= 0) return Math.trunc(n);
129
+ }
130
+ const direct = Number(message && message.bytes);
131
+ return Number.isFinite(direct) && direct >= 0 ? Math.trunc(direct) : 0;
132
+ }
133
+
134
+ /**
135
+ * The message projection the box gets (R-9): role/time/kind/text, nothing else crosses the lane.
136
+ * Two deliberate drops:
137
+ * - `kind: 'reasoning_hidden'` rows are stored with EMPTY text by design (a hidden/encrypted
138
+ * reasoning placeholder — conversation-store-v2 admits `text: ''` only for this kind), so
139
+ * every one of them was a `text: ''` row crowding the caller's message budget.
140
+ * - a row whose content was not persisted (the over-cap envelope: no string `content`, an
141
+ * `omitted: true` marker, and a byte count) is reported as `{ omitted: true, bytes }` rather
142
+ * than an empty `text`. It stays in the projection (it IS a real turn) but says so.
143
+ * `max_messages` counts KEPT messages, so hidden rows never consume the budget.
144
+ */
145
+ function projectMessages(context, { query, maxMessages }) {
146
+ const raw = Array.isArray(context && context.messages) ? context.messages : [];
147
+ const needle = String(query || '').trim().toLowerCase();
148
+ const kept = [];
149
+ for (const message of raw) {
150
+ if (!message || typeof message !== 'object') continue;
151
+ if (message.kind === 'reasoning_hidden') continue; // stored empty by design; never projected
152
+ const role = String(message.role || '');
153
+ const at = message.timestamp || message.created_at || '';
154
+ const kind = typeof message.kind === 'string' ? message.kind : '';
155
+ const omitted = message.omitted === true || typeof message.content !== 'string';
156
+ if (needle) {
157
+ // A row with no persisted text cannot contain the needle — same outcome the old
158
+ // `text.toLowerCase().includes(needle)` had for it, without claiming it is empty content.
159
+ if (omitted) continue;
160
+ if (!message.content.toLowerCase().includes(needle)) continue;
161
+ }
162
+ kept.push(omitted
163
+ ? { role, at, kind, omitted: true, bytes: omittedByteCount(message) }
164
+ : { role, at, kind, text: message.content });
165
+ }
166
+ // Newest LAST (orderMessages already sorts ascending; the slice keeps the tail = the newest).
167
+ const dropped = Math.max(0, kept.length - maxMessages);
168
+ return {
169
+ messages: kept.slice(kept.length - Math.min(kept.length, maxMessages)),
170
+ truncated: dropped > 0
171
+ || Boolean(context && context.has_more)
172
+ || Boolean(context && context.truncated_reason),
173
+ };
174
+ }
175
+
176
+ /**
177
+ * R-1 (§6.3): `args.ref` -> the session id, or the named refusal the lane speaks. The parser is the
178
+ * SAME one the search box uses (a hub link's `#session=<id>` / `review=<id>` / bare uuid), so a ref
179
+ * the UI accepts is a ref this op accepts.
180
+ */
181
+ function parseSessionRef(ref) {
182
+ const parsed = SessionSearchUtils.parseSessionIdentityQuery(typeof ref === 'string' ? ref : '');
183
+ const sessionId = parsed.sessionIds.length ? parsed.sessionIds[0] : '';
184
+ if (!sessionId) {
185
+ throw _namedError('session_ref_invalid', 'ref must name a session id (a bare id, review=<id>, or a URL containing one)');
186
+ }
187
+ return sessionId;
188
+ }
189
+
190
+ /** The frame's caller machine (lib/hub-bridge.js `callCtx.machineInstanceId`), '' when unknown. */
191
+ function callerMachineId(callCtx) {
192
+ return String((callCtx && callCtx.machineInstanceId) || '');
193
+ }
194
+
195
+ /**
196
+ * WP-3 (§6.3): is `sessionId` owned by the CALLING machine, per the directory? The caller already
197
+ * read locally, so a hub round-trip would only mirror its own miss back at it. An ownership resolver
198
+ * fault is REPORTED as "not the caller" — the resolver below then names its own outcome.
199
+ */
200
+ function ownerIsCaller(sessionId, deps, caller) {
201
+ if (!caller) return false;
202
+ try {
203
+ const located = require('./session-context-locator').locateSessionOwner(sessionId, deps);
204
+ return located.owner === 'machine' && String(located.machine.instanceId || '') === caller;
205
+ } catch {
206
+ return false; // REPORT: the directory could not speak -> never claim the caller owns it
207
+ }
208
+ }
209
+
210
+ /** A reader that could not run is a NAMED refusal, never "no such session" (AC-1b). */
211
+ function readLocalThrough(readSessionContext, args) {
212
+ return Promise.resolve(readSessionContext(args)).then((local) => {
213
+ if (local && typeof local === 'object' && local.ok === false) {
214
+ throw _namedError(
215
+ 'session_read_unavailable',
216
+ `the hub session reader failed for ${args.session_id}: ${local.reason || 'unknown'}`,
217
+ );
218
+ }
219
+ return local;
220
+ });
221
+ }
222
+
223
+ /**
224
+ * The ONE resolver call both session ops make (R-3/R-5): the hub order with the caller's machine
225
+ * excluded from the probe, read locally through the injected reader. Resolves to the context body +
226
+ * `location`, a `found:false` + `searched` miss, or `null` when the local read was deferred.
227
+ * `deps` rides through to lib/session-context-locator.js, so a host (or a test) can inject
228
+ * `forward` / `machineRows` / `localIdentity` alongside the reader.
229
+ */
230
+ function resolveSession(sessionId, args, callCtx, deps) {
231
+ const readSessionContext = deps.readSessionContext;
232
+ if (typeof readSessionContext !== 'function') {
233
+ throw _namedError('session_read_unavailable', 'no session reader is configured on this hub');
234
+ }
235
+ return require('./session-context-locator').readSessionContextAnywhere(
236
+ {
237
+ args: {
238
+ session_id: sessionId,
239
+ turn_limit: args.turn_limit,
240
+ byte_limit: clampInt(args.byte_limit, SESSION_CONTEXT_BYTE_LIMIT, 1024, SESSION_CONTEXT_BYTE_LIMIT),
241
+ cursor: args.cursor,
242
+ direction: args.direction,
243
+ format: 'messages',
244
+ projection: 'envelope',
245
+ scope: 'pool',
246
+ },
247
+ excludeMachineId: callerMachineId(callCtx),
248
+ },
249
+ { ...deps, readLocal: (localArgs) => readLocalThrough(readSessionContext, localArgs) },
250
+ );
251
+ }
252
+
253
+ /** A null resolver result is "the reader never answered" — never "no such session" (AC-1b). */
254
+ function assertResolverAnswered(result, sessionId) {
255
+ if (result == null) {
256
+ throw _namedError('session_read_unavailable', `the hub session reader did not answer for ${sessionId}`);
257
+ }
258
+ return result;
259
+ }
260
+
261
+ /** R-5: a caller that owns the ref gets its own machine named back, never a wasted probe. */
262
+ function callerMissEnvelope(caller) {
263
+ return {
264
+ ok: true, found: false, sessions: [], messages: [], searched: [{ machine_id: caller, machine_name: '', status: 'caller' }],
265
+ };
266
+ }
267
+
268
+ /**
269
+ * WP-3 (§6.3): `session.context` — resolve ONE session id anywhere in the pool and answer with the
270
+ * resolver's body (`location`, or `found:false` + `searched`).
271
+ */
272
+ function createSessionContextOp(deps = {}) {
273
+ return {
274
+ tier: 'none',
275
+ run: async (rawArgs, callCtx = {}) => {
276
+ const args = rawArgs && typeof rawArgs === 'object' ? rawArgs : {};
277
+ const sessionId = parseSessionRef(args.ref);
278
+ const caller = callerMachineId(callCtx);
279
+ if (ownerIsCaller(sessionId, deps, caller)) return callerMissEnvelope(caller);
280
+ return assertResolverAnswered(await resolveSession(sessionId, args, callCtx, deps), sessionId);
281
+ },
282
+ };
283
+ }
284
+
285
+ /**
286
+ * WP-3 (§6.3/R-9): `session.read` — the SAME resolver, projected for a reader: role/at/kind/text
287
+ * only, `machine` = the machine that answered (`location.machine_name`). A not-found-anywhere read
288
+ * names every `searched` machine in its message.
289
+ */
290
+ function createSessionReadOp(deps = {}) {
291
+ return {
292
+ tier: 'none',
293
+ // `args.machine` (R-12) is deliberately unread: WP-5 owns cross-machine targeting.
294
+ // `callCtx` is the frame context lib/hub-bridge.js passes as the SECOND argument
295
+ // ({ machineInstanceId, callerSessionId, … }).
296
+ run: async (rawArgs, callCtx = {}) => {
297
+ const args = rawArgs && typeof rawArgs === 'object' ? rawArgs : {};
298
+ const sessionId = parseSessionRef(args.ref);
299
+ const caller = callerMachineId(callCtx);
300
+ // The caller IS that machine: the row is on the caller's own disk, so a hub round-trip is the
301
+ // wrong tool — name that outcome instead.
302
+ if (ownerIsCaller(sessionId, deps, caller)) {
303
+ throw _namedError('session_on_caller', `session ${sessionId} lives on the calling machine; read it locally with walle_get_session`);
304
+ }
305
+ const context = assertResolverAnswered(await resolveSession(sessionId, args, callCtx, deps), sessionId);
306
+ const sessions = Array.isArray(context.sessions) ? context.sessions : [];
307
+ if (!sessions.length) throw _namedError('session_not_found', _notFoundMessage(sessionId, context));
308
+ const summary = sessions[0] || {};
309
+ const projected = projectMessages(context, { query: args.query, maxMessages: clampMaxMessages(args.max_messages) });
310
+ return {
311
+ session: {
312
+ id: String(summary.ctm_session_id || summary.session_id || sessionId),
313
+ title: String(summary.title || ''),
314
+ agent: String(summary.provider || ''),
315
+ cwd: String(summary.cwd || ''),
316
+ machine: String((context.location && context.location.machine_name) || ''),
317
+ },
318
+ messages: projected.messages,
319
+ truncated: projected.truncated,
320
+ };
321
+ },
322
+ };
323
+ }
324
+
325
+ /** R-5: a miss names every machine that was asked and what each answered. */
326
+ function _notFoundMessage(sessionId, context) {
327
+ const searched = Array.isArray(context && context.searched) ? context.searched : [];
328
+ const named = searched
329
+ .map((entry) => `${String(entry.machine_name || entry.machine_id || 'unknown')} (${String(entry.status || '')})`)
330
+ .join(', ');
331
+ return `no session ${sessionId} on ${named || 'any machine in this pool'}`;
332
+ }
333
+
334
+ /**
335
+ * WP-4 (§6.3): `session.search` — R-7 pool search, asked by a box over the lane. The hub runs its OWN
336
+ * search (local + one `scope=local` GET per dialable member) and answers the RRF-merged rows with a
337
+ * per-machine `machines` list. `excludeMachineId` is the CALLER's machine: it already searched
338
+ * locally, so the hub never dials it back.
339
+ */
340
+ function createSessionSearchOp(deps = {}) {
341
+ return {
342
+ tier: 'none',
343
+ run: async (rawArgs, callCtx = {}) => {
344
+ const args = rawArgs && typeof rawArgs === 'object' ? rawArgs : {};
345
+ const searchSessions = typeof deps.searchSessions === 'function' ? deps.searchSessions : defaultSearchSessions;
346
+ const result = await require('./session-context-locator').searchSessionsAnywhere(
347
+ {
348
+ query: String(args.query == null ? '' : args.query),
349
+ limit: clampInt(args.limit, SESSION_SEARCH_DEFAULT_LIMIT, 1, SESSION_SEARCH_MAX_LIMIT),
350
+ excludeMachineId: callerMachineId(callCtx),
351
+ scope: 'pool',
352
+ },
353
+ { ...deps, searchLocal: (localArgs) => readSearchThrough(searchSessions, localArgs) },
354
+ );
355
+ // A searcher that never answered is a NAMED refusal, never "nothing matched" (AC-1b idiom).
356
+ if (result == null) throw _namedError('session_search_unavailable', 'the hub session search did not answer');
357
+ return result;
358
+ },
359
+ };
360
+ }
361
+
362
+ /**
363
+ * R-7 production search leg: the SAME off-thread read-pool op `/api/ctm/session-memory/search`
364
+ * runs (server.js `_runCtmSessionMemoryOffThread('ctmSessionMemorySearch', …)`), reached through the
365
+ * process-wide active read pool. server.js is file-size frozen and injects only
366
+ * `readSessionContext`, so this default is resolved LAZILY here — the heavy search never runs on the
367
+ * hub's main loop for a remote caller, and requiring this module from a unit test never wires it.
368
+ */
369
+ function defaultSearchSessions(args = {}) {
370
+ let dbPath = '';
371
+ try {
372
+ dbPath = String(require('../db').getDbPath() || '');
373
+ } catch {
374
+ // REPORT: no DB bound yet (or an unusable module) -> the pool op answers its own named failure.
375
+ dbPath = '';
376
+ }
377
+ return require('./read-pool-client').requestOnActiveReadPool(
378
+ 'ctmSessionMemorySearch',
379
+ { dbPath, args },
380
+ { timeoutMs: SESSION_SEARCH_TIMEOUT_MS },
381
+ );
382
+ }
383
+
384
+ /** A searcher that could not run is a NAMED refusal, never "nothing matched" (AC-1b). */
385
+ function readSearchThrough(searchSessions, args) {
386
+ return Promise.resolve(searchSessions(args)).then((local) => {
387
+ if (local && typeof local === 'object' && local.ok === false && local.reason) {
388
+ throw _namedError(
389
+ 'session_search_unavailable',
390
+ `the hub session search failed for "${args.query}": ${local.reason}`,
391
+ );
392
+ }
393
+ return local;
394
+ });
395
+ }
396
+
397
+ /**
398
+ * Register the WP-1/WP-3/WP-4 read ops (`session.context`, `session.read`, `session.search`) on a hub
399
+ * bridge (lib/hub-bridge.js). `deps.readSessionContext(args)` is required; `deps.getMirrorSessionMachine(id)`
400
+ * and the other locator deps are optional and default to the locator's own production wiring.
401
+ * `deps.searchSessions(args)` is optional too: omitted, the op reads through the active off-thread
402
+ * read pool (`defaultSearchSessions`).
403
+ */
404
+ function registerSessionOps(hubBridge, deps = {}) {
405
+ if (!hubBridge || typeof hubBridge.registerOp !== 'function') {
406
+ throw new TypeError('registerSessionOps: hubBridge.registerOp must be a function');
407
+ }
408
+ hubBridge.registerOp('session.context', createSessionContextOp(deps));
409
+ hubBridge.registerOp('session.read', createSessionReadOp(deps));
410
+ hubBridge.registerOp('session.search', createSessionSearchOp(deps));
411
+ return hubBridge;
412
+ }
413
+
414
+ /**
415
+ * WP-2 (§6.4): `fs.read` — read ONE file on the hub the caller was granted `read` for.
416
+ * Args `{ path (absolute), offset? (0-based first line), limit? (lines, default/max 2000) }`.
417
+ * Returns `{ path, lines, total_lines, truncated }`. A path that is not absolute, or is a directory,
418
+ * is a NAMED refusal; a file over 1 MiB is read to the cap and reported `truncated: true`.
419
+ */
420
+ function createFsReadOp(deps = {}) {
421
+ const fsPromises = deps.fsPromises || fs.promises;
422
+ return {
423
+ tier: 'read',
424
+ run: async (rawArgs) => {
425
+ const args = rawArgs && typeof rawArgs === 'object' ? rawArgs : {};
426
+ const target = typeof args.path === 'string' ? args.path : '';
427
+ if (!target) throw _namedError('path_required', 'path is required');
428
+ if (!path.isAbsolute(target)) throw _namedError('path_not_absolute', `path must be absolute: ${target}`);
429
+ let stat = null;
430
+ try {
431
+ stat = await fsPromises.stat(target);
432
+ } catch {
433
+ throw _namedError('path_not_found', `no such file: ${target}`);
434
+ }
435
+ if (stat.isDirectory()) throw _namedError('path_is_directory', `path is a directory, not a file: ${target}`);
436
+
437
+ const offset = clampInt(args.offset, 0, 0, Number.MAX_SAFE_INTEGER);
438
+ const limit = clampInt(args.limit, FS_READ_DEFAULT_LIMIT, 1, FS_READ_MAX_LIMIT);
439
+ const bytes = Math.max(0, Math.min(Number(stat.size) || 0, FS_READ_CAP_BYTES));
440
+ const buffer = Buffer.alloc(bytes);
441
+ if (bytes > 0) {
442
+ const handle = await fsPromises.open(target, 'r');
443
+ try {
444
+ await handle.read(buffer, 0, bytes, 0);
445
+ } finally {
446
+ try { await handle.close(); } catch { /* expected: the handle is released with the process */ }
447
+ }
448
+ }
449
+ const fileTruncated = (Number(stat.size) || 0) > FS_READ_CAP_BYTES;
450
+ const lines = buffer.toString('utf8').split('\n');
451
+ // A capped read ends mid-line as often as not: drop the trailing fragment rather than return a
452
+ // half-line, and let `truncated` carry the truth.
453
+ if (fileTruncated && lines.length) lines.pop();
454
+ const total = lines.length;
455
+ const sliced = lines.slice(offset, offset + limit);
456
+ return {
457
+ path: target,
458
+ lines: sliced,
459
+ total_lines: total,
460
+ truncated: fileTruncated || offset + sliced.length < total,
461
+ };
462
+ },
463
+ };
464
+ }
465
+
466
+ /**
467
+ * WP-2 (§6.4): `fs.list` — list ONE directory on the hub (tier `read`). Args `{ path, glob? }`; the
468
+ * glob is a simple `*`/`?` match on the entry NAME (never a path glob). At most 2000 entries.
469
+ */
470
+ function createFsListOp(deps = {}) {
471
+ const fsPromises = deps.fsPromises || fs.promises;
472
+ return {
473
+ tier: 'read',
474
+ run: async (rawArgs) => {
475
+ const args = rawArgs && typeof rawArgs === 'object' ? rawArgs : {};
476
+ const target = typeof args.path === 'string' ? args.path : '';
477
+ if (!target) throw _namedError('path_required', 'path is required');
478
+ if (!path.isAbsolute(target)) throw _namedError('path_not_absolute', `path must be absolute: ${target}`);
479
+ let stat = null;
480
+ try {
481
+ stat = await fsPromises.stat(target);
482
+ } catch {
483
+ throw _namedError('path_not_found', `no such directory: ${target}`);
484
+ }
485
+ if (!stat.isDirectory()) throw _namedError('path_not_a_directory', `path is not a directory: ${target}`);
486
+
487
+ const matches = compileNameGlob(args.glob);
488
+ const dirents = await fsPromises.readdir(target, { withFileTypes: true });
489
+ const entries = [];
490
+ let truncated = false;
491
+ for (const dirent of dirents) {
492
+ if (matches && !matches(dirent.name)) continue;
493
+ if (entries.length >= FS_LIST_MAX_ENTRIES) {
494
+ truncated = true;
495
+ break;
496
+ }
497
+ const type = dirent.isDirectory() ? 'dir' : dirent.isSymbolicLink() ? 'link' : 'file';
498
+ entries.push({ name: dirent.name, type, size: await _entrySize(path.join(target, dirent.name), dirent) });
499
+ }
500
+ return { path: target, entries, truncated };
501
+ },
502
+ };
503
+ }
504
+
505
+ /**
506
+ * WP-2 (§6.4): `exec` — run a command on the hub as the hub user (tier `exec`).
507
+ * Args `{ command (<= 16 KiB), cwd? (absolute; default the hub user's home), timeout_ms? (default
508
+ * 30000, max 120000) }`. The child gets its OWN PROCESS GROUP (`detached: true`); at the deadline the
509
+ * whole group is SIGTERMed and, 1 s later, SIGKILLed. Returns
510
+ * `{ exit_code, signal, stdout, stderr, timed_out, truncated, ms }`. Uses spawn's async API — the hub
511
+ * main loop is never blocked.
512
+ */
513
+ function createExecOp(deps = {}) {
514
+ const spawnFn = deps.spawn || childProcess.spawn;
515
+ const platform = deps.platform || process.platform;
516
+ const homedir = deps.homedir || os.homedir;
517
+ const now = deps.now || (() => Date.now());
518
+ const killFn = deps.kill || ((pid, signal) => process.kill(pid, signal));
519
+ const fsPromises = deps.fsPromises || fs.promises;
520
+ const parentEnv = deps.env || process.env;
521
+ const shell = platform === 'darwin' ? '/bin/zsh' : '/bin/bash';
522
+
523
+ return {
524
+ tier: 'exec',
525
+ run: async (rawArgs) => {
526
+ const args = rawArgs && typeof rawArgs === 'object' ? rawArgs : {};
527
+ const command = typeof args.command === 'string' ? args.command : '';
528
+ if (!command.trim()) throw _namedError('exec_failed', 'command is required');
529
+ if (Buffer.byteLength(command, 'utf8') > EXEC_MAX_COMMAND_BYTES) {
530
+ throw _namedError('args_too_large', `command exceeds ${EXEC_MAX_COMMAND_BYTES} bytes`);
531
+ }
532
+ const cwd = args.cwd === undefined || args.cwd === null || args.cwd === '' ? homedir() : String(args.cwd);
533
+ if (!path.isAbsolute(cwd)) throw _namedError('cwd_not_absolute', `cwd must be absolute: ${cwd}`);
534
+ let cwdStat = null;
535
+ try {
536
+ cwdStat = await fsPromises.stat(cwd);
537
+ } catch {
538
+ throw _namedError('cwd_not_found', `cwd does not exist: ${cwd}`);
539
+ }
540
+ if (!cwdStat.isDirectory()) throw _namedError('cwd_not_a_directory', `cwd is not a directory: ${cwd}`);
541
+ const timeoutMs = clampInt(args.timeout_ms, EXEC_DEFAULT_TIMEOUT_MS, 1, EXEC_MAX_TIMEOUT_MS);
542
+ const startedAt = now();
543
+
544
+ return await new Promise((resolve, reject) => {
545
+ let child = null;
546
+ try {
547
+ child = spawnFn(shell, ['-lc', command], {
548
+ cwd,
549
+ env: execChildEnv(parentEnv),
550
+ // R-8: its OWN process group, so the deadline can take out a whole pipeline, not just zsh.
551
+ detached: true,
552
+ stdio: ['ignore', 'pipe', 'pipe'],
553
+ });
554
+ } catch (error) {
555
+ reject(_namedError('exec_failed', `could not start ${shell}: ${String((error && error.message) || error)}`));
556
+ return;
557
+ }
558
+
559
+ const collected = { stdout: '', stderr: '', outBytes: 0, errBytes: 0, truncated: false };
560
+ const onChunk = (streamName, chunk) => {
561
+ const text = Buffer.isBuffer(chunk) ? chunk.toString('utf8') : String(chunk);
562
+ const bytesField = streamName === 'stdout' ? 'outBytes' : 'errBytes';
563
+ const left = EXEC_OUTPUT_CAP_BYTES - collected[bytesField];
564
+ if (left <= 0) {
565
+ collected.truncated = true;
566
+ return;
567
+ }
568
+ if (Buffer.byteLength(text, 'utf8') > left) {
569
+ collected.truncated = true;
570
+ collected[streamName] += Buffer.from(text, 'utf8').subarray(0, left).toString('utf8');
571
+ collected[bytesField] = EXEC_OUTPUT_CAP_BYTES;
572
+ return;
573
+ }
574
+ collected[streamName] += text;
575
+ collected[bytesField] += Buffer.byteLength(text, 'utf8');
576
+ };
577
+ if (child.stdout) child.stdout.on('data', (chunk) => onChunk('stdout', chunk));
578
+ if (child.stderr) child.stderr.on('data', (chunk) => onChunk('stderr', chunk));
579
+
580
+ let timedOut = false;
581
+ let sigkillTimer = null;
582
+ const timer = setTimeout(() => {
583
+ timedOut = true;
584
+ try {
585
+ killFn(-child.pid, 'SIGTERM');
586
+ } catch {
587
+ // expected: the group is already gone (the command finished inside the same tick).
588
+ }
589
+ sigkillTimer = setTimeout(() => {
590
+ try {
591
+ killFn(-child.pid, 'SIGKILL');
592
+ } catch {
593
+ // expected: SIGTERM already reaped the group.
594
+ }
595
+ }, EXEC_KILL_GRACE_MS);
596
+ if (sigkillTimer && typeof sigkillTimer.unref === 'function') sigkillTimer.unref();
597
+ }, timeoutMs);
598
+
599
+ child.on('error', (error) => {
600
+ clearTimeout(timer);
601
+ if (sigkillTimer) clearTimeout(sigkillTimer);
602
+ reject(_namedError('exec_failed', String((error && error.message) || error)));
603
+ });
604
+ // `close` (not `exit`) so both pipes are fully flushed before the result is assembled.
605
+ child.on('close', (code, signal) => {
606
+ clearTimeout(timer);
607
+ if (sigkillTimer) clearTimeout(sigkillTimer);
608
+ resolve({
609
+ exit_code: code === null || code === undefined ? null : Number(code),
610
+ signal: signal || null,
611
+ stdout: collected.stdout,
612
+ stderr: collected.stderr,
613
+ timed_out: timedOut,
614
+ truncated: collected.truncated,
615
+ ms: Math.max(0, now() - startedAt),
616
+ });
617
+ });
618
+ });
619
+ },
620
+ };
621
+ }
622
+
623
+ /**
624
+ * WP-3 (docs/remote-session-hub-bridge-2026-10-30.html §3 P-2, D-4/D-7, §5 R-4, §6.4, §8 WP-3):
625
+ * `mcp.list` — the tool list of one HUB-side MCP server (tier `browser`). Args `{ server }`.
626
+ * The server allowlist and the client lifecycle live in lib/hub-bridge-mcp.js; this op is the lane's
627
+ * thin adapter, so a caller can never name a server that module does not allow.
628
+ */
629
+ function createMcpListOp(deps = {}) {
630
+ const mcp = deps.mcp || require('./hub-bridge-mcp');
631
+ return {
632
+ tier: 'browser',
633
+ run: async (rawArgs) => {
634
+ const args = rawArgs && typeof rawArgs === 'object' ? rawArgs : {};
635
+ const server = typeof args.server === 'string' ? args.server : '';
636
+ const tools = await mcp.listTools(server);
637
+ return { server, tools };
638
+ },
639
+ };
640
+ }
641
+
642
+ /**
643
+ * WP-3 (§6.4): `mcp.call` — run one tool on one HUB-side MCP server (tier `browser`).
644
+ * Args `{ server, tool, arguments? }`. The result is the MCP result `{ content, isError }` (with
645
+ * `truncated: true` when the 1 MiB ceiling trimmed it) — the box sees what the hub's client saw.
646
+ */
647
+ function createMcpCallOp(deps = {}) {
648
+ const mcp = deps.mcp || require('./hub-bridge-mcp');
649
+ return {
650
+ tier: 'browser',
651
+ run: async (rawArgs) => {
652
+ const args = rawArgs && typeof rawArgs === 'object' ? rawArgs : {};
653
+ const server = typeof args.server === 'string' ? args.server : '';
654
+ const tool = typeof args.tool === 'string' ? args.tool : '';
655
+ if (!tool) throw _namedError('mcp_tool_required', 'tool is required');
656
+ return mcp.callTool(server, tool, args.arguments);
657
+ },
658
+ };
659
+ }
660
+
661
+ /**
662
+ * Register the WP-3 MCP ops (`mcp.list`, `mcp.call`) on a hub bridge (lib/hub-bridge.js). Both are
663
+ * tier `browser` — R-4's separate tier, which neither an `exec` nor a `read` grant satisfies.
664
+ */
665
+ function registerMcpOps(hubBridge, deps = {}) {
666
+ if (!hubBridge || typeof hubBridge.registerOp !== 'function') {
667
+ throw new TypeError('registerMcpOps: hubBridge.registerOp must be a function');
668
+ }
669
+ hubBridge.registerOp('mcp.list', createMcpListOp(deps));
670
+ hubBridge.registerOp('mcp.call', createMcpCallOp(deps));
671
+ return hubBridge;
672
+ }
673
+
674
+ /**
675
+ * Register the WP-2 host ops (`fs.read`, `fs.list`, `exec`) on a hub bridge (lib/hub-bridge.js).
676
+ * Kept separate from `registerSessionOps` so a host that only serves session reads (a box, WP-1)
677
+ * never advertises exec-capable ops it has no intent to run.
678
+ */
679
+ function registerHostOps(hubBridge, deps = {}) {
680
+ if (!hubBridge || typeof hubBridge.registerOp !== 'function') {
681
+ throw new TypeError('registerHostOps: hubBridge.registerOp must be a function');
682
+ }
683
+ hubBridge.registerOp('fs.read', createFsReadOp(deps));
684
+ hubBridge.registerOp('fs.list', createFsListOp(deps));
685
+ hubBridge.registerOp('exec', createExecOp(deps));
686
+ return hubBridge;
687
+ }
688
+
689
+ module.exports = {
690
+ DEFAULT_MAX_MESSAGES,
691
+ MAX_MESSAGES,
692
+ FS_READ_CAP_BYTES,
693
+ FS_READ_DEFAULT_LIMIT,
694
+ FS_READ_MAX_LIMIT,
695
+ FS_LIST_MAX_ENTRIES,
696
+ EXEC_MAX_COMMAND_BYTES,
697
+ EXEC_DEFAULT_TIMEOUT_MS,
698
+ EXEC_MAX_TIMEOUT_MS,
699
+ EXEC_OUTPUT_CAP_BYTES,
700
+ EXEC_KILL_GRACE_MS,
701
+ SESSION_CONTEXT_BYTE_LIMIT,
702
+ SESSION_SEARCH_DEFAULT_LIMIT,
703
+ SESSION_SEARCH_MAX_LIMIT,
704
+ SESSION_SEARCH_TIMEOUT_MS,
705
+ clampInt,
706
+ clampMaxMessages,
707
+ compileNameGlob,
708
+ execChildEnv,
709
+ projectMessages,
710
+ createSessionContextOp,
711
+ createSessionReadOp,
712
+ createSessionSearchOp,
713
+ createFsReadOp,
714
+ createFsListOp,
715
+ createExecOp,
716
+ createMcpListOp,
717
+ createMcpCallOp,
718
+ registerSessionOps,
719
+ registerHostOps,
720
+ registerMcpOps,
721
+ };