create-walle 0.10.1 → 0.10.2

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 (341) hide show
  1. package/README.md +4 -0
  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 +6 -4
  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 +10 -22
  10. package/template/coding-task-manager/bin/claude-hook.js +7 -3
  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/lead-wait-census.js +1348 -0
  18. package/template/coding-task-manager/bin/repair-foreign-clone.js +564 -0
  19. package/template/coding-task-manager/bin/repair-resume-echo-titles.js +248 -0
  20. package/template/coding-task-manager/bin/write-lock-bench.js +111 -0
  21. package/template/coding-task-manager/db.js +705 -286
  22. package/template/coding-task-manager/git-utils.js +44 -0
  23. package/template/coding-task-manager/lib/adopted-host-redial.js +4 -0
  24. package/template/coding-task-manager/lib/agent-presets.js +15 -0
  25. package/template/coding-task-manager/lib/agent-title-apply.js +88 -0
  26. package/template/coding-task-manager/lib/agent-title-backfill-read.js +92 -0
  27. package/template/coding-task-manager/lib/api/host-stats.js +98 -0
  28. package/template/coding-task-manager/lib/api/ingress.js +35 -12
  29. package/template/coding-task-manager/lib/api/machine-pairing.js +285 -0
  30. package/template/coding-task-manager/lib/api/machine-pool.js +307 -0
  31. package/template/coding-task-manager/lib/api/machines.js +461 -0
  32. package/template/coding-task-manager/lib/api/misc-ops.js +20 -5
  33. package/template/coding-task-manager/lib/api/providers.js +53 -6
  34. package/template/coding-task-manager/lib/api/resume-from-store.js +25 -0
  35. package/template/coding-task-manager/lib/api/sessions.js +160 -8
  36. package/template/coding-task-manager/lib/api/transcript-history.js +17 -4
  37. package/template/coding-task-manager/lib/api/worktrees.js +38 -37
  38. package/template/coding-task-manager/lib/approval-drift.js +16 -1
  39. package/template/coding-task-manager/lib/approval-logical-frame.js +5 -1
  40. package/template/coding-task-manager/lib/approval-scope.js +68 -4
  41. package/template/coding-task-manager/lib/auth-context.js +32 -2
  42. package/template/coding-task-manager/lib/auth-rate-limit.js +41 -1
  43. package/template/coding-task-manager/lib/auth-rules.js +186 -45
  44. package/template/coding-task-manager/lib/broadcast-serialize.js +2 -1
  45. package/template/coding-task-manager/lib/browser-session-broker.js +9 -1
  46. package/template/coding-task-manager/lib/browser-use-adapter.js +33 -2
  47. package/template/coding-task-manager/lib/claude-markdown-ansi.js +27 -85
  48. package/template/coding-task-manager/lib/claude-session-title.js +6 -30
  49. package/template/coding-task-manager/lib/claude-table-layout.js +322 -0
  50. package/template/coding-task-manager/lib/client-diag-handler.js +5 -0
  51. package/template/coding-task-manager/lib/codex-config-guard.js +33 -3
  52. package/template/coding-task-manager/lib/codex-harness-qualification.js +12 -0
  53. package/template/coding-task-manager/lib/codex-launch-health.js +29 -2
  54. package/template/coding-task-manager/lib/codex-link-preparation.js +9 -8
  55. package/template/coding-task-manager/lib/codex-paths.js +2 -1
  56. package/template/coding-task-manager/lib/coding-agent-models.js +21 -30
  57. package/template/coding-task-manager/lib/coding-session-model-adapters.js +27 -2
  58. package/template/coding-task-manager/lib/coding-session-model-projection.js +5 -0
  59. package/template/coding-task-manager/lib/coding-session-model-runtime.js +1 -2
  60. package/template/coding-task-manager/lib/coding-session-model-state.js +10 -0
  61. package/template/coding-task-manager/lib/coding-session-model-sync-state.js +0 -1
  62. package/template/coding-task-manager/lib/conversation-import/cursor-guard-owner.js +10 -0
  63. package/template/coding-task-manager/lib/create/resolve-launch-params.js +8 -1
  64. package/template/coding-task-manager/lib/ctm-boot-lifecycle.js +17 -1
  65. package/template/coding-task-manager/lib/db-domain-tables.js +7 -0
  66. package/template/coding-task-manager/lib/db-domains.js +21 -2
  67. package/template/coding-task-manager/lib/db-owner-op-registry.js +7 -0
  68. package/template/coding-task-manager/lib/db-schema-source-files.js +1 -0
  69. package/template/coding-task-manager/lib/feature-manifest.js +1 -1
  70. package/template/coding-task-manager/lib/fs-watcher.js +3 -2
  71. package/template/coding-task-manager/lib/harness-history-transition.js +3 -3
  72. package/template/coding-task-manager/lib/headless-inflight-ops.js +203 -0
  73. package/template/coding-task-manager/lib/headless-missing-reply.js +42 -0
  74. package/template/coding-task-manager/lib/headless-term-service.js +55 -17
  75. package/template/coding-task-manager/lib/host-control-dial.js +167 -0
  76. package/template/coding-task-manager/lib/host-handoff-orchestrator.js +16 -2
  77. package/template/coding-task-manager/lib/host-handoff.js +51 -13
  78. package/template/coding-task-manager/lib/host-health-ledger.js +164 -12
  79. package/template/coding-task-manager/lib/host-self-truth-watchdog.js +4 -0
  80. package/template/coding-task-manager/lib/host-stats.js +328 -0
  81. package/template/coding-task-manager/lib/host-threadpool-evacuation.js +160 -0
  82. package/template/coding-task-manager/lib/host-threadpool-monitor.js +14 -1
  83. package/template/coding-task-manager/lib/hosted-input-dispatch.js +203 -0
  84. package/template/coding-task-manager/lib/hosted-sync-worker.js +113 -5
  85. package/template/coding-task-manager/lib/instance-id-ownership-manifest.js +4 -0
  86. package/template/coding-task-manager/lib/instance-manifest-runtime.js +3 -0
  87. package/template/coding-task-manager/lib/instance-manifest.js +13 -1
  88. package/template/coding-task-manager/lib/instance-sync-status.js +15 -0
  89. package/template/coding-task-manager/lib/launch-model-override.js +160 -1
  90. package/template/coding-task-manager/lib/launch-plan-worker.js +59 -2
  91. package/template/coding-task-manager/lib/lead-model-switch-runtime.js +57 -4
  92. package/template/coding-task-manager/lib/lead-model-switch.js +3 -2
  93. package/template/coding-task-manager/lib/lead-model-transition-store.js +61 -3
  94. package/template/coding-task-manager/lib/legacy-draft-cancellation-recovery.js +111 -0
  95. package/template/coding-task-manager/lib/login-tripwire.js +1 -0
  96. package/template/coding-task-manager/lib/machine-pairing.js +238 -0
  97. package/template/coding-task-manager/lib/machine-pool.js +409 -0
  98. package/template/coding-task-manager/lib/machine-registry.js +749 -0
  99. package/template/coding-task-manager/lib/machine-self.js +66 -0
  100. package/template/coding-task-manager/lib/main-thread-lint-exemptions.json +52 -4
  101. package/template/coding-task-manager/lib/media-journal-control-reader.js +473 -0
  102. package/template/coding-task-manager/lib/media-journal.js +84 -27
  103. package/template/coding-task-manager/lib/media-store-options.js +43 -15
  104. package/template/coding-task-manager/lib/migrations/v56-host-samples-and-machine-pool.js +76 -0
  105. package/template/coding-task-manager/lib/mirror-feed-sanitize.js +12 -3
  106. package/template/coding-task-manager/lib/model-proxy/anthropic-face.js +4 -0
  107. package/template/coding-task-manager/lib/model-proxy/chat-response-translators.js +3 -0
  108. package/template/coding-task-manager/lib/model-proxy/handoff.js +494 -0
  109. package/template/coding-task-manager/lib/model-proxy/lead-worker-picks.js +25 -0
  110. package/template/coding-task-manager/lib/model-proxy/native-lead-listener.js +61 -7
  111. package/template/coding-task-manager/lib/model-proxy/proxy-cli.js +200 -0
  112. package/template/coding-task-manager/lib/model-proxy/proxy-instance-record.js +257 -0
  113. package/template/coding-task-manager/lib/model-proxy/stream-accounting.js +205 -0
  114. package/template/coding-task-manager/lib/model-proxy/tokens.js +78 -0
  115. package/template/coding-task-manager/lib/model-proxy/upstream-outcome.js +9 -0
  116. package/template/coding-task-manager/lib/native-history-control.js +2 -2
  117. package/template/coding-task-manager/lib/native-lead-settings-client.js +2 -1
  118. package/template/coding-task-manager/lib/native-lead-tls.js +18 -4
  119. package/template/coding-task-manager/lib/oauth-proxy-supervisor.js +628 -64
  120. package/template/coding-task-manager/lib/owner-action-manifest-data.json +14 -0
  121. package/template/coding-task-manager/lib/painted-row-recorder.js +9 -1
  122. package/template/coding-task-manager/lib/prompt-submission-contract.js +21 -1
  123. package/template/coding-task-manager/lib/provider-login-broker.js +192 -9
  124. package/template/coding-task-manager/lib/provider-login-capture.js +153 -0
  125. package/template/coding-task-manager/lib/queue-draft-status-overlay.js +36 -0
  126. package/template/coding-task-manager/lib/raw-codex-history-window.js +5 -3
  127. package/template/coding-task-manager/lib/read-pool-client.js +5 -2
  128. package/template/coding-task-manager/lib/read-pool-op-registry.js +10 -1
  129. package/template/coding-task-manager/lib/recent-catalog-query.js +26 -0
  130. package/template/coding-task-manager/lib/recent-session-catalog-response.js +9 -0
  131. package/template/coding-task-manager/lib/remote-command-context.js +12 -0
  132. package/template/coding-task-manager/lib/remote-command-runtime.js +13 -1
  133. package/template/coding-task-manager/lib/remote-machine-catalog.js +1062 -0
  134. package/template/coding-task-manager/lib/remote-machine-create.js +693 -0
  135. package/template/coding-task-manager/lib/remote-machine-link.js +939 -0
  136. package/template/coding-task-manager/lib/remote-machine-proxy.js +520 -0
  137. package/template/coding-task-manager/lib/remote-session-forward.js +306 -0
  138. package/template/coding-task-manager/lib/remote-submission-status.js +6 -0
  139. package/template/coding-task-manager/lib/restart-outcome-truth.js +20 -3
  140. package/template/coding-task-manager/lib/restart-preflight.js +9 -2
  141. package/template/coding-task-manager/lib/restore-backoff-gate.js +10 -2
  142. package/template/coding-task-manager/lib/restore-prepare-retry.js +12 -5
  143. package/template/coding-task-manager/lib/restore-resume-batch.js +22 -1
  144. package/template/coding-task-manager/lib/resume-blocked-wire.js +62 -1
  145. package/template/coding-task-manager/lib/resume-cwd.js +13 -0
  146. package/template/coding-task-manager/lib/resume-from-store.js +12 -1
  147. package/template/coding-task-manager/lib/resume-origin-facts.js +38 -1
  148. package/template/coding-task-manager/lib/resume-preflight.js +21 -16
  149. package/template/coding-task-manager/lib/review-repo-admission.js +39 -6
  150. package/template/coding-task-manager/lib/review-repo-registry.js +17 -0
  151. package/template/coding-task-manager/lib/root-delivery-runtime.js +72 -15
  152. package/template/coding-task-manager/lib/root-delivery-selection.js +37 -1
  153. package/template/coding-task-manager/lib/root-prompt-admission.js +33 -2
  154. package/template/coding-task-manager/lib/root-prompt-flow.js +167 -33
  155. package/template/coding-task-manager/lib/scrollback-archive-store.js +7 -4
  156. package/template/coding-task-manager/lib/session-analysis-memory.js +2 -0
  157. package/template/coding-task-manager/lib/session-create/codex-native-provider-gate.js +218 -0
  158. package/template/coding-task-manager/lib/session-create/codex-resume-exit-classify.js +52 -0
  159. package/template/coding-task-manager/lib/session-create/delegate-worker.js +95 -6
  160. package/template/coding-task-manager/lib/session-create/identity.js +20 -1
  161. package/template/coding-task-manager/lib/session-create/prepared.js +69 -1
  162. package/template/coding-task-manager/lib/session-create/provider-launch-context.js +77 -0
  163. package/template/coding-task-manager/lib/session-create/provider-process.js +34 -37
  164. package/template/coding-task-manager/lib/session-create/response.js +30 -12
  165. package/template/coding-task-manager/lib/session-create/transcript.js +13 -4
  166. package/template/coding-task-manager/lib/session-create/worker-continuation.js +43 -1
  167. package/template/coding-task-manager/lib/session-create/worker-notices.js +94 -5
  168. package/template/coding-task-manager/lib/session-create/worker-observability.js +99 -7
  169. package/template/coding-task-manager/lib/session-create/worker-stop.js +11 -3
  170. package/template/coding-task-manager/lib/session-create/worker-wait-watcher.js +315 -0
  171. package/template/coding-task-manager/lib/session-geometry-authority-handler.js +10 -1
  172. package/template/coding-task-manager/lib/session-host-manager.js +152 -206
  173. package/template/coding-task-manager/lib/session-jobs.js +17 -9
  174. package/template/coding-task-manager/lib/session-lifecycle.js +18 -0
  175. package/template/coding-task-manager/lib/session-model-action-preconditions.js +9 -0
  176. package/template/coding-task-manager/lib/session-resource-sampler.js +19 -9
  177. package/template/coding-task-manager/lib/session-standup.js +67 -4
  178. package/template/coding-task-manager/lib/session-status-ledger.js +42 -3
  179. package/template/coding-task-manager/lib/session-status-runtime.js +45 -1
  180. package/template/coding-task-manager/lib/session-title-mirror.js +25 -57
  181. package/template/coding-task-manager/lib/session-transcript-trash.js +8 -1
  182. package/template/coding-task-manager/lib/startup-pointer-write.js +57 -0
  183. package/template/coding-task-manager/lib/state-sync/painted-frame-field.js +11 -0
  184. package/template/coding-task-manager/lib/storage/coding-session-model-store.js +21 -22
  185. package/template/coding-task-manager/lib/surviving-owner-bootstrap.js +7 -2
  186. package/template/coding-task-manager/lib/surviving-owner-recovery.js +2 -1
  187. package/template/coding-task-manager/lib/terminal-draft-http-status.js +25 -0
  188. package/template/coding-task-manager/lib/transcript-archiver.js +229 -229
  189. package/template/coding-task-manager/lib/transcript-frame-cache.js +12 -2
  190. package/template/coding-task-manager/lib/transcript-guard-job.js +55 -4
  191. package/template/coding-task-manager/lib/transcript-link.js +77 -0
  192. package/template/coding-task-manager/lib/transcript-manifest-store.js +8 -4
  193. package/template/coding-task-manager/lib/transcript-source.js +8 -3
  194. package/template/coding-task-manager/lib/transcript-store.js +40 -0
  195. package/template/coding-task-manager/lib/tunnel-lane-governor.js +6 -3
  196. package/template/coding-task-manager/lib/typing-interaction-trace.js +92 -0
  197. package/template/coding-task-manager/lib/typing-worker-stages.js +60 -0
  198. package/template/coding-task-manager/lib/visible-revision-watchdog.js +8 -12
  199. package/template/coding-task-manager/lib/wake-skip-reasons.js +46 -0
  200. package/template/coding-task-manager/lib/walle-supervisor.js +98 -14
  201. package/template/coding-task-manager/lib/worker-failure-classify.js +13 -1
  202. package/template/coding-task-manager/lib/ws/state-sync.js +19 -2
  203. package/template/coding-task-manager/lib/ws/terminal-attach.js +32 -1
  204. package/template/coding-task-manager/lib/ws-router.js +68 -1
  205. package/template/coding-task-manager/lib/ws-send-admission.js +22 -4
  206. package/template/coding-task-manager/oauth-proxy.js +99 -55
  207. package/template/coding-task-manager/package-lock.json +24 -0
  208. package/template/coding-task-manager/package.json +3 -0
  209. package/template/coding-task-manager/providers/codex-mcp-extract.js +121 -19
  210. package/template/coding-task-manager/providers/codex-mcp.js +14 -5
  211. package/template/coding-task-manager/public/css/app.css +279 -1
  212. package/template/coding-task-manager/public/css/reviews.css +4 -0
  213. package/template/coding-task-manager/public/index.html +294 -223
  214. package/template/coding-task-manager/public/js/app/machines-page.js +1252 -0
  215. package/template/coding-task-manager/public/js/app/models-tab.js +546 -36
  216. package/template/coding-task-manager/public/js/app/worktrees-panel.js +7 -5
  217. package/template/coding-task-manager/public/js/background-work.js +13 -7
  218. package/template/coding-task-manager/public/js/coding-session-model-presentation.js +44 -4
  219. package/template/coding-task-manager/public/js/core/session-commands.js +676 -0
  220. package/template/coding-task-manager/public/js/core/session-selectors.js +5 -1
  221. package/template/coding-task-manager/public/js/history-app-seam.js +26 -2
  222. package/template/coding-task-manager/public/js/history-painted-rows.js +17 -2
  223. package/template/coding-task-manager/public/js/history-reader-park.js +13 -1
  224. package/template/coding-task-manager/public/js/history-scroller.js +187 -9
  225. package/template/coding-task-manager/public/js/history-transcript-pages.js +5 -5
  226. package/template/coding-task-manager/public/js/machine-pool-shared.js +436 -0
  227. package/template/coding-task-manager/public/js/private-state-scope.js +31 -3
  228. package/template/coding-task-manager/public/js/prompt-submission-client.js +173 -8
  229. package/template/coding-task-manager/public/js/prompt-submission-tray.js +281 -0
  230. package/template/coding-task-manager/public/js/queue-panel-submission-reconcile.js +174 -1
  231. package/template/coding-task-manager/public/js/reviews.js +7 -3
  232. package/template/coding-task-manager/public/js/root-draft-lifetime.js +139 -2
  233. package/template/coding-task-manager/public/js/root-queue-builder-lifetime.js +16 -0
  234. package/template/coding-task-manager/public/js/row-join.js +4 -2
  235. package/template/coding-task-manager/public/js/session-model-picker.js +1 -1
  236. package/template/coding-task-manager/public/js/session-search-utils.js +46 -19
  237. package/template/coding-task-manager/public/js/state-sync-client.js +4 -0
  238. package/template/coding-task-manager/public/js/terminal/runtime-02.js +16 -7
  239. package/template/coding-task-manager/public/js/terminal/runtime-03.js +41 -0
  240. package/template/coding-task-manager/public/js/terminal/runtime-04.js +41 -4
  241. package/template/coding-task-manager/public/js/terminal/runtime-12.js +52 -2
  242. package/template/coding-task-manager/public/js/terminal/runtime-16.js +12 -12
  243. package/template/coding-task-manager/public/js/terminal/runtime-18.js +14 -0
  244. package/template/coding-task-manager/public/js/terminal/runtime-19.js +8 -4
  245. package/template/coding-task-manager/public/js/terminal/runtime-20.js +210 -73
  246. package/template/coding-task-manager/public/js/terminal/runtime-21.js +19 -6
  247. package/template/coding-task-manager/public/js/terminal/runtime-22.js +86 -0
  248. package/template/coding-task-manager/public/js/terminal-history-viewport.js +1 -1
  249. package/template/coding-task-manager/public/js/terminal-wheel.js +39 -2
  250. package/template/coding-task-manager/public/js/walle/chat-conversation.js +11 -3
  251. package/template/coding-task-manager/public/js/walle-session.js +30 -7
  252. package/template/coding-task-manager/public/m/app.css +226 -8
  253. package/template/coding-task-manager/public/m/app.js +502 -9
  254. package/template/coding-task-manager/public/m/index.html +38 -1
  255. package/template/coding-task-manager/public/m/machines.js +1313 -0
  256. package/template/coding-task-manager/public/m/pool-failover.js +391 -0
  257. package/template/coding-task-manager/public/m/private-queue-actions.js +26 -7
  258. package/template/coding-task-manager/public/m/sw.js +5 -0
  259. package/template/coding-task-manager/queue-engine.js +13 -0
  260. package/template/coding-task-manager/server/approvals.js +5 -6
  261. package/template/coding-task-manager/server/boot.js +136 -17
  262. package/template/coding-task-manager/server.js +902 -239
  263. package/template/coding-task-manager/session-integrity.js +7 -9
  264. package/template/coding-task-manager/workers/db-owner-worker.js +53 -7
  265. package/template/coding-task-manager/workers/read-pool-worker.js +17 -6
  266. package/template/coding-task-manager/workers/session-host-pool-process.js +18 -4
  267. package/template/coding-task-manager/workers/session-host-process.js +14 -3
  268. package/template/coding-task-manager/workers/transcript-archive-worker.js +1 -1
  269. package/template/coding-task-manager/workers/worktree-worker.js +34 -0
  270. package/template/package-lock.json +2 -2
  271. package/template/package.json +1 -1
  272. package/template/scripts/conversation-storage-v2-migration.js +78 -11
  273. package/template/shared/conversation-storage-v2-contract.js +42 -6
  274. package/template/shared/fixtures/worker-status-payloads.json +392 -0
  275. package/template/shared/git-remote-key.js +83 -0
  276. package/template/shared/host-identity.js +98 -2
  277. package/template/shared/owner-write-safety.js +135 -0
  278. package/template/shared/public-runtime.js +13 -5
  279. package/template/shared/release-schema.json +3 -2
  280. package/template/shared/report-citations.js +14 -0
  281. package/template/shared/sqlite-write-lock.js +361 -223
  282. package/template/shared/storage/contract.js +35 -3
  283. package/template/wall-e/agent.js +21 -0
  284. package/template/wall-e/api-walle.js +5 -0
  285. package/template/wall-e/bin/brain-purge-legacy-ctm.js +3 -2
  286. package/template/wall-e/bin/walle-mcp-stdio.js +12 -6
  287. package/template/wall-e/brain/helper-rules-schema.js +129 -0
  288. package/template/wall-e/brain/migrations.js +51 -22
  289. package/template/wall-e/brain/model-deployment-facts.js +31 -1
  290. package/template/wall-e/brain/owner-call-whitelist.js +16 -0
  291. package/template/wall-e/brain/schema-ensures.js +22 -0
  292. package/template/wall-e/brain.js +1 -1
  293. package/template/wall-e/coding/journal-dispatcher.js +51 -0
  294. package/template/wall-e/coding/session-journal.js +28 -40
  295. package/template/wall-e/coding-orchestrator.js +23 -26
  296. package/template/wall-e/http/auth.js +18 -1
  297. package/template/wall-e/http/blog-views-api.js +318 -0
  298. package/template/wall-e/http/helper-rules-api.js +321 -0
  299. package/template/wall-e/http/model-proxy-providers.js +3 -1
  300. package/template/wall-e/http/telemetry-api.js +12 -0
  301. package/template/wall-e/lib/blog-view-policy.js +88 -0
  302. package/template/wall-e/lib/blog-view-store.js +169 -0
  303. package/template/wall-e/lib/client-config-lock.js +2 -1
  304. package/template/wall-e/lib/coding-journal-writer-child-client.js +67 -18
  305. package/template/wall-e/lib/error-kinds.js +10 -1
  306. package/template/wall-e/lib/feature-manifest.js +1 -1
  307. package/template/wall-e/lib/helper-rules/cell-state.js +123 -0
  308. package/template/wall-e/lib/helper-rules/evaluate.js +357 -0
  309. package/template/wall-e/lib/helper-rules/explore-rubric.md +12 -0
  310. package/template/wall-e/lib/helper-rules/grade.js +277 -0
  311. package/template/wall-e/lib/helper-rules/label.js +247 -0
  312. package/template/wall-e/lib/helper-rules/lead-call-hook.js +522 -0
  313. package/template/wall-e/lib/helper-rules/store.js +667 -0
  314. package/template/wall-e/lib/mcp-integration.js +5 -6
  315. package/template/wall-e/lib/runtime-worker-pool.js +1 -0
  316. package/template/wall-e/lib/scheduler-worker-jobs.js +6 -0
  317. package/template/wall-e/lib/telemetry-db-schema.js +37 -0
  318. package/template/wall-e/lib/telemetry-process-client.js +76 -1
  319. package/template/wall-e/llm/default-fallback.js +4 -0
  320. package/template/wall-e/llm/model-catalog.js +13 -4
  321. package/template/wall-e/llm/model-roles.js +6 -0
  322. package/template/wall-e/llm/portkey-http.js +150 -0
  323. package/template/wall-e/llm/portkey-sync.js +15 -145
  324. package/template/wall-e/llm/worker-mcp-routing.js +61 -0
  325. package/template/wall-e/llm/worker-route.js +43 -1
  326. package/template/wall-e/loops/brain-custom-writes.js +45 -0
  327. package/template/wall-e/mcp-protocol-contract.js +41 -1
  328. package/template/wall-e/mcp-server.js +13 -2
  329. package/template/wall-e/mcp-worker-schemas.js +20 -2
  330. package/template/wall-e/memory/ctm-context-client.js +25 -5
  331. package/template/wall-e/shared/release-schema.json +3 -2
  332. package/template/wall-e/shared/sqlite-write-lock.js +361 -223
  333. package/template/wall-e/shared/storage/contract.js +35 -3
  334. package/template/wall-e/skills/_templates/delegate-worker/VERSION +1 -1
  335. package/template/wall-e/skills/_templates/delegate-worker/released-sha256.json +6 -0
  336. package/template/wall-e/skills/_templates/delegate-worker/templates/claude/SKILL.md +7 -2
  337. package/template/wall-e/skills/_templates/delegate-worker/templates/codex/SKILL.md +7 -2
  338. package/template/wall-e/tools/local-tools.js +6 -4
  339. package/template/wall-e/workers/brain-owner-worker.js +9 -0
  340. package/template/wall-e/workers/coding-journal-writer-child.js +8 -1
  341. package/template/wall-e/workers/telemetry-worker.js +8 -0
