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
@@ -4,7 +4,6 @@ const fs = require('node:fs');
4
4
  const os = require('node:os');
5
5
  const path = require('node:path');
6
6
  const crypto = require('node:crypto');
7
- const Database = requireBetterSqlite3();
8
7
 
9
8
  const DEFAULT_SEARCH_LIMIT = 10;
10
9
  const MAX_SEARCH_LIMIT = 50;
@@ -18,6 +17,7 @@ const CTM_SESSION_TABLES = [
18
17
  'ctm_sessions',
19
18
  'agent_sessions',
20
19
  ];
20
+ let Database = null;
21
21
 
22
22
  function requireBetterSqlite3() {
23
23
  try {
@@ -32,6 +32,21 @@ function requireBetterSqlite3() {
32
32
  }
33
33
  }
34
34
 
35
+ function loadBetterSqlite3() {
36
+ if (!Database) Database = requireBetterSqlite3();
37
+ return Database;
38
+ }
39
+
40
+ function assertDirectReadAllowed(options = {}) {
41
+ const env = options.env || process.env;
42
+ if (!env.CTM_PROCESS_ROLE || env.CTM_ALLOW_DIRECT_SESSION_CONTEXT_DB === '1') return;
43
+ const err = new Error(
44
+ 'CTM session context direct SQLite read is disabled inside CTM_PROCESS_ROLE; pass the CTM-owned db handle instead.'
45
+ );
46
+ err.code = 'CTM_DIRECT_DB_READ_BLOCKED';
47
+ throw err;
48
+ }
49
+
35
50
  function resolveCtmDbPath(env = process.env) {
36
51
  if (env.CTM_DB_PATH) return env.CTM_DB_PATH;
37
52
  if (env.CTM_DATA_DIR) return path.join(env.CTM_DATA_DIR, 'task-manager.db');
@@ -56,12 +71,14 @@ function resolveCtmDbCandidatePaths(env = process.env) {
56
71
  return candidates;
57
72
  }
58
73
 
59
- function openCtmDb({ dbPath, readonly = true, busyTimeoutMs = 2500 } = {}) {
60
- const resolved = path.resolve(dbPath || resolveCtmDbPath());
74
+ function openCtmDb({ dbPath, readonly = true, busyTimeoutMs = 2500, env = process.env } = {}) {
75
+ assertDirectReadAllowed({ env });
76
+ const resolved = path.resolve(dbPath || resolveCtmDbPath(env));
61
77
  if (!fs.existsSync(resolved)) {
62
78
  return { db: null, dbPath: resolved, close: () => {}, unavailable: true };
63
79
  }
64
- const db = new Database(resolved, { readonly, fileMustExist: true });
80
+ const SqliteDatabase = loadBetterSqlite3();
81
+ const db = new SqliteDatabase(resolved, { readonly, fileMustExist: true });
65
82
  const timeout = Number.isFinite(Number(busyTimeoutMs)) ? Math.max(0, Math.trunc(Number(busyTimeoutMs))) : 2500;
66
83
  db.pragma(`busy_timeout = ${timeout}`);
67
84
  if (readonly) {
@@ -186,6 +203,9 @@ function isDbSourceFailure(result) {
186
203
  function classifySqliteFailure(err, fallbackReason) {
187
204
  const code = String(err?.code || '');
188
205
  const message = String(err?.message || err || '');
206
+ if (code === 'CTM_DIRECT_DB_READ_BLOCKED') {
207
+ return { reason: 'ctm_db_direct_read_blocked' };
208
+ }
189
209
  if (/SQLITE_(BUSY|LOCKED)/.test(code) || /database is locked|database table is locked|busy/i.test(message)) {
190
210
  return { reason: 'ctm_db_locked' };
191
211
  }
@@ -289,11 +309,15 @@ function getCtmSessionContext({
289
309
 
290
310
  const sessions = [];
291
311
  const allMessages = [];
312
+ let servedFromRows = false;
292
313
  for (const bundle of uniqueBundles) {
293
314
  const conversations = getConversationRows(conn, bundle);
294
315
  const sessionMessages = [];
295
316
  for (const row of conversations) {
296
- const messages = parseConversationMessages(row);
317
+ // Phase 5: prefer the faithful per-message rows; fall back to the blob when absent.
318
+ const rowMessages = readSessionMessageRows(conn, row._conversation_id);
319
+ const messages = rowMessages || parseConversationMessages(row);
320
+ if (rowMessages) servedFromRows = true;
297
321
  for (let i = 0; i < messages.length; i += 1) {
298
322
  const normalized = normalizeMessage(messages[i], {
299
323
  row,
@@ -329,7 +353,7 @@ function getCtmSessionContext({
329
353
  messages: pagedMessages,
330
354
  transfer: {
331
355
  full_context_supported: true,
332
- served_from: 'session_conversations/session_messages',
356
+ served_from: servedFromRows ? 'session_message_rows' : 'session_conversations/session_messages',
333
357
  jsonl_fallback_used: false,
334
358
  deduped: Boolean(dedupe),
335
359
  },
@@ -488,67 +512,58 @@ function quoteIdent(value) {
488
512
  }
489
513
 
490
514
  function searchSessionMessagesFts(db, query, limit) {
491
- if (!hasTable(db, 'session_messages') || !hasTable(db, 'session_messages_fts')) return [];
492
- const msgSessionCol = idColumnFor(db, 'session_messages');
493
- if (!msgSessionCol) return [];
494
515
  const ftsQueries = buildFtsQueries(query);
495
516
  if (!ftsQueries.length) return [];
496
-
497
- try {
498
- const stmt = db.prepare(`
499
- SELECT sm.${quoteIdent(msgSessionCol)} AS conversation_id,
500
- sm.id AS message_rowid,
501
- sm.role,
502
- sm.message_index,
503
- sm.content,
504
- sm.created_at,
505
- fts.rank AS rank
506
- FROM session_messages_fts fts
507
- JOIN session_messages sm ON sm.id = fts.rowid
508
- WHERE session_messages_fts MATCH ?
509
- ORDER BY fts.rank
510
- LIMIT ?
511
- `);
512
- let rows = [];
513
- for (const ftsQuery of ftsQueries) {
514
- rows = stmt.all(ftsQuery, limit);
515
- if (rows.length) break;
516
- }
517
- return rows.map((row, index) => enrichSearchRow(db, row, {
518
- source_table: 'session_messages_fts',
519
- rank: index,
520
- score: row.rank,
521
- }));
522
- } catch {
523
- return [];
524
- }
517
+ // Phase: prefer the faithful per-message FTS (session_message_rows_fts); fall back to the legacy
518
+ // session_messages_fts only while it still exists (sessions not yet backfilled into rows). Each
519
+ // index is tried independently so a mid-retirement drop of the legacy table can't blank results.
520
+ const tryIndex = (cfg) => {
521
+ if (!hasTable(db, cfg.table) || !hasTable(db, cfg.fts)) return null;
522
+ const idCol = cfg.idCol || idColumnFor(db, cfg.table);
523
+ if (!idCol) return null;
524
+ try {
525
+ const stmt = db.prepare(`
526
+ SELECT sm.${quoteIdent(idCol)} AS conversation_id, sm.id AS message_rowid, sm.role,
527
+ sm.message_index, sm.${cfg.textCol} AS content, sm.${cfg.tsCol} AS created_at, fts.rank AS rank
528
+ FROM ${cfg.fts} fts JOIN ${cfg.table} sm ON sm.id = fts.rowid
529
+ WHERE ${cfg.fts} MATCH ? ORDER BY fts.rank LIMIT ?
530
+ `);
531
+ for (const ftsQuery of ftsQueries) {
532
+ const rows = stmt.all(ftsQuery, limit);
533
+ if (rows.length) return rows.map((row, index) => enrichSearchRow(db, row, { source_table: cfg.fts, rank: index, score: row.rank }));
534
+ }
535
+ return [];
536
+ } catch { return null; }
537
+ };
538
+ const rowsRes = tryIndex({ table: 'session_message_rows', fts: 'session_message_rows_fts', idCol: 'ctm_session_id', textCol: 'text', tsCol: 'timestamp' });
539
+ if (rowsRes && rowsRes.length) return rowsRes;
540
+ const legacyRes = tryIndex({ table: 'session_messages', fts: 'session_messages_fts', textCol: 'content', tsCol: 'created_at' });
541
+ return legacyRes || rowsRes || [];
525
542
  }
526
543
 
527
544
  function searchSessionMessagesLike(db, query, limit) {
528
- if (!hasTable(db, 'session_messages')) return [];
529
- const msgSessionCol = idColumnFor(db, 'session_messages');
530
- if (!msgSessionCol) return [];
531
545
  const like = `%${escapeLike(query)}%`;
532
- try {
533
- const rows = db.prepare(`
534
- SELECT ${quoteIdent(msgSessionCol)} AS conversation_id,
535
- id AS message_rowid,
536
- role,
537
- message_index,
538
- content,
539
- created_at
540
- FROM session_messages
541
- WHERE content LIKE ? ESCAPE '\\'
542
- ORDER BY created_at DESC, id DESC
543
- LIMIT ?
544
- `).all(like, limit);
545
- return rows.map((row, index) => enrichSearchRow(db, row, {
546
- source_table: 'session_messages',
547
- rank: index + 1000,
548
- }));
549
- } catch {
550
- return [];
551
- }
546
+ // Prefer the faithful rows (text column); fall back to the legacy session_messages (content)
547
+ // only while it exists. Each is tried independently.
548
+ const tryLike = (cfg) => {
549
+ if (!hasTable(db, cfg.table)) return null;
550
+ const idCol = cfg.idCol || idColumnFor(db, cfg.table);
551
+ if (!idCol) return null;
552
+ try {
553
+ const rows = db.prepare(`
554
+ SELECT ${quoteIdent(idCol)} AS conversation_id, id AS message_rowid, role, message_index,
555
+ ${cfg.textCol} AS content, ${cfg.tsCol} AS created_at
556
+ FROM ${cfg.table}
557
+ WHERE ${cfg.textCol} LIKE ? ESCAPE '\\'
558
+ ORDER BY ${cfg.tsCol} DESC, id DESC LIMIT ?
559
+ `).all(like, limit);
560
+ return rows.map((row, index) => enrichSearchRow(db, row, { source_table: cfg.table, rank: index + 1000 }));
561
+ } catch { return null; }
562
+ };
563
+ const rowsRes = tryLike({ table: 'session_message_rows', idCol: 'ctm_session_id', textCol: 'text', tsCol: 'timestamp' });
564
+ if (rowsRes && rowsRes.length) return rowsRes;
565
+ const legacyRes = tryLike({ table: 'session_messages', textCol: 'content', tsCol: 'created_at' });
566
+ return legacyRes || rowsRes || [];
552
567
  }
553
568
 
554
569
  function searchSessionConversationMessages(db, query, limit) {
@@ -595,7 +610,9 @@ function searchSessionConversationMessages(db, query, limit) {
595
610
  project_path: row.project_path || '',
596
611
  title: row.title || row.first_message || '',
597
612
  };
598
- const messages = parseConversationMessages(row);
613
+ // Candidates are found via the blob LIKE (still dual-written); reconstruct the messages
614
+ // from the faithful rows when present so search reads the same source as getCtmSessionContext.
615
+ const messages = readSessionMessageRows(db, conversationId) || parseConversationMessages(row);
599
616
  for (let i = 0; i < messages.length; i += 1) {
600
617
  const normalized = normalizeMessage(messages[i], {
601
618
  row,
@@ -905,6 +922,36 @@ function parseConversationMessages(row) {
905
922
  }
906
923
  }
907
924
 
925
+ // Phase 5: read the faithful per-message rows (session_message_rows) instead of the blob.
926
+ // The rows ARE the same parsed message objects the blob held (CTM writes them in lockstep),
927
+ // so this returns a byte-identical array — no re-embedding, no parser. Returns null when the
928
+ // table/rows are absent (pre-migration or a half-migrated session) so the caller falls back
929
+ // to parseConversationMessages(row) (the blob). Keyed by the SAME id the blob row uses.
930
+ function readSessionMessageRows(db, conversationId) {
931
+ if (!conversationId || !hasTable(db, 'session_message_rows')) return null;
932
+ try {
933
+ const rows = db.prepare(
934
+ 'SELECT role, text, timestamp, meta FROM session_message_rows WHERE ctm_session_id = ? ORDER BY message_index ASC'
935
+ ).all(conversationId);
936
+ if (!rows.length) return null;
937
+ return rows.map(messageRowFromColumns);
938
+ } catch {
939
+ return null;
940
+ }
941
+ }
942
+
943
+ // Rebuild the original importer message object: non-standard messages are stored VERBATIM in
944
+ // `meta`; simple ones are pure columns ({role,text,timestamp}). Mirrors db.js _messageRowToObject.
945
+ function messageRowFromColumns(r) {
946
+ if (r && r.meta) {
947
+ try {
948
+ const obj = JSON.parse(r.meta);
949
+ if (obj && typeof obj === 'object') return obj;
950
+ } catch { /* fall through to columns */ }
951
+ }
952
+ return { role: r.role, text: r.text, timestamp: r.timestamp || '' };
953
+ }
954
+
908
955
  function normalizeMessage(raw, { row, bundle, index, includeRaw }) {
909
956
  const role = normalizeRole(raw);
910
957
  const content = messageText(raw);
@@ -1280,7 +1327,8 @@ function backfillCtmSessionMessages({ db, dbPath, limit = 100, dry_run = false,
1280
1327
  let inserted_fts = 0;
1281
1328
  const txn = conn.transaction((rows) => {
1282
1329
  for (const row of rows) {
1283
- const messages = parseConversationMessages(row);
1330
+ // Phase 5: build the index from the faithful rows when present (survives blob retirement).
1331
+ const messages = readSessionMessageRows(conn, row._conversation_id) || parseConversationMessages(row);
1284
1332
  let sessionInserted = 0;
1285
1333
  for (let i = 0; i < messages.length; i += 1) {
1286
1334
  const raw = messages[i];
@@ -1 +1,4 @@
1
1
  DeepSeek mode reminder: keep tool-loop turns concise and avoid carrying reasoning blocks back into later tool-result requests.
2
+ - Emit tool calls ONLY through the tool-call API — never as DSML/text markup in your reply.
3
+ - Never truncate code with "..." placeholders; provide complete file or hunk content in every write.
4
+ - For multi-hunk or multi-file changes, prefer apply_patch over repeated edit_file calls.
@@ -0,0 +1,6 @@
1
+ Gemini-family adaptation:
2
+ - Emit tool calls ONLY through the function-calling API. Never print a function call, JSON blob, or code fence describing a call instead of making it.
3
+ - Do not wrap tool arguments in markdown fences; pass raw values.
4
+ - Re-read a file with read_file before editing if its content may have changed; copy old_string EXACTLY (whitespace included) from the latest read.
5
+ - Make one surgical edit per edit_file call; for sweeping changes use apply_patch.
6
+ - Verify with run_shell before claiming completion; report the actual command output.
@@ -0,0 +1,6 @@
1
+ GPT-family adaptation:
2
+ - Emit tool calls ONLY through the tool-call API. Never write a tool call as text, JSON, or XML inside your reply.
3
+ - Never truncate code with placeholders like "// ... rest of file unchanged" or "# existing code here". Every write_file must contain the COMPLETE file; every edit must contain the complete replacement text.
4
+ - For multi-hunk or multi-file changes, prefer apply_patch over repeated edit_file calls.
5
+ - Keep going until the task is fully done: implement, verify, and only then summarize. Do not end your turn with a plan or a promise of future work.
6
+ - Re-read a file with read_file before editing it if you have not seen its current content this session.
@@ -0,0 +1,7 @@
1
+ Local-model adaptation:
2
+ - Make ONE tool call at a time and wait for its result before deciding the next step.
3
+ - Keep responses short; spend tokens on tool calls, not narration.
4
+ - For edit_file, choose an old_string that is unique in the file and includes 2-3 surrounding lines of context; copy it EXACTLY from the latest read_file output.
5
+ - If a command fails or times out, read the error output and inspect the code BEFORE running the same command again.
6
+ - Prefer small files and small diffs; for changes spanning many locations, use apply_patch with complete hunks.
7
+ - Do not restate the task or the system prompt in your replies.
@@ -0,0 +1,115 @@
1
+ 'use strict';
2
+
3
+ class RuntimeDecisionHookBus {
4
+ constructor({ handlers = {}, telemetry = null } = {}) {
5
+ this.handlers = new Map();
6
+ this.telemetry = telemetry || null;
7
+ for (const [event, list] of Object.entries(handlers || {})) {
8
+ for (const handler of Array.isArray(list) ? list : [list]) {
9
+ this.use(event, handler);
10
+ }
11
+ }
12
+ }
13
+
14
+ use(event, handler) {
15
+ if (!event || typeof handler !== 'function') return this;
16
+ const name = String(event);
17
+ if (!this.handlers.has(name)) this.handlers.set(name, []);
18
+ this.handlers.get(name).push(handler);
19
+ return this;
20
+ }
21
+
22
+ async run(event, payload = {}, ctx = {}) {
23
+ const name = String(event || '');
24
+ const handlers = this.handlers.get(name) || [];
25
+ let decision = emptyDecision();
26
+ for (const handler of handlers) {
27
+ try {
28
+ const result = normalizeDecision(await handler({
29
+ ...payload,
30
+ decision,
31
+ event: name,
32
+ ctx,
33
+ }));
34
+ decision = mergeDecision(decision, result);
35
+ if (decision.stop || decision.denied) break;
36
+ } catch (error) {
37
+ const hookError = {
38
+ event: name,
39
+ error: error?.message || String(error),
40
+ };
41
+ decision.hookErrors.push(hookError);
42
+ try {
43
+ this.telemetry?.track?.('runtime_hook_error', {
44
+ event: name,
45
+ error_type: error?.name || 'Error',
46
+ });
47
+ } catch {}
48
+ }
49
+ }
50
+ return decision;
51
+ }
52
+ }
53
+
54
+ function emptyDecision() {
55
+ return {
56
+ denied: false,
57
+ stop: false,
58
+ reason: '',
59
+ input: undefined,
60
+ result: undefined,
61
+ output: undefined,
62
+ additionalContext: [],
63
+ metadata: {},
64
+ hookErrors: [],
65
+ };
66
+ }
67
+
68
+ function normalizeDecision(value) {
69
+ if (!value) return emptyDecision();
70
+ if (Array.isArray(value)) {
71
+ return value.reduce((acc, item) => mergeDecision(acc, normalizeDecision(item)), emptyDecision());
72
+ }
73
+ if (typeof value !== 'object') return emptyDecision();
74
+ const denied = value.denied === true || value.deny === true || value.behavior === 'deny';
75
+ const stop = value.stop === true || value.preventContinuation === true;
76
+ const reason = String(value.reason || value.message || value.stopReason || '');
77
+ return {
78
+ denied,
79
+ stop,
80
+ reason,
81
+ input: Object.prototype.hasOwnProperty.call(value, 'input') ? value.input
82
+ : Object.prototype.hasOwnProperty.call(value, 'updatedInput') ? value.updatedInput
83
+ : undefined,
84
+ result: Object.prototype.hasOwnProperty.call(value, 'result') ? value.result
85
+ : Object.prototype.hasOwnProperty.call(value, 'output') ? value.output
86
+ : undefined,
87
+ output: Object.prototype.hasOwnProperty.call(value, 'output') ? value.output : undefined,
88
+ additionalContext: Array.isArray(value.additionalContext) ? value.additionalContext
89
+ : value.additionalContext ? [value.additionalContext]
90
+ : [],
91
+ metadata: value.metadata && typeof value.metadata === 'object' ? { ...value.metadata } : {},
92
+ hookErrors: Array.isArray(value.hookErrors) ? value.hookErrors : [],
93
+ };
94
+ }
95
+
96
+ function mergeDecision(a = emptyDecision(), b = emptyDecision()) {
97
+ return {
98
+ denied: a.denied || b.denied,
99
+ stop: a.stop || b.stop,
100
+ reason: b.reason || a.reason || '',
101
+ input: b.input !== undefined ? b.input : a.input,
102
+ result: b.result !== undefined ? b.result : a.result,
103
+ output: b.output !== undefined ? b.output : a.output,
104
+ additionalContext: [...(a.additionalContext || []), ...(b.additionalContext || [])],
105
+ metadata: { ...(a.metadata || {}), ...(b.metadata || {}) },
106
+ hookErrors: [...(a.hookErrors || []), ...(b.hookErrors || [])],
107
+ };
108
+ }
109
+
110
+ module.exports = {
111
+ RuntimeDecisionHookBus,
112
+ emptyDecision,
113
+ mergeDecision,
114
+ normalizeDecision,
115
+ };
@@ -2,6 +2,78 @@
2
2
 
3
3
  const fs = require('fs');
4
4
  const path = require('path');
5
+ const { parseCustomHeaders } = require('../llm/portkey');
6
+
7
+ function readDevboxClaudeAuthHeaders({ home = process.env.HOME, fsImpl = fs } = {}) {
8
+ if (!home) return null;
9
+ const authFile = path.join(home, '.devbox', 'secrets', 'claude', 'auth_headers');
10
+ const raw = fsImpl.readFileSync(authFile, 'utf8').trim();
11
+ if (!raw) return null;
12
+ const headers = parseCustomHeaders(raw);
13
+ if (!Object.keys(headers).length) return null;
14
+ return { authFile, raw, headers };
15
+ }
16
+
17
+ function maskSecret(value) {
18
+ const text = String(value || '');
19
+ if (!text) return '';
20
+ if (text.length <= 12) return text.slice(0, 3) + '...';
21
+ return text.slice(0, 8) + '...' + text.slice(-4);
22
+ }
23
+
24
+ function normalizeDevboxBaseUrl(value) {
25
+ const url = String(value || '').trim().replace(/\/+$/, '');
26
+ if (!/^https?:\/\//i.test(url)) return '';
27
+ return /\/v\d+$/i.test(url) ? url : `${url}/v1`;
28
+ }
29
+
30
+ function detectDevboxClaudeBaseUrl({ env = process.env, home = env.HOME, fsImpl = fs } = {}) {
31
+ const envUrl = normalizeDevboxBaseUrl(env.ANTHROPIC_BASE_URL);
32
+ if (envUrl) return envUrl;
33
+
34
+ if (home) {
35
+ try {
36
+ const claudeScript = fsImpl.readFileSync(path.join(home, '.devbox', 'ai', 'claude', 'claude'), 'utf8');
37
+ const vpnMatch = claudeScript.match(/VPN_CHECK_URL="(https?:\/\/[^"]+)"/);
38
+ const scriptUrl = normalizeDevboxBaseUrl(vpnMatch && vpnMatch[1]);
39
+ if (scriptUrl) return scriptUrl;
40
+ } catch {}
41
+
42
+ try {
43
+ const logFile = path.join(home, '.devbox', 'logs', 'devbox-logs.log');
44
+ const log = fsImpl.readFileSync(logFile, 'utf8');
45
+ const matches = Array.from(log.matchAll(/ANTHROPIC_BASE_URL:\s*(https?:\/\/[^\s"}]+)/g));
46
+ const last = matches.length ? normalizeDevboxBaseUrl(matches[matches.length - 1][1]) : '';
47
+ if (last) return last;
48
+ } catch {}
49
+ }
50
+
51
+ return '';
52
+ }
53
+
54
+ function getDevboxClaudePortkeyGateway({ home = process.env.HOME, fsImpl = fs, env = process.env } = {}) {
55
+ try {
56
+ const auth = readDevboxClaudeAuthHeaders({ home, fsImpl });
57
+ const headers = auth && auth.headers;
58
+ const apiKey = headers && headers['x-portkey-api-key'];
59
+ if (!apiKey) return null;
60
+ return {
61
+ source: 'devbox-claude-auth-headers',
62
+ name: 'Portkey gateway',
63
+ label: 'devbox',
64
+ apiKey,
65
+ apiKeyMasked: maskSecret(apiKey),
66
+ customHeaders: headers,
67
+ hasProvider: Boolean(headers['x-portkey-provider']),
68
+ hasVirtualKey: Boolean(headers['x-portkey-virtual-key']),
69
+ hasConfig: Boolean(headers['x-portkey-config']),
70
+ hasMetadata: Boolean(headers['x-portkey-metadata']),
71
+ baseUrl: detectDevboxClaudeBaseUrl({ env, home, fsImpl }),
72
+ };
73
+ } catch {
74
+ return null;
75
+ }
76
+ }
5
77
 
6
78
  function configureDevboxGateway({ env = process.env, home = env.HOME, logger = console } = {}) {
7
79
  // Auto-detect corporate Claude Code gateway if not already configured. The
@@ -11,8 +83,8 @@ function configureDevboxGateway({ env = process.env, home = env.HOME, logger = c
11
83
  if (env.ANTHROPIC_CUSTOM_HEADERS_B64 || hasRealKey || !home) return false;
12
84
 
13
85
  try {
14
- const authFile = path.join(home, '.devbox', 'secrets', 'claude', 'auth_headers');
15
- const headers = fs.readFileSync(authFile, 'utf8').trim();
86
+ const auth = readDevboxClaudeAuthHeaders({ home });
87
+ const headers = auth && auth.raw;
16
88
  if (!headers) return false;
17
89
 
18
90
  env.ANTHROPIC_CUSTOM_HEADERS_B64 = Buffer.from(headers).toString('base64');
@@ -20,11 +92,8 @@ function configureDevboxGateway({ env = process.env, home = env.HOME, logger = c
20
92
  if (!env.ANTHROPIC_AUTH_TOKEN) env.ANTHROPIC_AUTH_TOKEN = 'sk-ant-api03-unused';
21
93
 
22
94
  if (!env.ANTHROPIC_BASE_URL) {
23
- try {
24
- const claudeScript = fs.readFileSync(path.join(home, '.devbox', 'ai', 'claude', 'claude'), 'utf8');
25
- const vpnMatch = claudeScript.match(/VPN_CHECK_URL="(https?:\/\/[^"]+)"/);
26
- if (vpnMatch) env.ANTHROPIC_BASE_URL = vpnMatch[1] + '/v1';
27
- } catch {}
95
+ const baseUrl = detectDevboxClaudeBaseUrl({ env, home });
96
+ if (baseUrl) env.ANTHROPIC_BASE_URL = baseUrl;
28
97
  }
29
98
 
30
99
  try { require('../compat').recordCompatUsage('devbox_gateway'); } catch {}
@@ -35,4 +104,9 @@ function configureDevboxGateway({ env = process.env, home = env.HOME, logger = c
35
104
  }
36
105
  }
37
106
 
38
- module.exports = { configureDevboxGateway };
107
+ module.exports = {
108
+ configureDevboxGateway,
109
+ detectDevboxClaudeBaseUrl,
110
+ getDevboxClaudePortkeyGateway,
111
+ readDevboxClaudeAuthHeaders,
112
+ };
@@ -0,0 +1,86 @@
1
+ 'use strict';
2
+
3
+ const {
4
+ PromptSectionRegistry,
5
+ appendPromptManifest,
6
+ buildPromptManifest,
7
+ normalizePromptManifestSection,
8
+ toolCatalogSignature,
9
+ } = require('../coding/prompt-section-registry');
10
+
11
+ function buildRuntimePromptManifest({
12
+ runtimeProfile = {},
13
+ systemPrompt = '',
14
+ userTask = '',
15
+ messages = [],
16
+ tools = [],
17
+ provider = '',
18
+ model = '',
19
+ metadata = {},
20
+ now = () => new Date().toISOString(),
21
+ } = {}) {
22
+ const registry = new PromptSectionRegistry({
23
+ provider: provider || runtimeProfile.provider || '',
24
+ model: model || runtimeProfile.model || '',
25
+ now,
26
+ });
27
+ registry.add({
28
+ id: 'stable.system-prompt',
29
+ kind: 'stable',
30
+ source: 'runtime.system',
31
+ content: systemPrompt,
32
+ cacheable: true,
33
+ metadata: {
34
+ runtimeProfile: runtimeProfile.profileId || runtimeProfile.runtimeProfile || '',
35
+ outputContract: runtimeProfile.outputContract || '',
36
+ },
37
+ });
38
+ if (userTask) {
39
+ registry.add({
40
+ id: 'dynamic.user-task',
41
+ kind: 'dynamic',
42
+ source: 'user',
43
+ content: userTask,
44
+ cacheable: false,
45
+ redactionPolicy: 'standard',
46
+ });
47
+ }
48
+ if (Array.isArray(messages) && messages.length) {
49
+ registry.add({
50
+ id: 'dynamic.message-window',
51
+ kind: 'dynamic',
52
+ source: 'runtime.messages',
53
+ content: JSON.stringify(messages.map((message) => ({
54
+ role: message.role,
55
+ contentType: Array.isArray(message.content) ? 'blocks' : typeof message.content,
56
+ }))),
57
+ cacheable: false,
58
+ metadata: { count: messages.length },
59
+ });
60
+ }
61
+ registry.add({
62
+ id: 'dynamic.tool-catalog',
63
+ kind: 'dynamic',
64
+ source: 'tool-registry',
65
+ content: toolCatalogSignature(tools),
66
+ cacheable: false,
67
+ metadata: { count: Array.isArray(tools) ? tools.length : 0 },
68
+ });
69
+ return registry.manifest({
70
+ metadata: {
71
+ runtimeProfile: runtimeProfile.profileId || runtimeProfile.runtimeProfile || '',
72
+ permissionProfile: runtimeProfile.permissionProfile || '',
73
+ persistenceProfile: runtimeProfile.persistenceProfile || '',
74
+ ...metadata,
75
+ },
76
+ });
77
+ }
78
+
79
+ module.exports = {
80
+ PromptSectionRegistry,
81
+ appendPromptManifest,
82
+ buildPromptManifest,
83
+ buildRuntimePromptManifest,
84
+ normalizePromptManifestSection,
85
+ toolCatalogSignature,
86
+ };