create-walle 0.9.21 → 0.9.23

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 (500) hide show
  1. package/README.md +27 -5
  2. package/package.json +2 -2
  3. package/template/CLAUDE.md +2 -2
  4. package/template/LICENSE +1 -1
  5. package/template/bin/ctm-dev-cleanup.js +24 -3
  6. package/template/bin/ctm-launch.sh +13 -0
  7. package/template/bin/dev.sh +156 -18
  8. package/template/bin/node-bin.sh +84 -0
  9. package/template/bin/pin-node.sh +51 -0
  10. package/template/claude-task-manager/api-prompts.js +1203 -182
  11. package/template/claude-task-manager/api-reviews.js +109 -15
  12. package/template/claude-task-manager/approval-agent.js +1360 -280
  13. package/template/claude-task-manager/bin/restart-ctm.sh +64 -23
  14. package/template/claude-task-manager/bin/storage-migration-supervisor.js +338 -0
  15. package/template/claude-task-manager/db.js +4417 -295
  16. package/template/claude-task-manager/docs/app-update-refresh-protocol.md +69 -0
  17. package/template/claude-task-manager/docs/approval-ai-refinement.md +138 -0
  18. package/template/claude-task-manager/docs/approval-rescue-loop.md +74 -0
  19. package/template/claude-task-manager/docs/codex-operational-warning-health.md +107 -0
  20. package/template/claude-task-manager/docs/codex-resume-state-guard-design.md +17 -12
  21. package/template/claude-task-manager/docs/codex-terminal-render-controller-handoff.md +311 -0
  22. package/template/claude-task-manager/docs/coding-agent-hooks-architecture.md +418 -0
  23. package/template/claude-task-manager/docs/conversation-import-freshness.md +20 -0
  24. package/template/claude-task-manager/docs/google-workspace-auth-health.md +77 -0
  25. package/template/claude-task-manager/docs/image-paste-ux.md +13 -0
  26. package/template/claude-task-manager/docs/ipad-web-preview.md +88 -0
  27. package/template/claude-task-manager/docs/main-loop-offload-architecture.md +66 -0
  28. package/template/claude-task-manager/docs/microsoft-dev-tunnel-phone-access-design.md +274 -519
  29. package/template/claude-task-manager/docs/mobile-live-streaming.md +27 -5
  30. package/template/claude-task-manager/docs/mobile-remote-submission-lifecycle.md +69 -0
  31. package/template/claude-task-manager/docs/phone-access-design.md +53 -15
  32. package/template/claude-task-manager/docs/phone-passkey-identity.md +122 -0
  33. package/template/claude-task-manager/docs/phone-setup.md +3 -0
  34. package/template/claude-task-manager/docs/prompt-editing-tree-design.md +25 -1
  35. package/template/claude-task-manager/docs/remote-desktop-access-design.md +268 -0
  36. package/template/claude-task-manager/docs/restart-lifecycle-architecture.md +95 -0
  37. package/template/claude-task-manager/docs/runtime-work-control-plane.md +53 -0
  38. package/template/claude-task-manager/docs/session-interactive-wait-surfaces.md +38 -0
  39. package/template/claude-task-manager/docs/session-needs-you-dismissal.md +84 -0
  40. package/template/claude-task-manager/docs/session-render-state-management-design.md +91 -3
  41. package/template/claude-task-manager/docs/session-standup-command-center-design.md +25 -1
  42. package/template/claude-task-manager/docs/session-title-authority.md +32 -0
  43. package/template/claude-task-manager/docs/session-workspace-binding.md +33 -0
  44. package/template/claude-task-manager/docs/skill-intent-resolution-design.md +72 -0
  45. package/template/claude-task-manager/docs/walle-mcp-supervisor-health.md +86 -0
  46. package/template/claude-task-manager/docs/walle-relay-phone-access-design.md +24 -15
  47. package/template/claude-task-manager/docs/walle-session-history-hydration.md +114 -0
  48. package/template/claude-task-manager/docs/walle-session-input-queue.md +104 -0
  49. package/template/claude-task-manager/docs/walle-session-model-catalog.md +90 -0
  50. package/template/claude-task-manager/docs/walle-session-model-preferences.md +15 -6
  51. package/template/claude-task-manager/git-utils.js +897 -27
  52. package/template/claude-task-manager/lib/agent-capabilities.js +33 -0
  53. package/template/claude-task-manager/lib/agent-cli-cache.js +37 -7
  54. package/template/claude-task-manager/lib/agent-hooks-installer.js +26 -2
  55. package/template/claude-task-manager/lib/agent-presets.js +17 -1
  56. package/template/claude-task-manager/lib/all-sessions-query.js +108 -0
  57. package/template/claude-task-manager/lib/approval-ai-refinement.js +488 -0
  58. package/template/claude-task-manager/lib/approval-self-adapt.js +168 -0
  59. package/template/claude-task-manager/lib/async-semaphore.js +44 -0
  60. package/template/claude-task-manager/lib/auth-context.js +5 -0
  61. package/template/claude-task-manager/lib/auth-rate-limit.js +47 -4
  62. package/template/claude-task-manager/lib/auth-rules.js +29 -2
  63. package/template/claude-task-manager/lib/auto-approval-verifier.js +129 -16
  64. package/template/claude-task-manager/lib/background-llm.js +144 -17
  65. package/template/claude-task-manager/lib/branch-inventory.js +212 -0
  66. package/template/claude-task-manager/lib/claude-desktop-sessions.js +15 -3
  67. package/template/claude-task-manager/lib/coalesce-sync-frames.js +151 -0
  68. package/template/claude-task-manager/lib/codex-launch-health.js +762 -0
  69. package/template/claude-task-manager/lib/codex-transcript-pager.js +51 -0
  70. package/template/claude-task-manager/lib/codex-zst.js +124 -0
  71. package/template/claude-task-manager/lib/coding-agent-models.js +233 -30
  72. package/template/claude-task-manager/lib/connection-health.js +232 -0
  73. package/template/claude-task-manager/lib/conversation-blob-parser.js +42 -0
  74. package/template/claude-task-manager/lib/conversation-tail-merge.js +89 -26
  75. package/template/claude-task-manager/lib/ctm-session-context-api.js +39 -10
  76. package/template/claude-task-manager/lib/cursor-conversation-store.js +354 -0
  77. package/template/claude-task-manager/lib/db-owner-worker-client.js +315 -0
  78. package/template/claude-task-manager/lib/document-review.js +141 -6
  79. package/template/claude-task-manager/lib/escalation-review.js +152 -0
  80. package/template/claude-task-manager/lib/graceful-shutdown.js +159 -0
  81. package/template/claude-task-manager/lib/headless-term-service.js +678 -0
  82. package/template/claude-task-manager/lib/heavy-worker-fallback.js +38 -0
  83. package/template/claude-task-manager/lib/jsonl-conversation-parser.js +542 -0
  84. package/template/claude-task-manager/lib/jsonl-range-reader.js +112 -0
  85. package/template/claude-task-manager/lib/main-db-census.js +216 -0
  86. package/template/claude-task-manager/lib/message-pagination.js +106 -4
  87. package/template/claude-task-manager/lib/microsoft-dev-tunnel-setup.js +750 -26
  88. package/template/claude-task-manager/lib/mobile-auth-api.js +274 -7
  89. package/template/claude-task-manager/lib/mobile-auth-store.js +592 -10
  90. package/template/claude-task-manager/lib/mobile-notification-dispatcher.js +15 -0
  91. package/template/claude-task-manager/lib/model-overview-brain-fallback.js +311 -0
  92. package/template/claude-task-manager/lib/model-overview-cache.js +141 -0
  93. package/template/claude-task-manager/lib/models-health-routing-notice.js +126 -0
  94. package/template/claude-task-manager/lib/node-pin-guard.js +93 -0
  95. package/template/claude-task-manager/lib/perf-tracker.js +242 -6
  96. package/template/claude-task-manager/lib/permission-match.js +76 -0
  97. package/template/claude-task-manager/lib/permission-sync.js +133 -20
  98. package/template/claude-task-manager/lib/process-title.js +35 -0
  99. package/template/claude-task-manager/lib/prompt-executions-query.js +25 -0
  100. package/template/claude-task-manager/lib/prompt-index-disk-cache.js +44 -0
  101. package/template/claude-task-manager/lib/prompt-intent.js +132 -0
  102. package/template/claude-task-manager/lib/provider-user-context.js +34 -0
  103. package/template/claude-task-manager/lib/read-pool-client.js +313 -0
  104. package/template/claude-task-manager/lib/readpool-breaker.js +31 -0
  105. package/template/claude-task-manager/lib/recent-sessions-breaker.js +12 -0
  106. package/template/claude-task-manager/lib/remote-feedback-client.js +72 -0
  107. package/template/claude-task-manager/lib/remote-relay-protocol.js +37 -4
  108. package/template/claude-task-manager/lib/remote-relay-store.js +159 -0
  109. package/template/claude-task-manager/lib/remote-submission-observer.js +278 -0
  110. package/template/claude-task-manager/lib/restart-guard.js +109 -0
  111. package/template/claude-task-manager/lib/restore-interruption-detector.js +439 -0
  112. package/template/claude-task-manager/lib/restore-policy.js +13 -0
  113. package/template/claude-task-manager/lib/restore-resume-batch.js +74 -0
  114. package/template/claude-task-manager/lib/restore-runtime.js +68 -0
  115. package/template/claude-task-manager/lib/restore-storm.js +34 -0
  116. package/template/claude-task-manager/lib/resume-cwd.js +36 -0
  117. package/template/claude-task-manager/lib/resume-preflight.js +313 -0
  118. package/template/claude-task-manager/lib/runtime-work-registry.js +444 -0
  119. package/template/claude-task-manager/lib/sanitize-openai-auth.js +31 -0
  120. package/template/claude-task-manager/lib/scheduler.js +21 -1
  121. package/template/claude-task-manager/lib/scrollback-snapshot-store.js +159 -0
  122. package/template/claude-task-manager/lib/serial-task-queue.js +64 -0
  123. package/template/claude-task-manager/lib/server-listeners.js +239 -0
  124. package/template/claude-task-manager/lib/session-capture.js +42 -7
  125. package/template/claude-task-manager/lib/session-content-backfill.js +131 -0
  126. package/template/claude-task-manager/lib/session-history.js +388 -43
  127. package/template/claude-task-manager/lib/session-host-manager.js +287 -0
  128. package/template/claude-task-manager/lib/session-image-refs.js +209 -0
  129. package/template/claude-task-manager/lib/session-jobs.js +399 -59
  130. package/template/claude-task-manager/lib/session-prompt-index.js +137 -0
  131. package/template/claude-task-manager/lib/session-restore.js +53 -0
  132. package/template/claude-task-manager/lib/session-standup.js +123 -23
  133. package/template/claude-task-manager/lib/session-state-bus.js +14 -0
  134. package/template/claude-task-manager/lib/session-stream.js +64 -16
  135. package/template/claude-task-manager/lib/session-timeline-summary.js +260 -0
  136. package/template/claude-task-manager/lib/session-token-usage.js +494 -0
  137. package/template/claude-task-manager/lib/session-workspace-binding.js +356 -0
  138. package/template/claude-task-manager/lib/setup-network-config.js +9 -0
  139. package/template/claude-task-manager/lib/size-cap.js +45 -0
  140. package/template/claude-task-manager/lib/size-cap.test.js +62 -0
  141. package/template/claude-task-manager/lib/skill-autocomplete.js +180 -1
  142. package/template/claude-task-manager/lib/skill-intent-resolver.js +304 -0
  143. package/template/claude-task-manager/lib/sqlite-driver.js +19 -3
  144. package/template/claude-task-manager/lib/standup-attention.js +7 -3
  145. package/template/claude-task-manager/lib/status-authority.js +39 -0
  146. package/template/claude-task-manager/lib/status-hooks.js +4 -0
  147. package/template/claude-task-manager/lib/storage-migration.js +235 -0
  148. package/template/claude-task-manager/lib/structured-capture.js +298 -0
  149. package/template/claude-task-manager/lib/sync-io-census.js +163 -0
  150. package/template/claude-task-manager/lib/tailscale-setup.js +6 -0
  151. package/template/claude-task-manager/lib/terminal-activity-evidence.js +33 -0
  152. package/template/claude-task-manager/lib/terminal-choice.js +364 -0
  153. package/template/claude-task-manager/lib/terminal-control-sanitize.js +17 -0
  154. package/template/claude-task-manager/lib/terminal-fingerprint.js +48 -0
  155. package/template/claude-task-manager/lib/terminal-output-flush.js +84 -0
  156. package/template/claude-task-manager/lib/timeline-order.js +122 -0
  157. package/template/claude-task-manager/lib/transcript-store.js +348 -43
  158. package/template/claude-task-manager/lib/transport-security.js +84 -1
  159. package/template/claude-task-manager/lib/wait-state.js +184 -0
  160. package/template/claude-task-manager/lib/walle-client.js +47 -5
  161. package/template/claude-task-manager/lib/walle-ctm-history.js +564 -4
  162. package/template/claude-task-manager/lib/walle-external-actions.js +135 -16
  163. package/template/claude-task-manager/lib/walle-history-hydration.js +46 -0
  164. package/template/claude-task-manager/lib/walle-native-health.js +403 -0
  165. package/template/claude-task-manager/lib/walle-repair.js +701 -0
  166. package/template/claude-task-manager/lib/walle-session-cache.js +109 -0
  167. package/template/claude-task-manager/lib/walle-session-context.js +57 -21
  168. package/template/claude-task-manager/lib/walle-session-model-catalog.js +34 -0
  169. package/template/claude-task-manager/lib/walle-supervisor.js +539 -63
  170. package/template/claude-task-manager/lib/walle-transcript.js +52 -0
  171. package/template/claude-task-manager/lib/worktree-active-sync.js +11 -7
  172. package/template/claude-task-manager/lib/worktree-cwd.js +32 -1
  173. package/template/claude-task-manager/package.json +1 -1
  174. package/template/claude-task-manager/prompt-harvest.js +89 -66
  175. package/template/claude-task-manager/providers/claude-code.js +51 -3
  176. package/template/claude-task-manager/providers/cursor.js +140 -45
  177. package/template/claude-task-manager/public/css/reviews.css +551 -61
  178. package/template/claude-task-manager/public/css/setup.css +191 -0
  179. package/template/claude-task-manager/public/css/walle-session.css +865 -10
  180. package/template/claude-task-manager/public/css/walle.css +154 -0
  181. package/template/claude-task-manager/public/designs/ai-providers-consolidation-v2.html +830 -0
  182. package/template/claude-task-manager/public/index.html +18516 -2058
  183. package/template/claude-task-manager/public/ipad.html +363 -0
  184. package/template/claude-task-manager/public/js/document-review-links.js +301 -0
  185. package/template/claude-task-manager/public/js/image-normalize.js +69 -36
  186. package/template/claude-task-manager/public/js/message-renderer.js +1265 -77
  187. package/template/claude-task-manager/public/js/prompts.js +66 -29
  188. package/template/claude-task-manager/public/js/reviews.js +901 -133
  189. package/template/claude-task-manager/public/js/session-activity-utils.js +11 -1
  190. package/template/claude-task-manager/public/js/session-search-utils.js +94 -10
  191. package/template/claude-task-manager/public/js/session-status-precedence.js +23 -5
  192. package/template/claude-task-manager/public/js/setup.js +1273 -176
  193. package/template/claude-task-manager/public/js/stream-view.js +691 -73
  194. package/template/claude-task-manager/public/js/terminal-reconciler.js +210 -0
  195. package/template/claude-task-manager/public/js/walle-session.js +2455 -158
  196. package/template/claude-task-manager/public/js/walle.js +455 -28
  197. package/template/claude-task-manager/public/m/app.css +2909 -262
  198. package/template/claude-task-manager/public/m/app.js +6601 -398
  199. package/template/claude-task-manager/public/m/claim.html +224 -17
  200. package/template/claude-task-manager/public/m/index.html +117 -21
  201. package/template/claude-task-manager/public/m/sw.js +3 -1
  202. package/template/claude-task-manager/public/manifest.json +2 -2
  203. package/template/claude-task-manager/public/prompts.html +30 -14
  204. package/template/claude-task-manager/queue-engine.js +507 -28
  205. package/template/claude-task-manager/scripts/repair-claude-session-images.js +27 -8
  206. package/template/claude-task-manager/server.js +14341 -2197
  207. package/template/claude-task-manager/session-integrity.js +160 -18
  208. package/template/claude-task-manager/session-search-ranking.js +1 -0
  209. package/template/claude-task-manager/session-utils.js +25 -5
  210. package/template/claude-task-manager/workers/approval-blocklist.js +96 -6
  211. package/template/claude-task-manager/workers/approval-widget-validator.js +14 -8
  212. package/template/claude-task-manager/workers/conversation-import-worker.js +11 -50
  213. package/template/claude-task-manager/workers/db-owner-worker.js +386 -0
  214. package/template/claude-task-manager/workers/harvest-worker.js +9 -55
  215. package/template/claude-task-manager/workers/headless-term-worker.js +9 -530
  216. package/template/claude-task-manager/workers/read-pool-worker.js +387 -0
  217. package/template/claude-task-manager/workers/scrollback-worker.js +11 -72
  218. package/template/claude-task-manager/workers/session-host-process.js +146 -0
  219. package/template/claude-task-manager/workers/session-integrity-worker.js +10 -54
  220. package/template/claude-task-manager/workers/state-detectors/base.js +18 -1
  221. package/template/claude-task-manager/workers/state-detectors/claude-code.js +182 -9
  222. package/template/claude-task-manager/workers/state-detectors/codex.js +150 -2
  223. package/template/claude-task-manager/workers/state-detectors/cursor.js +127 -0
  224. package/template/claude-task-manager/workers/state-detectors/gemini.js +21 -0
  225. package/template/claude-task-manager/workers/state-detectors/index.js +29 -0
  226. package/template/claude-task-manager/workers/state-detectors/opencode.js +103 -0
  227. package/template/docs/design/markdown-review-pane.md +206 -0
  228. package/template/docs/designs/2026-05-17-portkey-gateway-provider-ux.md +129 -38
  229. package/template/docs/designs/2026-05-20-mobile-worktree-finish-command.md +27 -0
  230. package/template/docs/designs/2026-05-22-ai-configuration-consolidation.md +248 -0
  231. package/template/docs/designs/ai-configuration-consolidation-mock.html +812 -0
  232. package/template/docs/private-memory-and-pii-policy.md +69 -0
  233. package/template/package.json +2 -1
  234. package/template/scripts/check-private-data.js +201 -0
  235. package/template/shared/sqlite-owner-guard.js +30 -0
  236. package/template/shared/sqlite-owner-write-queue.js +225 -0
  237. package/template/shared/sqlite-storage-policy.js +111 -0
  238. package/template/shared/sqlite-write-lock.js +428 -0
  239. package/template/wall-e/agent-runners/claude-code.js +5 -0
  240. package/template/wall-e/agent.js +166 -22
  241. package/template/wall-e/api-walle.js +524 -70
  242. package/template/wall-e/auth/provider-flows.js +11 -1
  243. package/template/wall-e/bin/walle-mcp-stdio.js +341 -17
  244. package/template/wall-e/brain.js +1614 -141
  245. package/template/wall-e/chat/attachment-blocks.js +96 -0
  246. package/template/wall-e/chat/attachments.js +2 -1
  247. package/template/wall-e/chat/capability-resolver.js +7 -7
  248. package/template/wall-e/chat/context-messages.js +28 -0
  249. package/template/wall-e/chat/conversation-frame.js +630 -0
  250. package/template/wall-e/chat/provider-messages.js +125 -0
  251. package/template/wall-e/chat.js +1002 -233
  252. package/template/wall-e/coding/acceptance-contract.js +170 -0
  253. package/template/wall-e/coding/acp-adapter.js +1 -1
  254. package/template/wall-e/coding/agent-catalog.js +3 -0
  255. package/template/wall-e/coding/artifact-store.js +93 -0
  256. package/template/wall-e/coding/capability-router.js +120 -0
  257. package/template/wall-e/coding/coding-run-controller.js +423 -0
  258. package/template/wall-e/coding/compaction-service.js +157 -12
  259. package/template/wall-e/coding/frontend-verification.js +258 -0
  260. package/template/wall-e/coding/lifecycle-hooks.js +75 -0
  261. package/template/wall-e/coding/local-preview-contract.js +157 -0
  262. package/template/wall-e/coding/permission-service.js +57 -13
  263. package/template/wall-e/coding/prompt-bundle.js +19 -1
  264. package/template/wall-e/coding/prompt-section-registry.js +227 -0
  265. package/template/wall-e/coding/provider-compat.js +15 -0
  266. package/template/wall-e/coding/runtime-events.js +224 -0
  267. package/template/wall-e/coding/runtime-mode.js +3 -0
  268. package/template/wall-e/coding/side-git-snapshot.js +160 -4
  269. package/template/wall-e/coding/snapshot-service.js +143 -1
  270. package/template/wall-e/coding/stream-processor.js +388 -34
  271. package/template/wall-e/coding/task-tool.js +141 -4
  272. package/template/wall-e/coding/tool-execution-controller.js +365 -0
  273. package/template/wall-e/coding/tool-registry.js +43 -5
  274. package/template/wall-e/coding/user-hooks.js +217 -0
  275. package/template/wall-e/coding-orchestrator.js +1330 -221
  276. package/template/wall-e/coding-prompts.js +20 -4
  277. package/template/wall-e/context/context-builder.js +15 -2
  278. package/template/wall-e/decision/confidence.js +1 -1
  279. package/template/wall-e/docs/coding-acceptance-contract.md +41 -0
  280. package/template/wall-e/docs/external-action-controller.md +26 -6
  281. package/template/wall-e/docs/telemetry-lifecycle.md +8 -2
  282. package/template/wall-e/embeddings.js +591 -53
  283. package/template/wall-e/external-action-controller.js +12 -0
  284. package/template/wall-e/http/auth.js +1 -0
  285. package/template/wall-e/http/chat-api.js +46 -11
  286. package/template/wall-e/http/model-admin.js +836 -34
  287. package/template/wall-e/lib/boot-profile.js +88 -0
  288. package/template/wall-e/lib/event-loop-monitor.js +93 -0
  289. package/template/wall-e/lib/service-health.js +194 -0
  290. package/template/wall-e/llm/anthropic.js +130 -5
  291. package/template/wall-e/llm/client.js +266 -63
  292. package/template/wall-e/llm/default-fallback.js +382 -0
  293. package/template/wall-e/llm/health.js +19 -0
  294. package/template/wall-e/llm/message-guard.js +78 -0
  295. package/template/wall-e/llm/model-catalog.js +252 -1
  296. package/template/wall-e/llm/openai.js +26 -4
  297. package/template/wall-e/llm/portkey-sync.js +654 -0
  298. package/template/wall-e/llm/provider-error.js +30 -2
  299. package/template/wall-e/llm/registry.js +5 -1
  300. package/template/wall-e/llm/request-compat.js +67 -0
  301. package/template/wall-e/loops/backfill.js +79 -23
  302. package/template/wall-e/loops/brain-optimize.js +67 -0
  303. package/template/wall-e/loops/ingest.js +25 -10
  304. package/template/wall-e/loops/question-digest.js +160 -0
  305. package/template/wall-e/loops/reflect.js +6 -4
  306. package/template/wall-e/loops/think.js +39 -12
  307. package/template/wall-e/mcp-server.js +318 -36
  308. package/template/wall-e/memory/ctm-context-client.js +52 -14
  309. package/template/wall-e/memory/ctm-operational-context.js +237 -0
  310. package/template/wall-e/memory/ctm-prompt-executions-client.js +128 -0
  311. package/template/wall-e/memory/ctm-session-context.js +111 -63
  312. package/template/wall-e/prompts/coding/deepseek.txt +3 -0
  313. package/template/wall-e/prompts/coding/gemini.txt +6 -0
  314. package/template/wall-e/prompts/coding/gpt.txt +6 -0
  315. package/template/wall-e/prompts/coding/local.txt +7 -0
  316. package/template/wall-e/runtime/decision-hooks.js +115 -0
  317. package/template/wall-e/runtime/devbox-gateway.js +82 -8
  318. package/template/wall-e/runtime/prompt-manifest.js +86 -0
  319. package/template/wall-e/runtime/tool-executor.js +269 -0
  320. package/template/wall-e/runtime/tool-result-envelope.js +138 -0
  321. package/template/wall-e/runtime/transcript-projection.js +60 -0
  322. package/template/wall-e/runtime/walle-runtime.js +224 -0
  323. package/template/wall-e/scripts/db-optimize/migrate.js +162 -0
  324. package/template/wall-e/scripts/db-optimize/recall-eval.js +117 -0
  325. package/template/wall-e/server.js +15 -0
  326. package/template/wall-e/session-files.js +9 -0
  327. package/template/wall-e/skills/_bundled/google-calendar/run.js +1 -1
  328. package/template/wall-e/skills/_bundled/gws-workspace/run.js +1 -1
  329. package/template/wall-e/skills/_bundled/slack-mentions/run.js +76 -6
  330. package/template/wall-e/skills/claude-code-reader.js +7 -3
  331. package/template/wall-e/skills/script-skill-runner.js +10 -0
  332. package/template/wall-e/skills/skill-planner.js +38 -0
  333. package/template/wall-e/tools/builtin-middleware.js +19 -9
  334. package/template/wall-e/tools/local-tools.js +1428 -16
  335. package/template/wall-e/tools/permission-checker.js +73 -5
  336. package/template/wall-e/tools/question-manager.js +117 -7
  337. package/template/wall-e/training/harvester.js +12 -28
  338. package/template/wall-e/training/replay.js +25 -80
  339. package/template/website/index.html +10 -10
  340. package/template/wall-e/eval/ab-test.js +0 -203
  341. package/template/wall-e/eval/agent-runner.js +0 -772
  342. package/template/wall-e/eval/agent-scorer.js +0 -461
  343. package/template/wall-e/eval/aggregator.js +0 -414
  344. package/template/wall-e/eval/allowed-test-commands.js +0 -34
  345. package/template/wall-e/eval/benchmark-generator.js +0 -113
  346. package/template/wall-e/eval/benchmarks/chat-eval.json +0 -1662
  347. package/template/wall-e/eval/benchmarks/chat.json +0 -82
  348. package/template/wall-e/eval/benchmarks/coding-agent-real.json +0 -1
  349. package/template/wall-e/eval/benchmarks/coding-agent.json +0 -1581
  350. package/template/wall-e/eval/benchmarks/coding.json +0 -122
  351. package/template/wall-e/eval/benchmarks/memory-retrieval.json +0 -234
  352. package/template/wall-e/eval/benchmarks/reasoning.json +0 -82
  353. package/template/wall-e/eval/benchmarks/swebench-lite-30.json +0 -212
  354. package/template/wall-e/eval/benchmarks.js +0 -669
  355. package/template/wall-e/eval/cc-replay.js +0 -719
  356. package/template/wall-e/eval/chat-eval.js +0 -525
  357. package/template/wall-e/eval/check-keys.js +0 -15
  358. package/template/wall-e/eval/check-providers.js +0 -42
  359. package/template/wall-e/eval/codex-cli-baseline.js +0 -669
  360. package/template/wall-e/eval/coding-agent-real.js +0 -570
  361. package/template/wall-e/eval/context-compactor.js +0 -251
  362. package/template/wall-e/eval/debug-agent003.js +0 -68
  363. package/template/wall-e/eval/diagnostics.js +0 -216
  364. package/template/wall-e/eval/eval-orchestrator.js +0 -642
  365. package/template/wall-e/eval/evaluate.js +0 -202
  366. package/template/wall-e/eval/evaluator.js +0 -373
  367. package/template/wall-e/eval/exporter.js +0 -212
  368. package/template/wall-e/eval/fixtures/express-basic/package.json +0 -9
  369. package/template/wall-e/eval/fixtures/express-basic/server.js +0 -115
  370. package/template/wall-e/eval/fixtures/express-basic/test.js +0 -83
  371. package/template/wall-e/eval/fixtures/express-buggy/package.json +0 -9
  372. package/template/wall-e/eval/fixtures/express-buggy/server.js +0 -113
  373. package/template/wall-e/eval/fixtures/express-buggy/test.js +0 -83
  374. package/template/wall-e/eval/fixtures/express-buggy-items/package.json +0 -9
  375. package/template/wall-e/eval/fixtures/express-buggy-items/server.js +0 -112
  376. package/template/wall-e/eval/fixtures/express-buggy-items/test.js +0 -83
  377. package/template/wall-e/eval/fixtures/express-buggy-search/package.json +0 -9
  378. package/template/wall-e/eval/fixtures/express-buggy-search/server.js +0 -121
  379. package/template/wall-e/eval/fixtures/express-buggy-search/test.js +0 -83
  380. package/template/wall-e/eval/fixtures/express-rename-data/data.js +0 -34
  381. package/template/wall-e/eval/fixtures/express-rename-data/package.json +0 -9
  382. package/template/wall-e/eval/fixtures/express-rename-data/server.js +0 -97
  383. package/template/wall-e/eval/fixtures/express-rename-data/test.js +0 -88
  384. package/template/wall-e/eval/fixtures/express-xss/package.json +0 -12
  385. package/template/wall-e/eval/fixtures/express-xss/server.js +0 -90
  386. package/template/wall-e/eval/fixtures/express-xss/test.js +0 -67
  387. package/template/wall-e/eval/fixtures/express-xss/views/profile.ejs +0 -9
  388. package/template/wall-e/eval/fixtures/fullstack-app/config/default.js +0 -9
  389. package/template/wall-e/eval/fixtures/fullstack-app/config/test.js +0 -13
  390. package/template/wall-e/eval/fixtures/fullstack-app/package.json +0 -11
  391. package/template/wall-e/eval/fixtures/fullstack-app/public/css/style.css +0 -137
  392. package/template/wall-e/eval/fixtures/fullstack-app/public/index.html +0 -46
  393. package/template/wall-e/eval/fixtures/fullstack-app/public/js/app.js +0 -121
  394. package/template/wall-e/eval/fixtures/fullstack-app/public/js/auth.js +0 -71
  395. package/template/wall-e/eval/fixtures/fullstack-app/public/js/items.js +0 -80
  396. package/template/wall-e/eval/fixtures/fullstack-app/public/js/users.js +0 -46
  397. package/template/wall-e/eval/fixtures/fullstack-app/public/login.html +0 -45
  398. package/template/wall-e/eval/fixtures/fullstack-app/public/register.html +0 -38
  399. package/template/wall-e/eval/fixtures/fullstack-app/scripts/migrate.js +0 -23
  400. package/template/wall-e/eval/fixtures/fullstack-app/scripts/seed.js +0 -46
  401. package/template/wall-e/eval/fixtures/fullstack-app/server/db.js +0 -99
  402. package/template/wall-e/eval/fixtures/fullstack-app/server/index.js +0 -94
  403. package/template/wall-e/eval/fixtures/fullstack-app/server/middleware/auth.js +0 -19
  404. package/template/wall-e/eval/fixtures/fullstack-app/server/middleware/logger.js +0 -19
  405. package/template/wall-e/eval/fixtures/fullstack-app/server/router.js +0 -50
  406. package/template/wall-e/eval/fixtures/fullstack-app/server/routes/auth.js +0 -69
  407. package/template/wall-e/eval/fixtures/fullstack-app/server/routes/health.js +0 -23
  408. package/template/wall-e/eval/fixtures/fullstack-app/server/routes/items.js +0 -88
  409. package/template/wall-e/eval/fixtures/fullstack-app/server/routes/users.js +0 -75
  410. package/template/wall-e/eval/fixtures/fullstack-app/server/test.js +0 -198
  411. package/template/wall-e/eval/fixtures/fullstack-app/server/utils/response.js +0 -34
  412. package/template/wall-e/eval/fixtures/fullstack-app/server/utils/validate.js +0 -26
  413. package/template/wall-e/eval/fixtures/fullstack-app/server.js +0 -8
  414. package/template/wall-e/eval/fixtures/fullstack-app/test.js +0 -12
  415. package/template/wall-e/eval/fixtures/monorepo-basic/package.json +0 -8
  416. package/template/wall-e/eval/fixtures/monorepo-basic/packages/api/data.js +0 -58
  417. package/template/wall-e/eval/fixtures/monorepo-basic/packages/api/middleware.js +0 -46
  418. package/template/wall-e/eval/fixtures/monorepo-basic/packages/api/package.json +0 -8
  419. package/template/wall-e/eval/fixtures/monorepo-basic/packages/api/routes.js +0 -64
  420. package/template/wall-e/eval/fixtures/monorepo-basic/packages/api/server.js +0 -56
  421. package/template/wall-e/eval/fixtures/monorepo-basic/packages/api/test.js +0 -116
  422. package/template/wall-e/eval/fixtures/monorepo-basic/packages/cli/commands.js +0 -61
  423. package/template/wall-e/eval/fixtures/monorepo-basic/packages/cli/index.js +0 -62
  424. package/template/wall-e/eval/fixtures/monorepo-basic/packages/cli/output.js +0 -43
  425. package/template/wall-e/eval/fixtures/monorepo-basic/packages/cli/package.json +0 -11
  426. package/template/wall-e/eval/fixtures/monorepo-basic/packages/cli/test.js +0 -44
  427. package/template/wall-e/eval/fixtures/monorepo-basic/packages/shared/formatters.js +0 -43
  428. package/template/wall-e/eval/fixtures/monorepo-basic/packages/shared/index.js +0 -12
  429. package/template/wall-e/eval/fixtures/monorepo-basic/packages/shared/package.json +0 -5
  430. package/template/wall-e/eval/fixtures/monorepo-basic/packages/shared/test.js +0 -55
  431. package/template/wall-e/eval/fixtures/monorepo-basic/packages/shared/validators.js +0 -29
  432. package/template/wall-e/eval/fixtures/monorepo-basic/test.js +0 -46
  433. package/template/wall-e/eval/fixtures/node-cli/index.js +0 -78
  434. package/template/wall-e/eval/fixtures/node-cli/package.json +0 -10
  435. package/template/wall-e/eval/fixtures/node-cli/test.js +0 -57
  436. package/template/wall-e/eval/fixtures/node-typed/package.json +0 -8
  437. package/template/wall-e/eval/fixtures/node-typed/src/handlers.js +0 -31
  438. package/template/wall-e/eval/fixtures/node-typed/src/utils.js +0 -33
  439. package/template/wall-e/eval/fixtures/node-typed/test.js +0 -36
  440. package/template/wall-e/eval/fixtures/python-flask/app.py +0 -14
  441. package/template/wall-e/eval/fixtures/python-flask/requirements.txt +0 -2
  442. package/template/wall-e/eval/fixtures/python-flask/test_app.py +0 -25
  443. package/template/wall-e/eval/fixtures/wall-e-subset/brain.js +0 -105
  444. package/template/wall-e/eval/fixtures/wall-e-subset/eval/aggregator.js +0 -101
  445. package/template/wall-e/eval/fixtures/wall-e-subset/eval/benchmarks/chat.json +0 -20
  446. package/template/wall-e/eval/fixtures/wall-e-subset/eval/benchmarks/coding.json +0 -32
  447. package/template/wall-e/eval/fixtures/wall-e-subset/eval/benchmarks.js +0 -64
  448. package/template/wall-e/eval/fixtures/wall-e-subset/eval/fixtures/simple-project/package.json +0 -6
  449. package/template/wall-e/eval/fixtures/wall-e-subset/eval/fixtures/simple-project/server.js +0 -31
  450. package/template/wall-e/eval/fixtures/wall-e-subset/eval/fixtures/simple-project/test.js +0 -18
  451. package/template/wall-e/eval/fixtures/wall-e-subset/eval/fixtures/simple-project/utils.js +0 -34
  452. package/template/wall-e/eval/fixtures/wall-e-subset/eval/runner.js +0 -104
  453. package/template/wall-e/eval/fixtures/wall-e-subset/eval/scorer.js +0 -73
  454. package/template/wall-e/eval/fixtures/wall-e-subset/eval/test.js +0 -134
  455. package/template/wall-e/eval/fixtures/wall-e-subset/llm/client.js +0 -99
  456. package/template/wall-e/eval/fixtures/wall-e-subset/llm/providers.js +0 -63
  457. package/template/wall-e/eval/fixtures/wall-e-subset/llm/test.js +0 -70
  458. package/template/wall-e/eval/fixtures/wall-e-subset/package.json +0 -10
  459. package/template/wall-e/eval/fixtures/wall-e-subset/test.js +0 -86
  460. package/template/wall-e/eval/harvester.js +0 -685
  461. package/template/wall-e/eval/head-to-head.js +0 -388
  462. package/template/wall-e/eval/humaneval-adapter.js +0 -321
  463. package/template/wall-e/eval/list-models.js +0 -31
  464. package/template/wall-e/eval/livecodebench-adapter.js +0 -291
  465. package/template/wall-e/eval/mail-integration.js +0 -443
  466. package/template/wall-e/eval/manifest.js +0 -186
  467. package/template/wall-e/eval/meta-harness/adapters/coding-agent.js +0 -57
  468. package/template/wall-e/eval/meta-harness/bootstrap-snapshot.js +0 -149
  469. package/template/wall-e/eval/meta-harness/candidate-store.js +0 -117
  470. package/template/wall-e/eval/meta-harness/cli.js +0 -86
  471. package/template/wall-e/eval/meta-harness/domain-spec.js +0 -154
  472. package/template/wall-e/eval/meta-harness/domains/coding-agent.domain.json +0 -84
  473. package/template/wall-e/eval/meta-harness/examples/env-bootstrap-candidate.js +0 -29
  474. package/template/wall-e/eval/meta-harness/experience-store.js +0 -174
  475. package/template/wall-e/eval/meta-harness/frontier.js +0 -96
  476. package/template/wall-e/eval/meta-harness/harness-interface.js +0 -90
  477. package/template/wall-e/eval/meta-harness/leakage-guard.js +0 -80
  478. package/template/wall-e/eval/meta-harness/optimizer.js +0 -207
  479. package/template/wall-e/eval/meta-harness/proposer-runner.js +0 -110
  480. package/template/wall-e/eval/meta-harness/reporting.js +0 -58
  481. package/template/wall-e/eval/meta-harness/telemetry.js +0 -27
  482. package/template/wall-e/eval/meta-harness/validation.js +0 -81
  483. package/template/wall-e/eval/promoter.js +0 -228
  484. package/template/wall-e/eval/provider-normalizer.js +0 -33
  485. package/template/wall-e/eval/replay.js +0 -395
  486. package/template/wall-e/eval/run-agent-benchmarks.js +0 -386
  487. package/template/wall-e/eval/run-codex-cli-baseline.js +0 -177
  488. package/template/wall-e/eval/run-coding-agent-real.js +0 -187
  489. package/template/wall-e/eval/run-eval.js +0 -435
  490. package/template/wall-e/eval/run-model-comparison.js +0 -142
  491. package/template/wall-e/eval/session-evaluator.js +0 -187
  492. package/template/wall-e/eval/session-miner.js +0 -207
  493. package/template/wall-e/eval/session-retrieval-benchmark.js +0 -150
  494. package/template/wall-e/eval/session-transcripts.js +0 -509
  495. package/template/wall-e/eval/shadow.js +0 -161
  496. package/template/wall-e/eval/swebench-adapter.js +0 -345
  497. package/template/wall-e/eval/swebench-docker.js +0 -192
  498. package/template/wall-e/eval/train.py +0 -320
  499. package/template/wall-e/eval/trainer.js +0 -232
  500. package/template/wall-e/eval/weekly-eval-loop.js +0 -241
