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
@@ -1,55 +1,16 @@
1
- // --- Conversation Import Worker Thread ---
2
- // Runs JSONL -> session_conversations import off the main event loop.
3
- // Opens its own better-sqlite3 connection; WAL mode supports concurrent access.
1
+ 'use strict';
4
2
 
5
- const { parentPort, workerData } = require('worker_threads');
6
- const path = require('path');
3
+ const { parentPort } = require('node:worker_threads');
7
4
 
8
- const dbModule = require(path.join(workerData.ctmDir, 'db'));
9
- dbModule.connectDb(workerData.dbPath);
10
-
11
- const { runIncrementalConversationImport } = require(path.join(workerData.ctmDir, 'api-prompts'));
12
-
13
- let running = false;
14
- let closing = false;
15
- let closed = false;
16
-
17
- function closeDbAndAck() {
18
- if (closed) return;
19
- closed = true;
20
- try { dbModule.closeDb({ checkpointMode: 'PASSIVE' }); } catch {}
21
- parentPort.postMessage({ type: 'closed' });
22
- setImmediate(() => process.exit(0));
23
- }
24
-
25
- parentPort.on('message', async (msg) => {
26
- if (msg.type === 'close') {
27
- closing = true;
28
- if (!running) closeDbAndAck();
29
- return;
30
- }
31
- if (msg.type !== 'run') return;
32
- if (closing) {
33
- parentPort.postMessage({ type: 'error', requestId: msg.requestId, dur: 0, error: 'worker closing' });
5
+ parentPort.on('message', (msg) => {
6
+ if (msg?.type === 'close') {
7
+ parentPort.postMessage({ type: 'closed' });
34
8
  return;
35
9
  }
36
- if (running) {
37
- parentPort.postMessage({ type: 'done', requestId: msg.requestId, dur: 0, result: { skipped: 'already_running' } });
38
- return;
39
- }
40
- running = true;
41
- const t0 = Date.now();
42
- try {
43
- const result = await runIncrementalConversationImport();
44
- parentPort.postMessage({ type: 'done', requestId: msg.requestId, dur: Date.now() - t0, result });
45
- } catch (e) {
46
- parentPort.postMessage({ type: 'error', requestId: msg.requestId, dur: Date.now() - t0, error: e.message });
47
- } finally {
48
- running = false;
49
- if (closing) closeDbAndAck();
50
- }
51
- });
52
-
53
- process.on('exit', () => {
54
- try { dbModule.closeDb({ checkpointMode: 'NONE' }); } catch {}
10
+ parentPort.postMessage({
11
+ type: 'error',
12
+ requestId: msg?.requestId,
13
+ dur: 0,
14
+ error: 'conversation import DB work is owned by the CTM DB owner worker',
15
+ });
55
16
  });
@@ -0,0 +1,386 @@
1
+ 'use strict';
2
+
3
+ const { parentPort, workerData } = require('node:worker_threads');
4
+ const { retryOnWriteLockBusy } = require('../../shared/sqlite-write-lock');
5
+
6
+ const db = require('../db');
7
+
8
+ // Background writer: transient write-lock contention with the main thread should
9
+ // retry rather than surface (e.g. a pasted image failing). Safe because a busy
10
+ // error means the write never started. This worker thread may async-wait freely.
11
+ const WRITE_LOCK_RETRIES = Math.max(0, Number(process.env.CTM_DB_OWNER_WORKER_BUSY_RETRIES) || 3);
12
+
13
+ let ready = false;
14
+ let closing = false;
15
+ let active = null;
16
+ let enqueued = 0;
17
+ let completed = 0;
18
+ let failed = 0;
19
+ const queue = [];
20
+
21
+ function _serializeError(err) {
22
+ return {
23
+ message: err && err.message ? err.message : String(err || 'unknown error'),
24
+ code: err && err.code ? err.code : undefined,
25
+ stack: err && err.stack ? String(err.stack) : undefined,
26
+ };
27
+ }
28
+
29
+ function _status() {
30
+ return {
31
+ ready,
32
+ active,
33
+ running: !!active,
34
+ pending: queue.length,
35
+ enqueued,
36
+ completed,
37
+ failed,
38
+ };
39
+ }
40
+
41
+ function _postStatus() {
42
+ try { parentPort.postMessage({ type: 'status', status: _status() }); } catch {}
43
+ }
44
+
45
+ function _ensureReady() {
46
+ if (!ready) throw new Error('DB owner worker is not ready');
47
+ }
48
+
49
+ let apiPrompts = null;
50
+ function _apiPrompts() {
51
+ if (!apiPrompts) apiPrompts = require('../api-prompts');
52
+ return apiPrompts;
53
+ }
54
+
55
+ let promptHarvest = null;
56
+ function _promptHarvest() {
57
+ if (!promptHarvest) promptHarvest = require('../prompt-harvest');
58
+ return promptHarvest;
59
+ }
60
+
61
+ let sessionIntegrity = null;
62
+ function _sessionIntegrity() {
63
+ if (!sessionIntegrity) sessionIntegrity = require('../session-integrity');
64
+ return sessionIntegrity;
65
+ }
66
+
67
+ let transcriptStore = null;
68
+ function _transcriptStore() {
69
+ if (!transcriptStore) transcriptStore = require('../lib/transcript-store');
70
+ return transcriptStore;
71
+ }
72
+
73
+ let sessionUtils = null;
74
+ function _sessionUtils() {
75
+ if (!sessionUtils) sessionUtils = require('../session-utils');
76
+ return sessionUtils;
77
+ }
78
+
79
+ let stripTerminalReplies = null;
80
+ function _stripLeakedTerminalGeneratedColorReplies(value) {
81
+ if (!stripTerminalReplies) {
82
+ stripTerminalReplies = require('../lib/terminal-control-sanitize').stripLeakedTerminalGeneratedColorReplies;
83
+ }
84
+ return stripTerminalReplies(value);
85
+ }
86
+
87
+ async function _runOp(op, payload = {}) {
88
+ _ensureReady();
89
+ switch (op) {
90
+ case 'appendScrollbackBatch': {
91
+ const sessionId = String(payload.sessionId || '');
92
+ const chunks = Array.isArray(payload.chunks) ? payload.chunks : [];
93
+ if (!sessionId || chunks.length === 0) return { appended: 0 };
94
+ db.appendScrollbackBatch(sessionId, chunks);
95
+ return { appended: chunks.length };
96
+ }
97
+ case 'clearScrollback': {
98
+ const sessionId = String(payload.sessionId || '');
99
+ if (!sessionId) return { cleared: false };
100
+ db.clearScrollback(sessionId);
101
+ return { cleared: true };
102
+ }
103
+ case 'prepareScrollbackForSession': {
104
+ const sessionId = String(payload.sessionId || '');
105
+ if (!sessionId) return { restoreAllowed: true, cleared: false };
106
+ return db.prepareScrollbackForSession(sessionId, payload.identity || {}, payload.options || {});
107
+ }
108
+ case 'loadRestoreScrollbackTail': {
109
+ // Offload the heavy restore-scrollback work OFF the main thread:
110
+ // 1. synchronous better-sqlite3 read (up to ~800 chunks / ~768KB)
111
+ // 2. chunks.map(c=>c.data).join('') over that whole payload
112
+ // 3. stripLeakedTerminalGeneratedColorReplies regex over the joined string
113
+ // 4. tail-cache truncation to tailCacheBytes
114
+ // This worker has its own WAL reader connection so the read is safe
115
+ // concurrent with the main process. Returns the final scrollData string
116
+ // (already stripped + tail-truncated) plus the loaded chunk count.
117
+ const sessionId = String(payload.sessionId || '');
118
+ if (!sessionId) return { scrollData: '', chunkCount: 0 };
119
+ const loadOpts = {};
120
+ if (Number.isFinite(Number(payload.maxChunks)) && Number(payload.maxChunks) > 0) {
121
+ loadOpts.maxChunks = Number(payload.maxChunks);
122
+ }
123
+ if (Number.isFinite(Number(payload.maxBytes)) && Number(payload.maxBytes) > 0) {
124
+ loadOpts.maxBytes = Number(payload.maxBytes);
125
+ }
126
+ const chunks = typeof db.loadScrollbackTail === 'function'
127
+ ? db.loadScrollbackTail(sessionId, loadOpts)
128
+ : db.loadScrollback(sessionId);
129
+ if (!Array.isArray(chunks) || chunks.length === 0) return { scrollData: '', chunkCount: 0 };
130
+ const chunkCount = chunks.length;
131
+ const scrollData = _stripLeakedTerminalGeneratedColorReplies(chunks.map(c => c.data).join(''));
132
+ if (!scrollData) return { scrollData: '', cacheSnapshot: '', chunkCount };
133
+ // Mirror _restoreScrollbackCacheFromChunks: the interim bootstrap cache is
134
+ // tail-truncated to tailCacheBytes, but the FULL (untruncated) scrollData
135
+ // is fed to background hydration. Return both so the main thread does only
136
+ // cheap field assignment (no join/regex/big-slice on the hot path).
137
+ const tailBytes = Number(payload.tailCacheBytes);
138
+ const cacheSnapshot = (Number.isFinite(tailBytes) && tailBytes > 0 && scrollData.length > tailBytes)
139
+ ? scrollData.slice(-tailBytes)
140
+ : scrollData;
141
+ return { scrollData, cacheSnapshot, chunkCount };
142
+ }
143
+ case 'batchRestoreIdentities': {
144
+ // Fix B Stage 3: precompute per-session restore metadata (identity /
145
+ // resolved / latest codex agent / title / scrollback seq seed) in ONE
146
+ // batched read off the main thread. Returns a plain object keyed by
147
+ // session id (Map is not structured-clone friendly across the worker
148
+ // boundary in a stable way, so serialize to an object here).
149
+ const sessionIds = Array.isArray(payload.sessionIds) ? payload.sessionIds : [];
150
+ if (!sessionIds.length || typeof db.batchRestoreIdentities !== 'function') {
151
+ return { entries: {} };
152
+ }
153
+ const map = db.batchRestoreIdentities(sessionIds);
154
+ const entries = {};
155
+ for (const [id, value] of map.entries()) entries[id] = value;
156
+ return { entries };
157
+ }
158
+ case 'retireStartupTask': {
159
+ const sessionId = String(payload.sessionId || '');
160
+ if (!sessionId) return { retired: false };
161
+ if (typeof db.markStartupTaskExited === 'function') db.markStartupTaskExited(sessionId);
162
+ db.removeStartupTask(sessionId);
163
+ return { retired: true };
164
+ }
165
+ case 'renameSession': {
166
+ const sessionId = String(payload.sessionId || '');
167
+ const liveSessionId = String(payload.liveSessionId || sessionId);
168
+ const title = String(payload.title || '').trim().slice(0, 120);
169
+ if (!sessionId || !title) return { renamed: false };
170
+ db.setSessionTitleNew(sessionId, title, true);
171
+ if (liveSessionId) (db.updateStartupTaskTitle || db.updateStartupTaskLabel)(liveSessionId, title);
172
+ return { renamed: true };
173
+ }
174
+ case 'heartbeatStartupTasks': {
175
+ const sessionIds = Array.isArray(payload.sessionIds) ? payload.sessionIds : [];
176
+ return { heartbeat: db.heartbeatStartupTasks(sessionIds) || 0 };
177
+ }
178
+ case 'saveImage': {
179
+ const promptId = Number(payload.promptId || 0);
180
+ const filename = payload.filename || 'image.png';
181
+ const mimeType = payload.mimeType || 'image/png';
182
+ const raw = payload.buffer || Buffer.alloc(0);
183
+ const buffer = Buffer.isBuffer(raw) ? raw : Buffer.from(raw);
184
+ return await db.saveImage(promptId, buffer, filename, mimeType);
185
+ }
186
+ case 'getWriteLockStats': {
187
+ // Read-only: this worker thread's own write-lock stats (the 5s-wait writer).
188
+ return payload && payload.reset ? db.resetWriteLockStats() : db.getWriteLockStats();
189
+ }
190
+ case 'getMessageExtractionStats': {
191
+ // Read-only: append-vs-full-rewrite counters for replaceSessionMessages, which
192
+ // runs on this worker for the conversation-import path (opportunity D).
193
+ const stats = db.getMessageExtractionStats ? db.getMessageExtractionStats() : null;
194
+ if (payload && payload.reset && db.resetMessageExtractionStats) db.resetMessageExtractionStats();
195
+ return stats;
196
+ }
197
+ case 'checkpointWal': {
198
+ return { rows: db.checkpointWal(payload.mode || 'PASSIVE') || [] };
199
+ }
200
+ case 'checkpointWalOrThrow': {
201
+ return { rows: db.checkpointWalOrThrow(payload.mode || 'PASSIVE') || [] };
202
+ }
203
+ case 'runIncrementalConversationImport': {
204
+ const result = await _apiPrompts().runIncrementalConversationImport();
205
+ return result || { done: true };
206
+ }
207
+ case 'runCursorConversationImport': {
208
+ const result = await _apiPrompts().runCursorConversationImport();
209
+ return result || { done: true };
210
+ }
211
+ case 'runIncrementalLifecycleRefresh': {
212
+ return _promptHarvest().runIncrementalLifecycleRefresh() || { done: true };
213
+ }
214
+ case 'runSessionIntegrity': {
215
+ return _sessionIntegrity().runIntegrityCheck({
216
+ db: db.getDb(),
217
+ getAllSessionFiles: _sessionUtils().getAllSessionFiles,
218
+ telemetry: null,
219
+ autoRecover: true,
220
+ }) || { checked: true };
221
+ }
222
+ case 'recoverSessionIntegrity': {
223
+ // Apply ONLY the recovery WRITES for issues the off-worker (read-pool) detect already
224
+ // found, so the heavy full-corpus detection scan never runs on this single serial
225
+ // worker (which would starve interactive writes → main-thread Dropbox-I/O freezes).
226
+ // recoverMismatches operates on the passed issues + a cheap file-index enumeration
227
+ // (not a transcript scan); repairSafeRelinkSwaps re-audits only when cross-links exist.
228
+ const integ = _sessionIntegrity();
229
+ const getAll = _sessionUtils().getAllSessionFiles;
230
+ const recoverable = Array.isArray(payload.recoverable) ? payload.recoverable : [];
231
+ let recovery = recoverable.length > 0
232
+ ? integ.recoverMismatches(db.getDb(), recoverable, getAll)
233
+ : null;
234
+ if (payload.hasCrossLinks) {
235
+ const relinkRecovery = integ.repairSafeRelinkSwaps(db.getDb(), null);
236
+ if (relinkRecovery && (relinkRecovery.fixed > 0 || relinkRecovery.skipped > 0)) {
237
+ if (!recovery) recovery = { fixed: 0, skipped: 0, actions: [] };
238
+ recovery.fixed += relinkRecovery.fixed;
239
+ recovery.skipped += relinkRecovery.skipped;
240
+ recovery.actions.push(...relinkRecovery.actions);
241
+ }
242
+ }
243
+ return { recovery };
244
+ }
245
+ case 'backfillSessionMessagesAsync': {
246
+ const result = await db.backfillSessionMessagesAsync(payload.options || {});
247
+ return { extracted: Number(result || 0) };
248
+ }
249
+ case 'runContentRowsBackfillSweep': {
250
+ // Phase 4 migration: populate session_message_rows for pre-migration sessions from
251
+ // their (small) blobs. Runs here so the chunked writes never block the main loop.
252
+ return db.runContentRowsBackfillSweep(payload.options || {});
253
+ }
254
+ case 'retireLegacyStores': {
255
+ // De-dup cleanup: drop session_messages + FTS once migration is complete. Cheap (DROP TABLE).
256
+ return db.retireLegacyStores();
257
+ }
258
+ case 'runVacuum': {
259
+ // Reclaim disk after retirement. EXCLUSIVE + heavy — runs here so the main loop's CPU is free,
260
+ // though it still serializes DB access for the duration. Operator-triggered only.
261
+ return db.runVacuum();
262
+ }
263
+ case 'pruneApprovalObservations': {
264
+ return db.pruneApprovalObservations(payload || {});
265
+ }
266
+ case 'pruneApprovalAiRefinementRules': {
267
+ return db.pruneApprovalAiRefinementRules(payload || {});
268
+ }
269
+ case 'importSessionConversation': {
270
+ // Durable conversation-cache write offloaded from apiSessionMessages' main-thread
271
+ // path: a multi-MB blob upsert + session_messages rewrite that froze the loop on
272
+ // cold Dropbox. Runs here so the disk I/O never blocks the event loop. Returns a
273
+ // small summary (no blob).
274
+ db.importSessionConversation(payload || {});
275
+ return { ok: true };
276
+ }
277
+ case 'catchUpTranscriptFiles': {
278
+ // Heavy JSONL tail ingest. Runs here (worker thread) so a cold-Dropbox fsync
279
+ // stall on a single statement can never freeze the main event loop. The main
280
+ // thread re-reads the freshly-ingested rows from its own connection (WAL) on
281
+ // the next message poll. Returns the summary only (no messages).
282
+ return _transcriptStore().catchUpTranscriptFiles(db.getDb(), payload || {});
283
+ }
284
+ case 'addApprovalObservation': {
285
+ return { id: db.addApprovalObservation(payload || {}) };
286
+ }
287
+ case 'drain': {
288
+ return { ok: true, ..._status() };
289
+ }
290
+ default: {
291
+ const err = new Error(`Unsupported DB owner worker op: ${op}`);
292
+ err.code = 'CTM_DB_OWNER_UNSUPPORTED_OP';
293
+ throw err;
294
+ }
295
+ }
296
+ }
297
+
298
+ function _pump() {
299
+ if (active || closing) return;
300
+ const task = queue.shift();
301
+ if (!task) {
302
+ _postStatus();
303
+ return;
304
+ }
305
+ active = task.op;
306
+ _postStatus();
307
+ Promise.resolve()
308
+ .then(() => retryOnWriteLockBusy(() => _runOp(task.op, task.payload), {
309
+ retries: WRITE_LOCK_RETRIES,
310
+ backoffMs: 60,
311
+ onRetry: ({ attempt, retries }) => {
312
+ console.warn(`[db-owner-worker] write-lock busy on '${task.op}', retry ${attempt}/${retries}`);
313
+ },
314
+ }))
315
+ .then((result) => {
316
+ completed += 1;
317
+ parentPort.postMessage({ type: 'response', requestId: task.requestId, result });
318
+ }, (err) => {
319
+ failed += 1;
320
+ parentPort.postMessage({ type: 'response', requestId: task.requestId, error: _serializeError(err) });
321
+ })
322
+ .finally(() => {
323
+ active = null;
324
+ _pump();
325
+ });
326
+ }
327
+
328
+ function _enqueue(msg) {
329
+ enqueued += 1;
330
+ queue.push({
331
+ requestId: msg.requestId,
332
+ op: msg.op,
333
+ payload: msg.payload || {},
334
+ });
335
+ _pump();
336
+ }
337
+
338
+ function _close() {
339
+ closing = true;
340
+ queue.length = 0;
341
+ try { db.closeDb({ checkpointMode: 'NONE' }); } catch {}
342
+ ready = false;
343
+ try { parentPort.postMessage({ type: 'closed' }); } catch {}
344
+ setImmediate(() => {
345
+ try { parentPort.close(); } catch {}
346
+ });
347
+ }
348
+
349
+ function _boot() {
350
+ try {
351
+ const dbPath = workerData && workerData.dbPath;
352
+ if (!dbPath) throw new Error('DB owner worker requires dbPath');
353
+ if (workerData.initDb) db.initDb(dbPath);
354
+ else db.connectDb(dbPath);
355
+ ready = true;
356
+ parentPort.postMessage({ type: 'ready', status: _status() });
357
+ } catch (err) {
358
+ parentPort.postMessage({ type: 'fatal', ..._serializeError(err) });
359
+ }
360
+ }
361
+
362
+ parentPort.on('message', (msg) => {
363
+ if (!msg || typeof msg !== 'object') return;
364
+ if (msg.type === 'request') {
365
+ _enqueue(msg);
366
+ return;
367
+ }
368
+ if (msg.type === 'status') {
369
+ _postStatus();
370
+ return;
371
+ }
372
+ if (msg.type === 'close') {
373
+ if (active) {
374
+ const interval = setInterval(() => {
375
+ if (active) return;
376
+ clearInterval(interval);
377
+ _close();
378
+ }, 10);
379
+ if (typeof interval.unref === 'function') interval.unref();
380
+ } else {
381
+ _close();
382
+ }
383
+ }
384
+ });
385
+
386
+ _boot();
@@ -1,61 +1,15 @@
1
- // --- Harvest Worker Thread ---
2
- // Runs prompt-harvest's runIncrementalLifecycleRefresh off the main event loop.
3
- // Opens its own better-sqlite3 connection (WAL mode supports concurrent access).
4
- // The main thread sends { type: 'run' } messages, receives { type: 'done', result } back.
1
+ 'use strict';
5
2
 
6
- const { parentPort, workerData } = require('worker_threads');
7
- const path = require('path');
8
-
9
- // Initialize DB module with the same path as main thread
10
- const dbModule = require(path.join(workerData.ctmDir, 'db'));
11
- dbModule.connectDb(workerData.dbPath);
12
-
13
- // Load harvest module (it uses dbModule.getDb() internally)
14
- const harvest = require(path.join(workerData.ctmDir, 'prompt-harvest'));
15
-
16
- let running = false;
17
- let closing = false;
18
- let closed = false;
19
-
20
- function closeDbAndAck() {
21
- if (closed) return;
22
- closed = true;
23
- try { dbModule.closeDb({ checkpointMode: 'PASSIVE' }); } catch {}
24
- parentPort.postMessage({ type: 'closed' });
25
- setImmediate(() => process.exit(0));
26
- }
3
+ const { parentPort } = require('node:worker_threads');
27
4
 
28
5
  parentPort.on('message', (msg) => {
29
- if (msg.type === 'close') {
30
- closing = true;
31
- if (!running) closeDbAndAck();
6
+ if (msg?.type === 'close') {
7
+ parentPort.postMessage({ type: 'closed' });
32
8
  return;
33
9
  }
34
- switch (msg.type) {
35
- case 'run': {
36
- if (closing) {
37
- parentPort.postMessage({ type: 'error', dur: 0, error: 'worker closing' });
38
- break;
39
- }
40
- running = true;
41
- const t0 = Date.now();
42
- try {
43
- harvest.runIncrementalLifecycleRefresh();
44
- const dur = Date.now() - t0;
45
- parentPort.postMessage({ type: 'done', dur });
46
- } catch (e) {
47
- const dur = Date.now() - t0;
48
- parentPort.postMessage({ type: 'error', dur, error: e.message });
49
- } finally {
50
- running = false;
51
- if (closing) closeDbAndAck();
52
- }
53
- break;
54
- }
55
- }
56
- });
57
-
58
- // Cleanup on thread exit
59
- process.on('exit', () => {
60
- try { dbModule.closeDb({ checkpointMode: 'NONE' }); } catch {}
10
+ parentPort.postMessage({
11
+ type: 'error',
12
+ dur: 0,
13
+ error: 'harvest DB work is owned by the CTM DB owner worker',
14
+ });
61
15
  });