@@ -134,6 +134,7 @@
134
134
  claudeLocalScrollback: null,
135
135
  parkedInLocalScrollback: null,
136
136
  providerOwnsWheel: null,
137
+ codexOwnedDown: null,
137
138
  isNativeRoute: true,
138
139
  nativeDelegate: false,
139
140
  preventNoScrollbackNativeOrSnapshot: true,
@@ -195,7 +196,13 @@
195
196
  && !exited && !parkedInLocalScrollback;
196
197
  const mouseUnknown = isAlt && !mouseActive && providerOwnsWheel && !parkedInLocalScrollback
197
198
  && !codexAltReaderUp;
198
- const shouldForward = mouseActive && providerOwnsWheel && !parkedInLocalScrollback;
199
+ // D-4 (codex-scroll-one-wheel-owner-and-reader-empty-pages-2026-10-24): a Codex app view's wheel
200
+ // has one owner -- CTM. Wheel-down with the reader closed is swallowed (never forwarded: Codex
201
+ // would scroll its own transcript).
202
+ const codexOwnedDown = agentKind === 'codex' && isAlt && mouseActive && deltaY > 0 && !exited
203
+ && !parkedInLocalScrollback;
204
+ const shouldForward = mouseActive && providerOwnsWheel && !parkedInLocalScrollback
205
+ && !codexOwnedDown;
199
206
  const isNativeRoute = wheelRoute === 'native' || (wheelRoute == null && !providerOwnsWheel);
