create-walle 0.10.0 → 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 (381) hide show
  1. package/README.md +88 -41
  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 +7 -5
  6. package/package.json +10 -4
  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/capture-codex-rollout-records.js +417 -0
  11. package/template/coding-task-manager/bin/census-codex-lead-history.js +325 -0
  12. package/template/coding-task-manager/bin/claude-hook.js +7 -3
  13. package/template/coding-task-manager/bin/claude-table-parity.js +307 -0
  14. package/template/coding-task-manager/bin/conversation-storage-auto-migration-lib.js +16 -1
  15. package/template/coding-task-manager/bin/conversation-storage-generation-evidence.js +9 -2
  16. package/template/coding-task-manager/bin/conversation-storage-service-entry-lib.js +16 -1
  17. package/template/coding-task-manager/bin/conversation-storage-walle-owner.js +247 -0
  18. package/template/coding-task-manager/bin/ctm-machine-pair.js +160 -0
  19. package/template/coding-task-manager/bin/lead-wait-census.js +1348 -0
  20. package/template/coding-task-manager/bin/repair-foreign-clone.js +564 -0
  21. package/template/coding-task-manager/bin/repair-resume-echo-titles.js +248 -0
  22. package/template/coding-task-manager/bin/seam-replay-codex.js +301 -0
  23. package/template/coding-task-manager/bin/write-lock-bench.js +111 -0
  24. package/template/coding-task-manager/db.js +705 -286
  25. package/template/coding-task-manager/git-utils.js +44 -0
  26. package/template/coding-task-manager/lib/adopted-host-redial.js +4 -0
  27. package/template/coding-task-manager/lib/agent-presets.js +15 -0
  28. package/template/coding-task-manager/lib/agent-title-apply.js +88 -0
  29. package/template/coding-task-manager/lib/agent-title-backfill-read.js +92 -0
  30. package/template/coding-task-manager/lib/api/host-stats.js +98 -0
  31. package/template/coding-task-manager/lib/api/ingress.js +35 -12
  32. package/template/coding-task-manager/lib/api/machine-pairing.js +285 -0
  33. package/template/coding-task-manager/lib/api/machine-pool.js +307 -0
  34. package/template/coding-task-manager/lib/api/machines.js +461 -0
  35. package/template/coding-task-manager/lib/api/misc-ops.js +20 -5
  36. package/template/coding-task-manager/lib/api/providers.js +53 -6
  37. package/template/coding-task-manager/lib/api/resume-from-store.js +25 -0
  38. package/template/coding-task-manager/lib/api/sessions.js +160 -8
  39. package/template/coding-task-manager/lib/api/transcript-history.js +17 -4
  40. package/template/coding-task-manager/lib/api/worktrees.js +38 -37
  41. package/template/coding-task-manager/lib/approval-drift.js +16 -1
  42. package/template/coding-task-manager/lib/approval-logical-frame.js +5 -1
  43. package/template/coding-task-manager/lib/approval-scope.js +68 -4
  44. package/template/coding-task-manager/lib/auth-context.js +32 -2
  45. package/template/coding-task-manager/lib/auth-rate-limit.js +41 -1
  46. package/template/coding-task-manager/lib/auth-rules.js +186 -45
  47. package/template/coding-task-manager/lib/broadcast-serialize.js +2 -1
  48. package/template/coding-task-manager/lib/browser-session-broker.js +9 -1
  49. package/template/coding-task-manager/lib/browser-use-adapter.js +33 -2
  50. package/template/coding-task-manager/lib/claude-markdown-ansi.js +27 -85
  51. package/template/coding-task-manager/lib/claude-session-title.js +6 -30
  52. package/template/coding-task-manager/lib/claude-table-layout.js +322 -0
  53. package/template/coding-task-manager/lib/client-diag-handler.js +25 -0
  54. package/template/coding-task-manager/lib/codex-config-guard.js +33 -3
  55. package/template/coding-task-manager/lib/codex-harness-qualification.js +12 -0
  56. package/template/coding-task-manager/lib/codex-history-terminal-renderer.js +33 -33
  57. package/template/coding-task-manager/lib/codex-launch-health.js +29 -2
  58. package/template/coding-task-manager/lib/codex-link-preparation.js +9 -8
  59. package/template/coding-task-manager/lib/codex-local-links.js +267 -0
  60. package/template/coding-task-manager/lib/codex-markdown-lists.js +160 -0
  61. package/template/coding-task-manager/lib/codex-native-history-prefix.js +4 -0
  62. package/template/coding-task-manager/lib/codex-paths.js +2 -1
  63. package/template/coding-task-manager/lib/codex-source-handoff.js +186 -0
  64. package/template/coding-task-manager/lib/coding-agent-models.js +21 -30
  65. package/template/coding-task-manager/lib/coding-session-model-adapters.js +27 -2
  66. package/template/coding-task-manager/lib/coding-session-model-projection.js +5 -0
  67. package/template/coding-task-manager/lib/coding-session-model-runtime.js +1 -2
  68. package/template/coding-task-manager/lib/coding-session-model-state.js +10 -0
  69. package/template/coding-task-manager/lib/coding-session-model-sync-state.js +0 -1
  70. package/template/coding-task-manager/lib/conversation-import/cursor-guard-owner.js +10 -0
  71. package/template/coding-task-manager/lib/create/resolve-launch-params.js +8 -1
  72. package/template/coding-task-manager/lib/ctm-boot-lifecycle.js +17 -1
  73. package/template/coding-task-manager/lib/db-domain-tables.js +7 -0
  74. package/template/coding-task-manager/lib/db-domains.js +21 -2
  75. package/template/coding-task-manager/lib/db-owner-op-registry.js +7 -0
  76. package/template/coding-task-manager/lib/db-owner-worker-client.js +22 -0
  77. package/template/coding-task-manager/lib/db-schema-source-files.js +1 -0
  78. package/template/coding-task-manager/lib/feature-manifest.js +1 -3
  79. package/template/coding-task-manager/lib/fs-watcher.js +3 -2
  80. package/template/coding-task-manager/lib/harness-history-transition.js +41 -14
  81. package/template/coding-task-manager/lib/headless-inflight-ops.js +203 -0
  82. package/template/coding-task-manager/lib/headless-missing-reply.js +42 -0
  83. package/template/coding-task-manager/lib/headless-term-service.js +60 -23
  84. package/template/coding-task-manager/lib/history-transition-read-op.js +179 -23
  85. package/template/coding-task-manager/lib/host-control-dial.js +167 -0
  86. package/template/coding-task-manager/lib/host-handoff-orchestrator.js +16 -2
  87. package/template/coding-task-manager/lib/host-handoff.js +51 -13
  88. package/template/coding-task-manager/lib/host-health-ledger.js +164 -12
  89. package/template/coding-task-manager/lib/host-self-truth-watchdog.js +4 -0
  90. package/template/coding-task-manager/lib/host-stats.js +328 -0
  91. package/template/coding-task-manager/lib/host-threadpool-evacuation.js +160 -0
  92. package/template/coding-task-manager/lib/host-threadpool-monitor.js +14 -1
  93. package/template/coding-task-manager/lib/hosted-input-dispatch.js +203 -0
  94. package/template/coding-task-manager/lib/hosted-sync-worker.js +113 -5
  95. package/template/coding-task-manager/lib/instance-id-ownership-manifest.js +4 -0
  96. package/template/coding-task-manager/lib/instance-manifest-runtime.js +3 -0
  97. package/template/coding-task-manager/lib/instance-manifest.js +13 -1
  98. package/template/coding-task-manager/lib/instance-sync-status.js +15 -0
  99. package/template/coding-task-manager/lib/kernel/diag-log.js +12 -0
  100. package/template/coding-task-manager/lib/launch-model-override.js +160 -1
  101. package/template/coding-task-manager/lib/launch-plan-worker.js +59 -2
  102. package/template/coding-task-manager/lib/lead-model-observer.js +17 -2
  103. package/template/coding-task-manager/lib/lead-model-switch-runtime.js +57 -4
  104. package/template/coding-task-manager/lib/lead-model-switch.js +11 -2
  105. package/template/coding-task-manager/lib/lead-model-transition-runtime.js +42 -4
  106. package/template/coding-task-manager/lib/lead-model-transition-store.js +61 -3
  107. package/template/coding-task-manager/lib/legacy-draft-cancellation-recovery.js +111 -0
  108. package/template/coding-task-manager/lib/login-tripwire.js +18 -0
  109. package/template/coding-task-manager/lib/machine-pairing.js +238 -0
  110. package/template/coding-task-manager/lib/machine-pool.js +409 -0
  111. package/template/coding-task-manager/lib/machine-registry.js +749 -0
  112. package/template/coding-task-manager/lib/machine-self.js +66 -0
  113. package/template/coding-task-manager/lib/main-thread-lint-exemptions.json +56 -4
  114. package/template/coding-task-manager/lib/media-journal-control-reader.js +473 -0
  115. package/template/coding-task-manager/lib/media-journal.js +84 -27
  116. package/template/coding-task-manager/lib/media-store-options.js +43 -15
  117. package/template/coding-task-manager/lib/migrations/v56-host-samples-and-machine-pool.js +76 -0
  118. package/template/coding-task-manager/lib/mirror-feed-sanitize.js +12 -3
  119. package/template/coding-task-manager/lib/model-execution-recipe-metadata.js +16 -3
  120. package/template/coding-task-manager/lib/model-proxy/anthropic-face.js +4 -0
  121. package/template/coding-task-manager/lib/model-proxy/chat-response-translators.js +3 -0
  122. package/template/coding-task-manager/lib/model-proxy/collaboration-codec.js +94 -0
  123. package/template/coding-task-manager/lib/model-proxy/handoff.js +494 -0
  124. package/template/coding-task-manager/lib/model-proxy/lead-worker-picks.js +25 -0
  125. package/template/coding-task-manager/lib/model-proxy/native-lead-listener.js +61 -7
  126. package/template/coding-task-manager/lib/model-proxy/proxy-cli.js +200 -0
  127. package/template/coding-task-manager/lib/model-proxy/proxy-instance-record.js +257 -0
  128. package/template/coding-task-manager/lib/model-proxy/responses-face.js +24 -2
  129. package/template/coding-task-manager/lib/model-proxy/stream-accounting.js +205 -0
  130. package/template/coding-task-manager/lib/model-proxy/tokens.js +78 -0
  131. package/template/coding-task-manager/lib/model-proxy/upstream-outcome.js +9 -0
  132. package/template/coding-task-manager/lib/native-history-control.js +62 -14
  133. package/template/coding-task-manager/lib/native-lead-settings-client.js +2 -1
  134. package/template/coding-task-manager/lib/native-lead-tls.js +18 -4
  135. package/template/coding-task-manager/lib/oauth-proxy-supervisor.js +628 -64
  136. package/template/coding-task-manager/lib/owner-action-manifest-data.json +14 -0
  137. package/template/coding-task-manager/lib/painted-row-recorder.js +9 -1
  138. package/template/coding-task-manager/lib/prompt-admission-trace.js +69 -0
  139. package/template/coding-task-manager/lib/prompt-submission-contract.js +21 -1
  140. package/template/coding-task-manager/lib/provider-login-broker.js +192 -9
  141. package/template/coding-task-manager/lib/provider-login-capture.js +153 -0
  142. package/template/coding-task-manager/lib/queue-draft-status-overlay.js +36 -0
  143. package/template/coding-task-manager/lib/raw-codex-history-window.js +5 -3
  144. package/template/coding-task-manager/lib/raw-history-block.js +3 -1
  145. package/template/coding-task-manager/lib/read-pool-client.js +36 -24
  146. package/template/coding-task-manager/lib/read-pool-op-registry.js +10 -1
  147. package/template/coding-task-manager/lib/read-pool-telemetry.js +14 -5
  148. package/template/coding-task-manager/lib/recent-catalog-query.js +26 -0
  149. package/template/coding-task-manager/lib/recent-session-catalog-response.js +9 -0
  150. package/template/coding-task-manager/lib/remote-command-context.js +12 -0
  151. package/template/coding-task-manager/lib/remote-command-runtime.js +18 -5
  152. package/template/coding-task-manager/lib/remote-machine-catalog.js +1062 -0
  153. package/template/coding-task-manager/lib/remote-machine-create.js +693 -0
  154. package/template/coding-task-manager/lib/remote-machine-link.js +939 -0
  155. package/template/coding-task-manager/lib/remote-machine-proxy.js +520 -0
  156. package/template/coding-task-manager/lib/remote-session-forward.js +306 -0
  157. package/template/coding-task-manager/lib/remote-submission-status.js +6 -0
  158. package/template/coding-task-manager/lib/restart-outcome-truth.js +20 -3
  159. package/template/coding-task-manager/lib/restart-preflight.js +9 -2
  160. package/template/coding-task-manager/lib/restore-backoff-gate.js +10 -2
  161. package/template/coding-task-manager/lib/restore-prepare-retry.js +12 -5
  162. package/template/coding-task-manager/lib/restore-resume-batch.js +22 -1
  163. package/template/coding-task-manager/lib/resume-blocked-wire.js +62 -1
  164. package/template/coding-task-manager/lib/resume-cwd.js +13 -0
  165. package/template/coding-task-manager/lib/resume-from-store.js +12 -1
  166. package/template/coding-task-manager/lib/resume-origin-facts.js +38 -1
  167. package/template/coding-task-manager/lib/resume-preflight.js +21 -16
  168. package/template/coding-task-manager/lib/review-repo-admission.js +39 -6
  169. package/template/coding-task-manager/lib/review-repo-registry.js +17 -0
  170. package/template/coding-task-manager/lib/root-delivery-runtime.js +72 -15
  171. package/template/coding-task-manager/lib/root-delivery-selection.js +37 -1
  172. package/template/coding-task-manager/lib/root-prompt-admission.js +43 -11
  173. package/template/coding-task-manager/lib/root-prompt-flow.js +175 -38
  174. package/template/coding-task-manager/lib/scrollback-archive-store.js +7 -4
  175. package/template/coding-task-manager/lib/server-memory-sampler-runtime.js +10 -0
  176. package/template/coding-task-manager/lib/server-memory-sampler.js +41 -2
  177. package/template/coding-task-manager/lib/session-analysis-memory.js +2 -0
  178. package/template/coding-task-manager/lib/session-create/codex-native-provider-gate.js +218 -0
  179. package/template/coding-task-manager/lib/session-create/codex-resume-exit-classify.js +52 -0
  180. package/template/coding-task-manager/lib/session-create/delegate-worker.js +95 -6
  181. package/template/coding-task-manager/lib/session-create/identity.js +20 -1
  182. package/template/coding-task-manager/lib/session-create/prepared.js +69 -1
  183. package/template/coding-task-manager/lib/session-create/provider-launch-context.js +77 -0
  184. package/template/coding-task-manager/lib/session-create/provider-process.js +38 -39
  185. package/template/coding-task-manager/lib/session-create/response.js +30 -12
  186. package/template/coding-task-manager/lib/session-create/transcript.js +13 -4
  187. package/template/coding-task-manager/lib/session-create/worker-continuation.js +43 -1
  188. package/template/coding-task-manager/lib/session-create/worker-notices.js +94 -5
  189. package/template/coding-task-manager/lib/session-create/worker-observability.js +99 -7
  190. package/template/coding-task-manager/lib/session-create/worker-stop.js +11 -3
  191. package/template/coding-task-manager/lib/session-create/worker-wait-watcher.js +315 -0
  192. package/template/coding-task-manager/lib/session-geometry-authority-handler.js +10 -1
  193. package/template/coding-task-manager/lib/session-host-manager.js +152 -206
  194. package/template/coding-task-manager/lib/session-jobs.js +17 -9
  195. package/template/coding-task-manager/lib/session-lifecycle.js +20 -50
  196. package/template/coding-task-manager/lib/session-model-action-preconditions.js +68 -3
  197. package/template/coding-task-manager/lib/session-resource-sampler.js +67 -9
  198. package/template/coding-task-manager/lib/session-standup.js +67 -4
  199. package/template/coding-task-manager/lib/session-status-ledger.js +42 -3
  200. package/template/coding-task-manager/lib/session-status-runtime.js +45 -1
  201. package/template/coding-task-manager/lib/session-status.js +2 -2
  202. package/template/coding-task-manager/lib/session-title-mirror.js +25 -57
  203. package/template/coding-task-manager/lib/session-transcript-trash.js +8 -1
  204. package/template/coding-task-manager/lib/startup-pointer-write.js +57 -0
  205. package/template/coding-task-manager/lib/state-sync/painted-frame-field.js +11 -0
  206. package/template/coding-task-manager/lib/storage/coding-session-model-store.js +21 -22
  207. package/template/coding-task-manager/lib/surviving-owner-bootstrap.js +7 -2
  208. package/template/coding-task-manager/lib/surviving-owner-recovery.js +2 -1
  209. package/template/coding-task-manager/lib/terminal-draft-http-status.js +25 -0
  210. package/template/coding-task-manager/lib/transcript-archiver.js +229 -229
  211. package/template/coding-task-manager/lib/transcript-frame-cache.js +12 -2
  212. package/template/coding-task-manager/lib/transcript-guard-job.js +55 -4
  213. package/template/coding-task-manager/lib/transcript-link.js +77 -0
  214. package/template/coding-task-manager/lib/transcript-manifest-store.js +8 -4
  215. package/template/coding-task-manager/lib/transcript-source.js +8 -3
  216. package/template/coding-task-manager/lib/transcript-store.js +40 -0
  217. package/template/coding-task-manager/lib/tunnel-lane-governor.js +6 -3
  218. package/template/coding-task-manager/lib/typing-interaction-trace.js +136 -2
  219. package/template/coding-task-manager/lib/typing-worker-stages.js +208 -1
  220. package/template/coding-task-manager/lib/usage-ledger/claude-parse.js +53 -2
  221. package/template/coding-task-manager/lib/usage-ledger/ingest.js +13 -4
  222. package/template/coding-task-manager/lib/usage-ledger/read.js +14 -0
  223. package/template/coding-task-manager/lib/usage-ledger/schema.js +49 -1
  224. package/template/coding-task-manager/lib/usage-ledger/store.js +337 -6
  225. package/template/coding-task-manager/lib/usage-ledger/task-read.js +123 -5
  226. package/template/coding-task-manager/lib/visible-revision-watchdog.js +8 -12
  227. package/template/coding-task-manager/lib/wake-skip-reasons.js +46 -0
  228. package/template/coding-task-manager/lib/walle-supervisor.js +98 -14
  229. package/template/coding-task-manager/lib/worker-failure-classify.js +13 -1
  230. package/template/coding-task-manager/lib/ws/input.js +1 -0
  231. package/template/coding-task-manager/lib/ws/state-sync.js +19 -2
  232. package/template/coding-task-manager/lib/ws/terminal-attach.js +32 -1
  233. package/template/coding-task-manager/lib/ws-router.js +68 -1
  234. package/template/coding-task-manager/lib/ws-send-admission.js +22 -4
  235. package/template/coding-task-manager/oauth-proxy.js +99 -55
  236. package/template/coding-task-manager/package-lock.json +24 -0
  237. package/template/coding-task-manager/package.json +3 -0
  238. package/template/coding-task-manager/protocol/message-table.json +0 -10
  239. package/template/coding-task-manager/protocol/messages.js +0 -10
  240. package/template/coding-task-manager/protocol/ws-schema.json +0 -20
  241. package/template/coding-task-manager/protocol/ws-schema.md +0 -2
  242. package/template/coding-task-manager/providers/codex-mcp-extract.js +121 -19
  243. package/template/coding-task-manager/providers/codex-mcp.js +14 -5
  244. package/template/coding-task-manager/public/css/app.css +279 -2
  245. package/template/coding-task-manager/public/css/reviews.css +4 -0
  246. package/template/coding-task-manager/public/index.html +297 -240
  247. package/template/coding-task-manager/public/js/app/machines-page.js +1252 -0
  248. package/template/coding-task-manager/public/js/app/models-tab.js +546 -36
  249. package/template/coding-task-manager/public/js/app/worktrees-panel.js +7 -5
  250. package/template/coding-task-manager/public/js/background-work.js +13 -7
  251. package/template/coding-task-manager/public/js/client-health-core.js +81 -0
  252. package/template/coding-task-manager/public/js/client-health-main.js +61 -0
  253. package/template/coding-task-manager/public/js/coding-session-model-presentation.js +44 -4
  254. package/template/coding-task-manager/public/js/core/session-commands.js +676 -0
  255. package/template/coding-task-manager/public/js/core/session-selectors.js +5 -1
  256. package/template/coding-task-manager/public/js/history-app-seam.js +26 -2
  257. package/template/coding-task-manager/public/js/history-painted-rows.js +17 -2
  258. package/template/coding-task-manager/public/js/history-reader-park.js +13 -1
  259. package/template/coding-task-manager/public/js/history-scroller.js +187 -9
  260. package/template/coding-task-manager/public/js/history-transcript-pages.js +5 -5
  261. package/template/coding-task-manager/public/js/machine-pool-shared.js +436 -0
  262. package/template/coding-task-manager/public/js/private-state-scope.js +31 -3
  263. package/template/coding-task-manager/public/js/prompt-submission-client.js +173 -4
  264. package/template/coding-task-manager/public/js/prompt-submission-tray.js +281 -0
  265. package/template/coding-task-manager/public/js/protocol.js +0 -10
  266. package/template/coding-task-manager/public/js/queue-panel-submission-reconcile.js +174 -1
  267. package/template/coding-task-manager/public/js/reviews.js +7 -3
  268. package/template/coding-task-manager/public/js/root-draft-lifetime.js +139 -2
  269. package/template/coding-task-manager/public/js/root-queue-builder-lifetime.js +16 -0
  270. package/template/coding-task-manager/public/js/row-join.js +18 -3
  271. package/template/coding-task-manager/public/js/session-model-picker.js +1 -1
  272. package/template/coding-task-manager/public/js/session-search-utils.js +46 -19
  273. package/template/coding-task-manager/public/js/session-usage-view.js +1 -0
  274. package/template/coding-task-manager/public/js/state-sync-client.js +4 -0
  275. package/template/coding-task-manager/public/js/terminal/runtime-02.js +16 -7
  276. package/template/coding-task-manager/public/js/terminal/runtime-03.js +41 -0
  277. package/template/coding-task-manager/public/js/terminal/runtime-04.js +41 -4
  278. package/template/coding-task-manager/public/js/terminal/runtime-12.js +52 -2
  279. package/template/coding-task-manager/public/js/terminal/runtime-16.js +12 -12
  280. package/template/coding-task-manager/public/js/terminal/runtime-18.js +14 -0
  281. package/template/coding-task-manager/public/js/terminal/runtime-19.js +8 -4
  282. package/template/coding-task-manager/public/js/terminal/runtime-20.js +210 -73
  283. package/template/coding-task-manager/public/js/terminal/runtime-21.js +19 -6
  284. package/template/coding-task-manager/public/js/terminal/runtime-22.js +86 -0
  285. package/template/coding-task-manager/public/js/terminal-history-viewport.js +1 -3
  286. package/template/coding-task-manager/public/js/terminal-wheel.js +39 -2
  287. package/template/coding-task-manager/public/js/walle/chat-conversation.js +11 -3
  288. package/template/coding-task-manager/public/js/walle-session.js +30 -7
  289. package/template/coding-task-manager/public/m/app.css +226 -8
  290. package/template/coding-task-manager/public/m/app.js +502 -9
  291. package/template/coding-task-manager/public/m/index.html +38 -1
  292. package/template/coding-task-manager/public/m/machines.js +1313 -0
  293. package/template/coding-task-manager/public/m/pool-failover.js +391 -0
  294. package/template/coding-task-manager/public/m/private-queue-actions.js +26 -7
  295. package/template/coding-task-manager/public/m/sw.js +5 -0
  296. package/template/coding-task-manager/queue-engine.js +13 -0
  297. package/template/coding-task-manager/server/approvals.js +5 -6
  298. package/template/coding-task-manager/server/boot.js +136 -17
  299. package/template/coding-task-manager/server.js +964 -425
  300. package/template/coding-task-manager/session-integrity.js +7 -9
  301. package/template/coding-task-manager/workers/db-owner-worker.js +53 -7
  302. package/template/coding-task-manager/workers/read-pool-worker.js +17 -6
  303. package/template/coding-task-manager/workers/session-host-pool-process.js +18 -4
  304. package/template/coding-task-manager/workers/session-host-process.js +14 -3
  305. package/template/coding-task-manager/workers/transcript-archive-worker.js +1 -1
  306. package/template/coding-task-manager/workers/worktree-worker.js +34 -0
  307. package/template/package-lock.json +2 -2
  308. package/template/package.json +1 -1
  309. package/template/scripts/conversation-storage-v2-migration.js +78 -11
  310. package/template/shared/conversation-storage-v2-contract.js +42 -6
  311. package/template/shared/fixtures/worker-status-payloads.json +392 -0
  312. package/template/shared/git-remote-key.js +83 -0
  313. package/template/shared/host-identity.js +98 -2
  314. package/template/shared/owner-write-safety.js +135 -0
  315. package/template/shared/public-runtime.js +13 -5
  316. package/template/shared/release-schema.json +3 -2
  317. package/template/shared/report-citations.js +14 -0
  318. package/template/shared/sqlite-write-lock.js +361 -223
  319. package/template/shared/storage/contract.js +35 -3
  320. package/template/wall-e/agent.js +21 -0
  321. package/template/wall-e/api-walle.js +5 -0
  322. package/template/wall-e/bin/brain-purge-legacy-ctm.js +3 -2
  323. package/template/wall-e/bin/walle-mcp-stdio.js +12 -6
  324. package/template/wall-e/brain/helper-rules-schema.js +129 -0
  325. package/template/wall-e/brain/migrations.js +51 -22
  326. package/template/wall-e/brain/model-deployment-facts.js +31 -1
  327. package/template/wall-e/brain/owner-call-whitelist.js +16 -0
  328. package/template/wall-e/brain/schema-ensures.js +22 -0
  329. package/template/wall-e/brain.js +1 -1
  330. package/template/wall-e/coding/host-capabilities.js +2 -2
  331. package/template/wall-e/coding/journal-dispatcher.js +51 -0
  332. package/template/wall-e/coding/session-journal.js +28 -40
  333. package/template/wall-e/coding-orchestrator.js +23 -26
  334. package/template/wall-e/fly.toml +1 -1
  335. package/template/wall-e/http/auth.js +18 -1
  336. package/template/wall-e/http/blog-views-api.js +318 -0
  337. package/template/wall-e/http/helper-rules-api.js +321 -0
  338. package/template/wall-e/http/model-proxy-providers.js +3 -1
  339. package/template/wall-e/http/telemetry-api.js +12 -0
  340. package/template/wall-e/lib/blog-view-policy.js +88 -0
  341. package/template/wall-e/lib/blog-view-store.js +169 -0
  342. package/template/wall-e/lib/client-config-lock.js +2 -1
  343. package/template/wall-e/lib/coding-journal-writer-child-client.js +67 -18
  344. package/template/wall-e/lib/error-kinds.js +10 -1
  345. package/template/wall-e/lib/feature-manifest.js +1 -1
  346. package/template/wall-e/lib/helper-rules/cell-state.js +123 -0
  347. package/template/wall-e/lib/helper-rules/evaluate.js +357 -0
  348. package/template/wall-e/lib/helper-rules/explore-rubric.md +12 -0
  349. package/template/wall-e/lib/helper-rules/grade.js +277 -0
  350. package/template/wall-e/lib/helper-rules/label.js +247 -0
  351. package/template/wall-e/lib/helper-rules/lead-call-hook.js +522 -0
  352. package/template/wall-e/lib/helper-rules/store.js +667 -0
  353. package/template/wall-e/lib/mcp-integration.js +5 -6
  354. package/template/wall-e/lib/runtime-worker-pool.js +1 -0
  355. package/template/wall-e/lib/scheduler-worker-jobs.js +6 -0
  356. package/template/wall-e/lib/telemetry-db-schema.js +37 -0
  357. package/template/wall-e/lib/telemetry-process-client.js +76 -1
  358. package/template/wall-e/llm/default-fallback.js +4 -0
  359. package/template/wall-e/llm/model-catalog.js +13 -4
  360. package/template/wall-e/llm/model-roles.js +6 -0
  361. package/template/wall-e/llm/portkey-http.js +150 -0
  362. package/template/wall-e/llm/portkey-sync.js +15 -145
  363. package/template/wall-e/llm/worker-mcp-routing.js +61 -0
  364. package/template/wall-e/llm/worker-route.js +43 -1
  365. package/template/wall-e/loops/brain-custom-writes.js +45 -0
  366. package/template/wall-e/mcp-protocol-contract.js +41 -1
  367. package/template/wall-e/mcp-server.js +13 -2
  368. package/template/wall-e/mcp-worker-schemas.js +20 -2
  369. package/template/wall-e/memory/ctm-context-client.js +25 -5
  370. package/template/wall-e/shared/release-schema.json +3 -2
  371. package/template/wall-e/shared/sqlite-write-lock.js +361 -223
  372. package/template/wall-e/shared/storage/contract.js +35 -3
  373. package/template/wall-e/skills/_templates/delegate-worker/VERSION +1 -1
  374. package/template/wall-e/skills/_templates/delegate-worker/released-sha256.json +6 -0
  375. package/template/wall-e/skills/_templates/delegate-worker/templates/claude/SKILL.md +7 -2
  376. package/template/wall-e/skills/_templates/delegate-worker/templates/codex/SKILL.md +7 -2
  377. package/template/wall-e/tools/local-tools.js +12 -5
  378. package/template/wall-e/workers/brain-owner-worker.js +9 -0
  379. package/template/wall-e/workers/coding-journal-writer-child.js +8 -1
  380. package/template/wall-e/workers/telemetry-worker.js +8 -0
  381. package/template/coding-task-manager/lib/giant-freeze-park.js +0 -31
