create-walle 0.9.22 → 0.9.24

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 (495) hide show
  1. package/README.md +22 -0
  2. package/package.json +1 -1
  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 +1190 -182
  11. package/template/claude-task-manager/api-reviews.js +104 -13
  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 +4071 -282
  16. package/template/claude-task-manager/docs/approval-ai-refinement.md +138 -0
  17. package/template/claude-task-manager/docs/approval-rescue-loop.md +74 -0
  18. package/template/claude-task-manager/docs/codex-operational-warning-health.md +107 -0
  19. package/template/claude-task-manager/docs/codex-resume-state-guard-design.md +17 -12
  20. package/template/claude-task-manager/docs/codex-terminal-render-controller-handoff.md +311 -0
  21. package/template/claude-task-manager/docs/coding-agent-hooks-architecture.md +418 -0
  22. package/template/claude-task-manager/docs/conversation-import-freshness.md +20 -0
  23. package/template/claude-task-manager/docs/google-workspace-auth-health.md +77 -0
  24. package/template/claude-task-manager/docs/image-paste-ux.md +10 -0
  25. package/template/claude-task-manager/docs/main-loop-offload-architecture.md +66 -0
  26. package/template/claude-task-manager/docs/microsoft-dev-tunnel-phone-access-design.md +274 -519
  27. package/template/claude-task-manager/docs/mobile-live-streaming.md +27 -5
  28. package/template/claude-task-manager/docs/mobile-remote-submission-lifecycle.md +69 -0
  29. package/template/claude-task-manager/docs/phone-access-design.md +53 -15
  30. package/template/claude-task-manager/docs/phone-passkey-identity.md +122 -0
  31. package/template/claude-task-manager/docs/phone-setup.md +3 -0
  32. package/template/claude-task-manager/docs/prompt-editing-tree-design.md +25 -1
  33. package/template/claude-task-manager/docs/remote-desktop-access-design.md +268 -0
  34. package/template/claude-task-manager/docs/restart-lifecycle-architecture.md +95 -0
  35. package/template/claude-task-manager/docs/runtime-work-control-plane.md +53 -0
  36. package/template/claude-task-manager/docs/session-interactive-wait-surfaces.md +38 -0
  37. package/template/claude-task-manager/docs/session-needs-you-dismissal.md +84 -0
  38. package/template/claude-task-manager/docs/session-render-state-management-design.md +91 -3
  39. package/template/claude-task-manager/docs/session-standup-command-center-design.md +25 -1
  40. package/template/claude-task-manager/docs/session-title-authority.md +32 -0
  41. package/template/claude-task-manager/docs/session-workspace-binding.md +33 -0
  42. package/template/claude-task-manager/docs/skill-intent-resolution-design.md +72 -0
  43. package/template/claude-task-manager/docs/walle-mcp-supervisor-health.md +86 -0
  44. package/template/claude-task-manager/docs/walle-relay-phone-access-design.md +24 -15
  45. package/template/claude-task-manager/docs/walle-session-history-hydration.md +114 -0
  46. package/template/claude-task-manager/docs/walle-session-input-queue.md +104 -0
  47. package/template/claude-task-manager/docs/walle-session-model-catalog.md +90 -0
  48. package/template/claude-task-manager/docs/walle-session-model-preferences.md +15 -6
  49. package/template/claude-task-manager/git-utils.js +751 -10
  50. package/template/claude-task-manager/lib/agent-capabilities.js +33 -0
  51. package/template/claude-task-manager/lib/agent-cli-cache.js +37 -7
  52. package/template/claude-task-manager/lib/agent-hooks-installer.js +26 -2
  53. package/template/claude-task-manager/lib/agent-presets.js +17 -1
  54. package/template/claude-task-manager/lib/all-sessions-query.js +108 -0
  55. package/template/claude-task-manager/lib/approval-ai-refinement.js +488 -0
  56. package/template/claude-task-manager/lib/approval-self-adapt.js +168 -0
  57. package/template/claude-task-manager/lib/async-semaphore.js +44 -0
  58. package/template/claude-task-manager/lib/auth-context.js +5 -0
  59. package/template/claude-task-manager/lib/auth-rate-limit.js +24 -1
  60. package/template/claude-task-manager/lib/auth-rules.js +26 -2
  61. package/template/claude-task-manager/lib/auto-approval-verifier.js +129 -16
  62. package/template/claude-task-manager/lib/background-llm.js +144 -17
  63. package/template/claude-task-manager/lib/branch-inventory.js +212 -0
  64. package/template/claude-task-manager/lib/claude-desktop-sessions.js +15 -3
  65. package/template/claude-task-manager/lib/coalesce-sync-frames.js +151 -0
  66. package/template/claude-task-manager/lib/codex-launch-health.js +762 -0
  67. package/template/claude-task-manager/lib/codex-transcript-pager.js +51 -0
  68. package/template/claude-task-manager/lib/codex-zst.js +124 -0
  69. package/template/claude-task-manager/lib/coding-agent-models.js +233 -30
  70. package/template/claude-task-manager/lib/connection-health.js +232 -0
  71. package/template/claude-task-manager/lib/conversation-blob-parser.js +42 -0
  72. package/template/claude-task-manager/lib/conversation-tail-merge.js +89 -26
  73. package/template/claude-task-manager/lib/ctm-session-context-api.js +39 -10
  74. package/template/claude-task-manager/lib/cursor-conversation-store.js +354 -0
  75. package/template/claude-task-manager/lib/db-owner-worker-client.js +315 -0
  76. package/template/claude-task-manager/lib/document-review.js +109 -5
  77. package/template/claude-task-manager/lib/escalation-review.js +152 -0
  78. package/template/claude-task-manager/lib/graceful-shutdown.js +159 -0
  79. package/template/claude-task-manager/lib/headless-term-service.js +678 -0
  80. package/template/claude-task-manager/lib/heavy-worker-fallback.js +38 -0
  81. package/template/claude-task-manager/lib/jsonl-conversation-parser.js +542 -0
  82. package/template/claude-task-manager/lib/jsonl-range-reader.js +112 -0
  83. package/template/claude-task-manager/lib/main-db-census.js +216 -0
  84. package/template/claude-task-manager/lib/message-pagination.js +106 -4
  85. package/template/claude-task-manager/lib/microsoft-dev-tunnel-setup.js +669 -28
  86. package/template/claude-task-manager/lib/mobile-auth-api.js +260 -7
  87. package/template/claude-task-manager/lib/mobile-auth-store.js +592 -10
  88. package/template/claude-task-manager/lib/mobile-notification-dispatcher.js +15 -0
  89. package/template/claude-task-manager/lib/model-overview-brain-fallback.js +311 -0
  90. package/template/claude-task-manager/lib/model-overview-cache.js +141 -0
  91. package/template/claude-task-manager/lib/models-health-routing-notice.js +126 -0
  92. package/template/claude-task-manager/lib/node-pin-guard.js +93 -0
  93. package/template/claude-task-manager/lib/perf-tracker.js +242 -6
  94. package/template/claude-task-manager/lib/permission-match.js +76 -0
  95. package/template/claude-task-manager/lib/permission-sync.js +133 -20
  96. package/template/claude-task-manager/lib/process-title.js +35 -0
  97. package/template/claude-task-manager/lib/prompt-executions-query.js +25 -0
  98. package/template/claude-task-manager/lib/prompt-index-disk-cache.js +44 -0
  99. package/template/claude-task-manager/lib/prompt-intent.js +132 -0
  100. package/template/claude-task-manager/lib/provider-user-context.js +34 -0
  101. package/template/claude-task-manager/lib/read-pool-client.js +313 -0
  102. package/template/claude-task-manager/lib/readpool-breaker.js +31 -0
  103. package/template/claude-task-manager/lib/recent-sessions-breaker.js +12 -0
  104. package/template/claude-task-manager/lib/remote-feedback-client.js +72 -0
  105. package/template/claude-task-manager/lib/remote-relay-protocol.js +37 -4
  106. package/template/claude-task-manager/lib/remote-relay-store.js +159 -0
  107. package/template/claude-task-manager/lib/remote-submission-observer.js +278 -0
  108. package/template/claude-task-manager/lib/restart-guard.js +46 -5
  109. package/template/claude-task-manager/lib/restore-interruption-detector.js +439 -0
  110. package/template/claude-task-manager/lib/restore-policy.js +13 -0
  111. package/template/claude-task-manager/lib/restore-resume-batch.js +74 -0
  112. package/template/claude-task-manager/lib/restore-runtime.js +68 -0
  113. package/template/claude-task-manager/lib/restore-storm.js +34 -0
  114. package/template/claude-task-manager/lib/resume-cwd.js +36 -0
  115. package/template/claude-task-manager/lib/resume-preflight.js +313 -0
  116. package/template/claude-task-manager/lib/runtime-work-registry.js +444 -0
  117. package/template/claude-task-manager/lib/sanitize-openai-auth.js +31 -0
  118. package/template/claude-task-manager/lib/scheduler.js +21 -1
  119. package/template/claude-task-manager/lib/scrollback-snapshot-store.js +159 -0
  120. package/template/claude-task-manager/lib/serial-task-queue.js +64 -0
  121. package/template/claude-task-manager/lib/server-listeners.js +239 -0
  122. package/template/claude-task-manager/lib/session-capture.js +42 -7
  123. package/template/claude-task-manager/lib/session-content-backfill.js +131 -0
  124. package/template/claude-task-manager/lib/session-history.js +388 -43
  125. package/template/claude-task-manager/lib/session-host-manager.js +287 -0
  126. package/template/claude-task-manager/lib/session-image-refs.js +209 -0
  127. package/template/claude-task-manager/lib/session-jobs.js +399 -59
  128. package/template/claude-task-manager/lib/session-prompt-index.js +137 -0
  129. package/template/claude-task-manager/lib/session-restore.js +53 -0
  130. package/template/claude-task-manager/lib/session-standup.js +87 -10
  131. package/template/claude-task-manager/lib/session-state-bus.js +14 -0
  132. package/template/claude-task-manager/lib/session-stream.js +53 -12
  133. package/template/claude-task-manager/lib/session-timeline-summary.js +260 -0
  134. package/template/claude-task-manager/lib/session-token-usage.js +494 -0
  135. package/template/claude-task-manager/lib/session-workspace-binding.js +356 -0
  136. package/template/claude-task-manager/lib/setup-network-config.js +9 -0
  137. package/template/claude-task-manager/lib/size-cap.js +45 -0
  138. package/template/claude-task-manager/lib/size-cap.test.js +62 -0
  139. package/template/claude-task-manager/lib/skill-autocomplete.js +180 -1
  140. package/template/claude-task-manager/lib/skill-intent-resolver.js +304 -0
  141. package/template/claude-task-manager/lib/sqlite-driver.js +19 -3
  142. package/template/claude-task-manager/lib/standup-attention.js +7 -3
  143. package/template/claude-task-manager/lib/status-authority.js +39 -0
  144. package/template/claude-task-manager/lib/status-hooks.js +4 -0
  145. package/template/claude-task-manager/lib/storage-migration.js +235 -0
  146. package/template/claude-task-manager/lib/structured-capture.js +298 -0
  147. package/template/claude-task-manager/lib/sync-io-census.js +163 -0
  148. package/template/claude-task-manager/lib/tailscale-setup.js +6 -0
  149. package/template/claude-task-manager/lib/terminal-activity-evidence.js +33 -0
  150. package/template/claude-task-manager/lib/terminal-choice.js +364 -0
  151. package/template/claude-task-manager/lib/terminal-control-sanitize.js +17 -0
  152. package/template/claude-task-manager/lib/terminal-fingerprint.js +48 -0
  153. package/template/claude-task-manager/lib/terminal-output-flush.js +84 -0
  154. package/template/claude-task-manager/lib/timeline-order.js +122 -0
  155. package/template/claude-task-manager/lib/transcript-store.js +348 -43
  156. package/template/claude-task-manager/lib/transport-security.js +34 -1
  157. package/template/claude-task-manager/lib/wait-state.js +184 -0
  158. package/template/claude-task-manager/lib/walle-client.js +47 -5
  159. package/template/claude-task-manager/lib/walle-ctm-history.js +564 -4
  160. package/template/claude-task-manager/lib/walle-external-actions.js +135 -16
  161. package/template/claude-task-manager/lib/walle-history-hydration.js +46 -0
  162. package/template/claude-task-manager/lib/walle-native-health.js +403 -0
  163. package/template/claude-task-manager/lib/walle-repair.js +701 -0
  164. package/template/claude-task-manager/lib/walle-session-cache.js +109 -0
  165. package/template/claude-task-manager/lib/walle-session-context.js +57 -21
  166. package/template/claude-task-manager/lib/walle-session-model-catalog.js +34 -0
  167. package/template/claude-task-manager/lib/walle-supervisor.js +539 -63
  168. package/template/claude-task-manager/lib/walle-transcript.js +36 -0
  169. package/template/claude-task-manager/lib/worktree-active-sync.js +5 -4
  170. package/template/claude-task-manager/lib/worktree-cwd.js +32 -1
  171. package/template/claude-task-manager/package.json +1 -1
  172. package/template/claude-task-manager/prompt-harvest.js +89 -66
  173. package/template/claude-task-manager/providers/claude-code.js +51 -3
  174. package/template/claude-task-manager/providers/cursor.js +140 -45
  175. package/template/claude-task-manager/public/css/reviews.css +541 -61
  176. package/template/claude-task-manager/public/css/setup.css +178 -0
  177. package/template/claude-task-manager/public/css/walle-session.css +865 -10
  178. package/template/claude-task-manager/public/css/walle.css +9 -0
  179. package/template/claude-task-manager/public/designs/ai-providers-consolidation-v2.html +830 -0
  180. package/template/claude-task-manager/public/index.html +18043 -2080
  181. package/template/claude-task-manager/public/js/document-review-links.js +106 -1
  182. package/template/claude-task-manager/public/js/image-normalize.js +69 -36
  183. package/template/claude-task-manager/public/js/message-renderer.js +1252 -75
  184. package/template/claude-task-manager/public/js/prompts.js +66 -29
  185. package/template/claude-task-manager/public/js/reviews.js +871 -127
  186. package/template/claude-task-manager/public/js/session-activity-utils.js +11 -1
  187. package/template/claude-task-manager/public/js/session-search-utils.js +94 -10
  188. package/template/claude-task-manager/public/js/session-status-precedence.js +23 -5
  189. package/template/claude-task-manager/public/js/setup.js +1238 -181
  190. package/template/claude-task-manager/public/js/stream-view.js +671 -72
  191. package/template/claude-task-manager/public/js/terminal-reconciler.js +210 -0
  192. package/template/claude-task-manager/public/js/walle-session.js +2455 -158
  193. package/template/claude-task-manager/public/js/walle.js +141 -10
  194. package/template/claude-task-manager/public/m/app.css +2033 -164
  195. package/template/claude-task-manager/public/m/app.js +5633 -433
  196. package/template/claude-task-manager/public/m/claim.html +219 -19
  197. package/template/claude-task-manager/public/m/index.html +105 -16
  198. package/template/claude-task-manager/public/m/sw.js +3 -1
  199. package/template/claude-task-manager/public/manifest.json +2 -2
  200. package/template/claude-task-manager/public/prompts.html +30 -14
  201. package/template/claude-task-manager/queue-engine.js +507 -28
  202. package/template/claude-task-manager/scripts/repair-claude-session-images.js +27 -8
  203. package/template/claude-task-manager/server.js +13981 -2107
  204. package/template/claude-task-manager/session-integrity.js +156 -18
  205. package/template/claude-task-manager/session-search-ranking.js +1 -0
  206. package/template/claude-task-manager/session-utils.js +25 -5
  207. package/template/claude-task-manager/workers/approval-blocklist.js +96 -6
  208. package/template/claude-task-manager/workers/approval-widget-validator.js +14 -8
  209. package/template/claude-task-manager/workers/conversation-import-worker.js +11 -50
  210. package/template/claude-task-manager/workers/db-owner-worker.js +386 -0
  211. package/template/claude-task-manager/workers/harvest-worker.js +9 -55
  212. package/template/claude-task-manager/workers/headless-term-worker.js +9 -530
  213. package/template/claude-task-manager/workers/read-pool-worker.js +387 -0
  214. package/template/claude-task-manager/workers/scrollback-worker.js +11 -72
  215. package/template/claude-task-manager/workers/session-host-process.js +146 -0
  216. package/template/claude-task-manager/workers/session-integrity-worker.js +10 -54
  217. package/template/claude-task-manager/workers/state-detectors/base.js +18 -1
  218. package/template/claude-task-manager/workers/state-detectors/claude-code.js +182 -9
  219. package/template/claude-task-manager/workers/state-detectors/codex.js +150 -2
  220. package/template/claude-task-manager/workers/state-detectors/cursor.js +127 -0
  221. package/template/claude-task-manager/workers/state-detectors/gemini.js +21 -0
  222. package/template/claude-task-manager/workers/state-detectors/index.js +29 -0
  223. package/template/claude-task-manager/workers/state-detectors/opencode.js +103 -0
  224. package/template/docs/design/markdown-review-pane.md +206 -0
  225. package/template/docs/designs/2026-05-17-portkey-gateway-provider-ux.md +54 -14
  226. package/template/docs/designs/2026-05-20-mobile-worktree-finish-command.md +27 -0
  227. package/template/docs/designs/2026-05-22-ai-configuration-consolidation.md +248 -0
  228. package/template/docs/designs/ai-configuration-consolidation-mock.html +812 -0
  229. package/template/docs/private-memory-and-pii-policy.md +69 -0
  230. package/template/package.json +2 -1
  231. package/template/scripts/check-private-data.js +201 -0
  232. package/template/shared/sqlite-owner-guard.js +30 -0
  233. package/template/shared/sqlite-owner-write-queue.js +225 -0
  234. package/template/shared/sqlite-storage-policy.js +111 -0
  235. package/template/shared/sqlite-write-lock.js +428 -0
  236. package/template/wall-e/agent-runners/claude-code.js +5 -0
  237. package/template/wall-e/agent.js +187 -22
  238. package/template/wall-e/api-walle.js +505 -69
  239. package/template/wall-e/auth/provider-flows.js +11 -1
  240. package/template/wall-e/bin/walle-mcp-stdio.js +341 -17
  241. package/template/wall-e/brain.js +1463 -136
  242. package/template/wall-e/chat/attachment-blocks.js +96 -0
  243. package/template/wall-e/chat/attachments.js +2 -1
  244. package/template/wall-e/chat/capability-resolver.js +7 -7
  245. package/template/wall-e/chat/context-messages.js +28 -0
  246. package/template/wall-e/chat/conversation-frame.js +630 -0
  247. package/template/wall-e/chat/provider-messages.js +125 -0
  248. package/template/wall-e/chat.js +926 -242
  249. package/template/wall-e/coding/acceptance-contract.js +170 -0
  250. package/template/wall-e/coding/acp-adapter.js +1 -1
  251. package/template/wall-e/coding/agent-catalog.js +3 -0
  252. package/template/wall-e/coding/artifact-store.js +93 -0
  253. package/template/wall-e/coding/capability-router.js +120 -0
  254. package/template/wall-e/coding/coding-run-controller.js +423 -0
  255. package/template/wall-e/coding/compaction-service.js +157 -12
  256. package/template/wall-e/coding/frontend-verification.js +258 -0
  257. package/template/wall-e/coding/lifecycle-hooks.js +75 -0
  258. package/template/wall-e/coding/local-preview-contract.js +157 -0
  259. package/template/wall-e/coding/permission-service.js +57 -13
  260. package/template/wall-e/coding/prompt-bundle.js +19 -1
  261. package/template/wall-e/coding/prompt-section-registry.js +227 -0
  262. package/template/wall-e/coding/provider-compat.js +15 -0
  263. package/template/wall-e/coding/runtime-events.js +224 -0
  264. package/template/wall-e/coding/runtime-mode.js +3 -0
  265. package/template/wall-e/coding/side-git-snapshot.js +160 -4
  266. package/template/wall-e/coding/snapshot-service.js +143 -1
  267. package/template/wall-e/coding/stream-processor.js +388 -34
  268. package/template/wall-e/coding/task-tool.js +141 -4
  269. package/template/wall-e/coding/tool-execution-controller.js +365 -0
  270. package/template/wall-e/coding/tool-registry.js +43 -5
  271. package/template/wall-e/coding/user-hooks.js +217 -0
  272. package/template/wall-e/coding-orchestrator.js +1224 -209
  273. package/template/wall-e/coding-prompts.js +20 -4
  274. package/template/wall-e/context/context-builder.js +15 -2
  275. package/template/wall-e/decision/confidence.js +1 -1
  276. package/template/wall-e/docs/coding-acceptance-contract.md +41 -0
  277. package/template/wall-e/docs/external-action-controller.md +26 -6
  278. package/template/wall-e/docs/telemetry-lifecycle.md +8 -2
  279. package/template/wall-e/embeddings.js +591 -53
  280. package/template/wall-e/external-action-controller.js +12 -0
  281. package/template/wall-e/http/auth.js +1 -0
  282. package/template/wall-e/http/chat-api.js +46 -11
  283. package/template/wall-e/http/model-admin.js +727 -56
  284. package/template/wall-e/lib/boot-profile.js +88 -0
  285. package/template/wall-e/lib/event-loop-monitor.js +93 -0
  286. package/template/wall-e/llm/anthropic.js +123 -5
  287. package/template/wall-e/llm/client.js +236 -67
  288. package/template/wall-e/llm/default-fallback.js +382 -0
  289. package/template/wall-e/llm/health.js +19 -0
  290. package/template/wall-e/llm/message-guard.js +78 -0
  291. package/template/wall-e/llm/model-catalog.js +252 -1
  292. package/template/wall-e/llm/openai.js +10 -3
  293. package/template/wall-e/llm/portkey-sync.js +489 -36
  294. package/template/wall-e/llm/provider-error.js +30 -2
  295. package/template/wall-e/llm/registry.js +5 -1
  296. package/template/wall-e/llm/request-compat.js +67 -0
  297. package/template/wall-e/loops/backfill.js +79 -23
  298. package/template/wall-e/loops/brain-optimize.js +67 -0
  299. package/template/wall-e/loops/ingest.js +25 -10
  300. package/template/wall-e/loops/question-digest.js +160 -0
  301. package/template/wall-e/loops/reflect.js +6 -4
  302. package/template/wall-e/loops/think.js +39 -12
  303. package/template/wall-e/mcp-server.js +318 -36
  304. package/template/wall-e/memory/ctm-context-client.js +52 -14
  305. package/template/wall-e/memory/ctm-operational-context.js +237 -0
  306. package/template/wall-e/memory/ctm-prompt-executions-client.js +128 -0
  307. package/template/wall-e/memory/ctm-session-context.js +111 -63
  308. package/template/wall-e/prompts/coding/deepseek.txt +3 -0
  309. package/template/wall-e/prompts/coding/gemini.txt +6 -0
  310. package/template/wall-e/prompts/coding/gpt.txt +6 -0
  311. package/template/wall-e/prompts/coding/local.txt +7 -0
  312. package/template/wall-e/runtime/decision-hooks.js +115 -0
  313. package/template/wall-e/runtime/devbox-gateway.js +82 -8
  314. package/template/wall-e/runtime/prompt-manifest.js +86 -0
  315. package/template/wall-e/runtime/tool-executor.js +269 -0
  316. package/template/wall-e/runtime/tool-result-envelope.js +138 -0
  317. package/template/wall-e/runtime/transcript-projection.js +60 -0
  318. package/template/wall-e/runtime/walle-runtime.js +224 -0
  319. package/template/wall-e/scripts/db-optimize/migrate.js +162 -0
  320. package/template/wall-e/scripts/db-optimize/recall-eval.js +117 -0
  321. package/template/wall-e/server.js +2 -0
  322. package/template/wall-e/session-files.js +9 -0
  323. package/template/wall-e/skills/_bundled/google-calendar/run.js +1 -1
  324. package/template/wall-e/skills/_bundled/gws-workspace/run.js +1 -1
  325. package/template/wall-e/skills/_bundled/slack-mentions/run.js +76 -6
  326. package/template/wall-e/skills/claude-code-reader.js +7 -3
  327. package/template/wall-e/skills/script-skill-runner.js +10 -0
  328. package/template/wall-e/skills/skill-planner.js +38 -0
  329. package/template/wall-e/tools/builtin-middleware.js +19 -9
  330. package/template/wall-e/tools/local-tools.js +1428 -16
  331. package/template/wall-e/tools/permission-checker.js +73 -5
  332. package/template/wall-e/tools/question-manager.js +117 -7
  333. package/template/wall-e/training/harvester.js +12 -28
  334. package/template/wall-e/training/replay.js +25 -80
  335. package/template/wall-e/eval/ab-test.js +0 -203
  336. package/template/wall-e/eval/agent-runner.js +0 -772
  337. package/template/wall-e/eval/agent-scorer.js +0 -461
  338. package/template/wall-e/eval/aggregator.js +0 -414
  339. package/template/wall-e/eval/allowed-test-commands.js +0 -34
  340. package/template/wall-e/eval/benchmark-generator.js +0 -113
  341. package/template/wall-e/eval/benchmarks/chat-eval.json +0 -1662
  342. package/template/wall-e/eval/benchmarks/chat.json +0 -82
  343. package/template/wall-e/eval/benchmarks/coding-agent-real.json +0 -1
  344. package/template/wall-e/eval/benchmarks/coding-agent.json +0 -1581
  345. package/template/wall-e/eval/benchmarks/coding.json +0 -122
  346. package/template/wall-e/eval/benchmarks/memory-retrieval.json +0 -234
  347. package/template/wall-e/eval/benchmarks/reasoning.json +0 -82
  348. package/template/wall-e/eval/benchmarks/swebench-lite-30.json +0 -212
  349. package/template/wall-e/eval/benchmarks.js +0 -669
  350. package/template/wall-e/eval/cc-replay.js +0 -719
  351. package/template/wall-e/eval/chat-eval.js +0 -525
  352. package/template/wall-e/eval/check-keys.js +0 -15
  353. package/template/wall-e/eval/check-providers.js +0 -42
  354. package/template/wall-e/eval/codex-cli-baseline.js +0 -669
  355. package/template/wall-e/eval/coding-agent-real.js +0 -570
  356. package/template/wall-e/eval/context-compactor.js +0 -251
  357. package/template/wall-e/eval/debug-agent003.js +0 -68
  358. package/template/wall-e/eval/diagnostics.js +0 -216
  359. package/template/wall-e/eval/eval-orchestrator.js +0 -642
  360. package/template/wall-e/eval/evaluate.js +0 -202
  361. package/template/wall-e/eval/evaluator.js +0 -373
  362. package/template/wall-e/eval/exporter.js +0 -212
  363. package/template/wall-e/eval/fixtures/express-basic/package.json +0 -9
  364. package/template/wall-e/eval/fixtures/express-basic/server.js +0 -115
  365. package/template/wall-e/eval/fixtures/express-basic/test.js +0 -83
  366. package/template/wall-e/eval/fixtures/express-buggy/package.json +0 -9
  367. package/template/wall-e/eval/fixtures/express-buggy/server.js +0 -113
  368. package/template/wall-e/eval/fixtures/express-buggy/test.js +0 -83
  369. package/template/wall-e/eval/fixtures/express-buggy-items/package.json +0 -9
  370. package/template/wall-e/eval/fixtures/express-buggy-items/server.js +0 -112
  371. package/template/wall-e/eval/fixtures/express-buggy-items/test.js +0 -83
  372. package/template/wall-e/eval/fixtures/express-buggy-search/package.json +0 -9
  373. package/template/wall-e/eval/fixtures/express-buggy-search/server.js +0 -121
  374. package/template/wall-e/eval/fixtures/express-buggy-search/test.js +0 -83
  375. package/template/wall-e/eval/fixtures/express-rename-data/data.js +0 -34
  376. package/template/wall-e/eval/fixtures/express-rename-data/package.json +0 -9
  377. package/template/wall-e/eval/fixtures/express-rename-data/server.js +0 -97
  378. package/template/wall-e/eval/fixtures/express-rename-data/test.js +0 -88
  379. package/template/wall-e/eval/fixtures/express-xss/package.json +0 -12
  380. package/template/wall-e/eval/fixtures/express-xss/server.js +0 -90
  381. package/template/wall-e/eval/fixtures/express-xss/test.js +0 -67
  382. package/template/wall-e/eval/fixtures/express-xss/views/profile.ejs +0 -9
  383. package/template/wall-e/eval/fixtures/fullstack-app/config/default.js +0 -9
  384. package/template/wall-e/eval/fixtures/fullstack-app/config/test.js +0 -13
  385. package/template/wall-e/eval/fixtures/fullstack-app/package.json +0 -11
  386. package/template/wall-e/eval/fixtures/fullstack-app/public/css/style.css +0 -137
  387. package/template/wall-e/eval/fixtures/fullstack-app/public/index.html +0 -46
  388. package/template/wall-e/eval/fixtures/fullstack-app/public/js/app.js +0 -121
  389. package/template/wall-e/eval/fixtures/fullstack-app/public/js/auth.js +0 -71
  390. package/template/wall-e/eval/fixtures/fullstack-app/public/js/items.js +0 -80
  391. package/template/wall-e/eval/fixtures/fullstack-app/public/js/users.js +0 -46
  392. package/template/wall-e/eval/fixtures/fullstack-app/public/login.html +0 -45
  393. package/template/wall-e/eval/fixtures/fullstack-app/public/register.html +0 -38
  394. package/template/wall-e/eval/fixtures/fullstack-app/scripts/migrate.js +0 -23
  395. package/template/wall-e/eval/fixtures/fullstack-app/scripts/seed.js +0 -46
  396. package/template/wall-e/eval/fixtures/fullstack-app/server/db.js +0 -99
  397. package/template/wall-e/eval/fixtures/fullstack-app/server/index.js +0 -94
  398. package/template/wall-e/eval/fixtures/fullstack-app/server/middleware/auth.js +0 -19
  399. package/template/wall-e/eval/fixtures/fullstack-app/server/middleware/logger.js +0 -19
  400. package/template/wall-e/eval/fixtures/fullstack-app/server/router.js +0 -50
  401. package/template/wall-e/eval/fixtures/fullstack-app/server/routes/auth.js +0 -69
  402. package/template/wall-e/eval/fixtures/fullstack-app/server/routes/health.js +0 -23
  403. package/template/wall-e/eval/fixtures/fullstack-app/server/routes/items.js +0 -88
  404. package/template/wall-e/eval/fixtures/fullstack-app/server/routes/users.js +0 -75
  405. package/template/wall-e/eval/fixtures/fullstack-app/server/test.js +0 -198
  406. package/template/wall-e/eval/fixtures/fullstack-app/server/utils/response.js +0 -34
  407. package/template/wall-e/eval/fixtures/fullstack-app/server/utils/validate.js +0 -26
  408. package/template/wall-e/eval/fixtures/fullstack-app/server.js +0 -8
  409. package/template/wall-e/eval/fixtures/fullstack-app/test.js +0 -12
  410. package/template/wall-e/eval/fixtures/monorepo-basic/package.json +0 -8
  411. package/template/wall-e/eval/fixtures/monorepo-basic/packages/api/data.js +0 -58
  412. package/template/wall-e/eval/fixtures/monorepo-basic/packages/api/middleware.js +0 -46
  413. package/template/wall-e/eval/fixtures/monorepo-basic/packages/api/package.json +0 -8
  414. package/template/wall-e/eval/fixtures/monorepo-basic/packages/api/routes.js +0 -64
  415. package/template/wall-e/eval/fixtures/monorepo-basic/packages/api/server.js +0 -56
  416. package/template/wall-e/eval/fixtures/monorepo-basic/packages/api/test.js +0 -116
  417. package/template/wall-e/eval/fixtures/monorepo-basic/packages/cli/commands.js +0 -61
  418. package/template/wall-e/eval/fixtures/monorepo-basic/packages/cli/index.js +0 -62
  419. package/template/wall-e/eval/fixtures/monorepo-basic/packages/cli/output.js +0 -43
  420. package/template/wall-e/eval/fixtures/monorepo-basic/packages/cli/package.json +0 -11
  421. package/template/wall-e/eval/fixtures/monorepo-basic/packages/cli/test.js +0 -44
  422. package/template/wall-e/eval/fixtures/monorepo-basic/packages/shared/formatters.js +0 -43
  423. package/template/wall-e/eval/fixtures/monorepo-basic/packages/shared/index.js +0 -12
  424. package/template/wall-e/eval/fixtures/monorepo-basic/packages/shared/package.json +0 -5
  425. package/template/wall-e/eval/fixtures/monorepo-basic/packages/shared/test.js +0 -55
  426. package/template/wall-e/eval/fixtures/monorepo-basic/packages/shared/validators.js +0 -29
  427. package/template/wall-e/eval/fixtures/monorepo-basic/test.js +0 -46
  428. package/template/wall-e/eval/fixtures/node-cli/index.js +0 -78
  429. package/template/wall-e/eval/fixtures/node-cli/package.json +0 -10
  430. package/template/wall-e/eval/fixtures/node-cli/test.js +0 -57
  431. package/template/wall-e/eval/fixtures/node-typed/package.json +0 -8
  432. package/template/wall-e/eval/fixtures/node-typed/src/handlers.js +0 -31
  433. package/template/wall-e/eval/fixtures/node-typed/src/utils.js +0 -33
  434. package/template/wall-e/eval/fixtures/node-typed/test.js +0 -36
  435. package/template/wall-e/eval/fixtures/python-flask/app.py +0 -14
  436. package/template/wall-e/eval/fixtures/python-flask/requirements.txt +0 -2
  437. package/template/wall-e/eval/fixtures/python-flask/test_app.py +0 -25
  438. package/template/wall-e/eval/fixtures/wall-e-subset/brain.js +0 -105
  439. package/template/wall-e/eval/fixtures/wall-e-subset/eval/aggregator.js +0 -101
  440. package/template/wall-e/eval/fixtures/wall-e-subset/eval/benchmarks/chat.json +0 -20
  441. package/template/wall-e/eval/fixtures/wall-e-subset/eval/benchmarks/coding.json +0 -32
  442. package/template/wall-e/eval/fixtures/wall-e-subset/eval/benchmarks.js +0 -64
  443. package/template/wall-e/eval/fixtures/wall-e-subset/eval/fixtures/simple-project/package.json +0 -6
  444. package/template/wall-e/eval/fixtures/wall-e-subset/eval/fixtures/simple-project/server.js +0 -31
  445. package/template/wall-e/eval/fixtures/wall-e-subset/eval/fixtures/simple-project/test.js +0 -18
  446. package/template/wall-e/eval/fixtures/wall-e-subset/eval/fixtures/simple-project/utils.js +0 -34
  447. package/template/wall-e/eval/fixtures/wall-e-subset/eval/runner.js +0 -104
  448. package/template/wall-e/eval/fixtures/wall-e-subset/eval/scorer.js +0 -73
  449. package/template/wall-e/eval/fixtures/wall-e-subset/eval/test.js +0 -134
  450. package/template/wall-e/eval/fixtures/wall-e-subset/llm/client.js +0 -99
  451. package/template/wall-e/eval/fixtures/wall-e-subset/llm/providers.js +0 -63
  452. package/template/wall-e/eval/fixtures/wall-e-subset/llm/test.js +0 -70
  453. package/template/wall-e/eval/fixtures/wall-e-subset/package.json +0 -10
  454. package/template/wall-e/eval/fixtures/wall-e-subset/test.js +0 -86
  455. package/template/wall-e/eval/harvester.js +0 -685
  456. package/template/wall-e/eval/head-to-head.js +0 -388
  457. package/template/wall-e/eval/humaneval-adapter.js +0 -321
  458. package/template/wall-e/eval/list-models.js +0 -31
  459. package/template/wall-e/eval/livecodebench-adapter.js +0 -291
  460. package/template/wall-e/eval/mail-integration.js +0 -443
  461. package/template/wall-e/eval/manifest.js +0 -186
  462. package/template/wall-e/eval/meta-harness/adapters/coding-agent.js +0 -57
  463. package/template/wall-e/eval/meta-harness/bootstrap-snapshot.js +0 -149
  464. package/template/wall-e/eval/meta-harness/candidate-store.js +0 -117
  465. package/template/wall-e/eval/meta-harness/cli.js +0 -86
  466. package/template/wall-e/eval/meta-harness/domain-spec.js +0 -154
  467. package/template/wall-e/eval/meta-harness/domains/coding-agent.domain.json +0 -84
  468. package/template/wall-e/eval/meta-harness/examples/env-bootstrap-candidate.js +0 -29
  469. package/template/wall-e/eval/meta-harness/experience-store.js +0 -174
  470. package/template/wall-e/eval/meta-harness/frontier.js +0 -96
  471. package/template/wall-e/eval/meta-harness/harness-interface.js +0 -90
  472. package/template/wall-e/eval/meta-harness/leakage-guard.js +0 -80
  473. package/template/wall-e/eval/meta-harness/optimizer.js +0 -207
  474. package/template/wall-e/eval/meta-harness/proposer-runner.js +0 -110
  475. package/template/wall-e/eval/meta-harness/reporting.js +0 -58
  476. package/template/wall-e/eval/meta-harness/telemetry.js +0 -27
  477. package/template/wall-e/eval/meta-harness/validation.js +0 -81
  478. package/template/wall-e/eval/promoter.js +0 -228
  479. package/template/wall-e/eval/provider-normalizer.js +0 -33
  480. package/template/wall-e/eval/replay.js +0 -395
  481. package/template/wall-e/eval/run-agent-benchmarks.js +0 -386
  482. package/template/wall-e/eval/run-codex-cli-baseline.js +0 -177
  483. package/template/wall-e/eval/run-coding-agent-real.js +0 -187
  484. package/template/wall-e/eval/run-eval.js +0 -435
  485. package/template/wall-e/eval/run-model-comparison.js +0 -142
  486. package/template/wall-e/eval/session-evaluator.js +0 -187
  487. package/template/wall-e/eval/session-miner.js +0 -207
  488. package/template/wall-e/eval/session-retrieval-benchmark.js +0 -150
  489. package/template/wall-e/eval/session-transcripts.js +0 -509
  490. package/template/wall-e/eval/shadow.js +0 -161
  491. package/template/wall-e/eval/swebench-adapter.js +0 -345
  492. package/template/wall-e/eval/swebench-docker.js +0 -192
  493. package/template/wall-e/eval/train.py +0 -320
  494. package/template/wall-e/eval/trainer.js +0 -232
  495. package/template/wall-e/eval/weekly-eval-loop.js +0 -241