200
207
  // D-2/D-8: the hand-off exclusion is `appMouse && isAlt` (a mouse-claiming alt-screen session),
201
208
  // NOT `parkedInLocalScrollback` -- that raw flag (viewportY < baseY) is ALSO true for a plain
@@ -224,6 +231,7 @@
224
231
  if (nativeDelegate) action = 'native-delegate';
225
232
  else if (mouseUnknown) action = 'mouse-unknown';
226
233
  else if (readerEnterEligible) action = 'reader-enter';
234
+ else if (codexOwnedDown) action = 'swallow';
227
235
  else if (shouldForward) action = 'forward';
228
236
  else if (historyHandoffEligible) action = 'history-handoff';
229
237
  else if (isNativeRoute && hasScrollback) action = 'native-fallthrough';
@@ -241,6 +249,7 @@
241
249
  claudeLocalScrollback,
242
250
  parkedInLocalScrollback,
243
251
  providerOwnsWheel,
252
+ codexOwnedDown,
244
253
  isNativeRoute,
245
254
  nativeDelegate,
246
255
  preventNoScrollbackNativeOrSnapshot,
@@ -344,11 +353,20 @@
344
353
  disposed = true;
345
354
  }
346
355
 
356
+ // D-5 (codex-scroll-one-wheel-owner-and-reader-empty-pages-2026-10-24): drop a report already
357
+ // merged for the NEXT frame -- the caller (index.html's reader-enter path) is switching the
358
+ // wheel's owner to CTM's reader this tick, so bytes queued for the app must not arrive after it.
359
+ // Not a drop: the pending flush simply finds no total and returns.
360
+ function cancel() {
361
+ sum = 0;
362
+ pendingOpts = null;
363
+ }
364
+
347
365
  function stats() {
348
366
  return { dropped };
349
367
  }