@@ -41,6 +41,11 @@ const EXTERNAL_COMPLETION_PAIR_RE = new RegExp(
41
41
  'i',
42
42
  );
43
43
  const NEGATED_COMPLETION_RE = /\b(?:not|never|didn'?t|haven'?t|hasn'?t|wasn'?t|isn'?t)\s+(?:actually\s+)?(?:done|complete|completed|executed|sent|emailed|created|scheduled|booked|stored|saved)\b/i;
44
+ const EMAIL_APPROVAL_RE = /\b(?:email|emails|e-mail|e-mails|mail|mails)\b/i;
45
+ const CALENDAR_APPROVAL_RE = /\b(?:calendar|calendars|event|events|invite|invites|schedule|scheduled|book|booked)\b/i;
46
+ const SLACK_APPROVAL_RE = /\bslack\b/i;
47
+ const REMINDER_APPROVAL_RE = /\b(?:reminder|reminders)\b/i;
48
+ const NOTIFICATION_APPROVAL_RE = /\b(?:notification|notifications|notify)\b/i;
44
49
 
45
50
  function normalizeApprovalText(text, { removeSpaces = false } = {}) {
46
51
  let value = String(text || '')
@@ -133,6 +138,26 @@ function isExternalActionConfirmationText(text, { pendingActions = [] } = {}) {
133
138
  return false;
134
139
  }
135
140
 
141
+ function externalActionDomainsForApprovalText(text) {
142
+ const value = String(text || '');
143
+ const domains = new Set();
144
+ if (EMAIL_APPROVAL_RE.test(value)) domains.add('email');
145
+ if (CALENDAR_APPROVAL_RE.test(value)) domains.add('calendar');
146
+ if (SLACK_APPROVAL_RE.test(value)) domains.add('slack');
147
+ if (REMINDER_APPROVAL_RE.test(value)) domains.add('reminder');
148
+ if (NOTIFICATION_APPROVAL_RE.test(value)) domains.add('notification');
149
+ return [...domains];
150
+ }
151
+
152
+ function isCurrentTurnExternalActionApprovalText(text) {
153
+ const value = String(text || '').trim();
154
+ if (!value) return false;
155
+ const negative = NEGATIVE_RE.test(value);
156
+ if (negative && !APPROVAL_WAIVER_RE.test(value)) return false;
157
+ if (!CONFIRMATION_RE.test(value) || !EXTERNAL_VERB_RE.test(value)) return false;
158
+ return externalActionDomainsForApprovalText(value).length > 0;
159
+ }
160
+
136
161
  function parseMaybeJson(value) {
137
162
  if (!value) return null;
138
163
  if (typeof value === 'object') return value;
@@ -140,9 +165,39 @@ function parseMaybeJson(value) {
140
165
  try { return JSON.parse(value); } catch { return null; }
141
166
  }
142
167
 
143
- function externalActionFromToolCall(toolCall) {
144
- if (!toolCall || typeof toolCall !== 'object') return null;
145
- const parsed = parseMaybeJson(toolCall.output || toolCall.result);
168
+ function parsedPayloadsFromValue(value) {
169
+ if (!value) return [];
170
+ const parsed = parseMaybeJson(value);
171
+ if (parsed && typeof parsed === 'object' && !Array.isArray(parsed)) return [parsed];
172
+ if (!Array.isArray(value)) return [];
173
+ const payloads = [];
174
+ for (const item of value) {
175
+ const itemParsed = parseMaybeJson(item);
176
+ if (itemParsed && typeof itemParsed === 'object' && !Array.isArray(itemParsed)) {
177
+ payloads.push(itemParsed);
178
+ continue;
179
+ }
180
+ if (!item || typeof item !== 'object') continue;
181
+ for (const key of ['content', 'text', 'output', 'result']) {
182
+ const nested = parseMaybeJson(item[key]);
183
+ if (nested && typeof nested === 'object' && !Array.isArray(nested)) {
184
+ payloads.push(nested);
185
+ }
186
+ }
187
+ }
188
+ return payloads;
189
+ }
190
+
191
+ function messageContentBlocks(message) {
192
+ const blocks = [];
193
+ for (const content of [message?.content, message?.message?.content]) {
194
+ if (Array.isArray(content)) blocks.push(...content);
195
+ else if (content && typeof content === 'object') blocks.push(content);
196
+ }
197
+ return blocks;
198
+ }
199
+
200
+ function externalActionFromParsedPayload(parsed) {
146
201
  if (!parsed || parsed.external_action !== true || parsed.blocked !== true) return null;
147
202
  const action = parsed.action;
148
203
  if (!action || typeof action !== 'object') return null;
@@ -150,22 +205,65 @@ function externalActionFromToolCall(toolCall) {
150
205
  return action;
151
206
  }
152
207
 
208
+ function externalActionFromToolCall(toolCall) {
209
+ if (!toolCall || typeof toolCall !== 'object') return null;
210
+ for (const parsed of parsedPayloadsFromValue(toolCall.output || toolCall.result)) {
211
+ const action = externalActionFromParsedPayload(parsed);
212
+ if (action) return action;
213
+ }
214
+ return null;
215
+ }
216
+
217
+ function externalActionFromContentBlock(block) {
218
+ if (!block || typeof block !== 'object') return null;
219
+ const type = block.type || block.kind || '';
220
+ if (type && type !== 'tool_result' && type !== 'tool_call_result') return null;
221
+ for (const key of ['content', 'text', 'output', 'result']) {
222
+ for (const parsed of parsedPayloadsFromValue(block[key])) {
223
+ const action = externalActionFromParsedPayload(parsed);
224
+ if (action) return action;
225
+ }
226
+ }
227
+ return null;
228
+ }
229
+
230
+ function collectPendingExternalActionsFromMessage(message) {
231
+ const seen = new Set();
232
+ const actions = [];
233
+ const add = (action) => {
234
+ if (!action) return;
235
+ const key = action.payloadHash || action.id;
236
+ if (seen.has(key)) return;
237
+ seen.add(key);
238
+ actions.push(action);
239
+ };
240
+
241
+ for (const toolCall of message?.toolCalls || []) {
242
+ add(externalActionFromToolCall(toolCall));
243
+ }
244
+ for (const block of messageContentBlocks(message)) {
245
+ add(externalActionFromContentBlock(block));
246
+ }
247
+
248
+ return actions;
249
+ }
250
+
251
+ function isSyntheticToolResultMessage(message) {
252
+ if (!message || message.role !== 'user') return false;
253
+ return messageContentBlocks(message).some((block) => {
254
+ const type = block?.type || block?.kind || '';
255
+ return type === 'tool_result' || type === 'tool_call_result';
256
+ });
257
+ }
258
+
153
259
  function extractLatestPendingExternalActions(history = []) {
154
260
  if (!Array.isArray(history)) return [];
155
261
  for (let i = history.length - 1; i >= 0; i -= 1) {
156
262
  const message = history[i];
157
- if (!message || message.role !== 'assistant') continue;
158
- const seen = new Set();
159
- const actions = [];
160
- for (const toolCall of message.toolCalls || []) {
161
- const action = externalActionFromToolCall(toolCall);
162
- if (!action) continue;
163
- const key = action.payloadHash || action.id;
164
- if (seen.has(key)) continue;
165
- seen.add(key);
166
- actions.push(action);
167
- }
168
- return actions;
263
+ if (!message) continue;
264
+ const actions = collectPendingExternalActionsFromMessage(message);
265
+ if (actions.length) return actions;
266
+ if (message.role === 'user' && !isSyntheticToolResultMessage(message)) break;
169
267
  }
170
268
  return [];
171
269
  }
@@ -195,9 +293,29 @@ function buildExternalActionApprovalsForMessage({
195
293
  }));
196
294
  }
197
295
 
296
+ function buildCurrentTurnExternalActionApprovalsForMessage({
297
+ userText = '',
298
+ ctmSessionId = '',
299
+ chatSessionId = '',
300
+ now = () => new Date(),
301
+ } = {}) {
302
+ if (!isCurrentTurnExternalActionApprovalText(userText)) return [];
303
+ return [{
304
+ decision: 'allow',
305
+ scope: 'current_turn_external_actions',
306
+ approvalScope: 'current_turn_external_actions',
307
+ domains: externalActionDomainsForApprovalText(userText),
308
+ source: 'ctm_user_current_turn_confirmation',
309
+ ctmSessionId,
310
+ chatSessionId,
311
+ confirmedAt: now().toISOString(),
312
+ confirmedByUserMessage: String(userText || '').slice(0, 500),
313
+ }];
314
+ }
315
+
198
316
  function parseToolResultPayload(toolCall) {
199
317
  if (!toolCall || typeof toolCall !== 'object') return null;
200
- return parseMaybeJson(toolCall.output || toolCall.result);
318
+ return parsedPayloadsFromValue(toolCall.output || toolCall.result)[0] || null;
201
319
  }
202
320
 
203
321
  function isSuccessfulExternalActionResult(toolCall) {
@@ -282,6 +400,7 @@ function buildPendingExternalActionNotExecutedReply({ actions = [] } = {}) {
282
400
  }
283
401
 
284
402
  module.exports = {
403
+ buildCurrentTurnExternalActionApprovalsForMessage,
285
404
  buildExternalActionApprovalsForMessage,
286
405
  buildPendingExternalActionNotExecutedReply,
287
406
  extractLatestPendingExternalActions,
@@ -0,0 +1,46 @@
1
+ 'use strict';
2
+
3
+ const DEFAULT_WALLE_HISTORY_RETRY_MS = 2500;
4
+
5
+ function isWalleLikeSession(session) {
6
+ if (!session || typeof session !== 'object') return false;
7
+ return session.type === 'walle'
8
+ || session.agentType === 'walle'
9
+ || session.meta?.type === 'walle'
10
+ || session._restoreTask?.type === 'walle'
11
+ || !!session._restoreTask?.chat_session_id
12
+ || !!session.chatSessionId;
13
+ }
14
+
15
+ function shouldAutoStartDeferredRestore(session, msg, source) {
16
+ if (!session?._restoreDeferred || !msg?.autoStartRestore) return false;
17
+ if (!isWalleLikeSession(session)) return true;
18
+ const normalizedSource = String(source || msg.type || '').trim();
19
+ // Wall-E history is not a terminal frame. A visible attach from older clients
20
+ // may still start the runtime, but snapshots/reflow/prewarm must not.
21
+ return normalizedSource === 'attach';
22
+ }
23
+
24
+ function shouldRequestWalleHistory(input = {}, opts = {}) {
25
+ if (opts.force === true) return true;
26
+ if (input.hasRenderableMessages === true) return false;
27
+ if (input.historyStatus === 'loaded' || input.loaded === true) return false;
28
+
29
+ const requested = input.requested === true || input.historyStatus === 'loading' || input.loading === true;
30
+ if (!requested) return true;
31
+
32
+ const retryAfterMs = Number.isFinite(Number(opts.retryAfterMs))
33
+ ? Math.max(0, Number(opts.retryAfterMs))
34
+ : DEFAULT_WALLE_HISTORY_RETRY_MS;
35
+ const requestedAt = Number(input.requestedAt || 0);
36
+ if (!requestedAt) return true;
37
+ const now = Number.isFinite(Number(opts.now)) ? Number(opts.now) : Date.now();
38
+ return now - requestedAt >= retryAfterMs;
39
+ }
40
+
41
+ module.exports = {
42
+ DEFAULT_WALLE_HISTORY_RETRY_MS,
43
+ isWalleLikeSession,
44
+ shouldAutoStartDeferredRestore,
45
+ shouldRequestWalleHistory,
46
+ };
@@ -0,0 +1,403 @@
1
+ 'use strict';
2
+
3
+ const fs = require('fs');
4
+ const path = require('path');
5
+ const { execFile } = require('child_process');
6
+
7
+ const WALL_E_NATIVE_DEPENDENCIES = Object.freeze([
8
+ 'better-sqlite3',
9
+ 'sqlite-vec',
10
+ 'tree-sitter-bash',
11
+ ]);
12
+
13
+ function safeRealpath(value) {
14
+ try { return fs.realpathSync.native ? fs.realpathSync.native(value) : fs.realpathSync(value); } catch {}
15
+ return '';
16
+ }
17
+
18
+ function inspectWalleNodeModules(cwd) {
19
+ const root = path.resolve(cwd);
20
+ const nodeModulesPath = path.join(root, 'node_modules');
21
+ const rootRealpath = safeRealpath(root) || root;
22
+ const expectedRealpath = path.join(rootRealpath, 'node_modules');
23
+ let stat = null;
24
+ try { stat = fs.lstatSync(nodeModulesPath); } catch {}
25
+ const exists = !!stat;
26
+ const symlink = !!(stat && stat.isSymbolicLink());
27
+ const realpath = exists ? (safeRealpath(nodeModulesPath) || nodeModulesPath) : '';
28
+ const ownedByWalleDir = !exists || realpath === expectedRealpath;
29
+ return {
30
+ path: nodeModulesPath,
31
+ realpath,
32
+ exists,
33
+ symlink,
34
+ ownedByWalleDir,
35
+ shared: exists && !ownedByWalleDir,
36
+ };
37
+ }
38
+
39
+ const NATIVE_CHECK_SCRIPT = `
40
+ const checked = ${JSON.stringify(WALL_E_NATIVE_DEPENDENCIES)};
41
+ function done(ok, payload) {
42
+ const base = {
43
+ ok,
44
+ node: {
45
+ execPath: process.execPath,
46
+ version: process.version,
47
+ modules: process.versions.modules || '',
48
+ platform: process.platform,
49
+ arch: process.arch
50
+ }
51
+ };
52
+ process.stdout.write(JSON.stringify(Object.assign(base, payload || {})));
53
+ process.exit(ok ? 0 : 42);
54
+ }
55
+ try {
56
+ const Database = require('better-sqlite3');
57
+ const db = new Database(':memory:');
58
+ const quick = db.pragma('quick_check');
59
+ let sqliteVec = 'not_checked';
60
+ let treeSitterBash = 'not_checked';
61
+ try {
62
+ const vec = require('sqlite-vec');
63
+ if (vec && typeof vec.load === 'function') {
64
+ vec.load(db);
65
+ sqliteVec = 'loaded';
66
+ } else {
67
+ sqliteVec = 'present';
68
+ }
69
+ } catch (err) {
70
+ throw new Error('sqlite-vec failed: ' + err.message);
71
+ } finally {
72
+ try { db.close(); } catch {}
73
+ }
74
+ try {
75
+ require('tree-sitter-bash');
76
+ treeSitterBash = 'loaded';
77
+ } catch (err) {
78
+ throw new Error('tree-sitter-bash failed: ' + err.message);
79
+ }
80
+ done(true, {
81
+ checked,
82
+ sqlite: { quick_check: quick && quick[0] ? quick[0].quick_check : 'unknown' },
83
+ sqlite_vec: sqliteVec,
84
+ tree_sitter_bash: treeSitterBash
85
+ });
86
+ } catch (err) {
87
+ done(false, {
88
+ checked,
89
+ error: {
90
+ name: err && err.name || 'Error',
91
+ code: err && err.code || '',
92
+ message: err && err.message || String(err || '')
93
+ }
94
+ });
95
+ }
96
+ `;
97
+
98
+ function execFileJson(file, args, options = {}) {
99
+ const execFileImpl = options.execFileImpl || execFile;
100
+ return new Promise((resolve) => {
101
+ execFileImpl(file, args, {
102
+ cwd: options.cwd,
103
+ env: options.env || process.env,
104
+ timeout: options.timeoutMs || 5000,
105
+ maxBuffer: 1024 * 1024,
106
+ }, (err, stdout, stderr) => {
107
+ resolve({
108
+ err,
109
+ stdout: String(stdout || ''),
110
+ stderr: String(stderr || ''),
111
+ code: err && typeof err.code !== 'undefined' ? err.code : 0,
112
+ signal: err && err.signal || null,
113
+ });
114
+ });
115
+ });
116
+ }
117
+
118
+ function classifyNativeDependencyError(message, code = '') {
119
+ const text = String(message || '');
120
+ if (/NODE_MODULE_VERSION/i.test(text) || /compiled against a different Node\.js version/i.test(text)) {
121
+ return 'native_dependency_abi_mismatch';
122
+ }
123
+ if (/Cannot find module/i.test(text) || code === 'MODULE_NOT_FOUND') {
124
+ return 'native_dependency_missing';
125
+ }
126
+ if (/ERR_DLOPEN_FAILED|dlopen|invalid ELF|mach-o|was built for/i.test(text) || code === 'ERR_DLOPEN_FAILED') {
127
+ return 'native_dependency_load_failed';
128
+ }
129
+ if (/timed out/i.test(text)) return 'native_dependency_check_timeout';
130
+ return 'native_dependency_failed';
131
+ }
132
+
133
+ function parseJsonOutput(stdout) {
134
+ const text = String(stdout || '').trim();
135
+ if (!text) return null;
136
+ try {
137
+ return JSON.parse(text.split(/\r?\n/).filter(Boolean).pop());
138
+ } catch {
139
+ return null;
140
+ }
141
+ }
142
+
143
+ function normalizeNativeHealth(raw, fallbackMessage = '') {
144
+ const payload = raw && typeof raw === 'object' ? raw : {};
145
+ if (payload.ok) {
146
+ return {
147
+ ok: true,
148
+ code: 'ok',
149
+ message: 'Wall-E native dependencies are loadable.',
150
+ checked: payload.checked || [],
151
+ node: payload.node || {},
152
+ sqlite: payload.sqlite || {},
153
+ sqlite_vec: payload.sqlite_vec || '',
154
+ tree_sitter_bash: payload.tree_sitter_bash || '',
155
+ rebuild_attempted: false,
156
+ };
157
+ }
158
+
159
+ const error = payload.error || {};
160
+ const message = error.message || fallbackMessage || 'Wall-E native dependency check failed.';
161
+ const code = classifyNativeDependencyError(message, error.code);
162
+ return {
163
+ ok: false,
164
+ code,
165
+ message,
166
+ checked: payload.checked || WALL_E_NATIVE_DEPENDENCIES,
167
+ node: payload.node || {},
168
+ error: {
169
+ name: error.name || 'Error',
170
+ code: error.code || '',
171
+ message,
172
+ },
173
+ rebuild_hint: `npm rebuild ${WALL_E_NATIVE_DEPENDENCIES.join(' ')} --loglevel=warn`,
174
+ rebuild_attempted: false,
175
+ };
176
+ }
177
+
178
+ async function checkWalleNativeDeps({
179
+ walleDir,
180
+ nodePath = process.execPath,
181
+ execFileImpl = execFile,
182
+ timeoutMs = 5000,
183
+ } = {}) {
184
+ const cwd = walleDir || path.resolve(__dirname, '..', '..', 'wall-e');
185
+ const nodeModules = inspectWalleNodeModules(cwd);
186
+ const result = await execFileJson(nodePath, ['-e', NATIVE_CHECK_SCRIPT], {
187
+ cwd,
188
+ execFileImpl,
189
+ timeoutMs,
190
+ });
191
+ const payload = parseJsonOutput(result.stdout);
192
+ if (payload) {
193
+ return {
194
+ ...normalizeNativeHealth(payload, result.stderr || result.err?.message),
195
+ node_modules: nodeModules,
196
+ };
197
+ }
198
+ return {
199
+ ...normalizeNativeHealth(null, result.stderr || result.err?.message || 'Native dependency check produced no JSON output.'),
200
+ node_modules: nodeModules,
201
+ };
202
+ }
203
+
204
+ function shouldRebuildNativeDeps(health) {
205
+ if (health?.node_modules?.shared) return false;
206
+ return Boolean(health && !health.ok && [
207
+ 'native_dependency_abi_mismatch',
208
+ 'native_dependency_load_failed',
209
+ 'native_dependency_missing',
210
+ ].includes(health.code));
211
+ }
212
+
213
+ function dependencyPackagePath(cwd, dependency) {
214
+ return path.join(cwd, 'node_modules', ...dependency.split('/'), 'package.json');
215
+ }
216
+
217
+ function missingNativeDependencies(cwd) {
218
+ return WALL_E_NATIVE_DEPENDENCIES.filter(dep => !fs.existsSync(dependencyPackagePath(cwd, dep)));
219
+ }
220
+
221
+ function normalizeNpmExecPath(value) {
222
+ if (!value) return null;
223
+ const resolved = path.resolve(value);
224
+ if (path.basename(resolved) === 'npx-cli.js') {
225
+ return path.join(path.dirname(resolved), 'npm-cli.js');
226
+ }
227
+ return resolved;
228
+ }
229
+
230
+ function npmCliCandidates(nodePath = process.execPath) {
231
+ const binDir = path.dirname(nodePath);
232
+ return [
233
+ path.join(binDir, 'node_modules', 'npm', 'bin', 'npm-cli.js'),
234
+ path.join(binDir, '..', 'lib', 'node_modules', 'npm', 'bin', 'npm-cli.js'),
235
+ path.join(binDir, '..', 'libexec', 'lib', 'node_modules', 'npm', 'bin', 'npm-cli.js'),
236
+ path.join(binDir, '..', '..', '..', '..', 'lib', 'node_modules', 'npm', 'bin', 'npm-cli.js'),
237
+ ].map(candidate => path.resolve(candidate));
238
+ }
239
+
240
+ function resolveNpmRunner({ env = process.env, nodePath = process.execPath } = {}) {
241
+ // Only trust the ambient npm_execpath when resolving npm for the SAME Node that
242
+ // launched this process. When rebuilding native deps for a specific (possibly
243
+ // different) target Node, that Node's own bundled npm must win — the ambient
244
+ // npm_execpath points at whatever npm launched CTM (or the test runner) and
245
+ // would rebuild against the wrong install/ABI.
246
+ let resolvingForCurrentNode = true;
247
+ try {
248
+ resolvingForCurrentNode = path.resolve(nodePath) === path.resolve(process.execPath);
249
+ } catch { resolvingForCurrentNode = true; }
250
+ if (resolvingForCurrentNode) {
251
+ const envPath = normalizeNpmExecPath(env.npm_execpath);
252
+ if (envPath && fs.existsSync(envPath)) return { type: 'node-cli', path: envPath };
253
+ }
254
+ for (const candidate of npmCliCandidates(nodePath)) {
255
+ if (fs.existsSync(candidate)) return { type: 'node-cli', path: candidate };
256
+ }
257
+ return { type: 'bin', path: 'npm' };
258
+ }
259
+
260
+ function npmChildEnv(nodePath = process.execPath) {
261
+ const nodeDir = path.dirname(nodePath);
262
+ return {
263
+ ...process.env,
264
+ PATH: [nodeDir, process.env.PATH || ''].filter(Boolean).join(path.delimiter),
265
+ npm_config_update_notifier: 'false',
266
+ };
267
+ }
268
+
269
+ async function runNpmForNode({
270
+ cwd,
271
+ args,
272
+ nodePath = process.execPath,
273
+ execFileImpl = execFile,
274
+ timeoutMs = 120000,
275
+ } = {}) {
276
+ const runner = resolveNpmRunner({ nodePath });
277
+ const env = npmChildEnv(nodePath);
278
+ if (runner.type === 'node-cli') {
279
+ const result = await execFileJson(nodePath, [runner.path, ...args], {
280
+ cwd,
281
+ env,
282
+ execFileImpl,
283
+ timeoutMs,
284
+ });
285
+ return {
286
+ ...result,
287
+ command: `node ${runner.path} ${args.join(' ')}`,
288
+ runner,
289
+ };
290
+ }
291
+
292
+ const result = await execFileJson('npm', args, {
293
+ cwd,
294
+ env,
295
+ execFileImpl,
296
+ timeoutMs,
297
+ });
298
+ return {
299
+ ...result,
300
+ command: `npm ${args.join(' ')}`,
301
+ runner,
302
+ };
303
+ }
304
+
305
+ async function rebuildWalleNativeDeps({
306
+ walleDir,
307
+ nodePath = process.execPath,
308
+ execFileImpl = execFile,
309
+ timeoutMs = 120000,
310
+ } = {}) {
311
+ const cwd = walleDir || path.resolve(__dirname, '..', '..', 'wall-e');
312
+
313
+ // Backstop against the ABI ping-pong: never let a process running under a
314
+ // non-pinned Node major rebuild the shared native binary (that flip is what
315
+ // crash-loops the daemon). The entry guard normally prevents reaching here
316
+ // under the wrong Node; this also covers direct/CLI rebuild callers.
317
+ try {
318
+ const { findPinRoot, readPin } = require('./node-pin-guard');
319
+ const pinRoot = findPinRoot(__dirname);
320
+ const pin = pinRoot ? readPin(pinRoot) : '';
321
+ if (pin && pin.split('.')[0] !== process.versions.node.split('.')[0]) {
322
+ return {
323
+ ok: false,
324
+ code: 'native_dependency_wrong_node_major',
325
+ message: `Refusing to rebuild Wall-E native dependencies under Node v${process.versions.node}: this repo is pinned to v${pin}. Rebuilding here would flip the shared better-sqlite3 ABI and crash-loop the daemon. Re-run under the pinned Node ("$(bash ${path.join(pinRoot, 'bin', 'node-bin.sh')})") or follow the deliberate upgrade procedure.`,
326
+ pinned: pin,
327
+ running: process.versions.node,
328
+ };
329
+ }
330
+ } catch { /* no pin guard available — non-owner/shipped context, proceed */ }
331
+
332
+ const nodeModules = inspectWalleNodeModules(cwd);
333
+ if (nodeModules.shared) {
334
+ return {
335
+ ok: false,
336
+ code: 'native_dependency_shared_node_modules',
337
+ message: `Refusing to rebuild Wall-E native dependencies because ${nodeModules.path} resolves outside this Wall-E checkout (${nodeModules.realpath}). Use the same Node runtime as the owner or install isolated Wall-E dependencies in this worktree.`,
338
+ node_modules: nodeModules,
339
+ };
340
+ }
341
+
342
+ const attempts = [];
343
+ const missing = missingNativeDependencies(cwd);
344
+ if (missing.length > 0) {
345
+ const install = await runNpmForNode({
346
+ cwd,
347
+ nodePath,
348
+ args: ['install', '--omit=dev', '--loglevel=warn'],
349
+ execFileImpl,
350
+ timeoutMs,
351
+ });
352
+ attempts.push(install);
353
+ if (install.err) {
354
+ const output = `${install.stdout}\n${install.stderr}`.trim();
355
+ return {
356
+ ok: false,
357
+ code: 'native_dependency_install_failed',
358
+ message: output || install.err.message || 'npm install failed',
359
+ command: attempts.map(a => a.command).join(' && '),
360
+ missing,
361
+ };
362
+ }
363
+ }
364
+
365
+ const result = await runNpmForNode({
366
+ cwd,
367
+ nodePath,
368
+ args: ['rebuild', ...WALL_E_NATIVE_DEPENDENCIES, '--loglevel=warn'],
369
+ execFileImpl,
370
+ timeoutMs,
371
+ });
372
+ attempts.push(result);
373
+ const output = `${result.stdout}\n${result.stderr}`.trim();
374
+ if (result.err) {
375
+ return {
376
+ ok: false,
377
+ code: 'native_dependency_rebuild_failed',
378
+ message: output || result.err.message || 'npm rebuild failed',
379
+ command: attempts.map(a => a.command).join(' && '),
380
+ missing,
381
+ };
382
+ }
383
+ return {
384
+ ok: true,
385
+ code: 'ok',
386
+ message: output || 'rebuilt dependencies successfully',
387
+ command: attempts.map(a => a.command).join(' && '),
388
+ missing,
389
+ };
390
+ }
391
+
392
+ module.exports = {
393
+ WALL_E_NATIVE_DEPENDENCIES,
394
+ checkWalleNativeDeps,
395
+ classifyNativeDependencyError,
396
+ inspectWalleNodeModules,
397
+ normalizeNativeHealth,
398
+ npmCliCandidates,
399
+ rebuildWalleNativeDeps,
400
+ resolveNpmRunner,
401
+ shouldRebuildNativeDeps,
402
+ _NATIVE_CHECK_SCRIPT: NATIVE_CHECK_SCRIPT,
403
+ };