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
@@ -44,9 +44,30 @@
44
44
  return { revision: 0, attachments: [], submission: null };
45
45
  }
46
46
 
47
+ // WP-2 (composer-image-chip-stuck-submission-recovery-2026-10-30.html §5 R-2/R-3b): the
48
+ // submission's decision point. Enter is forwarded ONLY after markEnterSent, so `enter_sent`
49
+ // in either phase slot means the provider may already hold the image -- such a submission is
50
+ // never aborted (2PC blocking caveat) and never re-sent.
51
+ function enterMayHaveBeenSent(draft) {
52
+ var submission = draft && draft.submission;
53
+ return !!(submission && (submission.phase === 'enter_sent' || submission.resumePhase === 'enter_sent'));
54
+ }
55
+
56
+ // R-4: no chip is ever without a working removal. 'dismiss-submitted' is the post-Enter
57
+ // LOCAL dismissal (no server DELETE, no re-send); 'disabled' survives only for the
58
+ // transient phases (freezing/awaiting_enter/editing/frozen), where Esc already aborts.
59
+ // A pre-Enter indeterminate submission falls through to the normal per-status rules, with
60
+ // an indeterminate chip mapping to 'remove' (its removal aborts the submission first).
47
61
  function dismissDisposition(draft, attachment) {
48
62
  if (!attachment || !VALID_STATUSES.has(attachment.status)) return 'disabled';
49
- if (draft && draft.submission) return 'disabled';
63
+ var submission = draft && draft.submission;
64
+ if (submission) {
65
+ if (submission.phase !== 'indeterminate') return 'disabled';
66
+ if (enterMayHaveBeenSent(draft)) {
67
+ return (submission.attachmentIds || []).indexOf(attachment.clientId) !== -1 ? 'dismiss-submitted' : 'disabled';
68
+ }
69
+ if (attachment.status === 'indeterminate') return 'remove';
70
+ }
50
71
  if (attachment.status === 'editing' || attachment.status === 'freezing' || attachment.status === 'frozen') {
51
72
  return 'disabled';
52
73
  }
@@ -670,8 +691,22 @@
670
691
  return attachment;
671
692
  }
672
693
 