350
368
 
351
- return { onWheel, dispose, stats };
369
+ return { onWheel, dispose, stats, cancel };
352
370
  }
353
371
 
354
372
  // S-15 (term-scroll-0933-baseline-and-click-forwarding-2026-09-24 §5 D-4, §6, §9 S-15): pure click
@@ -479,6 +497,13 @@
479
497
  deltaModes: {},
480
498
  droppedAtStart: null,
481
499
  droppedLatest: null,
500
+ // D-6 (codex-scroll-one-wheel-owner-and-reader-empty-pages-2026-10-24): the gesture's own
501
+ // direction/action split -- telemetry could not tell an up-fling from a down-fling, nor a
502
+ // reader-enter from a swallow, without these.
503
+ upEvents: 0,
504
+ downEvents: 0,
505
+ readerEnterEvents: 0,
506
+ swallowedEvents: 0,
482
507
  };
483
508
  }
484
509
 
@@ -532,6 +557,10 @@
532
557
  stepsPerEventP95: percentile(stepsSorted, 95),
533
558
  deltaMode: dominantMode,
534
559
  readerEvents: g.readerEvents, // D-15: events consumed by the open reader's native scroller (route 'reader')
560
+ upEvents: g.upEvents, // D-6: wheel events with deltaY < 0
561
+ downEvents: g.downEvents, // D-6: wheel events with deltaY > 0
562
+ readerEnterEvents: g.readerEnterEvents, // D-6: events that opened the continuous reader
563
+ swallowedEvents: g.swallowedEvents, // D-6: Codex app-view wheel-downs CTM swallowed
535
564
  droppedSteps,
