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
@@ -3,7 +3,8 @@ const crypto = require('crypto');
3
3
  const fsp = require('fs/promises');
4
4
  const EventEmitter = require('events');
5
5
  const { looksLikeCompactContinuation } = require('./compact-stitch');
6
- const { codexMessageFromEntry, codexUserKey } = require('./session-history');
6
+ const { codexMessageFromEntry, createCodexUserDeduper } = require('./session-history');
7
+ const { isProviderGeneratedUserContextText } = require('./provider-user-context');
7
8
 
8
9
  const MAX_READ_BYTES = 1024 * 1024; // 1MB cap per incremental read
9
10
  const MAX_TEXT_LEN = 50 * 1024; // 50KB text cap per event
@@ -136,10 +137,17 @@ class JsonlTailer {
136
137
  function extractText(content) {
137
138
  if (typeof content === 'string') return content;
138
139
  if (!Array.isArray(content)) return '';
139
- return content
140
- .filter(b => b.type === 'text')
141
- .map(b => b.text)
142
- .join('\n');
140
+ const parts = [];
141
+ let imageCount = 0;
142
+ for (const block of content) {
143
+ if (!block || typeof block !== 'object') continue;
144
+ if ((block.type === 'text' || block.type === 'input_text' || block.type === 'output_text') && block.text) {
145
+ parts.push(block.text);
146
+ } else if (block.type === 'image' || block.type === 'input_image' || block.type === 'image_ref') {
147
+ parts.push(`[Image #${++imageCount}]`);
148
+ }
149
+ }
150
+ return parts.join('\n');
143
151
  }
144
152
 
145
153
  function stripBase64Blobs(contentBlocks) {
@@ -522,7 +530,7 @@ class SessionStream extends EventEmitter {
522
530
  jsonlPath: jsonlPath || null,
523
531
  ring: [],
524
532
  userPromptCache: [], // Last 10 cleaned user text prompts (survives ring buffer churn)
525
- codexUserSeen: new Set(),
533
+ codexUserDeduper: createCodexUserDeduper(),
526
534
  seq: 0,
527
535
  lastActivity: 0,
528
536
  lastPtyActivity: 0,
@@ -641,6 +649,7 @@ class SessionStream extends EventEmitter {
641
649
  const content = entry.message.content;
642
650
  let text = extractText(content);
643
651
  if (text.length > MAX_TEXT_LEN) text = text.slice(0, MAX_TEXT_LEN) + `...truncated (${text.length} chars)`;
652
+ if (isProviderGeneratedUserContextText(text)) return;
644
653
 
645
654
  const evt = decorateStreamEvent({
646
655
  type: 'user',
@@ -829,9 +838,8 @@ class SessionStream extends EventEmitter {
829
838
  if (!msg) return false;
830
839
 
831
840
  if (msg.role === 'user') {
832
- const key = codexUserKey(msg.text);
833
- if (!key || st.codexUserSeen.has(key)) return true;
834
- st.codexUserSeen.add(key);
841
+ if (!st.codexUserDeduper) st.codexUserDeduper = createCodexUserDeduper();
842
+ if (!st.codexUserDeduper.remember(msg.text, msg.timestamp)) return true;
835
843
  const timestamp = eventTimestampMs({ timestamp: msg.timestamp });
836
844
  const evt = decorateStreamEvent({
837
845
  type: 'user',
@@ -875,6 +883,9 @@ class SessionStream extends EventEmitter {
875
883
  newStatus,
876
884
  reason,
877
885
  timestamp: Date.now(),
886
+ lastActivity: st.lastActivity || 0,
887
+ lastPtyActivity: st.lastPtyActivity || 0,
888
+ lastJsonlActivity: st.lastJsonlActivity || 0,
878
889
  };
879
890
  this.emit('status', statusEvt);
880
891
  }
@@ -952,9 +963,15 @@ class SessionStream extends EventEmitter {
952
963
  const sourceIds = typeof this._dbModule.getSessionConversationSourceIds === 'function'
953
964
  ? this._dbModule.getSessionConversationSourceIds(sessionId, { includeCtmFallback: true })
954
965
  : [sessionId];
966
+ // Prefer the blob-free meta row — the summary path only parses `messages` when the
967
+ // hot ring is incomplete (lazy via _dbMessagesForRow), so pulling the multi-MB blob
968
+ // here on every broadcast was pure waste (~20s of boot CPU, profiled).
969
+ const fetchRow = typeof this._dbModule.getSessionConversationMeta === 'function'
970
+ ? (id) => this._dbModule.getSessionConversationMeta(id)
971
+ : (id) => this._dbModule.getSessionConversation(id);
955
972
  return sourceIds
956
- .map(sourceId => this._dbModule.getSessionConversation(sourceId))
957
- .find(row => row && (row.last_user_content || row.messages || row.first_message)) || null;
973
+ .map(sourceId => fetchRow(sourceId))
974
+ .find(row => row && (row.last_user_content || row.messages_len || row.messages || row.first_message)) || null;
958
975
  } catch {
959
976
  return null;
960
977
  }
@@ -969,6 +986,29 @@ class SessionStream extends EventEmitter {
969
986
  return 0;
970
987
  }
971
988
 
989
+ // Resolve the `messages` JSON blob for a summary row, loading it lazily. A blob-free
990
+ // meta row (from getSessionConversationMeta) carries messages_len but not messages, so
991
+ // we fetch the blob on demand here — only when the caller actually needs the turns.
992
+ _dbMessagesForRow(row) {
993
+ if (!row || typeof row !== 'object') return null;
994
+ if (row.messages) return row.messages; // legacy/full row or test mock
995
+ // Memoize per row so the prompt-entries and turns paths share one blob load per
996
+ // getSummary (a meta row from getSessionConversationMeta has messages_len but no blob).
997
+ if (Object.prototype.hasOwnProperty.call(row, '_lazyMessages')) return row._lazyMessages;
998
+ if (!row.messages_len) { row._lazyMessages = null; return null; }
999
+ const id = row.ctm_session_id;
1000
+ let blob = null;
1001
+ if (id && this._dbModule) {
1002
+ if (typeof this._dbModule.getSessionConversationMessages === 'function') {
1003
+ try { blob = this._dbModule.getSessionConversationMessages(id) || null; } catch { blob = null; }
1004
+ } else if (typeof this._dbModule.getSessionConversation === 'function') {
1005
+ try { blob = this._dbModule.getSessionConversation(id)?.messages || null; } catch { blob = null; }
1006
+ }
1007
+ }
1008
+ row._lazyMessages = blob;
1009
+ return blob;
1010
+ }
1011
+
972
1012
  _latestTurnTimestamp(turns) {
973
1013
  let latest = 0;
974
1014
  for (const turn of Array.isArray(turns) ? turns : []) {
@@ -979,7 +1019,7 @@ class SessionStream extends EventEmitter {
979
1019
  }
980
1020
 
981
1021
  _shouldLoadDbTurnsForSummary(ringTurns, turns, dbRow) {
982
- if (!dbRow || !dbRow.messages) return Array.isArray(ringTurns) ? ringTurns.length < turns : true;
1022
+ if (!dbRow || !(dbRow.messages_len || dbRow.messages)) return Array.isArray(ringTurns) ? ringTurns.length < turns : true;
983
1023
  if (!Array.isArray(ringTurns) || ringTurns.length < turns) return true;
984
1024
  const dbTimestamp = this._dbRowTimestamp(dbRow);
985
1025
  const ringTimestamp = this._latestTurnTimestamp(ringTurns);
@@ -998,9 +1038,15 @@ class SessionStream extends EventEmitter {
998
1038
  if (entry) entries.push(entry);
999
1039
  };
1000
1040
 
1001
- if (row.messages) {
1041
+ // Reuse the blob only if it was ALREADY loaded for this summary (the turns path
1042
+ // loads it when the hot ring is incomplete and memoizes it on the row). Don't
1043
+ // trigger a fresh multi-MB load just for the prompt ledger — last_user_content
1044
+ // carries the same text below, and the hot prompt cache is the authority when the
1045
+ // ring is rich. This keeps the blob to at most one load per getSummary.
1046
+ const rowMessages = row.messages || row._lazyMessages || null;
1047
+ if (rowMessages) {
1002
1048
  try {
1003
- const dbMessages = JSON.parse(row.messages);
1049
+ const dbMessages = JSON.parse(rowMessages);
1004
1050
  if (Array.isArray(dbMessages)) {
1005
1051
  for (let i = dbMessages.length - 1; i >= 0; i--) {
1006
1052
  const m = dbMessages[i];
@@ -1027,10 +1073,11 @@ class SessionStream extends EventEmitter {
1027
1073
 
1028
1074
  _dbTurnsForSummary(sessionId, limit = 6, dbRow) {
1029
1075
  if (arguments.length < 3) dbRow = this._dbConversationRowForSummary(sessionId);
1030
- if (!dbRow || !dbRow.messages) return [];
1076
+ const rowMessages = this._dbMessagesForRow(dbRow);
1077
+ if (!rowMessages) return [];
1031
1078
  try {
1032
1079
  const maxTurns = Math.max(1, Number(limit) || 6);
1033
- const dbMessages = JSON.parse(dbRow.messages);
1080
+ const dbMessages = JSON.parse(rowMessages);
1034
1081
  if (!Array.isArray(dbMessages)) return [];
1035
1082
  return dbMessages
1036
1083
  .filter(m => m && (m.role === 'user' || m.role === 'assistant'))
@@ -1162,6 +1209,7 @@ class SessionStream extends EventEmitter {
1162
1209
  * filters framework preamble. */
1163
1210
  _cleanUserText(text) {
1164
1211
  if (!text) return '';
1212
+ if (isProviderGeneratedUserContextText(text)) return '';
1165
1213
 
1166
1214
  // /compact synthetic user message: discard the entire block, not just the
1167
1215
  // first preamble line. The body that follows ("Summary:\n1. Primary...")
@@ -0,0 +1,260 @@
1
+ 'use strict';
2
+
3
+ const MESSAGE_ROLES = new Set(['user', 'assistant']);
4
+ const RECENT_TURN_LIMIT = 6;
5
+
6
+ function _text(value) {
7
+ return String(value ?? '').replace(/\s+/g, ' ').trim();
8
+ }
9
+
10
+ function _messageText(message) {
11
+ return _text(message?.text ?? message?.content ?? message?.message ?? '');
12
+ }
13
+
14
+ function _timestampMs(value) {
15
+ if (typeof value === 'number' && Number.isFinite(value)) return value;
16
+ const parsed = Date.parse(String(value || ''));
17
+ return Number.isFinite(parsed) ? parsed : 0;
18
+ }
19
+
20
+ function _timestampIso(value) {
21
+ const ms = _timestampMs(value);
22
+ return ms ? new Date(ms).toISOString() : '';
23
+ }
24
+
25
+ function _cleanUserPrompt(text) {
26
+ const cleaned = _text(text)
27
+ .replace(/<image\b[\s\S]*?<\/image>\s*/gi, '')
28
+ .replace(/\[input_image\]\s*/g, '')
29
+ .trim();
30
+ if (!cleaned) return '';
31
+ if (/^this session is being continued from a previous conversation/i.test(cleaned)) return '';
32
+ return cleaned;
33
+ }
34
+
35
+ function _isAckOnlyPrompt(text) {
36
+ const normalized = _text(text).toLowerCase();
37
+ return /^(ok|okay|yes|yep|go ahead|continue|thanks|thank you|done|sounds good|looks good)$/i.test(normalized);
38
+ }
39
+
40
+ function _isContentRichPrompt(text) {
41
+ const cleaned = _cleanUserPrompt(text);
42
+ if (!cleaned || _isAckOnlyPrompt(cleaned)) return false;
43
+ if (cleaned.length >= 24) return true;
44
+ if (/[$/@#]|https?:\/\/|\b(fix|debug|review|implement|test|commit|merge|explain|why|how|what|where|find|update|design|use)\b/i.test(cleaned)) return true;
45
+ return false;
46
+ }
47
+
48
+ function _promptPayload(entry, source, freshness) {
49
+ if (!entry?.text) return null;
50
+ return {
51
+ text: entry.text,
52
+ source,
53
+ freshness,
54
+ confidence: _isContentRichPrompt(entry.text) ? 'medium' : 'low',
55
+ timestamp: entry.timestamp,
56
+ updatedAt: entry.timestamp,
57
+ isContentRich: _isContentRichPrompt(entry.text),
58
+ };
59
+ }
60
+
61
+ function _summaryActivityMs(summary) {
62
+ if (!summary || typeof summary !== 'object') return 0;
63
+ const values = [
64
+ summary.lastActivity,
65
+ summary.progress?.updatedAt,
66
+ summary.currentTask?.updatedAt,
67
+ summary.currentTask?.timestamp,
68
+ summary.currentTask?.promptTimestamp,
69
+ summary.intent?.updatedAt,
70
+ summary.latestPrompt?.updatedAt,
71
+ summary.latestPrompt?.timestamp,
72
+ summary.displayPrompt?.updatedAt,
73
+ summary.displayPrompt?.timestamp,
74
+ summary.aiSummary?.updatedAt,
75
+ ];
76
+ return values.reduce((latest, value) => Math.max(latest, _timestampMs(value)), 0);
77
+ }
78
+
79
+ function _summaryPromptMs(summary) {
80
+ if (!summary || typeof summary !== 'object') return 0;
81
+ return Math.max(
82
+ _timestampMs(summary.latestPrompt?.timestamp || summary.latestPrompt?.updatedAt),
83
+ _timestampMs(summary.displayPrompt?.timestamp || summary.displayPrompt?.updatedAt),
84
+ _timestampMs(summary.currentTask?.promptTimestamp || summary.currentTask?.timestamp),
85
+ _timestampMs(summary.intent?.timestamp || summary.intent?.updatedAt)
86
+ );
87
+ }
88
+
89
+ function _summaryProgressMs(summary) {
90
+ if (!summary || typeof summary !== 'object') return 0;
91
+ return Math.max(
92
+ _timestampMs(summary.progress?.updatedAt),
93
+ _timestampMs(summary.lastActivity)
94
+ );
95
+ }
96
+
97
+ function _hasPrompt(summary) {
98
+ return !!_text(summary?.latestPrompt?.text || summary?.displayPrompt?.text || summary?.lastPrompt || summary?.currentTask?.text);
99
+ }
100
+
101
+ function _hasProgress(summary) {
102
+ return !!_text(summary?.progress?.summary || summary?.progress?.text || summary?.progress || summary?.summary);
103
+ }
104
+
105
+ function summarizeMessagesForTimeline(messages, options = {}) {
106
+ const source = options.source || 'conversation-timeline';
107
+ const freshness = options.freshness || 'durable';
108
+ const sessionId = String(options.sessionId || '').trim();
109
+ const ctmSessionId = String(options.ctmSessionId || sessionId || '').trim();
110
+ const agentSessionId = String(options.agentSessionId || '').trim() || null;
111
+ const turns = [];
112
+
113
+ for (const message of Array.isArray(messages) ? messages : []) {
114
+ const role = String(message?.role || '').trim();
115
+ if (!MESSAGE_ROLES.has(role)) continue;
116
+ const text = role === 'user' ? _cleanUserPrompt(_messageText(message)) : _messageText(message);
117
+ if (!text) continue;
118
+ const timestamp = _timestampMs(message?.timestamp || message?.created_at || message?.createdAt || message?.time);
119
+ const turn = {
120
+ role,
121
+ text,
122
+ timestamp,
123
+ source: message?.source || source,
124
+ };
125
+ turns.push(turn);
126
+ }
127
+
128
+ turns.sort((a, b) => {
129
+ if (a.timestamp && b.timestamp && a.timestamp !== b.timestamp) return a.timestamp - b.timestamp;
130
+ if (a.timestamp && !b.timestamp) return -1;
131
+ if (!a.timestamp && b.timestamp) return 1;
132
+ return 0;
133
+ });
134
+ const userEntries = turns.filter(turn => turn.role === 'user');
135
+ const assistantEntries = turns.filter(turn => turn.role === 'assistant');
136
+
137
+ const latestUser = userEntries[userEntries.length - 1] || null;
138
+ const displayUser = [...userEntries].reverse().find(entry => _isContentRichPrompt(entry.text)) || latestUser;
139
+ const taskUser = latestUser && _isContentRichPrompt(latestUser.text) ? latestUser : displayUser;
140
+ const latestAssistantAfterTask = [...assistantEntries]
141
+ .reverse()
142
+ .find(entry => !taskUser?.timestamp || !entry.timestamp || entry.timestamp >= taskUser.timestamp)
143
+ || assistantEntries[assistantEntries.length - 1]
144
+ || null;
145
+ const latestActivity = turns.reduce((latest, turn) => Math.max(latest, turn.timestamp || 0), 0);
146
+ const latestPrompt = _promptPayload(latestUser, source, freshness);
147
+ const displayPrompt = _promptPayload(displayUser, source, freshness);
148
+ const currentTask = _promptPayload(taskUser, source, freshness) || {
149
+ text: null,
150
+ source,
151
+ freshness: 'missing',
152
+ confidence: 'low',
153
+ timestamp: 0,
154
+ updatedAt: 0,
155
+ promptTimestamp: 0,
156
+ };
157
+ if (currentTask?.text) {
158
+ currentTask.prompt = currentTask.text;
159
+ currentTask.fullPrompt = currentTask.text;
160
+ currentTask.promptTimestamp = currentTask.timestamp || 0;
161
+ }
162
+
163
+ const progress = latestAssistantAfterTask ? {
164
+ phase: '',
165
+ summary: latestAssistantAfterTask.text,
166
+ bullets: [latestAssistantAfterTask.text],
167
+ next: null,
168
+ source,
169
+ updatedAt: latestAssistantAfterTask.timestamp || latestActivity || 0,
170
+ } : {
171
+ phase: '',
172
+ summary: null,
173
+ bullets: [],
174
+ next: null,
175
+ source: 'none',
176
+ updatedAt: 0,
177
+ };
178
+
179
+ return {
180
+ sessionId: agentSessionId || sessionId,
181
+ ctmSessionId,
182
+ agentSessionId,
183
+ summary: null,
184
+ summarySource: null,
185
+ lastPrompt: latestPrompt?.text || '',
186
+ displayPrompt: displayPrompt?.text || '',
187
+ latestPrompt,
188
+ currentTask,
189
+ intent: currentTask?.text ? {
190
+ text: currentTask.text,
191
+ source: currentTask.source,
192
+ freshness: currentTask.freshness,
193
+ confidence: currentTask.confidence,
194
+ prompt: currentTask.text,
195
+ fullPrompt: currentTask.text,
196
+ timestamp: currentTask.timestamp || 0,
197
+ updatedAt: currentTask.updatedAt || 0,
198
+ } : null,
199
+ progress,
200
+ recentTurns: turns.slice(-RECENT_TURN_LIMIT).map(turn => ({
201
+ role: turn.role,
202
+ text: turn.text,
203
+ timestamp: turn.timestamp ? _timestampIso(turn.timestamp) : '',
204
+ source: turn.source,
205
+ })),
206
+ turnCount: turns.length,
207
+ lastActivity: latestActivity,
208
+ timelineSource: source,
209
+ timelineFreshness: freshness,
210
+ };
211
+ }
212
+
213
+ function mergeTimelineSummaries(primary, timeline) {
214
+ if (!primary) return timeline || null;
215
+ if (!timeline) return primary || null;
216
+
217
+ const merged = { ...primary };
218
+ const primaryPromptMs = _summaryPromptMs(primary);
219
+ const timelinePromptMs = _summaryPromptMs(timeline);
220
+ const timelinePromptWins = timelinePromptMs && (!primaryPromptMs || timelinePromptMs >= primaryPromptMs || !_hasPrompt(primary));
221
+ const primaryAiFresh = primary?.aiSummary?.status === 'fresh'
222
+ && _timestampMs(primary.aiSummary.updatedAt) >= timelinePromptMs;
223
+
224
+ if (timelinePromptWins) {
225
+ merged.lastPrompt = timeline.lastPrompt || merged.lastPrompt;
226
+ merged.displayPrompt = timeline.displayPrompt || merged.displayPrompt;
227
+ merged.latestPrompt = timeline.latestPrompt || merged.latestPrompt;
228
+ if (!primaryAiFresh) {
229
+ merged.currentTask = timeline.currentTask || merged.currentTask;
230
+ merged.intent = timeline.intent || merged.intent;
231
+ }
232
+ }
233
+
234
+ const primaryProgressMs = _summaryProgressMs(primary);
235
+ const timelineProgressMs = _summaryProgressMs(timeline);
236
+ if (timelineProgressMs && (!primaryProgressMs || timelineProgressMs >= primaryProgressMs || !_hasProgress(primary))) {
237
+ merged.progress = timeline.progress || merged.progress;
238
+ }
239
+
240
+ if ((!Array.isArray(primary.recentTurns) || primary.recentTurns.length === 0) && Array.isArray(timeline.recentTurns)) {
241
+ merged.recentTurns = timeline.recentTurns;
242
+ }
243
+ const latestActivity = Math.max(_summaryActivityMs(primary), _summaryActivityMs(timeline));
244
+ if (latestActivity) merged.lastActivity = latestActivity;
245
+ merged.timelineSource = timeline.timelineSource || merged.timelineSource;
246
+ merged.timelineFreshness = timeline.timelineFreshness || merged.timelineFreshness;
247
+ return merged;
248
+ }
249
+
250
+ module.exports = {
251
+ summarizeMessagesForTimeline,
252
+ mergeTimelineSummaries,
253
+ _private: {
254
+ _cleanUserPrompt,
255
+ _isContentRichPrompt,
256
+ _summaryActivityMs,
257
+ _summaryPromptMs,
258
+ _summaryProgressMs,
259
+ },
260
+ };