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,685 +0,0 @@
1
- 'use strict';
2
-
3
- const fs = require('fs');
4
- const path = require('path');
5
- const { createHash } = require('crypto');
6
- const { execFileSync } = require('child_process');
7
-
8
- let claudeDesktopSessions = null;
9
- function getClaudeDesktopSessions() {
10
- if (claudeDesktopSessions) return claudeDesktopSessions;
11
- try {
12
- claudeDesktopSessions = require('../../claude-task-manager/lib/claude-desktop-sessions');
13
- } catch {
14
- return null;
15
- }
16
- return claudeDesktopSessions;
17
- }
18
-
19
- // --- Task type classification ---
20
-
21
- function classifyTaskType(content) {
22
- if (!content) return 'chat';
23
- const lower = content.toLowerCase();
24
- // Coding signals
25
- if (/\b(function|class|const |let |var |import |require\(|def |async |await |return )\b/.test(content)) return 'coding';
26
- if (/\b(fix|bug|error|implement|refactor|test|deploy|build)\b/i.test(lower)) return 'coding';
27
- // Planning signals
28
- if (/\b(plan|design|architect\w*|roadmap|strategy|prioritize|brainstorm|spec\b|tradeoffs?|trade-offs?|discuss|proposal)\b/i.test(lower)) return 'planning';
29
- // QA signals
30
- if (/\b(what is|how do|explain|why does|describe|compare)\b/i.test(lower)) return 'qa';
31
- // Slack signals
32
- if (/\b(slack|reply|respond|message|dm|channel)\b/i.test(lower)) return 'slack-reply';
33
- return 'chat';
34
- }
35
-
36
- // --- Content hash for dedup ---
37
-
38
- function contentHash(source, prompt) {
39
- return createHash('sha256').update(`${source}:${prompt}`).digest('hex').slice(0, 16);
40
- }
41
-
42
- // --- Claude Code Session Harvesting ---
43
-
44
- async function harvestClaudeCodeSessions(since) {
45
- const claudeDir = path.join(process.env.HOME, '.claude', 'projects');
46
- if (!fs.existsSync(claudeDir)) return [];
47
-
48
- const samples = [];
49
- const jsonlFiles = findJsonlFiles(claudeDir);
50
-
51
- for (const file of jsonlFiles) {
52
- const stat = fs.statSync(file);
53
- if (since && stat.mtime < new Date(since)) continue;
54
-
55
- try {
56
- const lines = fs.readFileSync(file, 'utf8').split('\n').filter(Boolean);
57
- const messages = lines.map(line => {
58
- try { return JSON.parse(line); } catch { return null; }
59
- }).filter(Boolean);
60
-
61
- // Pair user->assistant turns
62
- for (let i = 0; i < messages.length - 1; i++) {
63
- const msg = messages[i];
64
- const next = messages[i + 1];
65
-
66
- if (msg.type !== 'human' && msg.role !== 'user') continue;
67
- if (next.type !== 'assistant' && next.role !== 'assistant') continue;
68
-
69
- const userContent = extractContent(msg);
70
- const assistantContent = extractContent(next);
71
- if (!userContent || userContent.length < 20) continue;
72
- if (!assistantContent || assistantContent.length < 20) continue;
73
-
74
- // Extract tool calls from assistant message
75
- const toolCalls = extractToolCalls(next);
76
-
77
- const id = contentHash('claude-code', userContent);
78
- samples.push({
79
- id,
80
- source: 'claude-code',
81
- session_id: path.basename(file, '.jsonl'),
82
- timestamp: msg.timestamp || stat.mtime.toISOString(),
83
- task_type: classifyTaskType(userContent),
84
- prompt: userContent,
85
- response: assistantContent,
86
- tool_calls: toolCalls,
87
- outcome: 'unknown',
88
- outcome_signal: { git_committed: false, git_diff: null, task_status: null, user_corrected: false },
89
- model: next.model || 'unknown',
90
- quality_label: 0.5,
91
- });
92
- }
93
- } catch (err) {
94
- console.error(`[harvester] Error parsing ${file}:`, err.message);
95
- }
96
- }
97
- return samples;
98
- }
99
-
100
- // --- Claude Desktop Session Harvesting ---
101
-
102
- async function harvestClaudeDesktopSessions(since) {
103
- const reader = getClaudeDesktopSessions();
104
- if (!reader) return [];
105
-
106
- const sessions = reader.listSessions();
107
- const samples = [];
108
-
109
- for (const session of sessions) {
110
- if (since && session.updatedAt && session.updatedAt <= since) continue;
111
- const messages = Array.isArray(session.messages) ? session.messages : [];
112
- for (let i = 0; i < messages.length - 1; i++) {
113
- const userMsg = messages[i];
114
- const assistantMsg = messages[i + 1];
115
- if (userMsg.role !== 'user' || assistantMsg.role !== 'assistant') continue;
116
- const userContent = userMsg.text || '';
117
- const assistantContent = assistantMsg.text || '';
118
- if (!userContent || userContent.length < 20) continue;
119
- if (!assistantContent || assistantContent.length < 20) continue;
120
-
121
- samples.push({
122
- id: contentHash('claude-desktop', `${session.uuid}:${i}:${userContent}`),
123
- source: 'claude-desktop',
124
- session_id: session.uuid,
125
- timestamp: userMsg.timestamp || session.updatedAt || session.createdAt || new Date().toISOString(),
126
- task_type: classifyTaskType(userContent),
127
- prompt: userContent,
128
- response: assistantContent,
129
- tool_calls: [],
130
- outcome: 'unknown',
131
- outcome_signal: { git_committed: false, git_diff: null, task_status: null, user_corrected: false },
132
- model: session.model || 'unknown',
133
- quality_label: 0.5,
134
- });
135
- }
136
- }
137
- return samples;
138
- }
139
-
140
- // --- Codex Session Harvesting ---
141
-
142
- async function harvestCodexSessions(since) {
143
- const codexDir = path.join(process.env.HOME, '.codex', 'sessions');
144
- if (!fs.existsSync(codexDir)) return [];
145
-
146
- const samples = [];
147
- const jsonlFiles = findJsonlFiles(codexDir);
148
-
149
- for (const file of jsonlFiles) {
150
- const stat = fs.statSync(file);
151
- if (since && stat.mtime < new Date(since)) continue;
152
-
153
- try {
154
- const lines = fs.readFileSync(file, 'utf8').split('\n').filter(Boolean);
155
- const messages = lines.map(line => {
156
- try { return JSON.parse(line); } catch { return null; }
157
- }).filter(Boolean);
158
-
159
- // Codex format: response_item with role
160
- const userMsgs = messages.filter(m => m.role === 'user' || (m.type === 'response_item' && m.item?.role === 'user'));
161
- const assistantMsgs = messages.filter(m => m.role === 'assistant' || (m.type === 'response_item' && m.item?.role === 'assistant'));
162
-
163
- // Pair them up sequentially
164
- const pairs = Math.min(userMsgs.length, assistantMsgs.length);
165
- for (let i = 0; i < pairs; i++) {
166
- const userContent = extractContent(userMsgs[i]);
167
- const assistantContent = extractContent(assistantMsgs[i]);
168
- if (!userContent || userContent.length < 20) continue;
169
- if (!assistantContent || assistantContent.length < 20) continue;
170
-
171
- const toolCalls = extractToolCalls(assistantMsgs[i]);
172
- const id = contentHash('codex', userContent);
173
-
174
- samples.push({
175
- id,
176
- source: 'codex',
177
- session_id: path.basename(file, '.jsonl'),
178
- timestamp: userMsgs[i].timestamp || stat.mtime.toISOString(),
179
- task_type: classifyTaskType(userContent),
180
- prompt: userContent,
181
- response: assistantContent,
182
- tool_calls: toolCalls,
183
- outcome: 'unknown',
184
- outcome_signal: { git_committed: false, git_diff: null, task_status: null, user_corrected: false },
185
- model: assistantMsgs[i].model || 'unknown',
186
- quality_label: 0.5,
187
- });
188
- }
189
- } catch (err) {
190
- console.error(`[harvester] Error parsing ${file}:`, err.message);
191
- }
192
- }
193
- return samples;
194
- }
195
-
196
- // --- CTM Session Harvesting ---
197
-
198
- async function harvestCtmSessions(since, dataDirOverride = null) {
199
- const dataDir = dataDirOverride || process.env.WALL_E_DATA_DIR || path.join(process.env.HOME, '.walle', 'data');
200
- const ctmDbPath = path.join(dataDir, 'task-manager.db');
201
- if (!fs.existsSync(ctmDbPath)) return [];
202
-
203
- let Database;
204
- try { Database = require('better-sqlite3'); } catch { return []; }
205
- let ctmDb;
206
- try {
207
- ctmDb = new Database(ctmDbPath, { readonly: true, fileMustExist: true });
208
- } catch {
209
- return [];
210
- }
211
-
212
- try {
213
- let sql = `
214
- SELECT u.session_id, u.message_text AS prompt, u.executed_at, u.project_path,
215
- a.message_text AS response, a.tool_uses
216
- FROM prompt_executions u
217
- JOIN prompt_executions a ON a.session_id = u.session_id AND a.message_index = u.message_index + 1
218
- WHERE u.role = 'user' AND a.role = 'assistant'
219
- AND length(u.message_text) >= 20 AND length(a.message_text) >= 20
220
- `;
221
- if (since) { sql += ` AND u.executed_at > ?`; }
222
- sql += ' ORDER BY u.executed_at DESC LIMIT 500';
223
-
224
- const rows = since ? ctmDb.prepare(sql).all(since) : ctmDb.prepare(sql).all();
225
- ctmDb.close();
226
-
227
- return rows.map(row => ({
228
- id: contentHash('ctm', row.prompt),
229
- source: 'ctm-session',
230
- session_id: row.session_id,
231
- timestamp: row.executed_at,
232
- task_type: classifyTaskType(row.prompt),
233
- prompt: row.prompt,
234
- response: row.response,
235
- tool_calls: (() => { try { return JSON.parse(row.tool_uses || '[]'); } catch { return []; } })(),
236
- outcome: 'unknown',
237
- outcome_signal: { git_committed: false, git_diff: null, task_status: null, user_corrected: false },
238
- model: 'claude',
239
- quality_label: 0.7,
240
- }));
241
- } catch (err) {
242
- try { ctmDb.close(); } catch {}
243
- console.error('[harvester] Error reading CTM sessions:', err.message);
244
- return [];
245
- }
246
- }
247
-
248
- // --- Wall-E Chat Harvesting ---
249
-
250
- async function harvestWalleChat(brain, since) {
251
- const messages = brain.listChatMessages ? brain.listChatMessages() : [];
252
- const samples = [];
253
-
254
- // Group by session
255
- const sessions = new Map();
256
- for (const msg of messages) {
257
- if (since && msg.created_at && msg.created_at < since) continue;
258
- const sid = msg.session_id || '__default__';
259
- if (!sessions.has(sid)) sessions.set(sid, []);
260
- sessions.get(sid).push(msg);
261
- }
262
-
263
- for (const [sid, msgs] of sessions) {
264
- for (let i = 0; i < msgs.length - 1; i++) {
265
- const userMsg = msgs[i];
266
- const assistantMsg = msgs[i + 1];
267
- if (userMsg.role !== 'user' || assistantMsg.role !== 'assistant') continue;
268
- if (!userMsg.content || userMsg.content.length < 20) continue;
269
- if (!assistantMsg.content || assistantMsg.content.length < 20) continue;
270
- // Skip tool-use-only messages
271
- if (isToolUseOnly(assistantMsg.content)) continue;
272
-
273
- const id = contentHash('walle-chat', userMsg.content);
274
- samples.push({
275
- id,
276
- source: 'walle-chat',
277
- session_id: sid,
278
- timestamp: userMsg.created_at || new Date().toISOString(),
279
- task_type: classifyTaskType(userMsg.content),
280
- prompt: userMsg.content,
281
- response: assistantMsg.content,
282
- tool_calls: [],
283
- outcome: 'unknown',
284
- outcome_signal: { git_committed: false, git_diff: null, task_status: null, user_corrected: false },
285
- model: assistantMsg.model_id || 'unknown',
286
- quality_label: 0.5,
287
- });
288
- }
289
- }
290
- return samples;
291
- }
292
-
293
- // --- Wall-E Task Harvesting ---
294
-
295
- async function harvestWalleTasks(brain, since) {
296
- const tasks = brain.listTasks ? brain.listTasks({ status: 'completed' }) : [];
297
- const samples = [];
298
-
299
- for (const task of tasks) {
300
- if (!task.result || !task.description) continue;
301
- if (task.description.length < 20) continue;
302
- if (since && task.created_at && task.created_at < since) continue;
303
-
304
- const id = contentHash('walle-task', task.description);
305
- const isSlack = task.source === 'slack';
306
- const quality = isSlack ? 0.8 : 0.7;
307
-
308
- samples.push({
309
- id,
310
- source: 'walle-task',
311
- session_id: task.id,
312
- timestamp: task.created_at || new Date().toISOString(),
313
- task_type: isSlack ? 'slack-reply' : classifyTaskType(task.description),
314
- prompt: task.description,
315
- response: task.result,
316
- tool_calls: [],
317
- outcome: 'completed',
318
- outcome_signal: { git_committed: false, git_diff: null, task_status: task.status, user_corrected: false },
319
- model: 'unknown',
320
- quality_label: quality,
321
- });
322
- }
323
- return samples;
324
- }
325
-
326
- // --- Git Correlation ---
327
-
328
- function findCommitsInWindow(cwd, startTime, endTime) {
329
- try {
330
- const result = execFileSync(
331
- 'git', ['log', `--after=${startTime}`, `--before=${endTime}`, '--format=%H|%s|%aI'],
332
- { cwd, encoding: 'utf8', timeout: 10000, stdio: ['pipe', 'pipe', 'pipe'] }
333
- ).trim();
334
- if (!result) return [];
335
- return result.split('\n').map(line => {
336
- const [hash, subject, date] = line.split('|');
337
- return { hash, subject, date };
338
- });
339
- } catch {
340
- return [];
341
- }
342
- }
343
-
344
- function getCommitDiff(cwd, hash) {
345
- try {
346
- if (!/^[0-9a-f]{7,40}$/i.test(hash)) return null;
347
- const result = execFileSync(
348
- 'git', ['show', '--stat', '--format=', hash],
349
- { cwd, encoding: 'utf8', timeout: 10000, stdio: ['pipe', 'pipe', 'pipe'] }
350
- ).trim();
351
- return result;
352
- } catch {
353
- return null;
354
- }
355
- }
356
-
357
- async function correlateGitOutcomes(samples, cwd) {
358
- if (!cwd || !fs.existsSync(path.join(cwd, '.git'))) return samples;
359
-
360
- for (const sample of samples) {
361
- if (sample.source !== 'claude-code' && sample.source !== 'codex') continue;
362
-
363
- const ts = new Date(sample.timestamp);
364
- const startTime = ts.toISOString();
365
- const endTime = new Date(ts.getTime() + 3600000).toISOString(); // +1 hour window
366
-
367
- const commits = findCommitsInWindow(cwd, startTime, endTime);
368
- if (commits.length > 0) {
369
- sample.outcome = 'committed';
370
- sample.outcome_signal.git_committed = true;
371
- sample.outcome_signal.git_diff = getCommitDiff(cwd, commits[0].hash);
372
- sample.quality_label = 1.0;
373
- }
374
- }
375
- return samples;
376
- }
377
-
378
- // --- Helpers ---
379
-
380
- function findJsonlFiles(dir) {
381
- const results = [];
382
- try {
383
- const entries = fs.readdirSync(dir, { withFileTypes: true, recursive: true });
384
- for (const entry of entries) {
385
- if (entry.isFile() && entry.name.endsWith('.jsonl')) {
386
- // node 20+ returns parentPath, older returns path property
387
- const parent = entry.parentPath || entry.path || dir;
388
- results.push(path.join(parent, entry.name));
389
- }
390
- }
391
- } catch {}
392
- return results;
393
- }
394
-
395
- function extractContent(msg) {
396
- if (typeof msg.content === 'string') return msg.content;
397
- if (Array.isArray(msg.content)) {
398
- const textParts = msg.content
399
- .filter(b => b.type === 'text')
400
- .map(b => b.text);
401
- // Count user-attached non-text blocks (images, documents) so the
402
- // replay path can warn the agent that input was incomplete. Without
403
- // this marker, an agent replaying a multimodal session sees only
404
- // the text portion of the user's prompt and goes off-target — saw
405
- // this burn a real cc-replay (ba1efb8b: user attached an image
406
- // showing a UI bug, walle got just "why auto approver missed this?"
407
- // and edited the wrong file). tool_use/tool_result are assistant
408
- // turn artifacts, not user attachments — don't count them.
409
- const imageCount = msg.content.filter(b => b.type === 'image').length;
410
- const docCount = msg.content.filter(b => b.type === 'document').length;
411
- let text = textParts.join('\n');
412
- if (imageCount > 0 || docCount > 0) {
413
- const parts = [];
414
- if (imageCount > 0) parts.push(`${imageCount} image${imageCount > 1 ? 's' : ''}`);
415
- if (docCount > 0) parts.push(`${docCount} document${docCount > 1 ? 's' : ''}`);
416
- const verb = (imageCount + docCount) > 1 ? 'are' : 'is';
417
- text = `[NOTE: User originally attached ${parts.join(' + ')} that ${verb} NOT visible in this replay. The text below may reference visual content you cannot see (e.g. "this button", "the screenshot shows"). Make BEST-EFFORT PROGRESS on the textual prompt — investigate the codebase, find the most likely intent, and make a concrete change. State your assumption explicitly in the final summary. Do NOT freeze or refuse to edit; producing a wrong edit is more useful for review than no edit at all.]\n\n${text}`;
418
- }
419
- return text;
420
- }
421
- if (msg.message?.content) return extractContent(msg.message);
422
- if (msg.item?.content) {
423
- if (Array.isArray(msg.item.content)) {
424
- return msg.item.content
425
- .filter(b => b.type === 'input_text' || b.type === 'output_text' || b.type === 'text')
426
- .map(b => b.text)
427
- .join('\n');
428
- }
429
- }
430
- return '';
431
- }
432
-
433
- function extractToolCalls(msg) {
434
- if (Array.isArray(msg.content)) {
435
- return msg.content
436
- .filter(b => b.type === 'tool_use')
437
- .map(b => ({ name: b.name, input: b.input }));
438
- }
439
- return [];
440
- }
441
-
442
- function isToolUseOnly(content) {
443
- if (typeof content !== 'string') return false;
444
- try {
445
- const parsed = JSON.parse(content);
446
- if (Array.isArray(parsed)) return parsed.every(b => b.type === 'tool_use');
447
- } catch {}
448
- return false;
449
- }
450
-
451
- // --- Coding Agent Session Harvesting ---
452
-
453
- function scoreCodingSession(session) {
454
- let score = 0;
455
- const toolCalls = session.tool_calls || [];
456
- if (toolCalls.length > 3) score += 0.2;
457
- if (session.git_committed) score += 0.3;
458
- if ((session.turns || 0) > 5) score += 0.1;
459
- // Check for review phase: tool calls that include grep/read after edit/write suggest review
460
- const toolNames = toolCalls.map(t => typeof t === 'string' ? t : t.name || '');
461
- const lastEditIdx = Math.max(
462
- toolNames.lastIndexOf('edit_file'),
463
- toolNames.lastIndexOf('write_file'),
464
- );
465
- const hasReviewAfterEdit = lastEditIdx >= 0 && toolNames.slice(lastEditIdx + 1).some(
466
- n => /read_file|grep|test|npm/.test(n)
467
- );
468
- if (hasReviewAfterEdit) score += 0.1;
469
- if ((session.files_modified || []).length > 1) score += 0.1;
470
- if (!session.user_corrected) score += 0.2;
471
- return Math.min(score, 1);
472
- }
473
-
474
- async function harvestCodingAgentSessions(since) {
475
- const dataDir = process.env.WALL_E_DATA_DIR || path.join(process.env.HOME, '.walle', 'data');
476
- const logDir = path.join(dataDir, 'coding-logs');
477
- if (!fs.existsSync(logDir)) return [];
478
-
479
- const sessions = [];
480
- let files;
481
- try {
482
- files = fs.readdirSync(logDir).filter(f => f.endsWith('.jsonl'));
483
- } catch { return []; }
484
-
485
- for (const file of files) {
486
- const filePath = path.join(logDir, file);
487
- const stat = fs.statSync(filePath);
488
- if (since && stat.mtime < new Date(since)) continue;
489
-
490
- try {
491
- const lines = fs.readFileSync(filePath, 'utf8').split('\n').filter(Boolean);
492
- const turns = lines.map(line => {
493
- try { return JSON.parse(line); } catch { return null; }
494
- }).filter(Boolean);
495
-
496
- if (turns.length === 0) continue;
497
-
498
- // First turn content is the initial prompt
499
- const firstTurn = turns[0];
500
- const prompt = firstTurn.content || '';
501
- if (!prompt || prompt.length < 20) continue;
502
-
503
- // Collect all tool calls across turns
504
- const allToolCalls = [];
505
- const filesModified = new Set();
506
- let hasUserCorrection = false;
507
-
508
- for (const t of turns) {
509
- const tcs = t.toolCalls || [];
510
- for (const tc of tcs) {
511
- allToolCalls.push(tc);
512
- // Track files modified by write/edit tools
513
- const name = tc.name || '';
514
- const input = tc.input || {};
515
- if (/edit_file|write_file|write_to_file/.test(name)) {
516
- const fp = input.path || input.file_path || input.filePath || '';
517
- if (fp) filesModified.add(fp);
518
- }
519
- }
520
- }
521
-
522
- // Check for git commits in the tool calls
523
- const gitCommitted = allToolCalls.some(tc => {
524
- const name = tc.name || '';
525
- const input = tc.input || {};
526
- const cmd = typeof input === 'string' ? input : input.command || '';
527
- return name === 'run_shell' && /git\s+commit/.test(cmd);
528
- });
529
-
530
- // Extract git diff if available
531
- let gitDiff = null;
532
- const diffCall = allToolCalls.find(tc => {
533
- const name = tc.name || '';
534
- const input = tc.input || {};
535
- const cmd = typeof input === 'string' ? input : input.command || '';
536
- return name === 'run_shell' && /git\s+diff/.test(cmd);
537
- });
538
- if (diffCall && diffCall.output) gitDiff = diffCall.output;
539
-
540
- const sessionId = path.basename(file, '.jsonl');
541
- const id = contentHash('coding-agent', `${sessionId}:${prompt}`);
542
-
543
- const session = {
544
- id,
545
- session_id: sessionId,
546
- prompt,
547
- tool_calls: allToolCalls,
548
- turns: turns.length,
549
- files_modified: [...filesModified],
550
- git_committed: gitCommitted,
551
- git_diff: gitDiff,
552
- user_corrected: hasUserCorrection,
553
- created_at: stat.mtime.toISOString(),
554
- };
555
-
556
- session.significance_score = scoreCodingSession(session);
557
- sessions.push(session);
558
- } catch (err) {
559
- console.error(`[harvester] Error parsing coding log ${file}:`, err.message);
560
- }
561
- }
562
-
563
- return sessions;
564
- }
565
-
566
- // --- Main Orchestrator ---
567
-
568
- async function runHarvest({ incremental = true, brain, dataDir } = {}) {
569
- if (!brain) throw new Error('brain is required');
570
- if (!dataDir) {
571
- dataDir = process.env.WALL_E_DATA_DIR || path.join(process.env.HOME, '.walle', 'data');
572
- }
573
-
574
- const outputDir = path.join(dataDir, 'training', 'harvested');
575
- if (!fs.existsSync(outputDir)) fs.mkdirSync(outputDir, { recursive: true });
576
-
577
- const allSamples = [];
578
- const stats = { total: 0, bySource: {}, byTaskType: {} };
579
-
580
- // Determine "since" for incremental harvesting
581
- const getSince = (source) => {
582
- if (!incremental) return null;
583
- const state = brain.getHarvestState(source);
584
- return state?.last_processed_at || null;
585
- };
586
-
587
- // Harvest from each source
588
- const claudeSamples = await harvestClaudeCodeSessions(getSince('claude-code'));
589
- const claudeDesktopSamples = await harvestClaudeDesktopSessions(getSince('claude-desktop'));
590
- const codexSamples = await harvestCodexSessions(getSince('codex'));
591
- const chatSamples = await harvestWalleChat(brain, getSince('walle-chat'));
592
- const taskSamples = await harvestWalleTasks(brain, getSince('walle-task'));
593
- const ctmSamples = await harvestCtmSessions(getSince('ctm-sessions'), dataDir);
594
-
595
- // Harvest coding agent sessions and store in brain
596
- const codingAgentSessions = await harvestCodingAgentSessions(getSince('coding-agent'));
597
- for (const session of codingAgentSessions) {
598
- try {
599
- const { classifyCodingType } = require('./benchmark-generator');
600
- session.classified_type = classifyCodingType(session);
601
- } catch { /* benchmark-generator not loaded yet — use default */ }
602
- if (typeof brain.insertCodingSession === 'function') brain.insertCodingSession(session);
603
- }
604
-
605
- allSamples.push(...claudeSamples, ...claudeDesktopSamples, ...codexSamples, ...chatSamples, ...taskSamples, ...ctmSamples);
606
-
607
- // Deduplicate by content hash
608
- const seen = new Set();
609
- const dedupedSamples = allSamples.filter(s => {
610
- if (seen.has(s.id)) return false;
611
- seen.add(s.id);
612
- return true;
613
- });
614
-
615
- // Build stats
616
- for (const s of dedupedSamples) {
617
- stats.bySource[s.source] = (stats.bySource[s.source] || 0) + 1;
618
- stats.byTaskType[s.task_type] = (stats.byTaskType[s.task_type] || 0) + 1;
619
- }
620
- stats.total = dedupedSamples.length;
621
-
622
- // Write to output file (EAGAIN-safe — data dir may be on Dropbox)
623
- if (dedupedSamples.length > 0) {
624
- const today = new Date().toISOString().slice(0, 10);
625
- const outputPath = path.join(outputDir, `${today}.jsonl`);
626
- const jsonl = dedupedSamples.map(s => JSON.stringify(s)).join('\n') + '\n';
627
- try {
628
- fs.appendFileSync(outputPath, jsonl);
629
- } catch (writeErr) {
630
- console.error(`[harvester] Write failed (${writeErr.code || writeErr.message}), skipping persist`);
631
- }
632
- }
633
-
634
- // Update harvest state for each source (EAGAIN-safe)
635
- const now = new Date().toISOString();
636
- try {
637
- if (claudeSamples.length > 0) {
638
- brain.updateHarvestState('claude-code', { lastProcessedAt: now, totalHarvested: claudeSamples.length });
639
- }
640
- if (claudeDesktopSamples.length > 0) {
641
- brain.updateHarvestState('claude-desktop', { lastProcessedAt: now, totalHarvested: claudeDesktopSamples.length });
642
- }
643
- if (codexSamples.length > 0) {
644
- brain.updateHarvestState('codex', { lastProcessedAt: now, totalHarvested: codexSamples.length });
645
- }
646
- if (chatSamples.length > 0) {
647
- brain.updateHarvestState('walle-chat', { lastProcessedAt: now, totalHarvested: chatSamples.length });
648
- }
649
- if (taskSamples.length > 0) {
650
- brain.updateHarvestState('walle-task', { lastProcessedAt: now, totalHarvested: taskSamples.length });
651
- }
652
- if (ctmSamples.length > 0) {
653
- brain.updateHarvestState('ctm-sessions', { lastProcessedAt: now, totalHarvested: ctmSamples.length });
654
- }
655
- if (codingAgentSessions.length > 0) {
656
- brain.updateHarvestState('coding-agent', { lastProcessedAt: now, totalHarvested: codingAgentSessions.length });
657
- }
658
- } catch (stateErr) {
659
- console.error(`[harvester] State update failed (${stateErr.code || stateErr.message}), will retry next cycle`);
660
- }
661
-
662
- return { samples: dedupedSamples, stats, codingAgentSessions: codingAgentSessions.length };
663
- }
664
-
665
- module.exports = {
666
- classifyTaskType,
667
- contentHash,
668
- harvestClaudeCodeSessions,
669
- harvestClaudeDesktopSessions,
670
- harvestCodexSessions,
671
- harvestCtmSessions,
672
- harvestWalleChat,
673
- harvestWalleTasks,
674
- harvestCodingAgentSessions,
675
- scoreCodingSession,
676
- correlateGitOutcomes,
677
- findCommitsInWindow,
678
- getCommitDiff,
679
- runHarvest,
680
- // Helpers (exported for testing)
681
- extractContent,
682
- extractToolCalls,
683
- isToolUseOnly,
684
- findJsonlFiles,
685
- };