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
@@ -8,6 +8,29 @@ try { embeddings = require('../embeddings'); } catch { embeddings = null; }
8
8
 
9
9
  const BATCH_SIZE = 20;
10
10
 
11
+ // Contradiction → question policy. Historically EVERY detected contradiction created a
12
+ // pending_question AND superseded the old knowledge — yielding ~2,000 questions/day that
13
+ // piled up (125k unanswered) because contradictions are mostly routine knowledge churn
14
+ // (working dir / current task / tool changed). We now ALWAYS supersede (newer wins) and
15
+ // only ask the owner when the contradiction is genuinely ambiguous. The offline detector
16
+ // flags mechanical churn (value_conflict / relationship_mismatch / stale_fact = "X was A,
17
+ // now B"); the LLM path is only invoked for the ambiguous remainder. So: ask only on
18
+ // LLM-detected contradictions (no offline `type`) or when the new fact's confidence is low.
19
+ const _OFFLINE_CONTRADICTION_TYPES = new Set(['value_conflict', 'relationship_mismatch', 'stale_fact']);
20
+ const _ASK_CONTRADICTION_CONFIDENCE = Number(process.env.WALL_E_ASK_CONTRADICTION_CONFIDENCE || 0.4);
21
+ function _contradictionQuestionsEnabled() {
22
+ return String(process.env.WALL_E_CONTRADICTION_QUESTIONS || 'on').toLowerCase() !== 'off';
23
+ }
24
+ function _shouldAskAboutContradiction(c) {
25
+ if (!c) return false;
26
+ if (c.type && _OFFLINE_CONTRADICTION_TYPES.has(c.type)) {
27
+ // Mechanical churn → supersede silently, unless the NEW fact itself is low-confidence.
28
+ const conf = Number(c.new_entry && c.new_entry.confidence);
29
+ return Number.isFinite(conf) && conf < _ASK_CONTRADICTION_CONFIDENCE;
30
+ }
31
+ return true; // LLM-detected (ambiguous) → ask
32
+ }
33
+
11
34
  async function runOnce(opts = {}) {
12
35
  // Centralized precheck: provider availability. (We don't pass
13
36
  // hasFreshSignal here because think.js still does work — self-resolve
@@ -74,20 +97,24 @@ async function runOnce(opts = {}) {
74
97
  e.object === contradiction.new_entry.object
75
98
  );
76
99
 
77
- // Insert pending question
78
- brain.insertQuestion({
79
- question_type: 'contradiction',
80
- question: contradiction.explanation,
81
- context: JSON.stringify({
82
- old_id: contradiction.old_id,
83
- new_entry: contradiction.new_entry,
84
- }),
85
- });
86
-
87
- // Supersede old knowledge
100
+ // Always supersede old knowledge (newer wins) — keeps the graph current.
88
101
  if (newInserted) {
89
102
  brain.supersedeKnowledge(contradiction.old_id, newInserted._id);
90
103
  }
104
+
105
+ // Only surface a question when genuinely worth the owner's input. Routine churn
106
+ // is superseded silently above (see _shouldAskAboutContradiction) — this stops the
107
+ // ~2,000/day pile-up while still escalating ambiguous/low-confidence conflicts.
108
+ if (_contradictionQuestionsEnabled() && _shouldAskAboutContradiction(contradiction)) {
109
+ brain.insertQuestion({
110
+ question_type: 'contradiction',
111
+ question: contradiction.explanation,
112
+ context: JSON.stringify({
113
+ old_id: contradiction.old_id,
114
+ new_entry: contradiction.new_entry,
115
+ }),
116
+ });
117
+ }
91
118
  }
92
119
 
93
120
  // Apply domain/topic classifications to memories
@@ -189,4 +216,4 @@ async function selfResolveQuestions(ownerName, opts = {}) {
189
216
  }
190
217
  }
191
218
 
192
- module.exports = { runOnce };
219
+ module.exports = { runOnce, _shouldAskAboutContradiction };
@@ -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;