package/README.md CHANGED
@@ -1,44 +1,103 @@
1
1
  # create-walle
2
2
 
3
- **Run your agents. Keep your context.** Set up CTM's coding workspace and Wall-E's personal agent and memory in one command. Run coding sessions side by side, delegate focused tasks, review results, and recover the decisions behind them.
3
+ **One workspace for your coding agents. Context that carries forward.**
4
4
 
5
- ## What You Get
5
+ Install **CTM** (Coding Task Manager) and **Wall-E** in one command. CTM runs coding agents in real terminals on your machine and gives them a browser workspace for sessions, worktrees, approvals and review. Wall-E is the personal agent alongside it, keeping project knowledge and preferences for later work.
6
6
 
7
- ### CTM (Coding Task Manager)
7
+ Different tasks suit different agents, so choose per session instead of committing to one up front.
8
8
 
9
- A web dashboard for running and managing AI coding sessions across multiple providers.
9
+ Start at [walle.sh](https://walle.sh), or follow the [illustrated walkthrough](https://walle.sh/blog/paste-the-link/) for the same workflow with more detail and examples.
10
10
 
11
- - **Sessions & history** — Run Claude Code, Codex, Gemini CLI, OpenCode, Cursor Agent, Wall-E, and shell sessions with persistent scrollback. Session features vary by agent.
12
- - **Delegated workers** — Delegate focused implementation tasks to Claude or Codex workers, and choose the model and effort for the work.
13
- - **Prompts & queues** — Save prompts, organize them, and queue work for a deliberate sequence.
14
- - **Review & approvals** — Review code and documents, with approval workflows where the connected agent supports them. Rich review is supported for Claude, Codex, OpenCode, and Wall-E.
15
- - **Remote phone & tablet access** — Configure access to the running host from a phone or tablet when you need to check in away from your desk.
16
- - **Models** — Set a default or choose a model by task and role. Claude and Codex support lead-model switching; Wall-E has its own native model configuration.
11
+ ## Quick start
17
12
 
18
- ### Wall-E (personal agent and memory)
13
+ ```bash
14
+ npx create-walle install ./walle
15
+ ```
19
16
 
20
- Wall-E brings searchable memory, connected tools, and reusable workflows to your work. Use its chat or connect compatible coding agents through MCP to look up shared memory and prior session history.
17
+ Install **Node.js 24.22.0 or later** and npm first. The installer manages the supported runtime for CTM and Wall-E; that runtime requires macOS 13.5 or later, or Linux with glibc 2.28 or later and kernel 4.18 or later.
21
18
 
22
- - **Chat** — Threaded conversations with a pinned Home thread. Chat can search memories, recall sessions, run skills, call configured MCP tools, and schedule jobs.
23
- - **Inbox and approvals** — One inbox for what needs your attention. Actions that leave your machine follow per-capability policies: allowed, asked for approval, or denied.
24
- - **Jobs** — Scheduled and one-off work (briefings, reflections, Slack inbound) with run history. Nothing runs on a schedule unless you configure it.
25
- - **Searchable memory** — Knowledge, entities, and timeline, available to the chat and to coding agents through MCP.
26
- - **Connected sources** — Optional integrations (for example Slack, with auto-replies only to an allowlist you set). They require the relevant accounts and permissions.
27
- - **Phone** — The same Wall-E views on the CTM phone app.
19
+ The command copies the project, installs dependencies and starts the server. Open **http://localhost:3456** to finish setup in the browser, then authenticate the agents and providers you choose and configure any optional connections or remote device access. The npm installation is the current path on macOS and Linux; the Mac app is still being updated.
28
20
 
29
- ## Install
21
+ ![CTM's session list with Claude Code and Codex sessions grouped under Running, Needs You and Idle, and two worker sessions nested beneath their lead.](https://walle.sh/blog/paste-the-link/img/fig-1-workspace.png)
30
22
 
31
- Install **Node.js 24.22.0 or later** and npm first. The installer manages the supported runtime for CTM and Wall-E.
23
+ Screenshots show the real application with fictional `acme-ledger` data and scripted agent dialogue.
32
24
 
33
- The managed Node runtime requires macOS 13.5 or later, or supported Linux with glibc 2.28 or later and kernel 4.18 or later.
25
+ ## Why CTM and Wall-E
34
26
 
35
- ```bash
36
- npx create-walle install ./walle
27
+ ### Choose the agent for the task
28
+
29
+ Every session has its own agent choice. Run Claude Code, Codex, Gemini CLI, OpenCode, Cursor Agent, Wall-E or a shell side by side and move between them from the same workspace.
30
+
31
+ The CLI, the model and the connection serving that model are separate decisions: the AI Providers area brings native agent options, direct provider connections and configured routers into one place, using your own accounts and credentials. Agents differ in what they support, so the available model-switching controls depend on the CLI you pick.
32
+
33
+ ### See what each agent needs
34
+
35
+ Running, Needs You and Idle group the session list by what requires attention, and delegated workers appear beneath the lead session that started them.
36
+
37
+ The session summary answers the next question — what is this agent trying to finish? — by bringing together the current task, recent progress and how fresh that information is. "Add jitter to webhook retries. Implementation is ready; the duplicate-delivery test still needs review." After a break, that is enough to decide which session to open.
38
+
39
+ ![CTM's session summary for the lead session, showing the current task, recent progress and freshness beside the session list.](https://walle.sh/blog/paste-the-link/img/fig-3-summary.png)
40
+
41
+ ### Coordinate worktrees, changes and workers
42
+
43
+ Start a session with its own **worktree** and CTM creates the branch and working directory and links them to the session, so an investigation and a test run can proceed in separate checkouts of the same repository.
44
+
45
+ The worktree panel shows **Ready to merge**, **Behind main** and **Dirty** states, uncommitted changes and branch drift, along with the sessions linked to each checkout. Changed-file and commit indicators connect a conversation to the code it touched, and describe the working tree rather than who wrote each line: sessions that share a checkout share that Git state.
46
+
47
+ For focused work, delegate to Claude or Codex workers, choose the model and effort, and inspect the result beneath the lead. Tasks that start servers still need separate ports and data directories. See the [delegation walkthrough](https://walle.sh/blog/delegation-guide/) for setup and an example task.
48
+
49
+ ### Let routine permissions move forward
50
+
51
+ Repeated prompts interrupt work, so CTM applies rules for decisions you have already made, such as allowing a particular test command in the project you are working on.
52
+
53
+ For requests that need more judgment, an approval flow can check the request against the task with a scoped AI review. Requests held for you stay visible as Needs You, with the reason available to inspect, and the Permissions panel shows the policy behind each decision so you can change or disable a rule. These settings govern CTM's automatic approval; the selected CLI also keeps its own permission controls.
54
+
55
+ ### Reuse the knowledge behind your code
56
+
57
+ Conversations hold more than the final patch: approaches that failed, constraints that mattered and the reasoning behind a decision. CTM records prompts, answers and tool calls as structured turns you can read and search by phrase, file reference or session link.
58
+
59
+ With Wall-E connected through MCP, paste the earlier session's URL into a new session and ask the agent to read that session, or let it search Wall-E:
60
+
61
+ ```text
62
+ Search Wall-E for the earlier retry investigation in acme-ledger.
63
+ Find the decision about the 30-second cap and use it when reviewing this diff.
37
64
  ```
38
65
 
39
- This copies the project, installs dependencies, and starts the server. Open **http://localhost:3456** to finish setup in the browser, then authenticate the agents and providers you choose and configure any optional integrations or remote device access.
66
+ ![A recorded session shown as prompts, answers and tool calls, including the reasoning behind the 30-second retry cap.](https://walle.sh/blog/paste-the-link/img/fig-6-conversation.png)
40
67
 
41
- Use the npm installation on macOS and Linux. The Mac app is being updated for this release.
68
+ The layers do different jobs. Recorded conversations preserve the discussion as it happened; search and selected context retrieval fit the parts that matter into a limited model context; durable memory keeps the facts, entities and preferences worth keeping. Retrieval is not automatic — the agent has to look, and it depends on which history and tools are connected — so check retrieved context against the current branch before relying on it.
69
+
70
+ ### Keep work available without keeping everything running
71
+
72
+ CTM can park an eligible inactive session to stop its process and free resources while the recorded conversation stays in the workspace, then bring it back when you need it.
73
+
74
+ A shared MCP gateway lets eligible tool servers reuse one process across sessions; tools needing session-specific state keep separate instances.
75
+
76
+ ### Use more than one machine
77
+
78
+ Pair another machine running CTM and its sessions join the same list, tagged by machine. Pick the machine when you start a session, open and type into it from the hub's browser, and sign that machine's coding agents in from the Machines page, on desktop or phone.
79
+
80
+ ### Review changes in one place
81
+
82
+ The Review page moves between rendered HTML or Markdown, source files and diffs, and new files appear before Git tracks them. Comments collect into one message for the session responsible for the change, keeping feedback beside the files that produced it.
83
+
84
+ For a small correction, open the current file in File or Source view, choose **Edit**, change the text and save: the working file changes and the diff reflects it, while historical revisions and binary files stay read-only.
85
+
86
+ ### A personal agent with context about you
87
+
88
+ Wall-E keeps its own chat threads, an inbox for what needs your attention, and scheduled or one-off jobs with run history. Schedules run only when you configure them.
89
+
90
+ Saved preferences and project knowledge carry into later work. Store `Show the failure and test evidence before proposing a rollout`, for example, and a later review brief can start from it instead of restating the point.
91
+
92
+ Optional connected sources such as Slack need their own accounts and permissions, and Slack auto-replies stay inside the allowlist you configure.
93
+
94
+ ## Try it on one project
95
+
96
+ This example is fictional and the dialogue is scripted; it illustrates the workflow rather than measuring an agent. A failed webhook delivery in `acme-ledger` needs better retry handling, so Claude Code investigates the retry behaviour in one session while Codex works on tests in a separate worktree.
97
+
98
+ A scoped test command proceeds under an approval rule, while a request to write outside the test transaction is held as Needs You until you release it.
99
+
100
+ Days later, a review session needs the reasoning behind the 30-second retry cap recorded during the earlier investigation. With Wall-E connected through MCP, paste that session's URL into the new session, or ask Wall-E to find it, and the agent works from the original reasoning while you read the design document and patch together.
42
101
 
43
102
  ## Commands
44
103
 
@@ -61,26 +120,15 @@ If an older installation asks for its existing Node executable during an update,
61
120
  npx create-walle update --installed-node /absolute/path/to/node
62
121
  ```
63
122
 
64
- ## Setup
65
-
66
- On first launch, the browser setup page guides you through:
67
-
68
- 1. **Browser setup** — finish the local installation in the dashboard
69
- 2. **Providers** — authenticate the coding agents and model providers you use
70
- 3. **Integrations** — optionally connect available sources with their required permissions
71
- 4. **Remote phone and tablet access** — optionally configure access to the running host
72
-
73
- ## Custom Port
123
+ Run on another port with `CTM_PORT`. Wall-E runs on `CTM_PORT + 1` — 5001 in this example:
74
124
 
75
125
  ```bash
76
126
  CTM_PORT=5000 npx create-walle install ./walle
77
127
  ```
78
128
 
79
- Wall-E runs on `CTM_PORT + 1` (e.g., 5001).
80
-
81
129
  ## Hosting and storage
82
130
 
83
- The dashboard and Wall-E memory run on the host where you install them. SQLite is the default storage. Coding providers and optional integrations may contact their own services and require their own accounts or permissions. Use backups and exports to preserve or move local data; do not treat file-sync services as database replication.
131
+ The dashboard and Wall-E memory run on the host where you install them, and SQLite is the default storage. Coding providers and optional integrations may contact their own services and require their own accounts or permissions. Use backups and exports to preserve or move local data; do not treat file-sync services as database replication.
84
132
 
85
133
  | Component | Default Port | What it does |
86
134
  |-----------|-------------|--------------|
@@ -89,13 +137,12 @@ The dashboard and Wall-E memory run on the host where you install them. SQLite i
89
137
 
90
138
  ## Updates and recovery
91
139
 
92
- Run `npx create-walle update` from your installation directory. Updates verify compatibility, back up existing databases, and check the services before reporting success. The command reports backup and recovery information if attention is needed.
93
-
94
- Keep your backups available, and resolve an update error before retrying.
140
+ Run `npx create-walle update` from your installation directory. Updates verify compatibility, back up existing databases and check the services before reporting success, and report backup and recovery information if attention is needed. Keep your backups available, and resolve an update error before retrying.
95
141
 
96
142
  ## Links
97
143
 
98
144
  - [Homepage](https://walle.sh)
145
+ - [Walkthrough](https://walle.sh/blog/paste-the-link/)
99
146
 
100
147
  ## License
101
148
 
@@ -0,0 +1,135 @@
1
+ 'use strict';
2
+
3
+ // Shared "no other account can write through this path" predicate for paths CTM and
4
+ // Wall-E did not create themselves (a Codex sessions root, an enrolled provider root,
5
+ // a data directory handed in by an installer, ~/.walle/data).
6
+ //
7
+ // The rule is Debian OpenSSH's `user-group-modes.patch` rule, adapted: world write is
8
+ // never acceptable, and group write is acceptable ONLY when the owning group is the
9
+ // current user's own one-member private group (the user-private-group scheme that
10
+ // `pam_umask(8)` sets up as umask 002 on every Debian/Ubuntu/Fedora login). On a shared
11
+ // group (`staff` on macOS, `users` on many hosts) the check is exactly as strict as
12
+ // before.
13
+ //
14
+ // Accepted gap (same as the Debian patch): a group password held in `/etc/gshadow`
15
+ // (usable through `newgrp`) and accounts that exist only in NSS (LDAP/SSSD) are invisible
16
+ // to the `/etc/group` + `/etc/passwd` parse this module performs, so a gid that cannot be
17
+ // proven from the local files is refused — the check always fails closed.
18
+
19
+ const fs = require('node:fs');
20
+ const os = require('node:os');
21
+
22
+ const MAX_DB_BYTES = 1024 * 1024;
23
+ const GROUP_PATH = '/etc/group';
24
+ const PASSWD_PATH = '/etc/passwd';
25
+
26
+ /** Default reader: one bounded read (≤ MAX_DB_BYTES), the fd always closed. */
27
+ function _readBoundedFile(filePath) {
28
+ const fd = fs.openSync(filePath, 'r');
29
+ try {
30
+ const stat = fs.fstatSync(fd);
31
+ if (Number(stat.size) > MAX_DB_BYTES) {
32
+ throw new Error(`${filePath} is larger than ${MAX_DB_BYTES} bytes`);
33
+ }
34
+ return fs.readFileSync(fd, 'utf8');
35
+ } finally {
36
+ fs.closeSync(fd);
37
+ }
38
+ }
39
+
40
+ // A seam explicitly passed as `null` means "this platform has no such call" (the Windows
41
+ // shape); `undefined` means "use the process default".
42
+ function _seam(deps, name, fallback) {
43
+ if (deps[name] === null) return null;
44
+ if (typeof deps[name] === 'function') return deps[name];
45
+ return typeof fallback === 'function' ? fallback : null;
46
+ }
47
+
48
+ // Split a local-database file into usable lines: blanks and `#` comments are skipped, and a
49
+ // `+`/`-` NIS compat line makes the whole file unprovable (return null).
50
+ function _usableLines(text) {
51
+ const lines = [];
52
+ for (const raw of String(text).split('\n')) {
53
+ const line = raw.trim();
54
+ if (!line || line.startsWith('#')) continue;
55
+ if (line.startsWith('+') || line.startsWith('-')) return null;
56
+ lines.push(line);
57
+ }
58
+ return lines;
59
+ }
60
+
61
+ function _numericField(value) {
62
+ return /^\d+$/.test(value || '') ? Number(value) : null;
63
+ }
64
+
65
+ /** D-2: `gid` is the current user's one-member private group. Any doubt ⇒ false. */
66
+ function isUserPrivateGroup(gid, deps = {}) {
67
+ try {
68
+ const getuid = _seam(deps, 'getuid', process.getuid);
69
+ const getgid = _seam(deps, 'getgid', process.getgid);
70
+ if (typeof getuid !== 'function' || typeof getgid !== 'function') return false;
71
+ const targetGid = _numericField(String(gid));
72
+ if (targetGid === null) return false;
73
+ if (Number(getgid()) !== targetGid) return false;
74
+ const uid = Number(getuid());
75
+ const usernameFn = _seam(deps, 'username', () => os.userInfo().username);
76
+ if (typeof usernameFn !== 'function') return false;
77
+ const username = String(usernameFn() || '');
78
+ if (!username) return false;
79
+ const readFile = _seam(deps, 'readFile', _readBoundedFile);
80
+ if (typeof readFile !== 'function') return false;
81
+
82
+ // (b) /etc/group: exactly one line with this gid, named after the login, members ⊆ {login}.
83
+ const groupLines = _usableLines(readFile(GROUP_PATH));
84
+ if (!groupLines) return false;
85
+ const groupEntries = [];
86
+ for (const line of groupLines) {
87
+ const fields = line.split(':');
88
+ const lineGid = fields.length >= 3 ? _numericField(fields[2]) : null;
89
+ if (lineGid === null || lineGid !== targetGid) continue;
90
+ if (fields.length !== 4) return false;
91
+ groupEntries.push({ name: fields[0], members: fields[3].split(',').map(m => m.trim()).filter(Boolean) });
92
+ }
93
+ if (groupEntries.length !== 1) return false;
94
+ const group = groupEntries[0];
95
+ if (group.name !== username) return false;
96
+ if (group.members.length > 1) return false;
97
+ if (group.members.length === 1 && group.members[0] !== username) return false;
98
+
99
+ // (c) /etc/passwd: every account whose primary gid is this gid is this uid, and one exists.
100
+ const passwdLines = _usableLines(readFile(PASSWD_PATH));
101
+ if (!passwdLines) return false;
102
+ let primaryAccounts = 0;
103
+ for (const line of passwdLines) {
104
+ const fields = line.split(':');
105
+ const lineGid = fields.length >= 4 ? _numericField(fields[3]) : null;
106
+ if (lineGid === null || lineGid !== targetGid) continue;
107
+ if (fields.length !== 7) return false;
108
+ primaryAccounts += 1;
109
+ const lineUid = _numericField(fields[2]);
110
+ if (lineUid === null || lineUid !== uid) return false;
111
+ }
112
+ if (primaryAccounts === 0) return false;
113
+ return true;
114
+ } catch {
115
+ /* expected: any unreadable or unparsable account database fails closed (D-3) */
116
+ return false;
117
+ }
118
+ }
119
+
120
+ /**
121
+ * True iff no account other than the current user can write through `stat`'s permission bits.
122
+ * Accepts fs.Stats (Number) and fs.BigIntStats (bigint) alike.
123
+ * @param {{ mode: number|bigint, gid: number|bigint }} stat
124
+ * @param {{ readFile?: (p: string) => string, getuid?: () => number, getgid?: () => number,
125
+ * username?: () => string }} [deps] test seams
126
+ * @returns {boolean}
127
+ */
128
+ function isWritableOnlyByOwner(stat, deps = {}) {
129
+ const mode = Number(stat.mode);
130
+ if ((mode & 0o002) !== 0) return false; // world write is never acceptable
131
+ if ((mode & 0o020) === 0) return true; // no group write: no file is read
132
+ return isUserPrivateGroup(Number(stat.gid), deps);
133
+ }
134
+
135
+ module.exports = { isWritableOnlyByOwner, isUserPrivateGroup, MAX_DB_BYTES, _readBoundedFile };
@@ -36,6 +36,11 @@ const os = require('node:os');
36
36
  const path = require('node:path');
37
37
  const { execFileSync } = require('node:child_process');
38
38
 
39
+ // The ONE "no other account can write through this path" predicate, shared with CTM and Wall-E. It
40
+ // is a relative SIBLING require on purpose: the mirror is byte-identical, so the same bytes resolve it
41
+ // from `shared/` and from `create-walle/lib/`.
42
+ const { isWritableOnlyByOwner } = require('./owner-write-safety');
43
+
39
44
  const {
40
45
  parseReleaseRuntimePolicy,
41
46
  releaseRuntimeArchive,
@@ -187,10 +192,13 @@ function publicRuntimeNpmEnv(nodeBin) {
187
192
 
188
193
  // ── the one cache-directory admission ───────────────────────────────────────────────────────────
189
194
  /**
190
- * Assert that `dir` is a REAL directory (never a link), owned by the current user, and not
191
- * group/other writable. Ancestors ABOVE the owned cache boundary are deliberately not inspected: a
192
- * system path or a sticky ancestor is not this installer's ownership requirement, and pretending
193
- * otherwise would refuse every legitimate `~/.walle` under a shared parent.
195
+ * Assert that `dir` is a REAL directory (never a link), owned by the current user, and writable only
196
+ * by its owner (a user-private group counts as the owner: world write is never acceptable, and group
197
+ * write is acceptable only when the owning group is the user's own one-member private group, the
198
+ * umask-002 scheme of a Debian/Ubuntu/Fedora login). Ancestors ABOVE the owned cache boundary are
199
+ * deliberately not inspected: a system path or a sticky ancestor is not this installer's ownership
200
+ * requirement, and pretending otherwise would refuse every legitimate `~/.walle` under a shared
201
+ * parent.
194
202
  */
195
203
  function assertOwnedCacheDirectory(fsOps, dir, phase) {
196
204
  let stat;
@@ -202,7 +210,7 @@ function assertOwnedCacheDirectory(fsOps, dir, phase) {
202
210
  if (stat.isSymbolicLink() || !stat.isDirectory()) {
203
211
  throw refuse(phase, 'public runtime cache directory is not a real directory');
204
212
  }
205
- if ((Number(stat.mode) & 0o022) !== 0) {
213
+ if (!isWritableOnlyByOwner(stat)) {
206
214
  throw refuse(phase, 'public runtime cache directory is group or other writable');
207
215
  }
208
216
  if (typeof process.getuid === 'function' && Number(stat.uid) !== process.getuid()) {
@@ -9,7 +9,7 @@
9
9
  21, 22, 23, 24, 25, 26, 27, 28, 29, 30,
10
10
  31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
11
11
  41, 42, 43, 44, 45, 46, 47, 48, 49, 50,
12
- 51, 52, 53, 54, 55
12
+ 51, 52, 53, 54, 55, 56
13
13
  ]
14
14
  },
15
15
  "walle": {
@@ -24,7 +24,8 @@
24
24
  61, 62, 63, 64, 65, 66, 67, 68, 69, 70,
25
25
  71, 72, 73, 74, 75, 76, 77, 78, 79, 80,
26
26
  81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96,
27
- 97, 98, 99
27
+ 97, 98, 99, 100,
28
+ 101
28
29
  ]
29
30
  }
30
31
  }
@@ -39,7 +39,9 @@
39
39
  "coding-task-manager/bin/seam-replay.js",
40
40
  "coding-task-manager/bin/session-access-lint.js",
41
41
  "coding-task-manager/bin/session-create-fanout-lint.js",
42
+ "coding-task-manager/bin/session-host-kill-lint.js",
42
43
  "coding-task-manager/bin/session-runtime-evidence-lint.js",
44
+ "coding-task-manager/bin/startup-pointer-writer-lint.js",
43
45
  "coding-task-manager/bin/status-verdict-lint.js",
44
46
  "coding-task-manager/bin/term-container-band-lint.js",
45
47
  "coding-task-manager/bin/terminal-write-lint.js",
@@ -1785,12 +1787,12 @@
1785
1787
  "coding-task-manager/lib/walle-deps-repair.js": "be85620d08795ea0fe9539820416d5cc50b654519abddab0811907fa3fe93a7f",
1786
1788
  "coding-task-manager/lib/walle-mcp-auto-config.js": "b978e9b15d9dac8179dde0feb5357c14957f7b4e36dab7e6779587bcde8faeff",
1787
1789
  "coding-task-manager/lib/walle-native-health.js": "9fdf7f17eb77837aac4ea16140a6f4e5a97d7a568945da30f29b9a7541c3d967",
1788
- "coding-task-manager/lib/walle-supervisor.js": "04b924f16c9bd001ed505347202dbec2876b57fc427a32c93d23586530181f83",
1790
+ "coding-task-manager/lib/walle-supervisor.js": "1eb9971a2ede9735e595952404f467f6775ad9f99545137faad86e3c6fb38af9",
1789
1791
  "coding-task-manager/public/js/client-health-worker.js": "07e300113ee749ac7a6adaaa1461502d1562087af395b6c89cf1b885f1f5e00e",
1790
1792
  "coding-task-manager/public/js/image-normalize-worker.js": "37cb0758bddcf10c66060fae52088c1a842409f30e919988e789cfea7d05e2be",
1791
- "coding-task-manager/public/m/app.js": "483f777f57efd28d7796713c33df48ffba47e5bfb50597b446a37b961f53d585",
1792
- "coding-task-manager/server.js": "24a9871d0d974aed567a1f15e563fae1dc055484822b24b0f58146bcedb90d34",
1793
- "scripts/conversation-storage-v2-migration.js": "80c66e41c9fb9b1d756fe21be17f3b07c6a65389712887043a86341fbf6a6879",
1793
+ "coding-task-manager/public/m/app.js": "8e4662e21c409003a2d61de3c044410055176b574d787b34f7ede776b62a7003",
1794
+ "coding-task-manager/server.js": "347578d2cab77abedb122df048f60415d8d392ed4caf4bd32fc92e91a9aa3f9a",
1795
+ "scripts/conversation-storage-v2-migration.js": "f2620ba24893c4d2ec6c594428ddb41dc098da38b4066f1df25fb87abbfaebfa",
1794
1796
  "shared/storage/schema-port.js": "e41cec8c075a6167fba2efd0177d9e20a11c0cd49ae176aaf36d5b9257409e67",
1795
1797
  "shared/storage/schema-sync.js": "7ca080e44e35e8178a0f74317023881f920ae75bde4f7431702ce1f9fa4a1d03",
1796
1798
  "wall-e/adapters/chatgpt.js": "8c0fa31ae65ed5c10776e50a1a26c131bc62cb1aa3d88eb4617e7b83b43789d9",
@@ -1815,7 +1817,7 @@
1815
1817
  "wall-e/channels/telegram-channel.plugin.json": "696d601804c91387824e80263b784f76ce5cad4b8ae81277d4b4030c1710e437",
1816
1818
  "wall-e/coding/action-memory-store.js": "5c7a467e9cb3e08dbfc7b27dec6724f8ea6eedac29d2c40f6c6bda3a4263a0c0",
1817
1819
  "wall-e/coding/hooks/plugin-loader.js": "f1ca5e032e64f68447af9317ad75821a5152ca25fad09ce4ac23e8cd39ac891c",
1818
- "wall-e/coding/host-capabilities.js": "1f320231fdf9ff078ec873255129168475ab5570b8864676836f678ea2ed70d4",
1820
+ "wall-e/coding/host-capabilities.js": "9dafbc2a76ba5e00911219316be7b5f57ca26db278275606ea7fad61631370bd",
1819
1821
  "wall-e/coding/prompt-capabilities.js": "e230871618f9f43e6c7a3a7f98ebda2e77bb522018c6d4c0b1e29d0b08926708",
1820
1822
  "wall-e/coding/user-hooks.js": "4a0d9b82894f6a23c126b09d8f1feca3aa894b171a9c815e11389b2d96b1e018",
1821
1823
  "wall-e/lib/boot-preflight.js": "4415c7c3dae9add70bebdd29d75ee68d09097c53732438d35c3cd1ae0de5f01e",
package/package.json CHANGED
@@ -1,7 +1,8 @@
1
1
  {
2
2
  "name": "create-walle",
3
- "version": "0.10.0",
4
- "description": "CTM + Wall-E — AI coding dashboard and personal digital twin agent. Multi-agent terminal for Claude Code, Codex, Gemini, Aider, OpenCode, and more, plus prompt editor, task queue, remote phone and tablet access, code/doc review, and an agent that learns from Slack, email & calendar.",
3
+ "version": "0.10.2",
4
+ "description": "CTM + Wall-E: one workspace for coding agents, worktrees and review, with shared session context and a personal agent.",
5
+ "homepage": "https://walle.sh",
5
6
  "bin": {
6
7
  "create-walle": "bin/create-walle.js"
7
8
  },
@@ -32,8 +33,13 @@
32
33
  "task-manager",
33
34
  "wall-e",
34
35
  "ai",
35
- "digital-twin",
36
36
  "claude",
37
- "personal-assistant"
37
+ "personal-assistant",
38
+ "coding-task-manager",
39
+ "coding-agents",
40
+ "codex",
41
+ "worktrees",
42
+ "mcp",
43
+ "memory"
38
44
  ]
39
45
  }
@@ -248,7 +248,7 @@ function checkDeps(pkgDir, opts = {}) {
248
248
  }
249
249
 
250
250
  // The package dirs a gate depends on, relative to a checkout root.
251
- const TREE_SUBS = ['', 'coding-task-manager', 'wall-e', 'shared', 'create-walle'];
251
+ const TREE_SUBS = ['', 'coding-task-manager', 'wall-e', 'shared', 'create-walle', 'ctm-relay'];
252
252
 
253
253
  // `npm --prefix <owner> install --no-save`: <owner> is the checkout that really
254
254
  // holds node_modules (a gate tree borrows it through a symlink). Never
@@ -56,6 +56,17 @@ bootstrap_candidates() {
56
56
  for cache_node in "$HOME"/.walle/runtimes/*/*/runtime/bin/node; do
57
57
  if [ -e "$cache_node" ]; then printf '%s\n' "$cache_node"; fi
58
58
  done
59
+ # Linux boxes (e.g. DGX Spark) install Node via nvm/fnm, so with a non-interactive ssh session
60
+ # that never sources the manager there is no `node` on PATH and none of the macOS Wall-E paths
61
+ # above exist. Any version found here only RUNS the fixed helper; the pin is still enforced by the
62
+ # candidate ladder below, so a version-globbed bootstrap can never select a mismatched ABI.
63
+ local manager_node
64
+ for manager_node in \
65
+ "$HOME"/.nvm/versions/node/*/bin/node \
66
+ "$HOME"/.local/share/fnm/node-versions/*/installation/bin/node \
67
+ "$HOME"/.fnm/node-versions/*/installation/bin/node; do
68
+ if [ -e "$manager_node" ]; then printf '%s\n' "$manager_node"; fi
69
+ done
59
70
  return 0
60
71
  }
61
72
 
@@ -5,8 +5,11 @@ const os = require('os');
5
5
  const { isMainThread } = require('node:worker_threads');
6
6
  const { classifySqliteError } = require('./lib/sqlite-driver');
7
7
  const { reportRouteError, routeError, tagRouteValidationError } = require('./lib/route-error');
8
+ const { terminalDraftHttpStatus: _terminalDraftStatus } = require('./lib/terminal-draft-http-status');
8
9
  // WP-2 (§9): the delivery-completion request projection lives with the image-protocol owners.
9
10
  const { buildDraftDeliveryCompletionRequest } = require('./lib/terminal-draft-publication-api');
11
+ const remoteSessionForward = require('./lib/remote-session-forward'); // WP-3 (§6/D-1..D-3): an image-draft request for a MIRROR id is answered by the owning box
12
+ const { overlayQueueDraftStatuses } = require('./lib/queue-draft-status-overlay'); // R-1 (§5): the queue-draft GET overlays durable engine status, never writes
10
13
  const db = require('./db-owner-client');
11
14
  const queueEngine = require('./queue-engine');
12
15
  const harvest = require('./prompt-harvest');
@@ -820,7 +823,10 @@ function handlePromptApi(req, res, url, deps = {}) {
820
823
  // --- Images ---
821
824
  if (p === '/api/images/upload' && m === 'POST') return handleUploadImage(req, res, url);
822
825
  if (/^\/api\/sessions\/[^/]+\/image-drafts(?:\/[^/]+(?:\/content|\/delivery|\/freeze|\/submit|\/retry)?)?$/.test(p)) {
823
- return handleTerminalImageDraft(req, res, url);
826
+ const route = _terminalDraftRoute(url); // WP-3: a MIRROR id is answered by the box; a local id takes the same-tick path
827
+ if (!route || !remoteSessionForward.isMirrorSessionRequest(req, url, route.sessionId)) return handleTerminalImageDraft(req, res, url);
828
+ return remoteSessionForward.maybeForwardSessionRequest(req, res, url, route.sessionId)
829
+ .then((forwarded) => (forwarded ? undefined : handleTerminalImageDraft(req, res, url)));
824
830
  }
825
831
  if (p === '/api/images/ingest-path' && m === 'POST') return handleIngestImagePath(req, res);
826
832
  if (p === '/api/mobile/attachments/upload' && m === 'POST') return handleUploadMobileAttachment(req, res, url);
@@ -1466,26 +1472,6 @@ function _terminalDraftRoute(url) {
1466
1472
  } catch { return null; }
1467
1473
  }
1468
1474
 
1469
- function _terminalDraftStatus(error) {
1470
- if (!error) return 500;
1471
- if (error.code === 'CTM_MAIN_DB_REQUEST_FORBIDDEN') return 501;
1472
- if (error.code === 'CTM_OWNERSHIP_UNAVAILABLE' || error.code === 'CTM_DB_OWNER_UNAVAILABLE' ||
1473
- error.code === 'CTM_MEDIA_JOURNAL_UNAVAILABLE') return 503;
1474
- if (error.code === 'CTM_DRAFT_NOT_FOUND' || error.code === 'CTM_DRAFT_SESSION_NOT_FOUND') return 404;
1475
- if (error.code === 'CTM_SESSION_OWNER_MISMATCH') return 409;
1476
- if (error.code === 'CTM_DRAFT_REVISION_CONFLICT') return 412;
1477
- // CTM_IMAGE_IDEMPOTENCY_CONFLICT is the legacy/mobile lanes' equivalent of the draft
1478
- // lane's idempotency conflict (media-store requestId dedupe) — same 409 semantic
1479
- // (WP-9 lane-parity: distinguishable from a malformed 400 without inspecting `code`).
1480
- if (error.code === 'CTM_DRAFT_IDEMPOTENCY_CONFLICT' || error.code === 'CTM_IMAGE_IDEMPOTENCY_CONFLICT' ||
1481
- error.code === 'CTM_DRAFT_DELIVERY_SUPERSEDED' ||
1482
- error.code === 'CTM_DRAFT_DELIVERY_STATE') return 409;
1483
- if (error.code === 'CTM_DRAFT_FROZEN' || error.code === 'CTM_DRAFT_REQUEST_CANCELLED') return 409;
1484
- if (error.code === 'CTM_DRAFT_IMAGE_INVALID' || error.code === 'CTM_DRAFT_SESSION_REQUIRED' ||
1485
- error.code === 'CTM_DRAFT_IDENTITY_INVALID' || error.code === 'CTM_DRAFT_DELIVERY_OUTCOME_INVALID') return 400;
1486
- return 500;
1487
- }
1488
-
1489
1475
  function _imageFailureStatus(error, fallbackStatus = 500) {
1490
1476
  const terminalStatus = _terminalDraftStatus(error);
1491
1477
  if (terminalStatus !== 500 || fallbackStatus === 500) return terminalStatus;
@@ -6891,7 +6877,9 @@ function mergeQueueDraftItemsByStatusTimestamp(existingItems, incomingItems) {
6891
6877
  function handleGetQueueDraft(req, res, sessionId) {
6892
6878
  const key = 'queue_draft_' + sessionId;
6893
6879
  const draft = _getPublishedSetting(key, { items: [], mode: 'manual' });
6894
- jsonResponse(res, 200, draft);
6880
+ // R-1 (§5): read-only projection. The engine is the authority for an item's
6881
+ // durable status; the stored snapshot is never rewritten on this route.
6882
+ jsonResponse(res, 200, overlayQueueDraftStatuses(draft, queueEngine.getItemStatusMap(sessionId)));
6895
6883
  }
6896
6884
 
6897
6885
  async function handleSaveQueueDraft(req, res, sessionId) {