694
+ // R-5 (WP-2): the ONE local removability predicate -- no server DELETE may be issued for a
695
+ // chip this returns false for. A submission blocks removal only while it is still transient
696
+ // (freezing/awaiting_enter) or after Enter may have been sent; a pre-Enter indeterminate
697
+ // submission is aborted by the removal itself (presumed abort, R-2).
698
+ function canRemoveAttachment(draft, clientId) {
699
+ if (draft && draft.submission && !(draft.submission.phase === 'indeterminate' && !enterMayHaveBeenSent(draft))) {
700
+ return false;
701
+ }
702
+ return _attachments(draft).some(function (attachment) {
703
+ return attachment && attachment.clientId === clientId;
704
+ });
705
+ }
706
+
673
707
  function removeAttachment(draft, clientId) {
674
- if (draft && draft.submission) return false;
708
+ if (!canRemoveAttachment(draft, clientId)) return false;
709
+ if (draft.submission) abortSubmission(draft, 'user-removed');
675
710
  var list = _attachments(draft);
676
711
  var index = list.findIndex(function (attachment) {
677
712
  return attachment && attachment.clientId === clientId;
@@ -797,8 +832,11 @@
797
832
 
798
833
  function abortSubmission(draft, error) {
799
834
  if (!draft || !draft.submission) return false;
835
+ var affected = new Set(draft.submission.attachmentIds || []);
800
836
  _attachments(draft).forEach(function (attachment) {
801
- if (attachment.status === 'freezing' || attachment.status === 'frozen') {
837
+ // A hydrated pre-Enter indeterminate submission (R-2) restores its own chips too.
838
+ if (attachment.status === 'freezing' || attachment.status === 'frozen'
839
+ || (attachment.status === 'indeterminate' && affected.has(attachment.clientId))) {
802
840
  attachment.status = attachment._preSubmissionStatus === 'unconfirmed' ? 'unconfirmed' : 'attached';
803
841
  delete attachment._preSubmissionStatus;
804
842
  }
@@ -824,15 +862,28 @@
824
862
  return true;
825
863
  }
826
864
 
827
- function retryIndeterminate(draft) {
828
- if (!draft || !draft.submission || draft.submission.phase !== 'indeterminate') return false;
829
- var affected = new Set(draft.submission.attachmentIds || []);
830
- _attachments(draft).forEach(function (attachment) {
831
- if (affected.has(attachment.clientId) && attachment.status === 'indeterminate') attachment.status = 'attached';
832
- });
833
- draft.submission = null;
834
- draft.revision += 1;
835
- return true;
865
+ // R-2/R-3b (WP-2): the single failure exit for a send/resume. Before Enter nothing was
866
+ // committed to the provider, so the submission is aborted (presumed abort) and the chips
867
+ // return to their pre-submission state; after Enter the outcome is unknown, so the
868
+ // submission stays locked as indeterminate until the user resolves it. Returns the outcome
869
+ // ('' when there was no submission) so the caller can pick its metric/toast without
870
+ // re-deriving the decision.
871
+ function failSubmission(draft, error) {
872
+ if (!draft || !draft.submission) return '';
873
+ if (enterMayHaveBeenSent(draft)) {
874
+ markIndeterminate(draft, error);
875
+ return 'indeterminate';
876
+ }
877
+ abortSubmission(draft, error);
878
+ return 'aborted';
879
+ }
880
+
881
+ // R-3b: after Enter the chip's removal is a LOCAL dismissal -- the provider may already hold
882
+ // the image, so the server row is never deleted and Enter is never re-sent.
883
+ function dismissSubmitted(draft) {
884
+ if (!draft || !draft.submission) return false;
885
+ if (draft.submission.phase !== 'indeterminate' || !enterMayHaveBeenSent(draft)) return false;
886
+ return completeSubmission(draft);
836
887
  }
837
888
 
838
889
  function completeSubmission(draft) {
@@ -948,6 +999,10 @@
948
999
  statusText: statusText,
949
1000
  createDraft: createDraft,
950
1001
  dismissDisposition: dismissDisposition,
1002
+ enterMayHaveBeenSent: enterMayHaveBeenSent,
1003
+ failSubmission: failSubmission,
1004
+ canRemoveAttachment: canRemoveAttachment,
1005
+ dismissSubmitted: dismissSubmitted,
951
1006
  addUploading: addUploading,
952
1007
  markReady: markReady,
953
1008
  adoptServerSnapshot: adoptServerSnapshot,
@@ -975,7 +1030,6 @@
975
1030
  markEnterSent: markEnterSent,
976
1031
  abortSubmission: abortSubmission,
977
1032
  markIndeterminate: markIndeterminate,
978
- retryIndeterminate: retryIndeterminate,
979
1033
  completeSubmission: completeSubmission,
980
1034
  serializeDraft: serializeDraft,
981
1035
  hydrateDraft: hydrateDraft,
@@ -142,30 +142,76 @@
142
142
  };
143
143
  }
144
144
 
145
+ // Observed tokens are `{label, start, end}` objects from the composer scan
146
+ // (image-composer-scan.js); plain label strings are accepted too.
147
+ function _observedTokenLabel(token) {
148
+ return typeof token === 'string' ? token : String(token && token.label || '');
149
+ }
150
+
151
+ // Only the OBSERVED provider label is an identity: `label` is the tray's local staging rank
152
+ // (_relabel in terminal-attachment-draft.js) and can differ from the agent's own ordinal.
153
+ function _attachmentLabel(attachment) {
154
+ return String((attachment && attachment.providerLabel) || '');
155
+ }
156
+
157
+ // A label is only a stable identity for providers that keep their ordinals
158
+ // across a deletion. Codex renumbers after a deletion (observedProviderLabelUpdates
159
+ // above), so a Codex chip always falls back to the count rule; a chip with no
160
+ // label has nothing to match on either.
161
+ function _labelKeyedAttachment(attachment, sessionProvider) {
162
+ return _attachmentLabel(attachment) !== '' &&
163
+ String((attachment && attachment.provider) || sessionProvider || '').toLowerCase() !== 'codex';
164
+ }
165
+
145
166
  function deriveObservedMembership(options) {
146
167
  options = options || {};
147
168
  var list = Array.isArray(options.attachments) ? options.attachments : [];
148
169
  var scan = options.scan || {};
149
170
  var settle = options.settle;
150
- var observedCount = Array.isArray(options.observedTokens) ? options.observedTokens.length : 0;
171
+ var tokens = Array.isArray(options.observedTokens) ? options.observedTokens : [];
172
+ var observedCount = tokens.length;
151
173
  var visible = list.filter(Boolean);
152
174
  var detached = [];
153
175
  var confirmedDeleted = [];
154
176
  var trusted = scan.known === true && scan.active === true && scan.markerFound === true;
155
- var attached = visible.filter(function (attachment) { return attachment.status === 'attached'; });
156
- if (!trusted || !settle || typeof settle.observe !== 'function' || attached.length <= observedCount) {
177
+ if (!trusted || !settle || typeof settle.observe !== 'function') {
157
178
  if (settle && typeof settle.reset === 'function') settle.reset();
158
179
  return { visible: visible, detachedClientIds: detached, confirmedDeletedClientIds: confirmedDeleted };
159
180
  }
181
+ // Multiset of observed labels. A chip that is no longer attached (indeterminate,
182
+ // failed, submitting) still owns one of these tokens: consume it first, by label, so
183
+ // that a departed chip cannot make an attached sibling look surplus.
184
+ var pool = tokens.map(_observedTokenLabel).filter(function (label) { return label !== ''; });
185
+ visible.forEach(function (attachment) {
186
+ if (attachment.status === 'attached' || !_labelKeyedAttachment(attachment, options.provider)) return;
187
+ var consumed = pool.indexOf(_attachmentLabel(attachment));
188
+ if (consumed >= 0) pool.splice(consumed, 1);
189
+ });
190
+ // Missing = a label-keyed attached chip whose label is not in the pool (one token per
191
+ // chip, in list order). Chips with no label (or a renumbering provider such as Codex)
192
+ // keep the count rule against the pool's REMAINING size, popped from the end.
193
+ var candidates = [];
194
+ var counted = [];
195
+ visible.forEach(function (attachment) {
196
+ if (attachment.status !== 'attached') return;
197
+ if (!_labelKeyedAttachment(attachment, options.provider)) { counted.push(attachment); return; }
198
+ var consumed = pool.indexOf(_attachmentLabel(attachment));
199
+ if (consumed >= 0) pool.splice(consumed, 1);
200
+ else candidates.push(attachment);
201
+ });
202
+ while (counted.length > pool.length) candidates.push(counted.pop());
203
+ if (!candidates.length) {
204
+ if (typeof settle.reset === 'function') settle.reset();
205
+ return { visible: visible, detachedClientIds: detached, confirmedDeletedClientIds: confirmedDeleted };
206
+ }
160
207
  if (!settle.observe(observedCount, options.nowMs)) {
161
208
  return { visible: visible, detachedClientIds: detached, confirmedDeletedClientIds: confirmedDeleted };
162
209
  }
163
- while (attached.length > observedCount) {
164
- var item = attached.pop();
210
+ candidates.forEach(function (item) {
165
211
  if (options.editWindowActive === true) confirmedDeleted.push(item.clientId);
166
212
  else detached.push(item.clientId);
167
213
  visible = visible.filter(function (candidate) { return candidate !== item; });
168
- }
214
+ });
169
215
  settle.reset();
170
216
  return { visible: visible, detachedClientIds: detached, confirmedDeletedClientIds: confirmedDeleted };
171
217
  }
@@ -97,6 +97,10 @@
97
97
  // WP-0 (unified-terminal-history-scroll-2026-09-24 §5 D-3): the history reader is mounted
98
98
  // for this pane -- decideWheel checks this FIRST, before every other fact below.
99
99
  readerOpen,
100
+ // WP-1 (wheel-reader-only-where-history-exists-2026-10-28 §5 D-1/D-3): does this session's
101
+ // provider have a reader history source at all? 'transcript' (claude/codex) -> true; every other
102
+ // provider has none, so its wheel-up must forward to the app rather than open a reader that exits.
103
+ historyReader,
100
104
  }) {
101
105
  return {
102
106
  deltaY, wheelStartViewportY,
@@ -106,6 +110,7 @@
106
110
  xtermProtocol, xtermEncoding,
107
111
  exited: !!exited, agentKind, hasScrollback: !!hasScrollback,
108
112
  readerOpen: !!readerOpen,
113
+ historyReader: historyReader === true,
109
114
  };
110
115
  }
111
116
 
@@ -148,7 +153,7 @@
148
153
  const {
149
154
  deltaY, wheelStartViewportY, bufferType, baseY, viewportY,
150
155
  tuiAltScreen, frameMouse, tuiAppMouse, tuiMouseEnc,
151
- xtermProtocol, xtermEncoding, exited, agentKind, hasScrollback,
156
+ xtermProtocol, xtermEncoding, exited, agentKind, hasScrollback, historyReader,
152
157
  } = facts;
153
158
  const terminalMouseState = deps.terminalMouseState;
154
159
  const terminalWheelRoute = deps.terminalWheelRoute;
@@ -192,7 +197,11 @@
192
197
  // D-4 (handoff-seed-keeps-mouse-modes-codex-reader-without-mouse-2026-10-06): a Codex tab owns
193
198
  // its transcript in-app and has no local scrollback on the alt screen, so an unproven mouse must
194
199
  // not strand it -- a wheel-UP opens the reader, which sends no mouse report and needs no proof.
195
- const codexAltReaderUp = agentKind === 'codex' && bufferType === 'alternate' && deltaY < 0
200
+ // WP-1 (wheel-reader-only-where-history-exists-2026-10-28 §5 D-1, §6): both reader arms require the
201
+ // capability -- a provider with no reader source must never reach 'reader-enter' (it would exit at
202
+ // once and lose the wheel). codex is always historyReader:true, so its cells stay byte-identical;
203
+ // gating it here is only observable for a hypothetical no-source codex (none).
204
+ const codexAltReaderUp = historyReader && agentKind === 'codex' && bufferType === 'alternate' && deltaY < 0
196
205
  && !exited && !parkedInLocalScrollback;
197
206
  const mouseUnknown = isAlt && !mouseActive && providerOwnsWheel && !parkedInLocalScrollback
198
207
  && !codexAltReaderUp;
@@ -225,7 +234,11 @@
225
234
  // screen left to snapshot into a continuous reader for a PTY that has already exited.
226
235
  // D-4 of handoff-seed-keeps-mouse-modes-codex-reader-without-mouse-2026-10-06: a Codex alt-screen
227
236
  // wheel-UP also opens the reader without a proven mouse (`codexAltReaderUp`).
228
- const readerEnterEligible = (shouldForward && isAlt && deltaY < 0 && !exited) || codexAltReaderUp;
237
+ // WP-1 (wheel-reader-only-where-history-exists-2026-10-28 §5 D-1/D-2): reader entry requires a
238
+ // reader source. With historyReader false nothing else changes -- the chain falls through to
239
+ // shouldForward -> 'forward' (the app owns its own wheel), or to mouseUnknown (already outranks it).
240
+ const readerEnterEligible = historyReader
241
+ && ((shouldForward && isAlt && deltaY < 0 && !exited) || codexAltReaderUp);
229
242
 
230
243
  let action = 'noop';
231
244
  if (nativeDelegate) action = 'native-delegate';
@@ -254,6 +267,9 @@
254
267
  nativeDelegate,
255
268
  preventNoScrollbackNativeOrSnapshot,
256
269
  mouseUnknown,
270
+ // WP-1 §5 D-1: the declared capability, echoed so the gesture recorder / tests can prove
271
+ // which provider branch ran (the readerOpen early return above carries no historyReader).
272
+ historyReader: historyReader === true,
257
273
  codexAltReaderUp,
258
274
  shouldForward,
259
275
  readerEnterEligible,
@@ -486,6 +502,8 @@
486
502
  baseY: null,
487
503
  appMouse: null,
488
504
  isAlt: null,
505
+ // WP-1 §5 D-3/S-4: prove which provider branch ran (reader-capable vs not) in the summary.
506
+ historyReader: null,
489
507
  mouseSource: null,
490
508
  frameTracking: null,
491
509
  sendTimestamps: [],
@@ -547,6 +565,7 @@
547
565
  baseY: g.baseY,
548
566
  appMouse: g.appMouse,
549
567
  isAlt: g.isAlt,
568
+ historyReader: g.historyReader, // WP-1: does this session's provider have a reader source? (null = no event carried it)
550
569
  mouseSource: g.mouseSource || 'unknown', // probe: which evidence path (frame|tui-mode|xterm|unknown) answered
551
570
  frameTracking: g.frameTracking == null ? null : g.frameTracking, // probe: raw frame.surface.mouse.tracking
552
571
  rttP50: percentile(sorted, 50),
@@ -581,6 +600,7 @@
581
600
  if (details.baseY !== undefined) gesture.baseY = details.baseY;
582
601
  if (details.appMouse !== undefined) gesture.appMouse = details.appMouse;
583
602
  if (details.isAlt !== undefined) gesture.isAlt = details.isAlt;
603
+ if (details.historyReader !== undefined) gesture.historyReader = details.historyReader;
584
604
  if (details.mouseSource !== undefined) gesture.mouseSource = details.mouseSource;
585
605
  if (details.frameTracking !== undefined) gesture.frameTracking = details.frameTracking;
586
606
  if (details.sessionId !== undefined) gesture.sessionId = details.sessionId;
@@ -1219,12 +1219,12 @@
1219
1219
  }
1220
1220
 
1221
1221
  // Fetch the active model for the badge (once, then cached in walle.js, which
1222
- // the service-alert layer also reads).
1222
+ // the service-alert layer also reads). CTM route: read via the panel, never the transport.
1223
1223
  function loadActiveModel() {
1224
- var api = currentApi();
1225
- if (!api || typeof api.get !== 'function') return;
1224
+ var fetchStatus = hook('fetchSetupStatus');
1225
+ if (!fetchStatus) return;
1226
1226
  var remember = hook('rememberActiveModel');
1227
- api.get('/api/setup/status', { signal: currentSignal() }).then(function(d) {
1227
+ fetchStatus({ signal: currentSignal() }).then(function(d) {
1228
1228
  if (!isCurrent()) return;
1229
1229
  if (remember) remember(d || null);
1230
1230
  if (d && (d.walle_model || d.walle_provider)) {
@@ -422,6 +422,12 @@ function _rerenderChatPane() {
422
422
  // result is panel state: the service-alert layer filters issues by the active
423
423
  // provider, and the provider-test dialog replays its auth_method.
424
424
  WE.activeModel = function() { return _cachedActiveModel; };
425
+ // /api/setup/status is CTM's own route, never Wall-E's: the conversation's transport prefixes
426
+ // /api/wall-e and the proxied read 404s (nightly-linux-host-portability-2026-10-27 WP-11), so the
427
+ // panel reads it here, like the pasted-image fetch below. A non-OK status is null, never a throw.
428
+ WE.fetchSetupStatus = function(opts) {
429
+ return fetch('/api/setup/status', { signal: opts && opts.signal }).then(function(r) { return r.ok ? r.json() : null; });
430
+ };
425
431
  WE.rememberActiveModel = function(status) {
426
432
  _cachedSetupStatus = status || null;
427
433
  if (status && (status.walle_model || status.walle_provider)) {
@@ -63,6 +63,16 @@
63
63
  // delegate chip answer is stale. Same frame on desktop and phone; both call one picker function.
64
64
  context.handleDelegatePrefChanged(message);
65
65
  return true;
66
+ case 'hub-bridge-pending':
67
+ case 'hub-bridge-pending-cleared': {
68
+ // R-5/R-13 hub-bridge ask fan-out (AC-2g). Not a Wall-E frame; it rides this dispatcher like
69
+ // lead-model-request. The Machines page owns the session toolbar banner and the Access block,
70
+ // and publishes itself as globalThis.CtmHubBridgeAccess; the frame is still consumed here when
71
+ // no page is loaded, so index.html's switch stays net zero.
72
+ const hubBridge = globalThis.CtmHubBridgeAccess;
73
+ if (hubBridge && typeof hubBridge.onFrame === 'function') hubBridge.onFrame(message);
74
+ return true;
75
+ }
66
76
  case 'walle-turn-terminal':
67
77
  // Broadcast companion to subscribed progress: inactive or recently
68
78
  // unsubscribed Wall-E tabs still learn that the canonical turn ended.
@@ -880,6 +880,14 @@ h3 {
880
880
  background: rgba(116, 215, 199, 0.10);
881
881
  color: #74d7c7;
882
882
  }
883
+
884
+ /* WP-3b: the landing-queue chip (`⇡#2/3 · 23m`) — the phone counterpart of the desktop
885
+ `.wt-landing` part. */
886
+ .session-diff-chip.landing {
887
+ border-color: rgba(122, 162, 247, 0.34);
888
+ background: rgba(122, 162, 247, 0.12);
889
+ color: #7aa2f7;
890
+ }
883
891
  /* Commits exist but merging changes nothing (integrated/superseded) — dim so it reads as
884
892
  low-priority/safe-to-clean vs genuine unmerged work. */
885
893
  .session-diff-chip.commits.commits-noop {
@@ -7141,6 +7149,14 @@ button.walle-model-effort-note.ctm-route-back {
7141
7149
  line-height: 18px;
7142
7150
  }
7143
7151
 
7152
+ /* WP-3b phone parity: the landing-queue mark on the SESSION ROW (`⇡#1/1`), same colors as
7153
+ `.session-diff-chip.landing`. */
7154
+ .row-diff-mark.landing {
7155
+ border-color: rgba(122, 162, 247, 0.34);
7156
+ background: rgba(122, 162, 247, 0.12);
7157
+ color: #7aa2f7;
7158
+ }
7159
+
7144
7160
  .session-row.home-row .row-actions {
7145
7161
  display: flex;
7146
7162
  flex-direction: row;
@@ -7423,6 +7439,66 @@ html[data-theme="light"] #view-walle {
7423
7439
  #phone-machines-card .mp-btn:active { opacity: 0.82; }
7424
7440
  #phone-machines-card .mp-btn.mp-primary { border-color: var(--accent, #7aa2f7); color: var(--accent, #7aa2f7); }
7425
7441
  #phone-machines-card .mp-btn.mp-danger { border-color: var(--red, #f7768e); color: var(--red, #f7768e); }
7442
+ /* hub bridge (R-13 / AC-2g): the same Access block and approval banner as the desktop card. */
7443
+ .mp-access { margin-top: 12px; padding-top: 10px; border-top: 1px solid var(--border, rgba(255, 255, 255, 0.12)); font-size: 14px; }
7444
+ .mp-access-head { display: flex; align-items: center; gap: 8px; }
7445
+ .mp-access-trust { display: flex; align-items: center; gap: 8px; color: var(--fg-dim, #a9b1d6); }
7446
+ .mp-access-trust select { min-height: 44px; padding: 0 10px; border: 1px solid var(--border, rgba(255, 255, 255, 0.12)); border-radius: 10px; background: var(--bg-light, #24283b); color: var(--fg); font-size: 14px; }
7447
+ .mp-access-trust-all { display: flex; align-items: center; gap: 8px; min-height: 44px; color: var(--fg-dim, #a9b1d6); }
7448
+ .mp-access-list { display: flex; flex-direction: column; gap: 6px; margin-top: 8px; }
7449
+ .mp-access-row { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; }
7450
+ .mp-access-pending { color: var(--yellow, #e0af68); }
7451
+ .mp-access-audit { color: var(--fg-dim, #a9b1d6); font-size: 13px; }
7452
+ .mp-access-text { overflow-wrap: anywhere; }
7453
+ .mp-access .mp-btn, .mp-approval-banner .mp-btn { display: inline-flex; align-items: center; min-height: 44px; padding: 0 12px; border: 1px solid var(--border, rgba(255, 255, 255, 0.12)); border-radius: 10px; background: var(--bg-light, #24283b); color: var(--fg); font-size: 14px; }
7454
+ .mp-access .mp-btn.mp-danger, .mp-approval-banner .mp-btn.mp-danger { border-color: var(--red, #f7768e); color: var(--red, #f7768e); }
7455
+ .mp-approval-banner { display: flex; flex-direction: column; align-items: stretch; gap: 8px; }
7456
+ /* The approval prompt's own classes (docs/hub-bridge-approval-scopes-2026-11-01.html §6.5). The
7457
+ structural classes are `hbb-*` on both surfaces; this is the phone's dressing: 44 px targets, no
7458
+ type below 12 px (bin/mobile-css-floor-lint.js), one column, and pairs that share the full width.
7459
+ Colours use the PHONE's tokens (--bg-soft, --line-strong, --blue, --ink, --amber): the desktop's
7460
+ --bg-light / --accent / --border are not defined here and would fall back to dark in light mode. */
7461
+ .mp-approval-banner .hbb-head, .mp-access .hbb-head { display: flex; gap: 10px; align-items: flex-start; }
7462
+ .mp-approval-banner .hbb-icon, .mp-access .hbb-icon {
7463
+ flex: 0 0 26px; height: 26px; border-radius: 8px; display: grid; place-items: center;
7464
+ background: color-mix(in srgb, var(--amber) 16%, transparent); color: var(--amber);
7465
+ }
7466
+ .mp-approval-banner .hub-bridge-banner-text, .mp-access .hub-bridge-banner-text {
7467
+ flex: 1 1 auto; min-width: 0; white-space: normal; overflow-wrap: anywhere; font-size: 14px;
7468
+ }
7469
+ .mp-approval-banner .hub-bridge-banner-text b, .mp-access .hub-bridge-banner-text b { font-weight: 600; }
7470
+ .mp-approval-banner .hbb-tier, .mp-access .hbb-tier {
7471
+ flex: 0 0 auto; font-size: 12px; font-weight: 700; letter-spacing: .04em; text-transform: uppercase;
7472
+ color: var(--amber); background: color-mix(in srgb, var(--amber) 16%, transparent);
7473
+ border-radius: 999px; padding: 4px 10px;
7474
+ }
7475
+ .mp-approval-banner .hbb-detail, .mp-access .hbb-detail {
7476
+ padding: 6px 8px; border-radius: 8px; background: var(--bg-soft);
7477
+ color: var(--fg-muted); font-size: 12px; white-space: pre-wrap; overflow-wrap: anywhere;
7478
+ }
7479
+ .mp-approval-banner .hbb-grants, .mp-access .hbb-grants {
7480
+ display: grid; grid-template-columns: 1fr; gap: 6px 10px; align-items: center; margin-left: 0;
7481
+ }
7482
+ .mp-approval-banner .hbb-label, .mp-access .hbb-label { font-size: 12px; color: var(--fg-muted); }
7483
+ .mp-approval-banner .hbb-seg, .mp-access .hbb-seg { display: flex; width: 100%; }
7484
+ .mp-approval-banner .hbb-btn, .mp-access .hbb-btn {
7485
+ display: inline-flex; align-items: center; justify-content: center; flex: 1 1 0;
7486
+ min-height: 44px; padding: 0 12px; border: 1px solid var(--line-strong);
7487
+ border-radius: 10px; background: var(--bg-soft); color: var(--fg); font-size: 14px;
7488
+ }
7489
+ .mp-approval-banner .hbb-seg .hbb-btn:first-child, .mp-access .hbb-seg .hbb-btn:first-child { border-radius: 10px 0 0 10px; }
7490
+ .mp-approval-banner .hbb-seg .hbb-btn + .hbb-btn, .mp-access .hbb-seg .hbb-btn + .hbb-btn { border-left: 0; border-radius: 0 10px 10px 0; }
7491
+ .mp-approval-banner .hbb-btn.hbb-primary, .mp-access .hbb-btn.hbb-primary {
7492
+ background: var(--blue); border-color: var(--blue);
7493
+ color: var(--ink); font-weight: 600;
7494
+ }
7495
+ .mp-approval-banner .hbb-foot, .mp-access .hbb-foot { display: flex; justify-content: space-between; align-items: center; gap: 8px; }
7496
+ .mp-approval-banner .hbb-note, .mp-access .hbb-note { font-size: 12px; color: var(--fg-dim); }
7497
+ .mp-approval-banner .hbb-deny, .mp-access .hbb-deny {
7498
+ display: inline-flex; align-items: center; justify-content: center; min-height: 44px; padding: 0 12px;
7499
+ border: 1px solid transparent; border-radius: 10px; background: transparent;
7500
+ color: var(--fg-muted); font-size: 14px;
7501
+ }
7426
7502
  #phone-machines-card .mp-card {
7427
7503
  margin-top: 10px;
7428
7504
  padding: 10px 12px;
@@ -7465,6 +7541,13 @@ html[data-theme="light"] #view-walle {
7465
7541
  white-space: nowrap;
7466
7542
  }
7467
7543
  #phone-machines-card .mp-meta { margin-top: 2px; color: var(--fg-dim); font-size: 12px; overflow-wrap: anywhere; }
7544
+ /* WP-3: the phone twin of the desktop card's .mpc-fleet — same line, same size as .mp-meta, tone
7545
+ from this page's own theme variables. Dark mode rides the variables like every other row. */
7546
+ #phone-machines-card .mp-fleet { margin-top: 2px; color: var(--fg-dim); font-size: 12px; overflow-wrap: anywhere; }
7547
+ #phone-machines-card .mp-fleet[data-fleet-tone="ok"] { color: var(--green, #9ece6a); }
7548
+ #phone-machines-card .mp-fleet[data-fleet-tone="pending"] { color: var(--yellow, #e0af68); }
7549
+ #phone-machines-card .mp-fleet[data-fleet-tone="warn"] { color: var(--red, #f7768e); }
7550
+ #phone-machines-card .mp-fleet[data-fleet-tone="muted"] { color: var(--fg-dim, #7d8590); }
7468
7551
  #phone-machines-card .mp-stale { color: var(--yellow, #e0af68); }
7469
7552
  #phone-machines-card .mp-error { color: var(--red, #f7768e); font-size: 13px; }
7470
7553
  #phone-machines-card .mp-sparks { display: flex; gap: 12px; margin-top: 8px; }
@@ -7546,3 +7629,60 @@ html[data-theme="light"] #view-walle {
7546
7629
  .pool-origin-name { color: var(--fg); font-weight: 600; }
7547
7630
  .pool-origin-state,
7548
7631
  .pool-origin-address { color: var(--fg-dim); font-size: 12px; overflow-wrap: anywhere; }
7632
+
7633
+ /* ── WP-9 (§9 S-9): the row's one Skills line and its Review sheet ────────────────────────────────
7634
+ PHONE = DESKTOP PARITY: the same line, the same three sections, the same actions and wording the
7635
+ desktop page renders in public/js/app/machines-page.js. The fonts stay at or above the phone floor
7636
+ (lint/mobile-css-floor.config.json), and the buttons keep the 44 px tap target. */
7637
+ #phone-machines-card .mp-skills { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; margin-top: 10px; }
7638
+ #phone-machines-card .mp-skills-line { color: var(--fg-dim); font-size: 12px; overflow-wrap: anywhere; }
7639
+ #phone-machines-card .mp-skills-review { flex: 0 0 auto; }
7640
+ /* WP-3 (§8 WP-3): the phone twin of the row's Models line, its /delegate warnings and its Review
7641
+ button. Fonts stay at or above the phone floor (lint/mobile-css-floor.config.json). */
7642
+ #phone-machines-card .mp-models { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; margin-top: 6px; }
7643
+ #phone-machines-card .mp-models-line { color: var(--fg-dim); font-size: 12px; overflow-wrap: anywhere; }
7644
+ #phone-machines-card .mp-models-sep { color: var(--fg-dim); font-size: 12px; }
7645
+ #phone-machines-card .mp-models-review { flex: 0 0 auto; }
7646
+ #phone-machines-card .mp-models-warn { flex-basis: 100%; color: var(--red, #f7768e); font-size: 12px; overflow-wrap: anywhere; }
7647
+ .mp-review-sheet { max-height: 88vh; overflow-y: auto; }
7648
+ .mp-review-section { margin-top: 14px; border-top: 1px solid var(--border, rgba(255, 255, 255, 0.12)); padding-top: 10px; }
7649
+ .mp-review-section h4 { margin: 0 0 6px; color: var(--fg); font-size: 13px; }
7650
+ .mp-review-section ul { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 10px; }
7651
+ .mp-review-item { display: flex; flex-wrap: wrap; align-items: center; gap: 6px 10px; }
7652
+ .mp-review-name { color: var(--fg); font-size: 13px; font-weight: 600; overflow-wrap: anywhere; }
7653
+ .mp-review-meta, .mp-review-where, .mp-review-note { color: var(--fg-dim); font-size: 12px; overflow-wrap: anywhere; }
7654
+ .mp-review-note { margin: 6px 0 0; }
7655
+ .mp-review-note.bad { color: var(--red, #f7768e); }
7656
+ .mp-review-empty { color: var(--fg-dim); font-size: 12px; }
7657
+ .mp-review-actions { display: flex; flex-wrap: wrap; gap: 8px; }
7658
+ /* WP-4 (§8 WP-4): the unreachable rows' one control — a 22px tick (the D-19 phone floor), then the
7659
+ 44px button under the list. */
7660
+ .mp-review-pick { display: inline-flex; align-items: center; gap: 8px; min-height: 44px; color: var(--fg); font-size: 13px; }
7661
+ .mp-review-pick input[type="checkbox"] { width: 22px; height: 22px; flex: 0 0 auto; }
7662
+ .mp-review-models-remove { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 10px; }
7663
+ .mp-review-models-remove .mp-btn { font-size: 13px; min-height: 44px; }
7664
+ /* WP-5 (§8 WP-5): "From this hub" — a heading level under the Models one, one 44px button per row. */
7665
+ .mp-review-from-hub { margin-top: 10px; }
7666
+ .mp-review-from-hub h5 { margin: 0 0 6px; color: var(--fg-dim); font-size: 12px; font-weight: 600; }
7667
+ .mp-review-from-hub .mp-review-actions .mp-btn { font-size: 13px; min-height: 44px; }
7668
+ .mp-review-plugins { display: flex; flex-direction: column; gap: 6px; }
7669
+ .mp-review-plugin { display: flex; align-items: center; gap: 8px; min-height: 44px; color: var(--fg); font-size: 13px; }
7670
+ .mp-review-plugin input[type="checkbox"] { width: 22px; height: 22px; flex: 0 0 auto; }
7671
+ .mp-review-diff {
7672
+ flex: 1 1 100%;
7673
+ max-height: 46vh;
7674
+ overflow: auto;
7675
+ border: 1px solid var(--border, rgba(255, 255, 255, 0.12));
7676
+ border-radius: 8px;
7677
+ padding: 8px;
7678
+ font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
7679
+ font-size: 12px;
7680
+ line-height: 1.5;
7681
+ }
7682
+ .mp-diff { display: flex; flex-direction: column; }
7683
+ .mp-diff span { white-space: pre-wrap; overflow-wrap: anywhere; }
7684
+ .mp-diff-file { margin: 8px 0 2px; color: var(--fg); font-size: 12px; font-weight: 600; overflow-wrap: anywhere; }
7685
+ .mp-diff-binary { margin: 0 0 4px; color: var(--fg-dim); font-size: 12px; }
7686
+ .mp-diff-add { color: var(--green, #9ece6a); }
7687
+ .mp-diff-del { color: var(--red, #f7768e); }
7688
+ .mp-diff-eq { color: var(--fg-dim); }