536
565
  },
537
566
  });
@@ -555,6 +584,14 @@
555
584
  if (details.mouseSource !== undefined) gesture.mouseSource = details.mouseSource;
556
585
  if (details.frameTracking !== undefined) gesture.frameTracking = details.frameTracking;
557
586
  if (details.sessionId !== undefined) gesture.sessionId = details.sessionId;
587
+ // D-6: direction + decided action per event, tallied as numbers (the client-diag detail
588
+ // filter keeps numbers; an object of counters would be stripped before the durable row).
589
+ if (typeof details.deltaY === 'number') {
590
+ if (details.deltaY < 0) gesture.upEvents += 1;
591
+ else if (details.deltaY > 0) gesture.downEvents += 1;
592
+ }
593
+ if (details.action === 'reader-enter') gesture.readerEnterEvents += 1;
594
+ else if (details.action === 'swallow') gesture.swallowedEvents += 1;
558
595
  scheduleIdleEnd();
559
596
  }
560
597
 
@@ -1152,11 +1152,16 @@
1152
1152
  chatHistoryLoaded = true;
1153
1153
  chatHistoryThread = tid;
1154
1154
  chatHistoryLoading = true;
1155
+ // B21: the load belongs to the mount that started it. isCurrent() reads whichever mount is
1156
+ // current when the request settles, so without this a load the shell aborted by re-showing
1157
+ // the view (shell.js show() aborts the old ctx.signal, then mounts again) painted its
1158
+ // AbortError into the NEW mount as "Could not load chat history".
1159
+ var owner = _mount;
1155
1160
  _mount.pane.innerHTML = '<div class="walle-loading">Loading chat history...</div>';
