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
@@ -37,6 +37,18 @@ const AGENT_CAPABILITIES = Object.freeze({
37
37
  resume: true,
38
38
  resumeSpec: (id) => ({ cmd: 'gemini', args: ['--session', id] }),
39
39
  }),
40
+ opencode: Object.freeze({
41
+ agentType: 'opencode',
42
+ providerId: 'opencode',
43
+ label: 'OpenCode',
44
+ liveStatus: true,
45
+ stateDetector: true,
46
+ structuredTranscript: false,
47
+ promptNavigation: 'terminal',
48
+ review: false,
49
+ resume: false,
50
+ resumeSpec: () => null,
51
+ }),
40
52
  walle: Object.freeze({
41
53
  agentType: 'walle',
42
54
  providerId: 'walle',
@@ -49,6 +61,23 @@ const AGENT_CAPABILITIES = Object.freeze({
49
61
  resume: false,
50
62
  resumeSpec: () => null,
51
63
  }),
64
+ cursor: Object.freeze({
65
+ agentType: 'cursor',
66
+ providerId: 'cursor',
67
+ label: 'Cursor',
68
+ liveStatus: true,
69
+ stateDetector: true,
70
+ structuredTranscript: false,
71
+ promptNavigation: 'terminal',
72
+ review: false,
73
+ resume: true,
74
+ // Cursor chats are cloud-backed: there's no local transcript (JSONL/SQLite)
75
+ // under ~/.cursor or ~/.local/share/cursor-agent that CTM can tail, so we
76
+ // never capture a concrete chatId. Targeted resume would need Cursor's
77
+ // cloud API. Fall back to `cursor-agent --resume` with no id, which opens
78
+ // Cursor's own session picker — the working resume path today.
79
+ resumeSpec: (id) => ({ cmd: 'cursor-agent', args: id ? ['--resume', id] : ['--resume'] }),
80
+ }),
52
81
  shell: Object.freeze({
53
82
  agentType: 'shell',
54
83
  providerId: 'shell',
@@ -69,6 +98,8 @@ function detectAgentType(cmd) {
69
98
  if (s.includes('claude')) return 'claude';
70
99
  if (s.includes('codex')) return 'codex';
71
100
  if (s.includes('gemini')) return 'gemini';
101
+ if (s.includes('opencode') || s.includes('open-code')) return 'opencode';
102
+ if (s.includes('cursor')) return 'cursor';
72
103
  if (s === 'walle' || s.includes('wall-e') || s.includes('walle')) return 'walle';
73
104
  return null;
74
105
  }
@@ -79,6 +110,8 @@ function normalizeAgentType(value) {
79
110
  if (AGENT_CAPABILITIES[s]) return s;
80
111
  if (s === 'claude-code') return 'claude';
81
112
  if (s === 'gemini-cli') return 'gemini';
113
+ if (s === 'opencode-cli' || s === 'open-code') return 'opencode';
114
+ if (s === 'cursor-agent' || s === 'cursor-cli') return 'cursor';
82
115
  return detectAgentType(s);
83
116
  }
84
117
 
@@ -6,7 +6,7 @@ const path = require('path');
6
6
  const crypto = require('crypto');
7
7
 
8
8
  const CACHE_VERSION = 1;
9
- const DEFAULT_AGENTS = Object.freeze(['claude', 'codex', 'gemini']);
9
+ const DEFAULT_AGENTS = Object.freeze(['claude', 'codex', 'gemini', 'cursor-agent']);
10
10
 
11
11
  function _pathHash(envPath) {
12
12
  return crypto.createHash('sha256').update(String(envPath || '')).digest('hex');
@@ -19,6 +19,34 @@ function _splitPath(envPath) {
19
19
  .filter(Boolean);
20
20
  }
21
21
 
22
+ // GUI-launched processes (e.g. the packaged "Coding Task Manager" app) inherit
23
+ // a minimal PATH that often omits user-local install dirs. cursor-agent (and
24
+ // the cursor/claude/codex installers) drop binaries in ~/.local/bin, so a CLI
25
+ // installed only there would read as "not detected on PATH" even though it
26
+ // works in a normal shell. Always probe these well-known dirs in addition to
27
+ // the process PATH so detection — and the absolute-path resolution that powers
28
+ // spawning — are independent of how CTM was launched.
29
+ function _extraBinDirs() {
30
+ const home = os.homedir();
31
+ if (!home) return ['/opt/homebrew/bin', '/usr/local/bin'];
32
+ return [
33
+ path.join(home, '.local', 'bin'),
34
+ path.join(home, 'bin'),
35
+ '/opt/homebrew/bin',
36
+ '/usr/local/bin',
37
+ ];
38
+ }
39
+
40
+ function _candidateBinDirs(envPath, extraDirs) {
41
+ const extras = Array.isArray(extraDirs) ? extraDirs : _extraBinDirs();
42
+ const seen = new Set();
43
+ const dirs = [];
44
+ for (const dir of [..._splitPath(envPath), ...extras]) {
45
+ if (dir && !seen.has(dir)) { seen.add(dir); dirs.push(dir); }
46
+ }
47
+ return dirs;
48
+ }
49
+
22
50
  function _isExecutable(filePath) {
23
51
  try {
24
52
  fs.accessSync(filePath, fs.constants.X_OK);
@@ -76,8 +104,8 @@ function _sameFingerprint(a, b) {
76
104
  a.lstat?.ctimeMs === b.lstat?.ctimeMs;
77
105
  }
78
106
 
79
- function _findOnPath(bin, envPath) {
80
- for (const dir of _splitPath(envPath)) {
107
+ function _findOnPath(bin, envPath, extraDirs) {
108
+ for (const dir of _candidateBinDirs(envPath, extraDirs)) {
81
109
  const candidate = path.resolve(dir, bin);
82
110
  const fingerprint = _statFingerprint(candidate);
83
111
  if (fingerprint) return fingerprint;
@@ -135,9 +163,9 @@ function _publicEntry(entry, envPath) {
135
163
  };
136
164
  }
137
165
 
138
- function discoverAgent(agent, { env = process.env, now = Date.now() } = {}) {
166
+ function discoverAgent(agent, { env = process.env, now = Date.now(), extraBinDirs } = {}) {
139
167
  const envPath = env.PATH || process.env.PATH || '';
140
- return _entryFromFingerprint(agent, _findOnPath(agent, envPath), envPath, now, 'path-scan');
168
+ return _entryFromFingerprint(agent, _findOnPath(agent, envPath, extraBinDirs), envPath, now, 'path-scan');
141
169
  }
142
170
 
143
171
  function getAvailableAgents({
@@ -145,6 +173,7 @@ function getAvailableAgents({
145
173
  agents = DEFAULT_AGENTS,
146
174
  env = process.env,
147
175
  now = Date.now(),
176
+ extraBinDirs,
148
177
  } = {}) {
149
178
  const envPath = env.PATH || process.env.PATH || '';
150
179
  const cache = _readCache(cacheFile);
@@ -160,7 +189,7 @@ function getAvailableAgents({
160
189
  const cached = cache.agents[agent];
161
190
  let entry = cached;
162
191
  if (!_isCachedEntryFresh(cached, envPath)) {
163
- entry = discoverAgent(agent, { env, now });
192
+ entry = discoverAgent(agent, { env, now, extraBinDirs });
164
193
  cache.agents[agent] = entry;
165
194
  changed = true;
166
195
  }
@@ -197,6 +226,7 @@ function resolveCliCommand(cmd, {
197
226
  agents = DEFAULT_AGENTS,
198
227
  env = process.env,
199
228
  now = Date.now(),
229
+ extraBinDirs,
200
230
  } = {}) {
201
231
  if (!cmd || typeof cmd !== 'string') return cmd;
202
232
  const base = path.basename(cmd);
@@ -206,7 +236,7 @@ function resolveCliCommand(cmd, {
206
236
  // a persisted CTM task points at a removed CLI path, recover via PATH.
207
237
  if (cmd.includes('/') && _statFingerprint(cmd)) return cmd;
208
238
 
209
- const available = getAvailableAgents({ cacheFile, agents, env, now });
239
+ const available = getAvailableAgents({ cacheFile, agents, env, now, extraBinDirs });
210
240
  const entry = available.agents[base];
211
241
  return entry?.available && entry.path ? entry.path : cmd;
212
242
  }
@@ -7,6 +7,11 @@
7
7
  // 2. ~/.codex/config.toml — [otel] block + [notify] block (custom TOML parser)
8
8
  // 3. ~/.gemini/settings.json — JSON hooks that run our bin/gemini-hook.js
9
9
  //
10
+ // Cursor is also a first-class coding-agent runtime, but it does not currently
11
+ // expose a documented hook config surface. Its live status comes from CTM's
12
+ // managed terminal lifecycle, so install/uninstall are no-op plans instead of
13
+ // writing speculative keys into ~/.cursor/cli-config.json.
14
+ //
10
15
  // Every write is idempotent: re-running install() is a no-op if the marker
11
16
  // strings (identifying our hook entries) are already present. uninstall()
12
17
  // removes only our entries and leaves everything else intact.
@@ -46,6 +51,20 @@ function ctmMarker(port) {
46
51
  return `ctm:${port}:${HOOK_BIN_DIR}`;
47
52
  }
48
53
 
54
+ function planTerminalManagedAgent(agent, preset) {
55
+ return {
56
+ agent,
57
+ filePath: expandHome(preset?.configPath || ''),
58
+ format: preset?.configFormat || 'none',
59
+ currentText: '',
60
+ nextText: '',
61
+ willWrite: false,
62
+ changes: [
63
+ { description: 'No config write: CTM tracks this runtime through the managed terminal lifecycle.' },
64
+ ],
65
+ };
66
+ }
67
+
49
68
  // ─── Claude settings.json (JSON, array-of-hooks shape) ────────────────────
50
69
 
51
70
  /**
@@ -61,8 +80,9 @@ function safeReadFile(p) {
61
80
  if (!fs.existsSync(p)) return '';
62
81
  try { return fs.readFileSync(p, 'utf8'); }
63
82
  catch (e) {
64
- const hint = (e.code === 'EDEADLK' || /deadlock/i.test(e.message))
65
- ? ' (file appears to be a cloud-storage placeholder — click the file in Finder to materialize it, then retry)'
83
+ const materializeProblem = e.code === 'EDEADLK' || e.errno === -11 || /deadlock|system error -11/i.test(e.message || '');
84
+ const hint = materializeProblem
85
+ ? ' (file appears to be a cloud-storage placeholder or dataless file — make it available offline, then retry)'
66
86
  : '';
67
87
  throw new Error(`cannot read ${p}: ${e.message}${hint}`);
68
88
  }
@@ -393,6 +413,7 @@ function unpatchCodexConfig(text, _port) {
393
413
  function planInstall(agent, port) {
394
414
  const preset = getPreset(agent);
395
415
  if (!preset) throw new Error(`Unknown agent preset: ${agent}`);
416
+ if (preset.liveStatusMode === 'terminal') return planTerminalManagedAgent(agent, preset);
396
417
  if (agent === 'claude-code') {
397
418
  const { __path, data, rawText } = readClaudeSettings();
398
419
  const next = patchClaudeSettings(data, port);
@@ -438,6 +459,7 @@ function planInstall(agent, port) {
438
459
  function planUninstall(agent, port) {
439
460
  const preset = getPreset(agent);
440
461
  if (!preset) throw new Error(`Unknown agent preset: ${agent}`);
462
+ if (preset.liveStatusMode === 'terminal') return planTerminalManagedAgent(agent, preset);
441
463
  if (agent === 'claude-code') {
442
464
  const { __path, data, rawText } = readClaudeSettings();
443
465
  const next = unpatchClaudeSettings(data, port);
@@ -481,6 +503,8 @@ function uninstall(agent, port) { return applyPlan(planUninstall(agent, port));
481
503
 
482
504
  /** Is this agent's config currently patched with our marker (for this port)? */
483
505
  function isInstalled(agent, port) {
506
+ const preset = getPreset(agent);
507
+ if (preset?.liveStatusMode === 'terminal') return true;
484
508
  const marker = ctmMarker(port);
485
509
  try {
486
510
  if (agent === 'claude-code') {
@@ -13,8 +13,9 @@
13
13
  * @property {Object} [telemetryEnv] - env vars to set when spawning this agent. Values may
14
14
  * contain "{{port}}" which will be replaced at spawn
15
15
  * time with the CTM HTTP port.
16
- * @property {string} [configPath] - path to the agent's user config file (for hook install)
16
+ * @property {string} [configPath] - path to the agent's user config file (for hook install/status context)
17
17
  * @property {'json' | 'toml'} [configFormat] - format of the config file (informs the patcher)
18
+ * @property {'hooks' | 'terminal'} [liveStatusMode] - how CTM gets live status for this runtime
18
19
  * @property {Array<{ kind: string, matcher: string|null, bin: string, route: string }>} [hooks]
19
20
  * Hooks to install into the agent's config.
20
21
  * kind — agent-specific event name ("Stop", "SessionStart", etc.)
@@ -40,6 +41,7 @@ const PRESETS = {
40
41
  },
41
42
  configPath: '~/.claude/settings.json',
42
43
  configFormat: 'json',
44
+ liveStatusMode: 'hooks',
43
45
  hooks: [
44
46
  { kind: 'SessionStart', matcher: null, bin: 'claude-hook', route: 'start' },
45
47
  { kind: 'UserPromptSubmit', matcher: null, bin: 'claude-hook', route: 'start' },
@@ -62,6 +64,7 @@ const PRESETS = {
62
64
  },
63
65
  configPath: '~/.codex/config.toml',
64
66
  configFormat: 'toml',
67
+ liveStatusMode: 'hooks',
65
68
  hooks: [
66
69
  // [notify] block handler; patcher writes this differently than Claude's hooks.
67
70
  { kind: 'notify', matcher: null, bin: 'codex-notify', route: 'stop' },
@@ -76,6 +79,7 @@ const PRESETS = {
76
79
  // No OTEL env — state flows through hooks only.
77
80
  configPath: '~/.gemini/settings.json',
78
81
  configFormat: 'json',
82
+ liveStatusMode: 'hooks',
79
83
  hooks: [
80
84
  { kind: 'BeforeAgent', matcher: null, bin: 'gemini-hook', route: 'start' },
81
85
  { kind: 'AfterAgent', matcher: null, bin: 'gemini-hook', route: 'stop' },
@@ -83,6 +87,18 @@ const PRESETS = {
83
87
  { kind: 'BeforeTool', matcher: null, bin: 'gemini-hook', route: 'menu' },
84
88
  ],
85
89
  },
90
+ 'cursor': {
91
+ presetId: 'cursor',
92
+ name: 'Cursor',
93
+ commandRegex: /(^|\/)cursor-agent(\s|$)/,
94
+ // Cursor Agent CLI does not currently expose a documented settings hook
95
+ // contract like Claude/Codex/Gemini. CTM still owns reliable live status
96
+ // for Cursor sessions it launches through the managed PTY lifecycle.
97
+ configPath: '~/.cursor/cli-config.json',
98
+ configFormat: 'json',
99
+ liveStatusMode: 'terminal',
100
+ hooks: [],
101
+ },
86
102
  };
87
103
 
88
104
  /** Detect which preset applies to a given spawn command (same contract as server.js's detectAgentType). */
@@ -0,0 +1,108 @@
1
+ 'use strict';
2
+
3
+ // Shared "all sessions" read query. Extracted from db.getAllSessionsData() so the
4
+ // SAME logic runs both on the main thread (db.js, via the live connection) AND on the
5
+ // read-pool worker (via a read-only connection) — keeping the recent-sessions rebuild
6
+ // off the main event loop (opportunity A follow-up). It is a pure read (two window-
7
+ // function queries + an in-memory join), so it is safe to run on a read-only WAL
8
+ // connection in a worker. Takes the database handle as a parameter — no module-level
9
+ // connection — so neither caller can accidentally diverge from the other.
10
+
11
+ function _columnSet(d, table) {
12
+ try {
13
+ return new Set(d.prepare(`PRAGMA table_info(${table})`).all().map(c => c.name));
14
+ } catch {
15
+ return new Set();
16
+ }
17
+ }
18
+
19
+ function queryAllSessionsData(d) {
20
+ const scCols = _columnSet(d, 'session_conversations');
21
+ const scLastMessageAt = scCols.has('last_message_at') ? 'sc.last_message_at' : "''";
22
+ const rows = d.prepare(`
23
+ SELECT c.*, a.agent_session_id, a.provider_resume_id, a.jsonl_path, a.first_message, a.file_size,
24
+ a.modified_at, a.hostname, a.model, a.git_branch,
25
+ a.thread_source, a.parent_agent_session_id, a.agent_nickname, a.agent_role,
26
+ COALESCE(agent_list.agent_session_ids, '') as agent_session_ids,
27
+ COALESCE(agent_list.agent_session_count, 0) as agent_session_count,
28
+ MAX(COALESCE(a.user_msg_count, 0), COALESCE(sc.user_msg_count, 0)) as user_msg_count,
29
+ COALESCE(NULLIF(a.last_user_content, ''), sc.last_user_content) as last_user_content,
30
+ COALESCE(NULLIF(a.first_assistant_text, ''), sc.first_assistant_text) as first_assistant_text,
31
+ COALESCE(NULLIF(a.rename_name, ''), sc.rename_name) as rename_name,
32
+ COALESCE(NULLIF(${scLastMessageAt}, ''), '') as last_message_at
33
+ FROM ctm_sessions c
34
+ LEFT JOIN (
35
+ SELECT *, ROW_NUMBER() OVER (
36
+ PARTITION BY ctm_session_id
37
+ ORDER BY COALESCE(NULLIF(modified_at, ''), updated_at, created_at) DESC,
38
+ updated_at DESC,
39
+ created_at DESC
40
+ ) as rn
41
+ FROM agent_sessions
42
+ ) a ON a.ctm_session_id = c.id AND a.rn = 1
43
+ LEFT JOIN (
44
+ SELECT ctm_session_id,
45
+ group_concat(agent_session_id, ',') as agent_session_ids,
46
+ COUNT(*) as agent_session_count
47
+ FROM (
48
+ SELECT ctm_session_id, agent_session_id
49
+ FROM agent_sessions
50
+ ORDER BY COALESCE(NULLIF(modified_at, ''), updated_at, created_at) DESC,
51
+ updated_at DESC,
52
+ created_at DESC
53
+ ) ordered_agents
54
+ GROUP BY ctm_session_id
55
+ ) agent_list ON agent_list.ctm_session_id = c.id
56
+ LEFT JOIN session_conversations sc ON sc.ctm_session_id = a.agent_session_id
57
+ `).all();
58
+
59
+ const agentRows = d.prepare(`
60
+ SELECT
61
+ a.agent_session_id,
62
+ a.ctm_session_id,
63
+ a.provider,
64
+ a.provider_resume_id,
65
+ a.project_path,
66
+ a.jsonl_path,
67
+ COALESCE(NULLIF(a.first_message, ''), sc.first_message) as first_message,
68
+ a.file_size,
69
+ a.modified_at,
70
+ a.hostname,
71
+ COALESCE(NULLIF(a.model, ''), sc.model_id) as model,
72
+ sc.model_provider as model_provider,
73
+ COALESCE(NULLIF(a.git_branch, ''), sc.git_branch) as git_branch,
74
+ MAX(COALESCE(a.user_msg_count, 0), COALESCE(sc.user_msg_count, 0)) as user_msg_count,
75
+ a.slug,
76
+ a.thread_source,
77
+ a.parent_agent_session_id,
78
+ a.agent_nickname,
79
+ a.agent_role,
80
+ a.created_at,
81
+ a.updated_at,
82
+ COALESCE(NULLIF(a.last_user_content, ''), sc.last_user_content) as last_user_content,
83
+ COALESCE(NULLIF(a.first_assistant_text, ''), sc.first_assistant_text) as first_assistant_text,
84
+ COALESCE(NULLIF(a.rename_name, ''), sc.rename_name) as rename_name,
85
+ COALESCE(NULLIF(${scLastMessageAt}, ''), '') as last_message_at
86
+ FROM agent_sessions a
87
+ LEFT JOIN session_conversations sc ON sc.ctm_session_id = a.agent_session_id
88
+ ORDER BY
89
+ a.ctm_session_id ASC,
90
+ COALESCE(NULLIF(a.modified_at, ''), a.updated_at, a.created_at) DESC,
91
+ a.created_at DESC
92
+ `).all();
93
+
94
+ const byCtmId = new Map();
95
+ for (const agent of agentRows) {
96
+ if (!agent.ctm_session_id) continue;
97
+ if (!byCtmId.has(agent.ctm_session_id)) byCtmId.set(agent.ctm_session_id, []);
98
+ byCtmId.get(agent.ctm_session_id).push(agent);
99
+ }
100
+
101
+ for (const row of rows) {
102
+ row.agent_sessions = byCtmId.get(row.id) || [];
103
+ row.agent_session_count = row.agent_sessions.length;
104
+ }
105
+ return rows;
106
+ }
107
+
108
+ module.exports = { queryAllSessionsData };