@@ -6,6 +6,7 @@ const brain = require('./brain');
6
6
  const { createSessionIngestService } = require('./memory/session-ingest-service');
7
7
  const ctmSessionContext = require('./memory/ctm-session-context');
8
8
  const ctmContextClient = require('./memory/ctm-context-client');
9
+ const ctmOperationalContext = require('./memory/ctm-operational-context');
9
10
  const { collectIngestRecords } = require('./sources/base');
10
11
  const { ensureBuiltinSourceAdapters } = require('./sources/builtin');
11
12
  const sourceRegistry = require('./sources/registry');
@@ -192,6 +193,8 @@ const TOOL_OUTPUT_SCHEMAS = {
192
193
  },
193
194
  walle_memory_status: ANY_OBJECT_SCHEMA,
194
195
  walle_live_capabilities: ANY_OBJECT_SCHEMA,
196
+ walle_ctm_context: ANY_OBJECT_SCHEMA,
197
+ walle_ctm_remote_access_status: ANY_OBJECT_SCHEMA,
195
198
  walle_search_sessions: ANY_OBJECT_SCHEMA,
196
199
  walle_get_session: ANY_OBJECT_SCHEMA,
197
200
  walle_context_pack: ANY_OBJECT_SCHEMA,
@@ -243,6 +246,8 @@ const TOOL_ANNOTATIONS = {
243
246
  brain_stats: READ_ONLY_TOOL_ANNOTATION,
244
247
  walle_memory_status: READ_ONLY_TOOL_ANNOTATION,
245
248
  walle_live_capabilities: READ_ONLY_TOOL_ANNOTATION,
249
+ walle_ctm_context: READ_ONLY_TOOL_ANNOTATION,
250
+ walle_ctm_remote_access_status: READ_ONLY_TOOL_ANNOTATION,
246
251
  walle_list_sources: READ_ONLY_TOOL_ANNOTATION,
247
252
  walle_source_ingest: ADDITIVE_WRITE_TOOL_ANNOTATION,
248
253
  walle_search_sessions: READ_ONLY_TOOL_ANNOTATION,
@@ -280,6 +285,7 @@ const MCP_TOOLS = [
280
285
  limit: { type: 'number', description: 'Max memories/session snippets/entities per source (default 5, max 20)' },
281
286
  include_memories: { type: 'boolean', description: 'Include Wall-E memory search results (default true when route needs Wall-E)' },
282
287
  include_sessions: { type: 'boolean', description: 'Include CTM coding-session context (default true for session routes)' },
288
+ include_ctm_operational: { type: 'boolean', description: 'Include CTM operational context such as current phone URLs and Dev Tunnel status (default true for CTM operational routes)' },
283
289
  include_entities: { type: 'boolean', description: 'Include knowledge-graph entity matches (default true for people/work routes)' },
284
290
  entity_name: { type: 'string', description: 'Optional explicit entity/person/project/tool name to look up' },
285
291
  force_memory: { type: 'boolean', description: 'Search Wall-E memory even when routing says live/public/direct' },
@@ -501,6 +507,33 @@ const MCP_TOOLS = [
501
507
  properties: {},
502
508
  },
503
509
  },
510
+ {
511
+ name: 'walle_ctm_context',
512
+ description: 'Resolve CTM operational and session-memory context for CTM primary, mobile phone URLs, Dev Tunnel, /m/, and related CTM session-memory questions. Use this instead of generic memory for CTM remote-access answers.',
513
+ inputSchema: {
514
+ type: 'object',
515
+ properties: {
516
+ query: { type: 'string', description: 'The CTM/mobile/session-memory question to resolve' },
517
+ context: { type: 'string', description: 'Optional nearby conversation context' },
518
+ limit: { type: 'number', description: 'Max CTM session-memory snippets to include (default 5, max 10)' },
519
+ force: { type: 'boolean', description: 'Force CTM operational lookup even if the query classifier is unsure' },
520
+ timeout_ms: { type: 'number', description: 'Timeout for CTM API calls (default 6000)' },
521
+ cooldown_ms: { type: 'number', description: 'Cooldown for CTM API retry suppression (default 0 for this exact lookup)' },
522
+ },
523
+ required: ['query'],
524
+ },
525
+ },
526
+ {
527
+ name: 'walle_ctm_remote_access_status',
528
+ description: 'Read current CTM setup/network status and summarize active phone access URLs, including Microsoft Dev Tunnel and Tailscale. Read-only.',
529
+ inputSchema: {
530
+ type: 'object',
531
+ properties: {
532
+ timeout_ms: { type: 'number', description: 'Timeout for the CTM setup/network API call (default 6000)' },
533
+ cooldown_ms: { type: 'number', description: 'Cooldown for CTM API retry suppression (default 0)' },
534
+ },
535
+ },
536
+ },
504
537
  {
505
538
  name: 'walle_list_sources',
506
539
  description: 'List source adapters Wall-E can ingest, including Claude Code, Codex, Gemini, and Wall-E JSONL sessions.',
@@ -627,7 +660,10 @@ const MCP_TOOLS = [
627
660
  description: 'Run a dry integrity scan for brain memory, knowledge, entity, and index consistency.',
628
661
  inputSchema: {
629
662
  type: 'object',
630
- properties: {},
663
+ properties: {
664
+ limit: { type: 'number', description: 'Max issue rows to return in the sample (default 50, max 500)' },
665
+ include_all: { type: 'boolean', description: 'Return all issue rows instead of a bounded sample' },
666
+ },
631
667
  },
632
668
  },
633
669
  {
@@ -702,24 +738,47 @@ async function executeTool(name, args) {
702
738
  until: args.until,
703
739
  };
704
740
  const hasFilters = Object.values(filters).some(Boolean);
705
- let results = brain.searchMemories({ query: args.query, limit, ...filters });
706
- // Hybrid: merge with vector results if embeddings available
707
- if (!hasFilters && _embeddings && _embeddings.isAvailable()) {
708
- try {
709
- const queryEmb = await _embeddings.computeEmbedding(args.query);
710
- if (queryEmb) {
711
- const vectorResults = _embeddings.searchSimilarMemories(queryEmb, limit);
712
- if (vectorResults.length > 0) {
713
- results = _embeddings.reciprocalRankFusion(results, vectorResults, limit);
714
- }
741
+ // Person-aware recall: if the query references a person, expand the search to
742
+ // their aliases / email / @handle so messages that reference them indirectly
743
+ // still match (full-name-only search misses email/handle mentions).
744
+ let personTerms;
745
+ let resolvedPerson = '';
746
+ try {
747
+ const inferred = inferEntityName(args.query);
748
+ if (inferred) {
749
+ const ident = brain.resolvePersonIdentities(inferred);
750
+ if (ident && Array.isArray(ident.terms) && ident.terms.length > 1) {
751
+ personTerms = ident.terms;
752
+ resolvedPerson = ident.canonical;
715
753
  }
716
- } catch {}
717
- }
718
- return {
719
- results: results.map(formatMemoryResult),
754
+ }
755
+ } catch {}
756
+ const memorySearch = await searchWallEMemories({
757
+ query: args.query,
758
+ limit,
759
+ filters,
760
+ hybrid: !hasFilters,
761
+ terms: personTerms,
762
+ });
763
+ const out = {
764
+ results: memorySearch.results.map(formatMemoryResult),
720
765
  filters_applied: Object.fromEntries(Object.entries(filters).filter(([, value]) => Boolean(value))),
721
- vector_search_used: Boolean(!hasFilters && _embeddings && _embeddings.isAvailable()),
766
+ vector_search_used: memorySearch.vector_search_used,
767
+ source: memorySearch.source,
768
+ warnings: memorySearch.source.ok ? [] : [memorySearch.source],
722
769
  };
770
+ if (resolvedPerson) out.resolved_person = resolvedPerson;
771
+ // Empty stored memory is NOT a dead end — steer the caller to escalate to
772
+ // live sources / the full chat pipeline rather than declining.
773
+ if (memorySearch.source.ok && memorySearch.results.length === 0) {
774
+ out.hint = 'No stored memory matched. The brain may not have ingested this yet — this does NOT mean no history exists.';
775
+ out.next_steps = [
776
+ 'Call ask_walle with the original request — it can search LIVE Slack / Gmail / Calendar and compose the reply.',
777
+ ...(inferEntityName(args.query) ? ["Call list_people / entity_search to resolve the person's email or @handle, then search those."] : []),
778
+ 'If this is a write/compose request, draft it with [placeholders] for any unknowns instead of declining.',
779
+ ];
780
+ }
781
+ return out;
723
782
  }
724
783
  case 'remember': {
725
784
  const result = brain.insertKnowledge({
@@ -821,7 +880,7 @@ async function executeTool(name, args) {
821
880
  let entityCount = 0, embeddingCount = 0;
822
881
  try { entityCount = brain.listEntities({ limit: 1 }).length > 0 ? brain.getDb().prepare('SELECT COUNT(*) as c FROM entities').get().c : 0; } catch {}
823
882
  try { embeddingCount = brain.getDb().prepare("SELECT COUNT(*) as c FROM embedding_map").get().c; } catch {}
824
- return { ...stats, entity_count: entityCount, embedding_count: embeddingCount };
883
+ return { ...stats, entity_count: entityCount, embedding_count: embeddingCount, storage_risk: brain.getStorageRisk?.() || null };
825
884
  }
826
885
  case 'walle_memory_status': {
827
886
  ensureBuiltinSourceAdapters();
@@ -830,6 +889,7 @@ async function executeTool(name, args) {
830
889
  return {
831
890
  ok: true,
832
891
  stats,
892
+ storage_risk: brain.getStorageRisk?.() || null,
833
893
  ctm_db: await getCtmDbStatus(),
834
894
  resources: {
835
895
  static: MCP_RESOURCES.map((resource) => resource.uri),
@@ -844,6 +904,22 @@ async function executeTool(name, args) {
844
904
  case 'walle_live_capabilities': {
845
905
  return getLiveCapabilities();
846
906
  }
907
+ case 'walle_ctm_context': {
908
+ return ctmOperationalContext.lookupCtmOperationalContext(args);
909
+ }
910
+ case 'walle_ctm_remote_access_status': {
911
+ const status = await ctmContextClient.getRemoteAccessStatus({}, {
912
+ timeoutMs: args.timeout_ms || 6000,
913
+ cooldownMs: args.cooldown_ms || 0,
914
+ });
915
+ return {
916
+ ok: !status.reason,
917
+ source: status.source || 'ctm-api',
918
+ reason: status.reason || '',
919
+ api_transport: status.api_transport || null,
920
+ remote_access: status.reason ? null : ctmOperationalContext.summarizeRemoteAccess(status),
921
+ };
922
+ }
847
923
  case 'walle_list_sources': {
848
924
  ensureBuiltinSourceAdapters();
849
925
  return {
@@ -877,16 +953,21 @@ async function executeTool(name, args) {
877
953
  const ctmResults = args.prefer_db === false
878
954
  ? { ok: false, results: [], skipped: true, reason: 'prefer_db_false' }
879
955
  : await safeCtmSearchSessions({ query: args.query, limit });
880
- const memoryResults = args.include_memory === false
881
- ? []
882
- : brain.searchMemories({ query: args.query, limit: limit * 4 })
883
- .filter(isSessionMemory)
884
- .slice(0, limit * 2)
885
- .map((memory, index) => ({
886
- ...formatSessionMemory(memory),
887
- source_layer: 'wall-e-memory',
888
- rank: 10000 + index,
889
- }));
956
+ const memorySearch = args.include_memory === false
957
+ ? {
958
+ results: [],
959
+ source: { searched: false, ok: true, source: 'wall-e-memory', count: 0, reason: '' },
960
+ vector_search_used: false,
961
+ }
962
+ : await searchWallEMemories({ query: args.query, limit: limit * 4, hybrid: false });
963
+ const memoryResults = memorySearch.results
964
+ .filter(isSessionMemory)
965
+ .slice(0, limit * 2)
966
+ .map((memory, index) => ({
967
+ ...formatSessionMemory(memory),
968
+ source_layer: 'wall-e-memory',
969
+ rank: 10000 + index,
970
+ }));
890
971
  const ctmSourceLayer = ctmResults.source === 'ctm-api' ? 'ctm-api' : 'ctm-db';
891
972
  const dbResults = (ctmResults.results || []).map((result, index) => ({
892
973
  ...result,
@@ -915,6 +996,10 @@ async function executeTool(name, args) {
915
996
  },
916
997
  wall_e_memory: {
917
998
  searched: args.include_memory !== false,
999
+ ok: Boolean(memorySearch.source.ok),
1000
+ source: memorySearch.source.source,
1001
+ reason: memorySearch.source.reason || '',
1002
+ error: memorySearch.source.error || '',
918
1003
  count: memoryResults.length,
919
1004
  },
920
1005
  },
@@ -997,7 +1082,10 @@ async function executeTool(name, args) {
997
1082
  }
998
1083
  case 'walle_repair_status': {
999
1084
  const repair = require('./utils/repair');
1000
- return repair.scanIntegrity();
1085
+ return compactRepairScan(repair.scanIntegrity(), {
1086
+ limit: args.limit,
1087
+ include_all: args.include_all,
1088
+ });
1001
1089
  }
1002
1090
  case 'walle_rebuild_ctm_message_index': {
1003
1091
  requireWriteConfirmation('walle_rebuild_ctm_message_index', args);
@@ -1038,6 +1126,19 @@ function routeWallEQuery(query, opts = {}) {
1038
1126
  const selfProfile = add('self_profile', [/\b(my|me)\b.*\b(writing style|communication style|tone|personality|leadership style|work style)\b/, /\banaly[sz]e my\b/, /\bwhat.*\bpatterns\b.*\bme\b/, /\bam i too\b/]);
1039
1127
  const liveAction = add('live_action', [/\bsend\b/, /\bpost\b/, /\bcreate\b/, /\bschedule\b/, /\bopen\b/, /\bdelete\b/, /\bupdate\b/, /\bunread\b/, /\binbox\b/, /\btoday'?s calendar\b/, /\btomorrow'?s calendar\b/]);
1040
1128
  const publicCurrent = add('public_current', [/\bweb\b/, /\bpublic\b/, /\bnews\b/, /\blatest\b/, /\bcurrent\b/, /\bprice\b/, /\bstock\b/, /\bweather\b/, /\bdocs?\b/, /\bofficial\b/]);
1129
+ const ctmOperational = ctmOperationalContext.classifyCtmOperationalQuery(query, { context: opts.context });
1130
+ if (ctmOperational.required) {
1131
+ matched.push({ name: 'ctm_operational_context', hits: ctmOperational.matched });
1132
+ return {
1133
+ route: 'ctm_operational_context',
1134
+ should_use_walle: true,
1135
+ primary_tools: ['walle_ctm_context', 'walle_ctm_remote_access_status', 'walle_search_sessions'],
1136
+ secondary_tools: ['walle_lookup_context', 'search_memories'],
1137
+ avoid_until_memory_miss: ['web_search', 'web_fetch'],
1138
+ reason: ctmOperational.reason,
1139
+ matched,
1140
+ };
1141
+ }
1041
1142
 
1042
1143
  if (selfProfile) {
1043
1144
  return {
@@ -1118,7 +1219,9 @@ async function lookupWallEContext(args = {}) {
1118
1219
  const isProfileLookup = route.matched?.some(match => match.name === 'self_profile');
1119
1220
  const includeMemories = args.include_memories === true || (args.include_memories !== false && shouldUseWallE);
1120
1221
  const includeSessions = args.include_sessions === true
1121
- || (args.include_sessions !== false && (route.route === 'walle_session_context' || isProfileLookup));
1222
+ || (args.include_sessions !== false && (route.route === 'walle_session_context' || route.route === 'ctm_operational_context' || isProfileLookup));
1223
+ const includeCtmOperational = args.include_ctm_operational === true
1224
+ || (args.include_ctm_operational !== false && route.route === 'ctm_operational_context');
1122
1225
  const includeEntities = args.include_entities === true
1123
1226
  || (args.include_entities !== false && (route.route === 'walle_private_memory' || args.force_memory));
1124
1227
  const inferredEntityName = String(args.entity_name || inferEntityName(query) || '').trim();
@@ -1130,13 +1233,34 @@ async function lookupWallEContext(args = {}) {
1130
1233
  session_results: [],
1131
1234
  entity_results: [],
1132
1235
  context_pack: null,
1236
+ ctm_operational_context: null,
1133
1237
  sources: {
1134
1238
  memories: { searched: false, count: 0 },
1135
1239
  ctm_sessions: { searched: false, count: 0 },
1240
+ ctm_operational: { searched: false, count: 0 },
1136
1241
  entities: { searched: false, count: 0 },
1137
1242
  },
1138
1243
  };
1139
1244
 
1245
+ if (includeCtmOperational) {
1246
+ const operational = await ctmOperationalContext.lookupCtmOperationalContext({
1247
+ query,
1248
+ context: args.context,
1249
+ limit,
1250
+ force: true,
1251
+ });
1252
+ result.ctm_operational_context = operational;
1253
+ result.sources.ctm_operational = {
1254
+ searched: true,
1255
+ ok: Boolean(operational.ok),
1256
+ required: Boolean(operational.required),
1257
+ reason: operational.ok ? '' : 'ctm_operational_context_unavailable',
1258
+ remote_access: operational.sources?.remote_access || null,
1259
+ ctm_sessions: operational.sources?.ctm_sessions || null,
1260
+ count: (operational.session_results || []).length,
1261
+ };
1262
+ }
1263
+
1140
1264
  if (includeSessions) {
1141
1265
  const sessionQuery = isProfileLookup ? 'thorough review fix issues commit high-agency' : query;
1142
1266
  const sessionSearch = await safeCtmSearchSessions({
@@ -1169,21 +1293,37 @@ async function lookupWallEContext(args = {}) {
1169
1293
  since: args.since,
1170
1294
  until: args.until,
1171
1295
  };
1172
- result.memory_results = brain.searchMemories({ query: memoryQuery, limit, ...filters }).map(formatMemoryResult);
1296
+ const memorySearch = await searchWallEMemories({
1297
+ query: memoryQuery,
1298
+ limit,
1299
+ filters,
1300
+ hybrid: !Object.values(filters).some(Boolean),
1301
+ });
1302
+ result.memory_results = memorySearch.results.map(formatMemoryResult);
1173
1303
  result.sources.memories = {
1174
1304
  searched: true,
1175
1305
  query: memoryQuery,
1176
1306
  filters_applied: Object.fromEntries(Object.entries(filters).filter(([, value]) => Boolean(value))),
1307
+ ok: Boolean(memorySearch.source.ok),
1308
+ source: memorySearch.source.source,
1309
+ reason: memorySearch.source.reason || '',
1310
+ error: memorySearch.source.error || '',
1311
+ vector_search_used: memorySearch.vector_search_used,
1177
1312
  count: result.memory_results.length,
1178
1313
  };
1179
1314
  }
1180
1315
 
1181
1316
  if (includeEntities) {
1182
1317
  if (inferredEntityName) {
1183
- result.entity_results = searchEntitiesForContext(inferredEntityName, limit);
1318
+ const entitySearch = safeSearchEntitiesForContext(inferredEntityName, limit);
1319
+ result.entity_results = entitySearch.results;
1184
1320
  result.sources.entities = {
1185
1321
  searched: true,
1186
1322
  query: inferredEntityName,
1323
+ ok: Boolean(entitySearch.ok),
1324
+ source: entitySearch.source,
1325
+ reason: entitySearch.reason || '',
1326
+ error: entitySearch.error || '',
1187
1327
  count: result.entity_results.length,
1188
1328
  };
1189
1329
  } else {
@@ -1220,6 +1360,98 @@ function compactSnippet(text, max = 260) {
1220
1360
  return cleaned.length > max ? cleaned.slice(0, Math.max(0, max - 1)).trimEnd() + '...' : cleaned;
1221
1361
  }
1222
1362
 
1363
+ function classifySourceError(err, fallbackReason = 'source_read_failed') {
1364
+ const code = String(err?.code || '');
1365
+ const message = String(err?.message || err || '');
1366
+ const text = `${code} ${message}`.toLowerCase();
1367
+ let reason = fallbackReason;
1368
+ if (/sqlite_(corrupt|notadb)|database disk image is malformed|malformed database|database schema is corrupt/.test(text)) {
1369
+ reason = 'sqlite_structural_corruption';
1370
+ } else if (/sqlite_(busy|locked)|database is locked|database table is locked/.test(text)) {
1371
+ reason = 'sqlite_locked';
1372
+ } else if (/sqlite_cantopen|unable to open database file/.test(text)) {
1373
+ reason = 'sqlite_unavailable';
1374
+ } else if (/database not initialized/.test(text)) {
1375
+ reason = 'sqlite_not_initialized';
1376
+ }
1377
+ return {
1378
+ ok: false,
1379
+ reason,
1380
+ error: message,
1381
+ code: code || undefined,
1382
+ };
1383
+ }
1384
+
1385
+ function sourceStatus(source, patch = {}) {
1386
+ return {
1387
+ searched: true,
1388
+ ok: true,
1389
+ source,
1390
+ reason: '',
1391
+ error: '',
1392
+ count: 0,
1393
+ ...patch,
1394
+ };
1395
+ }
1396
+
1397
+ function safeBrainSearchMemories(args = {}) {
1398
+ try {
1399
+ const results = brain.searchMemories(args);
1400
+ return {
1401
+ results,
1402
+ source: sourceStatus('wall-e-memory', {
1403
+ ok: true,
1404
+ count: results.length,
1405
+ }),
1406
+ };
1407
+ } catch (err) {
1408
+ const failure = classifySourceError(err, 'wall_e_memory_search_failed');
1409
+ return {
1410
+ results: [],
1411
+ source: sourceStatus('wall-e-memory', {
1412
+ ...failure,
1413
+ count: 0,
1414
+ }),
1415
+ };
1416
+ }
1417
+ }
1418
+
1419
+ async function searchWallEMemories({ query, limit, filters = {}, hybrid = true, terms } = {}) {
1420
+ const base = safeBrainSearchMemories({ query, limit, terms, ...filters });
1421
+ let results = base.results;
1422
+ let vectorSearchUsed = false;
1423
+ const vectorStatus = { attempted: false, ok: true, reason: '', error: '' };
1424
+
1425
+ if (base.source.ok && hybrid && _embeddings && _embeddings.isAvailable()) {
1426
+ vectorStatus.attempted = true;
1427
+ try {
1428
+ const queryEmb = await _embeddings.computeEmbedding(query);
1429
+ if (queryEmb) {
1430
+ const vectorResults = _embeddings.searchSimilarMemories(queryEmb, limit);
1431
+ if (vectorResults.length > 0) {
1432
+ results = _embeddings.reciprocalRankFusion(results, vectorResults, limit);
1433
+ vectorSearchUsed = true;
1434
+ }
1435
+ }
1436
+ } catch (err) {
1437
+ const failure = classifySourceError(err, 'wall_e_vector_search_failed');
1438
+ vectorStatus.ok = false;
1439
+ vectorStatus.reason = failure.reason;
1440
+ vectorStatus.error = failure.error;
1441
+ }
1442
+ }
1443
+
1444
+ return {
1445
+ results,
1446
+ vector_search_used: vectorSearchUsed,
1447
+ source: sourceStatus('wall-e-memory', {
1448
+ ...base.source,
1449
+ count: results.length,
1450
+ vector: vectorStatus,
1451
+ }),
1452
+ };
1453
+ }
1454
+
1223
1455
  function evidenceFromMemory(memory, aspect) {
1224
1456
  return {
1225
1457
  kind: 'memory',
@@ -1265,17 +1497,20 @@ function profileAspectEvidence(aspect, limit) {
1265
1497
 
1266
1498
  for (const query of PROFILE_ASPECT_QUERIES[aspect] || []) {
1267
1499
  if (rows.length >= limit) break;
1268
- for (const memory of brain.searchMemories({ query, limit: Math.max(limit, 4) })) {
1500
+ const memorySearch = safeBrainSearchMemories({ query, limit: Math.max(limit, 4) });
1501
+ for (const memory of memorySearch.results) {
1269
1502
  addMemory(memory);
1270
1503
  if (rows.length >= limit) break;
1271
1504
  }
1272
1505
  }
1273
1506
 
1274
1507
  if (aspect === 'preferences') {
1275
- for (const row of brain.findKnowledge({ category: 'preference', status: 'active', limit, orderBy: 'confidence DESC' })) {
1276
- addKnowledge(row);
1277
- if (rows.length >= limit) break;
1278
- }
1508
+ try {
1509
+ for (const row of brain.findKnowledge({ category: 'preference', status: 'active', limit, orderBy: 'confidence DESC' })) {
1510
+ addKnowledge(row);
1511
+ if (rows.length >= limit) break;
1512
+ }
1513
+ } catch {}
1279
1514
  }
1280
1515
 
1281
1516
  return rows.slice(0, limit);
@@ -1476,6 +1711,7 @@ function buildPostflightCheck(args = {}) {
1476
1711
 
1477
1712
  function inferEntityName(query) {
1478
1713
  const text = String(query || '').trim();
1714
+ // End-anchored question patterns (case-insensitive): the whole tail is the name.
1479
1715
  for (const pattern of [
1480
1716
  /\bdo you know\s+(.+?)[?.!]?$/i,
1481
1717
  /\bwho is\s+(.+?)[?.!]?$/i,
@@ -1487,6 +1723,19 @@ function inferEntityName(query) {
1487
1723
  return match[1].replace(/^["']|["']$/g, '').trim();
1488
1724
  }
1489
1725
  }
1726
+ // Mid-sentence references to a proper-noun name (1-3 capitalized words), e.g.
1727
+ // "search history about Eric Gu", "write Eric Gu's anniversary note",
1728
+ // "a note for Eric Gu". Case-sensitive so it keys on the capitalized name.
1729
+ const NAME = "([A-Z][\\w.-]*(?:\\s+[A-Z][\\w.-]*){0,2})";
1730
+ for (const pattern of [
1731
+ new RegExp("\\b(?:note|message|email|card|memo)\\s+(?:to|for|about)\\s+" + NAME),
1732
+ new RegExp("\\babout\\s+" + NAME),
1733
+ new RegExp("\\bfor\\s+" + NAME + "(?:'s)?\\b"),
1734
+ new RegExp(NAME + "'s\\b"),
1735
+ ]) {
1736
+ const match = text.match(pattern);
1737
+ if (match?.[1]) return match[1].trim();
1738
+ }
1490
1739
  return '';
1491
1740
  }
1492
1741
 
@@ -1512,6 +1761,39 @@ function searchEntitiesForContext(name, limit) {
1512
1761
  }));
1513
1762
  }
1514
1763
 
1764
+ function safeSearchEntitiesForContext(name, limit) {
1765
+ try {
1766
+ const results = searchEntitiesForContext(name, limit);
1767
+ return {
1768
+ ok: true,
1769
+ source: 'wall-e-entities',
1770
+ results,
1771
+ count: results.length,
1772
+ };
1773
+ } catch (err) {
1774
+ const failure = classifySourceError(err, 'wall_e_entity_search_failed');
1775
+ return {
1776
+ ...failure,
1777
+ source: 'wall-e-entities',
1778
+ results: [],
1779
+ count: 0,
1780
+ };
1781
+ }
1782
+ }
1783
+
1784
+ function compactRepairScan(scan = {}, { limit = 50, include_all = false } = {}) {
1785
+ const issues = Array.isArray(scan.issues) ? scan.issues : [];
1786
+ const cap = include_all ? issues.length : clampLimit(limit, 50, 500);
1787
+ const sample = issues.slice(0, cap);
1788
+ return {
1789
+ ...scan,
1790
+ issues: sample,
1791
+ issues_sample: sample,
1792
+ issues_truncated: sample.length < issues.length,
1793
+ total_issues: issues.length,
1794
+ };
1795
+ }
1796
+
1515
1797
  function clampLimit(value, fallback, max) {
1516
1798
  const n = Number(value || fallback);
1517
1799
  if (!Number.isFinite(n)) return fallback;
@@ -2,7 +2,7 @@
2
2
 
3
3
  const ctmSessionContext = require('./ctm-session-context');
4
4
 
5
- const DEFAULT_TIMEOUT_MS = 700;
5
+ const DEFAULT_TIMEOUT_MS = 2500;
6
6
  const DEFAULT_COOLDOWN_MS = 15000;
7
7
 
8
8
  let apiFailureUntil = 0;
@@ -11,16 +11,18 @@ let lastApiFailure = null;
11
11
  function resolveApiBaseUrl(env = process.env) {
12
12
  const explicit = env.CTM_SESSION_MEMORY_API_BASE_URL || env.CTM_API_BASE_URL || env.CTM_BASE_URL;
13
13
  if (explicit) return explicit.replace(/\/+$/, '');
14
- if (env.WALLE_CTM_API === '1' && (env.CTM_PORT || env.DEV_CTM_PORT)) {
15
- return `http://127.0.0.1:${env.CTM_PORT || env.DEV_CTM_PORT}`;
16
- }
17
- return '';
14
+ if (env.WALLE_CTM_API === '0') return '';
15
+ return `http://127.0.0.1:${env.CTM_PORT || env.DEV_CTM_PORT || '3456'}`;
18
16
  }
19
17
 
20
18
  function apiDisabled(env = process.env) {
21
19
  return env.WALLE_CTM_API_DISABLED === '1' || env.CTM_SESSION_MEMORY_API === '0';
22
20
  }
23
21
 
22
+ function directFallbackAllowed(env = process.env, options = {}) {
23
+ return options.allowDirectFallback === true || env.WALLE_CTM_DIRECT_READ_FALLBACK === '1';
24
+ }
25
+
24
26
  async function getHealth(options = {}) {
25
27
  return apiFirst({
26
28
  path: '/api/ctm/session-memory/health',
@@ -61,6 +63,24 @@ async function getSessionContext(args = {}, options = {}) {
61
63
  });
62
64
  }
63
65
 
66
+ async function getRemoteAccessStatus(args = {}, options = {}) {
67
+ return apiFirst({
68
+ path: '/api/setup/network',
69
+ fallback: () => ({
70
+ ok: false,
71
+ source: 'ctm-api',
72
+ authority: 'ctm',
73
+ reason: 'ctm_api_required',
74
+ remote_access: null,
75
+ }),
76
+ options: {
77
+ ...options,
78
+ preferApi: args.prefer_api !== false && options.preferApi !== false,
79
+ timeoutMs: options.timeoutMs ?? 6000,
80
+ },
81
+ });
82
+ }
83
+
64
84
  async function buildContextPack(args = {}, options = {}) {
65
85
  return apiFirst({
66
86
  path: '/api/ctm/session-memory/context-pack',
@@ -112,21 +132,38 @@ async function backfillMessageIndex(args = {}, options = {}) {
112
132
  async function apiFirst({ path, method = 'GET', body, fallback, options = {} }) {
113
133
  const env = options.env || process.env;
114
134
  const preferApi = options.preferApi !== false;
115
- const fallbackResult = () => annotateFallback(fallback(), {
116
- attempted: false,
117
- skipped: true,
118
- reason: apiDisabled(env) ? 'api_disabled' : 'api_base_url_missing',
119
- });
135
+ const fallbackResult = (apiTransport) => {
136
+ if (directFallbackAllowed(env, options)) return annotateFallback(fallback(), apiTransport);
137
+ return {
138
+ ok: false,
139
+ source: 'ctm-api',
140
+ authority: 'ctm',
141
+ reason: 'ctm_api_required',
142
+ api_transport: apiTransport,
143
+ };
144
+ };
120
145
 
121
- if (!preferApi || apiDisabled(env)) return fallbackResult();
146
+ if (!preferApi || apiDisabled(env)) {
147
+ return fallbackResult({
148
+ attempted: false,
149
+ skipped: true,
150
+ reason: apiDisabled(env) ? 'api_disabled' : 'api_not_preferred',
151
+ });
152
+ }
122
153
 
123
154
  const baseUrl = resolveApiBaseUrl(env);
124
- if (!baseUrl) return fallbackResult();
155
+ if (!baseUrl) {
156
+ return fallbackResult({
157
+ attempted: false,
158
+ skipped: true,
159
+ reason: 'api_base_url_missing',
160
+ });
161
+ }
125
162
 
126
163
  const now = Date.now();
127
164
  const cooldownMs = options.cooldownMs ?? DEFAULT_COOLDOWN_MS;
128
165
  if (cooldownMs > 0 && apiFailureUntil > now) {
129
- return annotateFallback(fallback(), {
166
+ return fallbackResult({
130
167
  attempted: false,
131
168
  skipped: true,
132
169
  reason: 'api_cooldown',
@@ -154,7 +191,7 @@ async function apiFirst({ path, method = 'GET', body, fallback, options = {} })
154
191
  } catch (err) {
155
192
  lastApiFailure = err.message;
156
193
  apiFailureUntil = Date.now() + cooldownMs;
157
- return annotateFallback(fallback(), {
194
+ return fallbackResult({
158
195
  attempted: true,
159
196
  ok: false,
160
197
  base_url: baseUrl,
@@ -224,6 +261,7 @@ module.exports = {
224
261
  getHealth,
225
262
  searchSessions,
226
263
  getSessionContext,
264
+ getRemoteAccessStatus,
227
265
  buildContextPack,
228
266
  backfillMessageIndex,
229
267
  resetApiState,