1156
1161
  apiGet('/chat/history?session_id=' + encodeURIComponent(tid) + '&limit=200').then(function(data) {
1157
1162
  // Drop a load whose thread (or generation) the user has already left: the
1158
1163
  // view's per-selection ctx is false the moment another thread is selected.
1159
- if (!isCurrent() || currentThreadId() !== tid) return;
1164
+ if (_mount !== owner || !isCurrent() || currentThreadId() !== tid) return;
1160
1165
  var msgs = data.data || [];
1161
1166
  var nodes = (Array.isArray(msgs) ? msgs : []).map(_chatNode).filter(Boolean);
1162
1167
  if (Array.isArray(msgs) && msgs.length > 0) {
@@ -1201,6 +1206,8 @@
1201
1206
  chatHistory = nodes;
1202
1207
  renderChatUI();
1203
1208
  }).catch(function(error) {
1209
+ // A superseded load owns no state: the mount that replaced it started its own.
1210
+ if (_mount !== owner) return;
1204
1211
  chatHistoryLoading = false;
1205
1212
  chatHistoryLoaded = false;
1206
1213
  chatHistoryThread = null;
@@ -2106,8 +2113,9 @@
2106
2113
  if (!activeModelSnapshot()) loadActiveModel();
2107
2114
 
2108
2115
  // Load the active thread's history: once per view, and again whenever the
2109
- // selection moves to a different thread.
2110
- if (!chatHistoryLoaded || chatHistoryThread !== tid) {
2116
+ // selection moves to a different thread. A load still in flight was started by the
2117
+ // previous mount, whose ctx.signal the shell aborted before mounting this one (B21).
2118
+ if (!chatHistoryLoaded || chatHistoryThread !== tid || chatHistoryLoading) {
2111
2119
  loadHistory(tid);
2112
2120
  } else {
2113
2121
  renderChatUI();
@@ -14177,15 +14177,29 @@ window.WalleSession = (function() {
14177
14177
  }, TRANSCRIPT_ATTACH_DEBOUNCE_MS);
14178
14178
  }
14179
14179
 
14180
+ var pageLocation = null;
14181
+ // FU-4: the location subsystem is the shared module the Wall-E shell
14182
+ // created for this surface and published in ONE named place
14183
+ // (public/js/walle/shell.js `WalleShell.location`) — never the panel
14184
+ // global `window.WE`. The shell is created only when the WALL-E panel is
14185
+ // opened, so a coding session driven without it would send a weather
14186
+ // prompt with no location at all (B1); until a shell publishes its
14187
+ // instance, this composer uses one of its own over the same desktop
14188
+ // transport the panel uses (public/js/walle.js `_walleTransport`).
14189
+ function locationForMessage() {
14190
+ if (typeof window === 'undefined') return null;
14191
+ var shell = window.WalleShell || null;
14192
+ if (shell && shell.location) return shell.location;
14193
+ if (pageLocation) return pageLocation;
14194
+ if (!window.WalleLocation || typeof window.WalleLocation.create !== 'function') return null;
14195
+ if (!window.WalleTransport || typeof window.WalleTransport.desktop !== 'function') return null;
14196
+ pageLocation = window.WalleLocation.create({ api: window.WalleTransport.desktop({ base: '' }) });
14197
+ return pageLocation;
14198
+ }
14199
+
14180
14200
  function maybePrepareLocationForMessage(message) {
14181
- // FU-4: the location subsystem is the shared module the Wall-E shell
14182
- // created for this surface and published in ONE named place
14183
- // (public/js/walle/shell.js `WalleShell.location`) — never the panel
14184
- // global `window.WE`. A page with no shell mounted (or no location.js)
14185
- // simply has nothing to prepare.
14186
14201
  try {
14187
- var shell = (typeof window !== 'undefined' && window.WalleShell) || null;
14188
- var location = shell && shell.location;
14202
+ var location = locationForMessage();
14189
14203
  if (location && typeof location.prepareForMessage === 'function') {
14190
14204
  return Promise.resolve(location.prepareForMessage(message));
14191
14205
  }
@@ -18575,6 +18589,15 @@ window.WalleSession = (function() {
18575
18589
  var pushedProjectionEpoch = Math.max(0, Number(msg.projectionEpoch) || 0);
18576
18590
  var knownRowCount = Number(ws._conversationUpdatedRowCount || ws._durableHistoryWatermark || 0) || 0;
18577
18591
  var knownTimestamp = String(ws._conversationUpdatedRowTimestamp || '');
18592
+ // A projection change over a store that is empty on both sides -- the server reports no durable
18593
+ // row and this client has never held one -- has nothing to re-project. The jsonl watcher's
18594
+ // walle-file-new import of a just-created session pushes exactly that (measured 2026-10-26 with
18595
+ // a WS frame probe: rowCount 0, rowMaxTimestamp '', projectionChanged true, ~1.2 s after
18596
+ // creation; the watcher's first scan is silent, so not every session gets it). The forced replace
18597
+ // it triggered could only answer total 0, and it wiped a live Web surface the server never had
18598
+ // (the render spec's synthetic turns). A push that carries rows, or reaches a client that holds
18599
+ // durable rows, is still judged by `ahead` below.
18600
+ if (pushedRowCount === 0 && !pushedTimestamp && knownRowCount === 0) return;
18578
18601
  var ahead = pushedRowCount > knownRowCount
18579
18602
  || (!!pushedTimestamp && pushedTimestamp !== knownTimestamp && pushedRowCount >= knownRowCount)
18580
18603
  || msg.projectionChanged === true;
@@ -3129,7 +3129,15 @@ html[data-theme="light"] .nav-item.active {
3129
3129
  z-index: 42;
3130
3130
  flex-shrink: 0;
3131
3131
  display: grid;
3132
- grid-template-columns: minmax(0, 1fr) 52px;
3132
+ /* field | dictation mic | Send — the mic sits in the composer's CONTROL ROW
3133
+ beside the send button, exactly as the desktop chat row places it
3134
+ (`.walle-chat-input-row`: textarea, mic, Send). It is a grid item of
3135
+ `.composer`, never of `.composer-field`: that field is a single-column grid
3136
+ with a 5px gap, so a mic placed inside it took a row of its own and pushed
3137
+ the whole composer down (143px at 390px wide before, 94px after) — B8/AC-8b.
3138
+ `auto`, not `44px`, so the column collapses to nothing in a browser where
3139
+ `dictation.js` cannot attach a mic. */
3140
+ grid-template-columns: minmax(0, 1fr) auto 52px;
3133
3141
  align-items: start;
3134
3142
  gap: 8px;
3135
3143
  padding: 10px 12px calc(10px + env(safe-area-inset-bottom));
@@ -3151,8 +3159,11 @@ html[data-theme="light"] .nav-item.active {
3151
3159
  opacity: 0.65;
3152
3160
  }
3153
3161
 
3162
+ /* Legacy: the model control now lives in the send menu (`#send-model-option`),
3163
+ so `app.js` only ever REMOVES this class; the extra column keeps the model
3164
+ column where it always was, with the mic's column added for the row above. */
3154
3165
  .composer.has-model-picker {
3155
- grid-template-columns: minmax(0, 1fr) 58px 52px;
3166
+ grid-template-columns: minmax(0, 1fr) auto 58px 52px;
3156
3167
  }
3157
3168
 
3158
3169
  .composer-field {
@@ -3163,6 +3174,22 @@ html[data-theme="light"] .nav-item.active {
3163
3174
  min-width: 0;
3164
3175
  }
3165
3176
 
3177
+ /* The mic button itself is built by public/js/walle/dictation.js and sized
3178
+ `28px x 28px` by the shared `.walle-dictation-mic` rule in `/css/walle.css`
3179
+ (a dense pointer target in the desktop chat row). The phone floors every
3180
+ control at 44px (`button { min-height: 44px }` above), so a 28px mic came out
3181
+ 28 x 44 — under the 44px width floor AC-8b measures. On the phone the mic is a
3182
+ touch target in the composer's control row, so it takes the phone's real
3183
+ target size on both axes. */
3184
+ .composer .walle-dictation-mic {
3185
+ width: 44px;
3186
+ height: 44px;
3187
+ }
3188
+
3189
+ .composer .walle-dictation-mic-slot {
3190
+ align-self: center;
3191
+ }
3192
+
3166
3193
  .composer-attachments {
3167
3194
  display: grid;
3168
3195
  gap: 6px;
@@ -3634,11 +3661,19 @@ html[data-theme="light"] .nav-item.active {
3634
3661
  font-weight: 950;
3635
3662
  }
3636
3663
 
3664
+ /* The menu belongs to the composer it opens from (`#detail-composer` is
3665
+ `position: relative`), so it is anchored to that box: `bottom: calc(100% + 8px)`
3666
+ puts it one small gap above the composer's top edge and it tracks the composer
3667
+ for free — a wrapped mic row, the prompt-history strip, attachments, and the
3668
+ on-screen keyboard inset (`.detail-view` already shrinks by
3669
+ `--mobile-keyboard-offset`). A viewport-relative offset cannot do that: the
3670
+ composer is content-sized, so any fixed pixel offset is wrong the moment the
3671
+ composer grows, and the menu then covers the input it exists to serve. */
3637
3672
  .send-menu {
3638
- position: fixed;
3673
+ position: absolute;
3639
3674
  left: max(12px, env(safe-area-inset-left));
3640
3675
  right: max(12px, env(safe-area-inset-right));
3641
- bottom: calc(var(--mobile-keyboard-offset, 0px) + env(safe-area-inset-bottom) + 96px);
3676
+ bottom: calc(100% + 8px);
3642
3677
  z-index: 52;
3643
3678
  display: grid;
3644
3679
  grid-template-columns: repeat(2, minmax(0, 1fr));
@@ -6026,7 +6061,9 @@ a.mobile-health-row-action {
6026
6061
  }
6027
6062
 
6028
6063
  .composer {
6029
- grid-template-columns: minmax(0, 1fr) 68px;
6064
+ /* field | mic | Send, as in the phone rule: the mic keeps the control row it
6065
+ shares with the send button when the pane widens. */
6066
+ grid-template-columns: minmax(0, 1fr) auto 68px;
6030
6067
  align-items: center;
6031
6068
  gap: 12px;
6032
6069
  padding: 16px clamp(20px, 3vw, 36px) calc(18px + env(safe-area-inset-bottom));
@@ -6040,7 +6077,7 @@ a.mobile-health-row-action {
6040
6077
  }
6041
6078
 
6042
6079
  .composer.has-model-picker {
6043
- grid-template-columns: minmax(0, 1fr) 92px 68px;
6080
+ grid-template-columns: minmax(0, 1fr) auto 92px 68px;
6044
6081
  }
6045
6082
 
6046
6083
  .composer-editor {
@@ -6107,10 +6144,13 @@ a.mobile-health-row-action {
6107
6144
  right: 8px;
6108
6145
  }
6109
6146
 
6147
+ /* Anchored to the composer (see the base .send-menu rule), so the offsets are
6148
+ composer-relative: `--tablet-list-w` is the pane offset already carried by
6149
+ `.detail-view`, and adding it here would double it. */
6110
6150
  .send-menu {
6111
- left: calc(var(--tablet-list-w) + clamp(20px, 3vw, 36px));
6151
+ left: clamp(20px, 3vw, 36px);
6112
6152
  right: clamp(20px, 3vw, 36px);
6113
- bottom: calc(var(--mobile-keyboard-offset, 0px) + env(safe-area-inset-bottom) + 104px);
6153
+ bottom: calc(100% + 10px);
6114
6154
  max-width: 680px;
6115
6155
  }
6116
6156
 
@@ -7328,3 +7368,181 @@ html[data-theme="light"] #view-walle {
7328
7368
  scroll inside their own box instead. */
7329
7369
  #walle-content .walle-body :where(pre, table, img, video, canvas, svg) { max-width: 100%; }
7330
7370
  #walle-content .walle-body :where(pre, table) { overflow-x: auto; }
7371
+
7372
+ /* ── WP-5 machine surfaces (docs/remote-machine-hub-sessions-2026-10-22.html §6.6, D-11, S-16) ──
7373
+ The phone twin of the desktop chip/card styles: same facts, same states, phone-sized targets.
7374
+ A local session renders no chip at all, so local rows are unchanged. */
7375
+ .machine-chip {
7376
+ flex: 0 0 auto;
7377
+ max-width: 44%;
7378
+ overflow: hidden;
7379
+ text-overflow: ellipsis;
7380
+ white-space: nowrap;
7381
+ padding: 1px 8px;
7382
+ border-radius: 999px;
7383
+ font-size: 12px;
7384
+ line-height: 18px;
7385
+ color: var(--purple, #bb9af7);
7386
+ background: color-mix(in srgb, var(--purple, #bb9af7) 18%, transparent);
7387
+ }
7388
+
7389
+ /* Unreachable is a STATE of the same chip, not a different badge. */
7390
+ .machine-chip.unreachable {
7391
+ color: var(--yellow, #e0af68);
7392
+ background: color-mix(in srgb, var(--yellow, #e0af68) 18%, transparent);
7393
+ border: 1px dashed color-mix(in srgb, var(--yellow, #e0af68) 45%, transparent);
7394
+ }
7395
+
7396
+ /* The same-repo / browse hint under the new-session machine choice (desktop .ns-machine-hint). */
7397
+ .machine-hint { display: block; margin-top: 4px; color: var(--fg-dim); font-size: 12px; font-weight: 400; }
7398
+ .machine-hint.warn { color: var(--yellow, #e0af68); }
7399
+
7400
+ /* ── WP-6: the phone Machines page (public/m/machines.js) ──────────────────────────────────────
7401
+ The phone twin of the desktop machines page (public/js/app/machines-page.js): This Mac card, then
7402
+ one card per registry member, then the toolbar. Same facts, same actions, same badges — a card the
7403
+ phone and the desktop can never disagree about. Font sizes stay at or above the 12 px floor and
7404
+ every tappable control is at least 44 px (bin/mobile-css-floor-lint.js). */
7405
+ #phone-machines-card .mp-toolbar {
7406
+ display: flex;
7407
+ flex-wrap: wrap;
7408
+ gap: 8px;
7409
+ margin: 10px 0 4px;
7410
+ }
7411
+ #phone-machines-card .mp-btn {
7412
+ display: inline-flex;
7413
+ align-items: center;
7414
+ min-height: 44px;
7415
+ padding: 0 12px;
7416
+ border: 1px solid var(--border, rgba(255, 255, 255, 0.12));
7417
+ border-radius: 10px;
7418
+ background: var(--bg-light, #24283b);
7419
+ color: var(--fg);
7420
+ font-size: 14px;
7421
+ font-weight: 500;
7422
+ }
7423
+ #phone-machines-card .mp-btn:active { opacity: 0.82; }
7424
+ #phone-machines-card .mp-btn.mp-primary { border-color: var(--accent, #7aa2f7); color: var(--accent, #7aa2f7); }
7425
+ #phone-machines-card .mp-btn.mp-danger { border-color: var(--red, #f7768e); color: var(--red, #f7768e); }
7426
+ #phone-machines-card .mp-card {
7427
+ margin-top: 10px;
7428
+ padding: 10px 12px;
7429
+ border: 1px solid var(--border, rgba(255, 255, 255, 0.09));
7430
+ border-radius: 12px;
7431
+ background: var(--bg-light, #24283b);
7432
+ }
7433
+ #phone-machines-card .mp-card.mp-self { border-color: var(--accent, #7aa2f7); }
7434
+ #phone-machines-card .mp-head { display: flex; align-items: center; gap: 8px; }
7435
+ #phone-machines-card .mp-dot {
7436
+ width: 8px;
7437
+ height: 8px;
7438
+ flex: 0 0 auto;
7439
+ border-radius: 50%;
7440
+ background: var(--fg-dim, #7d8590);
7441
+ }
7442
+ #phone-machines-card .mp-dot[data-health="reachable"] { background: var(--green, #9ece6a); }
7443
+ #phone-machines-card .mp-dot[data-health="unhealthy"] { background: var(--red, #f7768e); }
7444
+ #phone-machines-card .mp-dot[data-health="unknown"] { background: var(--yellow, #e0af68); }
7445
+ #phone-machines-card .mp-name {
7446
+ flex: 1 1 auto;
7447
+ min-width: 0;
7448
+ min-height: 44px;
7449
+ padding: 0 6px;
7450
+ border: 1px solid transparent;
7451
+ border-radius: 8px;
7452
+ background: transparent;
7453
+ color: var(--fg);
7454
+ font-size: 15px;
7455
+ font-weight: 600;
7456
+ }
7457
+ #phone-machines-card .mp-name:focus { border-color: var(--accent, #7aa2f7); outline: none; }
7458
+ #phone-machines-card .mp-cred {
7459
+ flex: 0 0 auto;
7460
+ padding: 2px 8px;
7461
+ border-radius: 999px;
7462
+ background: var(--bg, #1a1b26);
7463
+ color: var(--fg-dim, #7d8590);
7464
+ font-size: 12px;
7465
+ white-space: nowrap;
7466
+ }
7467
+ #phone-machines-card .mp-meta { margin-top: 2px; color: var(--fg-dim); font-size: 12px; overflow-wrap: anywhere; }
7468
+ #phone-machines-card .mp-stale { color: var(--yellow, #e0af68); }
7469
+ #phone-machines-card .mp-error { color: var(--red, #f7768e); font-size: 13px; }
7470
+ #phone-machines-card .mp-sparks { display: flex; gap: 12px; margin-top: 8px; }
7471
+ #phone-machines-card .mp-spark { display: flex; align-items: center; gap: 6px; min-width: 0; }
7472
+ #phone-machines-card .mp-spark-label { color: var(--fg-dim); font-size: 12px; letter-spacing: 0.04em; }
7473
+ #phone-machines-card .mp-spark-val { color: var(--fg); font-size: 12px; }
7474
+ #phone-machines-card .mp-facts { display: flex; flex-wrap: wrap; gap: 4px 14px; margin-top: 8px; }
7475
+ #phone-machines-card .mp-fact { display: flex; gap: 6px; min-width: 0; }
7476
+ #phone-machines-card .mp-fact-label { color: var(--fg-dim); font-size: 12px; }
7477
+ #phone-machines-card .mp-fact-value { color: var(--fg); font-size: 12px; overflow-wrap: anywhere; }
7478
+ #phone-machines-card .mp-actions { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 10px; }
7479
+ #phone-machines-card .mp-fav[aria-pressed="true"] { border-color: var(--yellow, #e0af68); color: var(--yellow, #e0af68); }
7480
+ /* P-7 "Sign in to <member> too": the row that takes this phone to a member's own origin, because a
7481
+ passkey is pinned to its hostname. It is the phone twin of .mpc-signin-row on the desktop page. */
7482
+ #phone-machines-card .mp-signin-row { flex-direction: column; align-items: flex-start; gap: 2px; margin-top: 8px; width: 100%; }
7483
+ #phone-machines-card .mp-signin-hint { color: var(--fg-dim); font-size: 12px; font-weight: 400; overflow-wrap: anywhere; }
7484
+ #phone-machines-card .mp-status:not(:empty) { margin-top: 8px; color: var(--fg-dim); font-size: 12px; }
7485
+
7486
+ /* The Add-machine / Show-a-code dialogs reuse the model-sheet chrome, so only the fields are new. */
7487
+ .mp-modal .mp-modal-label { display: block; margin: 10px 0 4px; color: var(--fg-dim); font-size: 12px; }
7488
+ .mp-modal .mp-modal-input {
7489
+ display: block;
7490
+ width: 100%;
7491
+ min-height: 44px;
7492
+ margin-bottom: 8px;
7493
+ padding: 8px 10px;
7494
+ border: 1px solid var(--border, rgba(255, 255, 255, 0.12));
7495
+ border-radius: 10px;
7496
+ background: var(--bg-light, #24283b);
7497
+ color: var(--fg);
7498
+ font-size: 16px;
7499
+ }
7500
+ .mp-modal .mp-modal-or,
7501
+ .mp-modal .mp-modal-sub { margin: 6px 0; color: var(--fg-dim); font-size: 12px; }
7502
+ .mp-modal .mp-modal-actions { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 8px; }
7503
+ .mp-modal .mp-modal-error:not(:empty) { margin: 6px 0 0; color: var(--red, #f7768e); font-size: 12px; }
7504
+ .mp-modal .mp-pair-preview { min-height: 20px; color: var(--fg-dim); font-size: 12px; overflow-wrap: anywhere; }
7505
+ .mp-modal .mp-code-value {
7506
+ margin: 8px 0;
7507
+ color: var(--accent, #7aa2f7);
7508
+ font-size: 22px;
7509
+ letter-spacing: 0.14em;
7510
+ text-align: center;
7511
+ }
7512
+ .mp-modal .mp-modal-legacy { margin-top: 12px; color: var(--fg-dim); font-size: 12px; }
7513
+
7514
+ /* The new-session machine row (D-1: N > MACHINE_PICKER_CARD_LIMIT opens the search sheet). */
7515
+ .machine-picker-row { display: block; width: 100%; text-align: left; }
7516
+
7517
+ /* ── the machine search sheet (public/m/machines.js, D-2/D-3) ─────────────────────────────────── */
7518
+ .machine-sheet-group { margin-bottom: 10px; }
7519
+ .machine-sheet-group-label {
7520
+ margin: 6px 0 4px;
7521
+ color: var(--fg-dim);
7522
+ font-size: 12px;
7523
+ letter-spacing: 0.04em;
7524
+ text-transform: uppercase;
7525
+ }
7526
+ .machine-sheet-row { flex-direction: column; align-items: flex-start; gap: 2px; }
7527
+ .machine-sheet-row-name { color: var(--fg); font-weight: 600; overflow-wrap: anywhere; }
7528
+ .machine-sheet-row-meta { color: var(--fg-dim); font-size: 12px; overflow-wrap: anywhere; }
7529
+ .machine-sheet-row[disabled] { opacity: 0.6; }
7530
+ .machine-sheet-empty { color: var(--fg-dim); font-size: 13px; }
7531
+
7532
+ /* P-7: the pool failover roster / hand-over banner. */
7533
+ .pool-from-banner-host:empty { display: none; }
7534
+ .pool-from-banner {
7535
+ margin: 8px 12px;
7536
+ padding: 8px 10px;
7537
+ border: 1px solid var(--yellow, #e0af68);
7538
+ border-radius: 10px;
7539
+ color: var(--fg);
7540
+ font-size: 13px;
7541
+ }
7542
+ .pool-failover-list { padding: 0 12px; }
7543
+ .pool-failover-copy { color: var(--fg-dim); font-size: 13px; }
7544
+ .pool-origin-rows { list-style: none; margin: 0; padding: 0; }
7545
+ .pool-origin-row { display: flex; flex-direction: column; gap: 2px; padding: 8px 0; border-bottom: 1px solid var(--border, rgba(255, 255, 255, 0.09)); }
7546
+ .pool-origin-name { color: var(--fg); font-weight: 600; }
7547
+ .pool-origin-state,
7548
+ .pool-origin-address { color: var(--fg-dim); font-size: 12px; overflow-wrap: anywhere; }