@xopcai/xopc 0.0.124 → 0.0.126

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 (496) hide show
  1. package/README.md +56 -102
  2. package/README.zh-CN.md +51 -98
  3. package/dist/browser-ext/manifest.json +1 -1
  4. package/dist/extensions/feishu/src/schema/config-schema.d.ts +6 -6
  5. package/dist/extensions/feishu/src/workflow-progress.js +1 -1
  6. package/dist/extensions/telegram/src/adapters/streaming-adapter.js +1 -1
  7. package/dist/extensions/telegram/src/config-schema.d.ts +8 -8
  8. package/dist/extensions/telegram/src/inbound-processor.js +1 -1
  9. package/dist/extensions/telegram/src/plugin.js +1 -1
  10. package/dist/extensions/telegram/src/routing-integration.js +2 -2
  11. package/dist/extensions/telegram/src/workflow-progress.js +1 -1
  12. package/dist/extensions/telegram/xopc.extension.json +1 -1
  13. package/dist/extensions/weixin/src/api/api.js +1 -1
  14. package/dist/extensions/weixin/src/config-schema.d.ts +3 -3
  15. package/dist/extensions/weixin/src/plugin.js +1 -1
  16. package/dist/extensions/weixin/src/workflow-progress.js +1 -1
  17. package/dist/gateway/static/root/assets/Combination-BzaXOLd9.js +41 -0
  18. package/dist/gateway/static/root/assets/{agent-avatar-dicebear-B5uSVAyJ.js → agent-avatar-dicebear-C70vgt60.js} +1 -1
  19. package/dist/gateway/static/root/assets/agents-DRYVahI-.js +2 -0
  20. package/dist/gateway/static/root/assets/app-management-settings-panel-D9-HW6cy.js +1 -0
  21. package/dist/gateway/static/root/assets/appearance-settings-BHlahIDL.js +1 -0
  22. package/dist/gateway/static/root/assets/apps-page-BdJ1eQg3.js +1 -0
  23. package/dist/gateway/static/root/assets/{archive-plugin-CXUGRp2i.js → archive-plugin-B-aoIt0w.js} +1 -1
  24. package/dist/gateway/static/root/assets/{attachment-load-Cmiub3Wg.js → attachment-load-BD0G0FD5.js} +1 -1
  25. package/dist/gateway/static/root/assets/automation-suggestion-card-iJRVI7aZ.js +1 -0
  26. package/dist/gateway/static/root/assets/automations-page-D8hYQbkl.js +4 -0
  27. package/dist/gateway/static/root/assets/{binary-plugins-0Izz-N3p.js → binary-plugins-B0mNlVSz.js} +1 -1
  28. package/dist/gateway/static/root/assets/{block-editor-C1Kv0IkJ.js → block-editor-CJY9Lu5G.js} +3 -3
  29. package/dist/gateway/static/root/assets/browser-settings-page-CiWEO-Iy.js +8 -0
  30. package/dist/gateway/static/root/assets/capability-presets-api-Bgc8ag55.js +1 -0
  31. package/dist/gateway/static/root/assets/capability-presets-settings-panel-B1nIi0TC.js +1 -0
  32. package/dist/gateway/static/root/assets/{channel-recipient-api-BeA2aVor.js → channel-recipient-api-0sauApoC.js} +1 -1
  33. package/dist/gateway/static/root/assets/channels-settings-BddPdqVo.js +1 -0
  34. package/dist/gateway/static/root/assets/code-editor-gbRgS14t.js +1 -0
  35. package/dist/gateway/static/root/assets/connectors-page-Ba2GDhSE.js +2 -0
  36. package/dist/gateway/static/root/assets/{directory-picker-path-field-2rjzUu57.js → directory-picker-path-field-CiEc4KmY.js} +1 -1
  37. package/dist/gateway/static/root/assets/dist-By6Rh2ee.js +1 -0
  38. package/dist/gateway/static/root/assets/dist-CkobR7mk.js +1 -0
  39. package/dist/gateway/static/root/assets/dist-DokQNVMQ.js +1 -0
  40. package/dist/gateway/static/root/assets/dreaming-settings-4bvpk5wr.js +3 -0
  41. package/dist/gateway/static/root/assets/extension-debug-page-BbyczVZ3.js +1 -0
  42. package/dist/gateway/static/root/assets/extension-page-DLN1I3DR.js +1 -0
  43. package/dist/gateway/static/root/assets/extension-settings-page-D9VGHmYJ.js +1 -0
  44. package/dist/gateway/static/root/assets/{fetch-BU5S0Sn7.js → fetch-5V96dUz3.js} +1 -1
  45. package/dist/gateway/static/root/assets/{gateway-config-api-BIPGwrl1.js → gateway-config-api-BtIzObwp.js} +1 -1
  46. package/dist/gateway/static/root/assets/gateway-settings-KFsGGDhg.js +1 -0
  47. package/dist/gateway/static/root/assets/{gateway-startup-retry-Cd0Zz30N.js → gateway-startup-retry-DEMad2wt.js} +1 -1
  48. package/dist/gateway/static/root/assets/goal-create-dialog-4PcF6Sh6.js +1 -0
  49. package/dist/gateway/static/root/assets/goal-detail-page-B482PSaG.js +1 -0
  50. package/dist/gateway/static/root/assets/{goals-config-api-B95KdGMj.js → goals-config-api-CVN7-pdM.js} +1 -1
  51. package/dist/gateway/static/root/assets/goals-page-CUdgJuDn.js +2 -0
  52. package/dist/gateway/static/root/assets/goals-settings-IYCH3-Pi.js +1 -0
  53. package/dist/gateway/static/root/assets/heartbeat-settings-Cf_a2Bmz.js +1 -0
  54. package/dist/gateway/static/root/assets/{html-workspace-editor-CQLWDiwE.js → html-workspace-editor-DV90ddkE.js} +1 -1
  55. package/dist/gateway/static/root/assets/index-CA2tR2vm.js +256 -0
  56. package/dist/gateway/static/root/assets/index-Ds3u0LOk.css +1 -0
  57. package/dist/gateway/static/root/assets/keyboard-shortcuts-settings-lKTg6St7.js +1 -0
  58. package/dist/gateway/static/root/assets/logs-page-BCporcNH.js +2 -0
  59. package/dist/gateway/static/root/assets/{markdown-editor-AssmZFx4.js → markdown-editor-BFOjBBla.js} +2 -2
  60. package/dist/gateway/static/root/assets/markdown-split-Bv4k6iGJ.js +1 -0
  61. package/dist/gateway/static/root/assets/{media-plugins-BhIQU5yS.js → media-plugins-Bbi8g3N8.js} +1 -1
  62. package/dist/gateway/static/root/assets/messages-C22hxE1N.js +3 -0
  63. package/dist/gateway/static/root/assets/models-hub-panel-D68Pyow7.js +2 -0
  64. package/dist/gateway/static/root/assets/notes-page-CuUMOiyv.js +1 -0
  65. package/dist/gateway/static/root/assets/notes-workbench-Dx2N5zTk.js +2 -0
  66. package/dist/gateway/static/root/assets/page-tabs-Cp395RYD.js +1 -0
  67. package/dist/gateway/static/root/assets/{preview-open-alternatives-DGzet1d7.js → preview-open-alternatives-DqV5OM4m.js} +1 -1
  68. package/dist/gateway/static/root/assets/project-detail-page-sB8AzZi3.js +1 -0
  69. package/dist/gateway/static/root/assets/projects-page-LBnJqWK2.js +1 -0
  70. package/dist/gateway/static/root/assets/remote-access-hub-Dbj0o6SC.js +1 -0
  71. package/dist/gateway/static/root/assets/{save-bar-controls-Cqgb-jqa.js → save-bar-controls-BItmzAzI.js} +1 -1
  72. package/dist/gateway/static/root/assets/{schedule-field-DVZcI8Yt.js → schedule-field-BQ8IjjCn.js} +1 -1
  73. package/dist/gateway/static/root/assets/{schema-form-Bj7sOxC8.js → schema-form-BRpD6x3d.js} +1 -1
  74. package/dist/gateway/static/root/assets/sessions-page-DhDZKspB.js +1 -0
  75. package/dist/gateway/static/root/assets/settings-advanced-gate-BvXLMNL6.js +1 -0
  76. package/dist/gateway/static/root/assets/{settings-collapsible-section-BmXn-8N6.js → settings-collapsible-section-BKSPQM4R.js} +1 -1
  77. package/dist/gateway/static/root/assets/settings-form-section-BmyfthNQ.js +1 -0
  78. package/dist/gateway/static/root/assets/settings-page-Cfm9UxAr.js +1 -0
  79. package/dist/gateway/static/root/assets/settings-page-layout-Bls5tfbH.js +1 -0
  80. package/dist/gateway/static/root/assets/setup-status-panel-kQEsTGAs.js +1 -0
  81. package/dist/gateway/static/root/assets/{share-preview-page-IB1v8i86.js → share-preview-page-DbYZNAPb.js} +1 -1
  82. package/dist/gateway/static/root/assets/shares-settings-BtR4B0kn.js +1 -0
  83. package/dist/gateway/static/root/assets/skill-reload-api-CJNVOWoK.js +1 -0
  84. package/dist/gateway/static/root/assets/skills-page-DcWDHrt3.js +2 -0
  85. package/dist/gateway/static/root/assets/{system-settings-panel-BxQ384RC.js → system-settings-panel-DKDAojWM.js} +1 -1
  86. package/dist/gateway/static/root/assets/{typed-models-lib-BkcpvFYO.js → typed-models-lib-BCCV4Kkp.js} +1 -1
  87. package/dist/gateway/static/root/assets/{use-channel-catalog-Cd0FaEQ4.js → use-channel-catalog-NBqg3iFY.js} +1 -1
  88. package/dist/gateway/static/root/assets/{user-profile-settings-panel-DQ7NnRSY.js → user-profile-settings-panel-suQ2x-LB.js} +1 -1
  89. package/dist/gateway/static/root/assets/{utils-YKhVf7Ka.js → utils-DPGVr3tS.js} +1 -1
  90. package/dist/gateway/static/root/assets/{vendor-codemirror-CNP1wPe7.js → vendor-codemirror-BvNgyE1Q.js} +1 -1
  91. package/dist/gateway/static/root/assets/voice-api-key-field-DaJASKFP.js +1 -0
  92. package/dist/gateway/static/root/assets/work-item-detail-page-BrCZpAWh.js +1 -0
  93. package/dist/gateway/static/root/assets/workflow-run-setup-panel-BTkRVNAh.js +3 -0
  94. package/dist/gateway/static/root/assets/{workflow-start-dialog-BNJVCWoS.js → workflow-start-dialog-DAImVtdO.js} +1 -1
  95. package/dist/gateway/static/root/assets/workflows-page-vyJ8wSXm.js +18 -0
  96. package/dist/gateway/static/root/index.html +8 -7
  97. package/dist/package.js +1 -1
  98. package/dist/src/activity/context.d.ts +11 -0
  99. package/dist/src/activity/context.js +36 -0
  100. package/dist/src/activity/context.js.map +1 -0
  101. package/dist/src/activity/emitter.d.ts +6 -0
  102. package/dist/src/activity/emitter.js +43 -0
  103. package/dist/src/activity/emitter.js.map +1 -0
  104. package/dist/src/activity/index.d.ts +3 -0
  105. package/dist/src/activity/index.js +3 -0
  106. package/dist/src/activity/service.d.ts +12 -0
  107. package/dist/src/activity/service.js +59 -0
  108. package/dist/src/activity/service.js.map +1 -0
  109. package/dist/src/activity/types.d.ts +109 -0
  110. package/dist/src/activity/types.js +1 -0
  111. package/dist/src/agent/agent-manager.d.ts +7 -0
  112. package/dist/src/agent/agent-manager.js +12 -5
  113. package/dist/src/agent/agent-manager.js.map +1 -1
  114. package/dist/src/agent/child-agent-factory.d.ts +2 -0
  115. package/dist/src/agent/child-agent-factory.js +2 -0
  116. package/dist/src/agent/child-agent-factory.js.map +1 -1
  117. package/dist/src/agent/coding/index.d.ts +1 -0
  118. package/dist/src/agent/coding/index.js +2 -0
  119. package/dist/src/agent/coding/turn-diff-tracker.d.ts +67 -0
  120. package/dist/src/agent/coding/turn-diff-tracker.js +233 -0
  121. package/dist/src/agent/coding/turn-diff-tracker.js.map +1 -0
  122. package/dist/src/agent/context/project-context.js +2 -2
  123. package/dist/src/agent/context/workspace-seed.js +2 -2
  124. package/dist/src/agent/embedded/run-for-session.js +1 -1
  125. package/dist/src/agent/goals/post-turn.js +2 -2
  126. package/dist/src/agent/ipc/bus.js +1 -1
  127. package/dist/src/agent/mcp/bundle-mcp-materialize.js +1 -1
  128. package/dist/src/agent/mcp/bundle-mcp-runtime.js +1 -1
  129. package/dist/src/agent/mcp/mcp-transport-config.js +1 -1
  130. package/dist/src/agent/mcp/mcp-transport.js +1 -1
  131. package/dist/src/agent/memory/dreaming/config.d.ts +2 -2
  132. package/dist/src/agent/memory/dreaming/config.js +3 -3
  133. package/dist/src/agent/memory/dreaming/config.js.map +1 -1
  134. package/dist/src/agent/memory/dreaming/constants.d.ts +1 -1
  135. package/dist/src/agent/memory/dreaming/constants.js +1 -1
  136. package/dist/src/agent/memory/dreaming/constants.js.map +1 -1
  137. package/dist/src/agent/memory/dreaming/deep-promotion.d.ts +1 -0
  138. package/dist/src/agent/memory/dreaming/deep-promotion.js +11 -20
  139. package/dist/src/agent/memory/dreaming/deep-promotion.js.map +1 -1
  140. package/dist/src/agent/memory/dreaming/events.d.ts +3 -3
  141. package/dist/src/agent/memory/dreaming/events.js +6 -6
  142. package/dist/src/agent/memory/dreaming/events.js.map +1 -1
  143. package/dist/src/agent/memory/dreaming/last-run.d.ts +2 -2
  144. package/dist/src/agent/memory/dreaming/last-run.js +1 -1
  145. package/dist/src/agent/memory/dreaming/last-run.js.map +1 -1
  146. package/dist/src/agent/memory/dreaming/light-sweep.d.ts +1 -1
  147. package/dist/src/agent/memory/dreaming/light-sweep.js +3 -3
  148. package/dist/src/agent/memory/dreaming/light-sweep.js.map +1 -1
  149. package/dist/src/agent/memory/dreaming/preview.d.ts +1 -0
  150. package/dist/src/agent/memory/dreaming/preview.js +2 -2
  151. package/dist/src/agent/memory/dreaming/preview.js.map +1 -1
  152. package/dist/src/agent/memory/dreaming/rem-patterns.d.ts +1 -1
  153. package/dist/src/agent/memory/dreaming/rem-patterns.js +13 -13
  154. package/dist/src/agent/memory/dreaming/rem-patterns.js.map +1 -1
  155. package/dist/src/agent/memory/dreaming/scope.d.ts +14 -0
  156. package/dist/src/agent/memory/dreaming/scope.js +27 -0
  157. package/dist/src/agent/memory/dreaming/scope.js.map +1 -0
  158. package/dist/src/agent/memory/dreaming/short-term-store.d.ts +4 -4
  159. package/dist/src/agent/memory/dreaming/short-term-store.js +17 -17
  160. package/dist/src/agent/memory/dreaming/short-term-store.js.map +1 -1
  161. package/dist/src/agent/memory/plugin-discovery.js +1 -1
  162. package/dist/src/agent/models/manager.js +1 -1
  163. package/dist/src/agent/orchestration/agent-event-handler.d.ts +2 -0
  164. package/dist/src/agent/orchestration/agent-event-handler.js +13 -0
  165. package/dist/src/agent/orchestration/agent-event-handler.js.map +1 -1
  166. package/dist/src/agent/orchestration/agent-orchestrator.js +22 -12
  167. package/dist/src/agent/orchestration/agent-orchestrator.js.map +1 -1
  168. package/dist/src/agent/sandbox/command-validator.js +12 -0
  169. package/dist/src/agent/sandbox/command-validator.js.map +1 -1
  170. package/dist/src/agent/service.d.ts +2 -1
  171. package/dist/src/agent/service.js +24 -9
  172. package/dist/src/agent/service.js.map +1 -1
  173. package/dist/src/agent/service.types.d.ts +7 -0
  174. package/dist/src/agent/session/session-inspector.d.ts +5 -3
  175. package/dist/src/agent/session/session-inspector.js +17 -8
  176. package/dist/src/agent/session/session-inspector.js.map +1 -1
  177. package/dist/src/agent/skills/hub-pull.js +1 -1
  178. package/dist/src/agent/source-context/types.d.ts +1 -1
  179. package/dist/src/agent/source-context/types.js +1 -1
  180. package/dist/src/agent/source-context/types.js.map +1 -1
  181. package/dist/src/agent/tool-manuals/index.js +15 -6
  182. package/dist/src/agent/tool-manuals/index.js.map +1 -1
  183. package/dist/src/agent/tool-manuals/xopc-use.d.ts +1 -0
  184. package/dist/src/agent/tool-manuals/xopc-use.js +204 -0
  185. package/dist/src/agent/tool-manuals/xopc-use.js.map +1 -0
  186. package/dist/src/agent/tools/apply-patch.js +116 -62
  187. package/dist/src/agent/tools/apply-patch.js.map +1 -1
  188. package/dist/src/agent/tools/concurrency.d.ts +8 -0
  189. package/dist/src/agent/tools/concurrency.js +31 -0
  190. package/dist/src/agent/tools/concurrency.js.map +1 -0
  191. package/dist/src/agent/tools/dreaming-tool.d.ts +2 -0
  192. package/dist/src/agent/tools/dreaming-tool.js +13 -10
  193. package/dist/src/agent/tools/dreaming-tool.js.map +1 -1
  194. package/dist/src/agent/tools/exec-command.js +4 -0
  195. package/dist/src/agent/tools/exec-command.js.map +1 -1
  196. package/dist/src/agent/tools/executor.d.ts +6 -4
  197. package/dist/src/agent/tools/executor.js +7 -4
  198. package/dist/src/agent/tools/executor.js.map +1 -1
  199. package/dist/src/agent/tools/factory.d.ts +10 -0
  200. package/dist/src/agent/tools/factory.js +16 -1
  201. package/dist/src/agent/tools/factory.js.map +1 -1
  202. package/dist/src/agent/tools/find.js +2 -0
  203. package/dist/src/agent/tools/find.js.map +1 -1
  204. package/dist/src/agent/tools/goal-tool.js +2 -2
  205. package/dist/src/agent/tools/grep.js +2 -0
  206. package/dist/src/agent/tools/grep.js.map +1 -1
  207. package/dist/src/agent/tools/index.d.ts +3 -0
  208. package/dist/src/agent/tools/index.js +4 -1
  209. package/dist/src/agent/tools/list-dir.js +2 -0
  210. package/dist/src/agent/tools/list-dir.js.map +1 -1
  211. package/dist/src/agent/tools/memory-tool.d.ts +1 -0
  212. package/dist/src/agent/tools/memory-tool.js +2 -2
  213. package/dist/src/agent/tools/memory-tool.js.map +1 -1
  214. package/dist/src/agent/tools/metadata.d.ts +15 -0
  215. package/dist/src/agent/tools/metadata.js +26 -0
  216. package/dist/src/agent/tools/metadata.js.map +1 -0
  217. package/dist/src/agent/tools/read.js +2 -0
  218. package/dist/src/agent/tools/read.js.map +1 -1
  219. package/dist/src/agent/tools/workflow-tool.js +1 -1
  220. package/dist/src/agent/tools/write.js +6 -0
  221. package/dist/src/agent/tools/write.js.map +1 -1
  222. package/dist/src/agent/tools/xopc-use-tool.d.ts +34 -0
  223. package/dist/src/agent/tools/xopc-use-tool.js +636 -0
  224. package/dist/src/agent/tools/xopc-use-tool.js.map +1 -0
  225. package/dist/src/agent/workflow/subagent-runner.d.ts +1 -0
  226. package/dist/src/agent/workflow/subagent-runner.js +5 -1
  227. package/dist/src/agent/workflow/subagent-runner.js.map +1 -1
  228. package/dist/src/agent/workflow/workflow-child-tools.js +5 -0
  229. package/dist/src/agent/workflow/workflow-child-tools.js.map +1 -1
  230. package/dist/src/agent-manifest/schema.d.ts +27 -27
  231. package/dist/src/automations/api/routes.js +1 -1
  232. package/dist/src/automations/domain/validation.d.ts +55 -55
  233. package/dist/src/automations/draft/automation-draft-validator.d.ts +25 -25
  234. package/dist/src/automations/service/action-executor.js +2 -2
  235. package/dist/src/browser/cdp-local-launcher.js +1 -1
  236. package/dist/src/browser/providers/browser-ext-install.js +3 -3
  237. package/dist/src/browser/providers/cloakbrowser.js +2 -2
  238. package/dist/src/browser/providers/playwright-doctor.js +1 -1
  239. package/dist/src/browser/stealth.js +1 -1
  240. package/dist/src/chat-commands/agent-edit.js +1 -1
  241. package/dist/src/chat-commands/builtins/config.js +1 -1
  242. package/dist/src/chat-commands/builtins/goal.js +2 -2
  243. package/dist/src/chat-commands/context.js +1 -1
  244. package/dist/src/cli/commands/agent.js +1 -1
  245. package/dist/src/cli/commands/doctor/checks/database-schema.js +2 -2
  246. package/dist/src/cli/commands/doctor/checks/session-integrity.js +1 -1
  247. package/dist/src/cli/commands/extension-marketplace.js +1 -1
  248. package/dist/src/cli/commands/extension-pack.js +1 -1
  249. package/dist/src/cli/commands/gateway/lifecycle.js +1 -1
  250. package/dist/src/cli/commands/goal.js +3 -3
  251. package/dist/src/cli/commands/init.js +1 -1
  252. package/dist/src/cli/commands/project.js +4 -4
  253. package/dist/src/config/agent-profile.js +1 -1
  254. package/dist/src/config/gateway-bind.js +1 -1
  255. package/dist/src/config/index.js +1 -1
  256. package/dist/src/config/loader.js +1 -1
  257. package/dist/src/config/models-json.d.ts +14 -14
  258. package/dist/src/config/models-json.js +1 -1
  259. package/dist/src/config/schema.d.ts +60 -60
  260. package/dist/src/connectors/health.d.ts +2 -1
  261. package/dist/src/connectors/health.js +59 -1
  262. package/dist/src/connectors/health.js.map +1 -1
  263. package/dist/src/connectors/install.d.ts +1 -0
  264. package/dist/src/connectors/install.js +28 -1
  265. package/dist/src/connectors/install.js.map +1 -1
  266. package/dist/src/connectors/instances.js +7 -0
  267. package/dist/src/connectors/instances.js.map +1 -1
  268. package/dist/src/connectors/materialize.js +2 -1
  269. package/dist/src/connectors/materialize.js.map +1 -1
  270. package/dist/src/connectors/registries/modelscope.js +38 -13
  271. package/dist/src/connectors/registries/modelscope.js.map +1 -1
  272. package/dist/src/connectors/types.d.ts +2 -0
  273. package/dist/src/daemon/launchd.js +1 -1
  274. package/dist/src/daemon/systemd.js +1 -1
  275. package/dist/src/extensions/discover-extensions.js +1 -1
  276. package/dist/src/extensions/loader.js +2 -2
  277. package/dist/src/gateway/agents-admin.js +1 -1
  278. package/dist/src/gateway/dreaming-automation-reconciler.d.ts +1 -0
  279. package/dist/src/gateway/dreaming-automation-reconciler.js +62 -42
  280. package/dist/src/gateway/dreaming-automation-reconciler.js.map +1 -1
  281. package/dist/src/gateway/hono/app.js +7 -1
  282. package/dist/src/gateway/hono/app.js.map +1 -1
  283. package/dist/src/gateway/hono/lib/config-payload.d.ts +14 -14
  284. package/dist/src/gateway/hono/lib/static-ui.js +1 -1
  285. package/dist/src/gateway/hono/middleware/log-context.js +8 -1
  286. package/dist/src/gateway/hono/middleware/log-context.js.map +1 -1
  287. package/dist/src/gateway/hono/routes/activity.d.ts +14 -0
  288. package/dist/src/gateway/hono/routes/activity.js +72 -0
  289. package/dist/src/gateway/hono/routes/activity.js.map +1 -0
  290. package/dist/src/gateway/hono/routes/connectors.js +46 -2
  291. package/dist/src/gateway/hono/routes/connectors.js.map +1 -1
  292. package/dist/src/gateway/hono/routes/dreaming.js +111 -66
  293. package/dist/src/gateway/hono/routes/dreaming.js.map +1 -1
  294. package/dist/src/gateway/hono/routes/goals.js +1 -1
  295. package/dist/src/gateway/hono/routes/index.js +2 -0
  296. package/dist/src/gateway/hono/routes/index.js.map +1 -1
  297. package/dist/src/gateway/hono/routes/memory.js +2 -2
  298. package/dist/src/gateway/hono/routes/projects.js +903 -50
  299. package/dist/src/gateway/hono/routes/projects.js.map +1 -1
  300. package/dist/src/gateway/hono/routes/sessions.js +102 -2
  301. package/dist/src/gateway/hono/routes/sessions.js.map +1 -1
  302. package/dist/src/gateway/hono/routes/workflows.js +2 -2
  303. package/dist/src/gateway/lock.js +1 -1
  304. package/dist/src/gateway/ports.js +1 -1
  305. package/dist/src/gateway/service/sessions-api.d.ts +10 -0
  306. package/dist/src/gateway/service/sessions-api.js +31 -0
  307. package/dist/src/gateway/service/sessions-api.js.map +1 -1
  308. package/dist/src/gateway/service.js +28 -16
  309. package/dist/src/gateway/service.js.map +1 -1
  310. package/dist/src/goals/goal-store.js +1 -1
  311. package/dist/src/goals/goal-store.js.map +1 -1
  312. package/dist/src/goals/goal-workflow-judge.js +1 -1
  313. package/dist/src/infra/ports.js +1 -1
  314. package/dist/src/infra/ssh-tunnel.js +1 -1
  315. package/dist/src/infra/update-check.js +1 -1
  316. package/dist/src/infra/update-restart.js +1 -1
  317. package/dist/src/mcp/channel-bridge.js +1 -1
  318. package/dist/src/media/store.js +1 -1
  319. package/dist/src/media/store.js.map +1 -1
  320. package/dist/src/media/types.d.ts +1 -1
  321. package/dist/src/media/uri.js +2 -1
  322. package/dist/src/media/uri.js.map +1 -1
  323. package/dist/src/migrations/runner.js +1 -1
  324. package/dist/src/notes/service.js +65 -6
  325. package/dist/src/notes/service.js.map +1 -1
  326. package/dist/src/notes/store.js +1 -1
  327. package/dist/src/projects/project-service.d.ts +2 -1
  328. package/dist/src/projects/project-service.js +59 -2
  329. package/dist/src/projects/project-service.js.map +1 -1
  330. package/dist/src/projects/project-store.d.ts +2 -1
  331. package/dist/src/projects/project-store.js +43 -0
  332. package/dist/src/projects/project-store.js.map +1 -1
  333. package/dist/src/projects/types.d.ts +10 -0
  334. package/dist/src/projects/workspace.js +1 -1
  335. package/dist/src/routing/agent-session-key.js +1 -1
  336. package/dist/src/routing/resolve-route.js +1 -1
  337. package/dist/src/routing/resolve-tui-session-key.js +1 -1
  338. package/dist/src/session/client-history.d.ts +3 -0
  339. package/dist/src/session/client-history.js +24 -9
  340. package/dist/src/session/client-history.js.map +1 -1
  341. package/dist/src/session/init-session-turn.js +1 -1
  342. package/dist/src/session/resolve-session.js +1 -1
  343. package/dist/src/session/session-context-for-llm.d.ts +2 -0
  344. package/dist/src/session/session-context-for-llm.js +14 -1
  345. package/dist/src/session/session-context-for-llm.js.map +1 -1
  346. package/dist/src/session/session-title.js +2 -2
  347. package/dist/src/session/store.js +3 -3
  348. package/dist/src/session/store.js.map +1 -1
  349. package/dist/src/session/types.d.ts +4 -0
  350. package/dist/src/session/types.js.map +1 -1
  351. package/dist/src/storage/sqlite/activity-repository.d.ts +8 -0
  352. package/dist/src/storage/sqlite/activity-repository.js +208 -0
  353. package/dist/src/storage/sqlite/activity-repository.js.map +1 -0
  354. package/dist/src/storage/sqlite/connection.js +1 -1
  355. package/dist/src/storage/sqlite/index.d.ts +1 -0
  356. package/dist/src/storage/sqlite/index.js +2 -1
  357. package/dist/src/storage/sqlite/migrations/022_work_items.sql +61 -0
  358. package/dist/src/storage/sqlite/migrations/023_work_item_attachments.sql +15 -0
  359. package/dist/src/storage/sqlite/migrations/024_activity_events.sql +62 -0
  360. package/dist/src/storage/sqlite/migrations/runner.d.ts +1 -1
  361. package/dist/src/storage/sqlite/migrations/runner.js +3 -3
  362. package/dist/src/storage/sqlite/migrations/runner.js.map +1 -1
  363. package/dist/src/storage/sqlite/migrations/runner.ts +1 -1
  364. package/dist/src/storage/sqlite/row-mappers.js +1 -1
  365. package/dist/src/storage/sqlite/schema.js +1 -1
  366. package/dist/src/storage/sqlite/schema.sql +141 -0
  367. package/dist/src/storage/sqlite/session-repository.js +11 -0
  368. package/dist/src/storage/sqlite/session-repository.js.map +1 -1
  369. package/dist/src/tui/backends/embedded-backend.d.ts +13 -0
  370. package/dist/src/tui/backends/embedded-backend.js +76 -7
  371. package/dist/src/tui/backends/embedded-backend.js.map +1 -1
  372. package/dist/src/tui/backends/gateway-sse-backend.d.ts +13 -0
  373. package/dist/src/tui/backends/gateway-sse-backend.js +53 -0
  374. package/dist/src/tui/backends/gateway-sse-backend.js.map +1 -1
  375. package/dist/src/tui/chat-history.js +16 -3
  376. package/dist/src/tui/chat-history.js.map +1 -1
  377. package/dist/src/tui/clipboard-image.js +1 -1
  378. package/dist/src/tui/components/assistant-message.js +12 -2
  379. package/dist/src/tui/components/assistant-message.js.map +1 -1
  380. package/dist/src/tui/components/chat-log.d.ts +23 -3
  381. package/dist/src/tui/components/chat-log.js +68 -9
  382. package/dist/src/tui/components/chat-log.js.map +1 -1
  383. package/dist/src/tui/components/tool-execution.d.ts +8 -0
  384. package/dist/src/tui/components/tool-execution.js +87 -77
  385. package/dist/src/tui/components/tool-execution.js.map +1 -1
  386. package/dist/src/tui/components/tui-bottom-bar.js +9 -5
  387. package/dist/src/tui/components/tui-bottom-bar.js.map +1 -1
  388. package/dist/src/tui/components/visual-truncate.d.ts +1 -0
  389. package/dist/src/tui/components/visual-truncate.js +28 -1
  390. package/dist/src/tui/components/visual-truncate.js.map +1 -1
  391. package/dist/src/tui/tool-summary.d.ts +22 -0
  392. package/dist/src/tui/tool-summary.js +212 -0
  393. package/dist/src/tui/tool-summary.js.map +1 -0
  394. package/dist/src/tui/tui-backend.d.ts +16 -0
  395. package/dist/src/tui/tui-command-formatters.js +2 -2
  396. package/dist/src/tui/tui-commands.d.ts +9 -0
  397. package/dist/src/tui/tui-commands.js +95 -6
  398. package/dist/src/tui/tui-commands.js.map +1 -1
  399. package/dist/src/tui/tui-picker-overlay.d.ts +1 -0
  400. package/dist/src/tui/tui-picker-overlay.js +36 -1
  401. package/dist/src/tui/tui-picker-overlay.js.map +1 -1
  402. package/dist/src/tui/tui-picker-services.d.ts +13 -0
  403. package/dist/src/tui/tui-run-state.js +11 -0
  404. package/dist/src/tui/tui-run-state.js.map +1 -1
  405. package/dist/src/tui/tui-run-status-format.d.ts +3 -0
  406. package/dist/src/tui/tui-run-status-format.js +33 -0
  407. package/dist/src/tui/tui-run-status-format.js.map +1 -0
  408. package/dist/src/tui/tui-session-actions.d.ts +5 -0
  409. package/dist/src/tui/tui-session-actions.js +24 -0
  410. package/dist/src/tui/tui-session-actions.js.map +1 -1
  411. package/dist/src/tui/tui-timeline-picker.d.ts +19 -0
  412. package/dist/src/tui/tui-timeline-picker.js +81 -0
  413. package/dist/src/tui/tui-timeline-picker.js.map +1 -0
  414. package/dist/src/tui/tui-timeline.d.ts +15 -0
  415. package/dist/src/tui/tui-timeline.js +65 -0
  416. package/dist/src/tui/tui-timeline.js.map +1 -0
  417. package/dist/src/tui/tui-tool-diff.d.ts +15 -0
  418. package/dist/src/tui/tui-tool-diff.js +178 -7
  419. package/dist/src/tui/tui-tool-diff.js.map +1 -1
  420. package/dist/src/tui/tui-types.d.ts +1 -0
  421. package/dist/src/tui/tui-types.js +1 -0
  422. package/dist/src/tui/tui-types.js.map +1 -1
  423. package/dist/src/tui/tui.js +31 -25
  424. package/dist/src/tui/tui.js.map +1 -1
  425. package/dist/src/utils/index.js +1 -1
  426. package/dist/src/utils/logger/index.js +1 -1
  427. package/dist/src/utils/logger/stats.d.ts +3 -3
  428. package/dist/src/utils/logger.js +1 -1
  429. package/dist/src/work-items/agent-context.d.ts +7 -0
  430. package/dist/src/work-items/agent-context.js +75 -0
  431. package/dist/src/work-items/agent-context.js.map +1 -0
  432. package/dist/src/work-items/index.d.ts +4 -0
  433. package/dist/src/work-items/index.js +4 -0
  434. package/dist/src/work-items/types.d.ts +112 -0
  435. package/dist/src/work-items/types.js +1 -0
  436. package/dist/src/work-items/work-item-service.d.ts +35 -0
  437. package/dist/src/work-items/work-item-service.js +277 -0
  438. package/dist/src/work-items/work-item-service.js.map +1 -0
  439. package/dist/src/work-items/work-item-store.d.ts +21 -0
  440. package/dist/src/work-items/work-item-store.js +302 -0
  441. package/dist/src/work-items/work-item-store.js.map +1 -0
  442. package/dist/src/workflows/draft/workflow-draft-service.js +1 -1
  443. package/dist/src/workflows/service/workflow-run-service.js +4 -3
  444. package/dist/src/workflows/service/workflow-run-service.js.map +1 -1
  445. package/dist/src/workflows/service/workflow-session-bridge.js +4 -1
  446. package/dist/src/workflows/service/workflow-session-bridge.js.map +1 -1
  447. package/package.json +5 -5
  448. package/dist/gateway/static/root/assets/Combination-HAlzriaz.js +0 -41
  449. package/dist/gateway/static/root/assets/agents-BjIxt67Z.js +0 -2
  450. package/dist/gateway/static/root/assets/app-management-settings-panel-CYCONLIL.js +0 -1
  451. package/dist/gateway/static/root/assets/appearance-settings-Clw3ryKg.js +0 -1
  452. package/dist/gateway/static/root/assets/apps-page-QICTeGjX.js +0 -1
  453. package/dist/gateway/static/root/assets/automation-suggestion-card-CU0-4nQ-.js +0 -1
  454. package/dist/gateway/static/root/assets/automations-page-Car-jtiz.js +0 -1
  455. package/dist/gateway/static/root/assets/browser-settings-page-CMeBJzlS.js +0 -8
  456. package/dist/gateway/static/root/assets/capability-presets-api-BmQTM9Il.js +0 -1
  457. package/dist/gateway/static/root/assets/capability-presets-settings-panel-DZEJEoCF.js +0 -1
  458. package/dist/gateway/static/root/assets/channels-settings-kkW-xFau.js +0 -1
  459. package/dist/gateway/static/root/assets/code-editor-dZTY2dRW.js +0 -1
  460. package/dist/gateway/static/root/assets/connectors-page-BvaQvO5F.js +0 -2
  461. package/dist/gateway/static/root/assets/dist-Mys7eFJ5.js +0 -1
  462. package/dist/gateway/static/root/assets/dist-wO9a2_ID.js +0 -1
  463. package/dist/gateway/static/root/assets/dreaming-settings-DnHO686d.js +0 -1
  464. package/dist/gateway/static/root/assets/extension-debug-page-BGLRuWVN.js +0 -1
  465. package/dist/gateway/static/root/assets/extension-page-D978ePp9.js +0 -1
  466. package/dist/gateway/static/root/assets/extension-settings-page-B6Ih4Swx.js +0 -1
  467. package/dist/gateway/static/root/assets/gateway-settings-CMEA3r5u.js +0 -1
  468. package/dist/gateway/static/root/assets/goal-create-dialog-B-KHKeXN.js +0 -1
  469. package/dist/gateway/static/root/assets/goal-detail-page-BxrSoWdj.js +0 -1
  470. package/dist/gateway/static/root/assets/goals-page-BTJzIl28.js +0 -2
  471. package/dist/gateway/static/root/assets/goals-settings-BJyEuLLm.js +0 -1
  472. package/dist/gateway/static/root/assets/heartbeat-settings-wkOjYNQT.js +0 -1
  473. package/dist/gateway/static/root/assets/index-BLaXr6Ev.css +0 -1
  474. package/dist/gateway/static/root/assets/index-c_9TVr_C.js +0 -191
  475. package/dist/gateway/static/root/assets/keyboard-shortcuts-settings-BT8T4DyC.js +0 -1
  476. package/dist/gateway/static/root/assets/logs-page-CrxBJUgI.js +0 -2
  477. package/dist/gateway/static/root/assets/markdown-split-Dv66bO2b.js +0 -1
  478. package/dist/gateway/static/root/assets/messages-O6TAtdFC.js +0 -3
  479. package/dist/gateway/static/root/assets/models-hub-panel-DOOpz6y1.js +0 -2
  480. package/dist/gateway/static/root/assets/notes-page-Br16pK9v.js +0 -1
  481. package/dist/gateway/static/root/assets/notes-workbench-PSJAi0ZC.js +0 -2
  482. package/dist/gateway/static/root/assets/project-detail-page-CIGGgKuw.js +0 -1
  483. package/dist/gateway/static/root/assets/projects-page-B2grhsBt.js +0 -1
  484. package/dist/gateway/static/root/assets/remote-access-hub-CXMORxBD.js +0 -1
  485. package/dist/gateway/static/root/assets/sessions-page-Bi2wkBzU.js +0 -1
  486. package/dist/gateway/static/root/assets/settings-advanced-gate-B1L3G4IA.js +0 -1
  487. package/dist/gateway/static/root/assets/settings-form-section-BnqYMWHR.js +0 -1
  488. package/dist/gateway/static/root/assets/settings-page-BfRSHJmO.js +0 -1
  489. package/dist/gateway/static/root/assets/settings-page-layout-CdWZU1hd.js +0 -1
  490. package/dist/gateway/static/root/assets/setup-status-panel-CWtPM7RK.js +0 -1
  491. package/dist/gateway/static/root/assets/shares-settings-ngbsBgij.js +0 -1
  492. package/dist/gateway/static/root/assets/skill-reload-api-BIe442Gv.js +0 -1
  493. package/dist/gateway/static/root/assets/skills-page-BfchZRVa.js +0 -2
  494. package/dist/gateway/static/root/assets/voice-api-key-field-C5Ov8Uk_.js +0 -1
  495. package/dist/gateway/static/root/assets/workflow-run-setup-panel-BYD9BtOq.js +0 -3
  496. package/dist/gateway/static/root/assets/workflows-page-BYF29ANm.js +0 -18
@@ -47,14 +47,14 @@ async function runDreamingDeepPromotion(params) {
47
47
  const now = params.now ?? /* @__PURE__ */ new Date();
48
48
  const startedAt = now.toISOString();
49
49
  const runId = `${startedAt}:${process.pid}:${Math.random().toString(16).slice(2)}`;
50
- const memoryPath = path.join(params.workspaceDir, MEMORY_MD_FILENAME);
50
+ const memoryPath = path.join(params.dreamingRoot, MEMORY_MD_FILENAME);
51
51
  const t0 = Date.now();
52
52
  const earlyExitReason = !cfg.enabled ? "dreaming disabled" : cfg.limit === 0 ? "dreaming limit=0" : null;
53
53
  if (earlyExitReason) {
54
54
  const finishedAt = (/* @__PURE__ */ new Date()).toISOString();
55
55
  const empty = emptyDeepPhaseSkipped();
56
56
  await writeDreamingDeepLastRun({
57
- workspaceDir: params.workspaceDir,
57
+ dreamingRoot: params.dreamingRoot,
58
58
  lastRun: buildDeepLastRun({
59
59
  runId,
60
60
  startedAt,
@@ -80,8 +80,8 @@ async function runDreamingDeepPromotion(params) {
80
80
  };
81
81
  }
82
82
  try {
83
- const result = await withDreamingPromotionLock(params.workspaceDir, async () => {
84
- const { store } = await loadDreamingStore({ workspaceDir: params.workspaceDir });
83
+ const result = await withDreamingPromotionLock(params.dreamingRoot, async () => {
84
+ const { store } = await loadDreamingStore({ dreamingRoot: params.dreamingRoot });
85
85
  const nowMs = now.getTime();
86
86
  const ranked = Object.values(store.entries ?? {}).filter((e) => {
87
87
  if (!e || typeof e !== "object") return false;
@@ -155,7 +155,7 @@ async function runDreamingDeepPromotion(params) {
155
155
  }
156
156
  if (appliedCandidates.length === 0) {
157
157
  await saveDreamingStore({
158
- workspaceDir: params.workspaceDir,
158
+ dreamingRoot: params.dreamingRoot,
159
159
  store
160
160
  });
161
161
  return {
@@ -181,23 +181,13 @@ async function runDreamingDeepPromotion(params) {
181
181
  }
182
182
  sectionLines.push("");
183
183
  const next = `${header}${existing.endsWith("\n") || existing.length === 0 ? existing : `${existing}\n`}${sectionLines.join("\n")}`;
184
+ await fs.mkdir(path.dirname(memoryPath), { recursive: true });
184
185
  await fs.writeFile(memoryPath, next, "utf-8");
185
186
  const nowIso = now.toISOString();
186
187
  for (const c of appliedCandidates) {
187
- const writeResult = await params.memoryManager?.write({
188
- kind: "derived_insight",
189
- content: c.snippet,
190
- source: {
191
- provider: "dreaming",
192
- path: c.path,
193
- lineStart: c.startLine,
194
- lineEnd: c.endLine
195
- },
196
- tags: ["dreaming", "promoted"]
197
- });
198
188
  params.memoryManager?.recordSignal({
199
189
  source: "dreaming",
200
- recordId: writeResult?.record?.id,
190
+ recordId: `dreaming:${c.key}`,
201
191
  score: c.score,
202
192
  content: c.snippet,
203
193
  metadata: {
@@ -218,11 +208,12 @@ async function runDreamingDeepPromotion(params) {
218
208
  }
219
209
  store.updatedAt = nowIso;
220
210
  await saveDreamingStore({
221
- workspaceDir: params.workspaceDir,
211
+ dreamingRoot: params.dreamingRoot,
222
212
  store
223
213
  });
224
214
  log.info({
225
215
  workspaceDir: params.workspaceDir,
216
+ dreamingRoot: params.dreamingRoot,
226
217
  candidates: ranked.length,
227
218
  applied: appliedCandidates.length
228
219
  }, "Dreaming deep promotion complete");
@@ -239,7 +230,7 @@ async function runDreamingDeepPromotion(params) {
239
230
  const empty = emptyDeepPhaseSkipped();
240
231
  const resultSkipped = "skipped" in result ? result.skipped : empty;
241
232
  await writeDreamingDeepLastRun({
242
- workspaceDir: params.workspaceDir,
233
+ dreamingRoot: params.dreamingRoot,
243
234
  lastRun: buildDeepLastRun({
244
235
  runId,
245
236
  startedAt,
@@ -268,7 +259,7 @@ async function runDreamingDeepPromotion(params) {
268
259
  const em = err instanceof Error ? err.message : String(err);
269
260
  const z = emptyDeepPhaseSkipped();
270
261
  await writeDreamingDeepLastRun({
271
- workspaceDir: params.workspaceDir,
262
+ dreamingRoot: params.dreamingRoot,
272
263
  lastRun: buildDeepLastRun({
273
264
  runId,
274
265
  startedAt,
@@ -1 +1 @@
1
- {"version":3,"file":"deep-promotion.js","names":[],"sources":["../../../../../src/agent/memory/dreaming/deep-promotion.ts"],"sourcesContent":["import fs from 'node:fs/promises';\nimport path from 'node:path';\n\nimport { createLogger } from '../../../utils/logger.js';\nimport { MEMORY_MD_FILENAME } from './constants.js';\nimport {\n loadDreamingStore,\n saveDreamingStore,\n withDreamingPromotionLock,\n type DreamingStoreEntry,\n} from './short-term-store.js';\nimport {\n DREAMING_LAST_RUN_FORMAT_VERSION,\n emptyDeepPhaseSkipped,\n writeDreamingDeepLastRun,\n type DreamingDeepLastRun,\n type DreamingDeepPhaseSkipped,\n} from './last-run.js';\nimport type { DreamingDeepConfig } from './config.js';\nimport type { MemoryManager } from '../manager.js';\nimport {\n clamp01,\n compareCandidatesByScore,\n computeCandidateScore,\n extractPromotionMarkers,\n isContaminatedSnippet,\n isExpiredEntry,\n isoDay,\n readFileLines,\n resolveDeepDefaults,\n sliceRange,\n snippetHash,\n} from './utils.js';\n\nconst log = createLogger('Dreaming:Deep');\n\nexport type { DreamingDeepConfig } from './config.js';\n\nexport type DreamingPromotionCandidate = DreamingStoreEntry & {\n avgScore: number;\n /** Time-decay-adjusted final score used for ranking. */\n score: number;\n /** Raw recency decay multiplier (0–1). */\n recencyDecay: number;\n};\n\n\nfunction markerForPromotion(key: string, hash: string): string {\n // Quote values to allow spaces/colons in key.\n return `<!-- xopc-memory-promotion key=\"${key}\" hash=\"${hash}\" -->`;\n}\n\n\nasync function rehydrateSnippet(params: {\n workspaceDir: string;\n candidate: DreamingPromotionCandidate;\n}): Promise<{ snippet: string; startLine: number; endLine: number } | null> {\n const fullPath = path.join(params.workspaceDir, params.candidate.path);\n const lines = await readFileLines(fullPath);\n if (!lines) return null;\n\n const startLine = Math.max(1, Math.floor(params.candidate.startLine));\n const endLine = Math.max(startLine, Math.floor(params.candidate.endLine));\n const snippet = sliceRange(lines, startLine, endLine);\n if (!snippet) return null;\n return { snippet, startLine, endLine };\n}\n\n\nfunction buildDeepLastRun(base: {\n runId: string;\n startedAt: string;\n finishedAt: string;\n t0: number;\n ok: boolean;\n reason: string;\n config: DreamingDeepConfig;\n memoryPath: string;\n errorMessage?: string;\n deep: DreamingDeepLastRun['deep'];\n}): DreamingDeepLastRun {\n const durationMs = Math.max(0, Date.now() - base.t0);\n return {\n version: DREAMING_LAST_RUN_FORMAT_VERSION,\n phase: 'deep',\n runId: base.runId,\n startedAt: base.startedAt,\n finishedAt: base.finishedAt,\n durationMs,\n ok: base.ok,\n reason: base.reason,\n config: base.config,\n memoryPath: base.memoryPath,\n ...(base.errorMessage ? { errorMessage: base.errorMessage } : {}),\n deep: base.deep,\n };\n}\n\nexport async function runDreamingDeepPromotion(params: {\n workspaceDir: string;\n config?: Partial<DreamingDeepConfig>;\n memoryManager?: MemoryManager;\n now?: Date;\n}): Promise<{\n ok: boolean;\n reason: string;\n candidates: number;\n applied: number;\n memoryPath: string;\n}> {\n const cfg = resolveDeepDefaults(params.config);\n const now = params.now ?? new Date();\n const startedAt = now.toISOString();\n const runId = `${startedAt}:${process.pid}:${Math.random().toString(16).slice(2)}`;\n const memoryPath = path.join(params.workspaceDir, MEMORY_MD_FILENAME);\n const t0 = Date.now();\n\n // Early exit for disabled or zero-limit configurations.\n const earlyExitReason = !cfg.enabled ? 'dreaming disabled' : cfg.limit === 0 ? 'dreaming limit=0' : null;\n if (earlyExitReason) {\n const finishedAt = new Date().toISOString();\n const empty = emptyDeepPhaseSkipped();\n await writeDreamingDeepLastRun({\n workspaceDir: params.workspaceDir,\n lastRun: buildDeepLastRun({\n runId,\n startedAt,\n finishedAt,\n t0,\n ok: true,\n reason: earlyExitReason,\n config: cfg,\n memoryPath,\n deep: { candidatesRanked: 0, applied: 0, skipped: empty },\n }),\n }).catch(() => undefined);\n return { ok: true, reason: earlyExitReason, candidates: 0, applied: 0, memoryPath };\n }\n\n try {\n const result = await withDreamingPromotionLock(params.workspaceDir, async () => {\n const { store } = await loadDreamingStore({ workspaceDir: params.workspaceDir });\n\n const nowMs = now.getTime();\n\n const all = Object.values(store.entries ?? {}).filter((e): e is DreamingStoreEntry => {\n if (!e || typeof e !== 'object') return false;\n if (e.promotedAt) return false;\n if (!e.path || !e.path.startsWith('memory/')) return false;\n if (e.recallCount < cfg.minRecallCount) return false;\n // Require minimum unique queries to avoid single-query inflation.\n if ((e.queryHashes?.length ?? 0) < cfg.minUniqueQueries) return false;\n // Expire entries older than maxAgeDays since last recall.\n if (isExpiredEntry(e.lastRecalledAt, nowMs, cfg.maxAgeDays)) return false;\n const avg = e.recallCount > 0 ? e.totalScore / e.recallCount : 0;\n return clamp01(avg) >= cfg.minScore;\n });\n\n const ranked: DreamingPromotionCandidate[] = all\n .map((e) => {\n const { avgScore, score, recencyDecay } = computeCandidateScore(e, nowMs, cfg.recencyHalfLifeDays);\n return { ...e, avgScore, score, recencyDecay };\n })\n .sort(compareCandidatesByScore)\n .slice(0, cfg.limit);\n\n if (ranked.length === 0) {\n const z = emptyDeepPhaseSkipped();\n return { ok: true, reason: 'no eligible candidates', candidates: 0, applied: 0, memoryPath, skipped: z };\n }\n\n const existing = await fs.readFile(memoryPath, 'utf-8').catch((err: unknown) => {\n if ((err as NodeJS.ErrnoException | undefined)?.code === 'ENOENT') return '';\n throw err;\n });\n const existingMarkers = extractPromotionMarkers(existing);\n\n const appliedCandidates: Array<{\n key: string;\n hash: string;\n snippet: string;\n path: string;\n startLine: number;\n endLine: number;\n score: number;\n recallCount: number;\n avgScore: number;\n }> = [];\n\n const skipped: DreamingDeepPhaseSkipped = emptyDeepPhaseSkipped();\n for (const candidate of ranked) {\n if (existingMarkers.keys.has(candidate.key)) {\n skipped.alreadyPromotedKey += 1;\n // Treat as already applied; mark promotedAt for idempotency and keep going.\n const entry = store.entries[candidate.key];\n if (entry && !entry.promotedAt) {\n entry.promotedAt = now.toISOString();\n }\n continue;\n }\n const rehydrated = await rehydrateSnippet({ workspaceDir: params.workspaceDir, candidate });\n if (!rehydrated) {\n skipped.rehydrateFailed += 1;\n continue;\n }\n if (isContaminatedSnippet(rehydrated.snippet)) {\n skipped.contaminated += 1;\n continue;\n }\n const hash = snippetHash(rehydrated.snippet);\n if (existingMarkers.hashes.has(hash)) {\n skipped.hashDuplicate += 1;\n // Already promoted (possibly from a different key/line range). Mark promoted for idempotency.\n const entry = store.entries[candidate.key];\n if (entry && !entry.promotedAt) {\n entry.promotedAt = now.toISOString();\n }\n continue;\n }\n appliedCandidates.push({\n key: candidate.key,\n hash,\n snippet: rehydrated.snippet,\n path: candidate.path,\n startLine: rehydrated.startLine,\n endLine: rehydrated.endLine,\n score: candidate.score,\n recallCount: candidate.recallCount,\n avgScore: candidate.avgScore,\n });\n }\n\n if (appliedCandidates.length === 0) {\n await saveDreamingStore({ workspaceDir: params.workspaceDir, store });\n return {\n ok: true,\n reason: 'candidates were stale or already applied',\n candidates: ranked.length,\n applied: 0,\n memoryPath,\n skipped,\n };\n }\n\n const day = isoDay(now);\n const header = existing.trim().length > 0 ? '' : '# Long-Term Memory\\n\\n';\n const sectionLines: string[] = ['', `## Promoted From Short-Term Memory (${day})`, ''];\n for (const c of appliedCandidates) {\n const src = `${c.path}:${c.startLine}-${c.endLine}`;\n sectionLines.push(markerForPromotion(c.key, c.hash));\n sectionLines.push(\n `- ${c.snippet} [score=${c.score.toFixed(3)} recalls=${c.recallCount} avg=${c.avgScore.toFixed(3)} source=${src}]`,\n );\n }\n sectionLines.push('');\n\n const next = `${header}${existing.endsWith('\\n') || existing.length === 0 ? existing : `${existing}\\n`}${sectionLines.join('\\n')}`;\n await fs.writeFile(memoryPath, next, 'utf-8');\n\n const nowIso = now.toISOString();\n for (const c of appliedCandidates) {\n const writeResult = await params.memoryManager?.write({\n kind: 'derived_insight',\n content: c.snippet,\n source: {\n provider: 'dreaming',\n path: c.path,\n lineStart: c.startLine,\n lineEnd: c.endLine,\n },\n tags: ['dreaming', 'promoted'],\n });\n params.memoryManager?.recordSignal({\n source: 'dreaming',\n recordId: writeResult?.record?.id,\n score: c.score,\n content: c.snippet,\n metadata: {\n path: c.path,\n startLine: c.startLine,\n endLine: c.endLine,\n recallCount: c.recallCount,\n avgScore: c.avgScore,\n },\n });\n const entry = store.entries[c.key];\n if (entry) {\n entry.promotedAt = nowIso;\n entry.snippet = c.snippet;\n entry.startLine = c.startLine;\n entry.endLine = c.endLine;\n }\n }\n store.updatedAt = nowIso;\n await saveDreamingStore({ workspaceDir: params.workspaceDir, store });\n\n log.info(\n { workspaceDir: params.workspaceDir, candidates: ranked.length, applied: appliedCandidates.length },\n 'Dreaming deep promotion complete',\n );\n\n return {\n ok: true,\n reason: 'applied promotions',\n candidates: ranked.length,\n applied: appliedCandidates.length,\n memoryPath,\n skipped,\n };\n });\n\n const finishedAt = new Date().toISOString();\n const empty = emptyDeepPhaseSkipped();\n const resultSkipped = 'skipped' in result ? result.skipped : empty;\n await writeDreamingDeepLastRun({\n workspaceDir: params.workspaceDir,\n lastRun: buildDeepLastRun({\n runId,\n startedAt,\n finishedAt,\n t0,\n ok: result.ok,\n reason: result.reason,\n config: cfg,\n memoryPath: result.memoryPath,\n deep: {\n candidatesRanked: result.candidates,\n applied: result.applied,\n skipped: resultSkipped,\n },\n }),\n }).catch(() => undefined);\n\n return {\n ok: result.ok,\n reason: result.reason,\n candidates: result.candidates,\n applied: result.applied,\n memoryPath: result.memoryPath,\n };\n } catch (err) {\n const finishedAt = new Date().toISOString();\n const em = err instanceof Error ? err.message : String(err);\n const z = emptyDeepPhaseSkipped();\n await writeDreamingDeepLastRun({\n workspaceDir: params.workspaceDir,\n lastRun: buildDeepLastRun({\n runId,\n startedAt,\n finishedAt,\n t0,\n ok: false,\n reason: 'error',\n config: cfg,\n memoryPath,\n errorMessage: em,\n deep: { candidatesRanked: 0, applied: 0, skipped: z },\n }),\n }).catch(() => undefined);\n throw err;\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"deep-promotion.js","names":[],"sources":["../../../../../src/agent/memory/dreaming/deep-promotion.ts"],"sourcesContent":["import fs from 'node:fs/promises';\nimport path from 'node:path';\n\nimport { createLogger } from '../../../utils/logger.js';\nimport { MEMORY_MD_FILENAME } from './constants.js';\nimport {\n loadDreamingStore,\n saveDreamingStore,\n withDreamingPromotionLock,\n type DreamingStoreEntry,\n} from './short-term-store.js';\nimport {\n DREAMING_LAST_RUN_FORMAT_VERSION,\n emptyDeepPhaseSkipped,\n writeDreamingDeepLastRun,\n type DreamingDeepLastRun,\n type DreamingDeepPhaseSkipped,\n} from './last-run.js';\nimport type { DreamingDeepConfig } from './config.js';\nimport type { MemoryManager } from '../manager.js';\nimport {\n clamp01,\n compareCandidatesByScore,\n computeCandidateScore,\n extractPromotionMarkers,\n isContaminatedSnippet,\n isExpiredEntry,\n isoDay,\n readFileLines,\n resolveDeepDefaults,\n sliceRange,\n snippetHash,\n} from './utils.js';\n\nconst log = createLogger('Dreaming:Deep');\n\nexport type { DreamingDeepConfig } from './config.js';\n\nexport type DreamingPromotionCandidate = DreamingStoreEntry & {\n avgScore: number;\n /** Time-decay-adjusted final score used for ranking. */\n score: number;\n /** Raw recency decay multiplier (0–1). */\n recencyDecay: number;\n};\n\n\nfunction markerForPromotion(key: string, hash: string): string {\n // Quote values to allow spaces/colons in key.\n return `<!-- xopc-memory-promotion key=\"${key}\" hash=\"${hash}\" -->`;\n}\n\n\nasync function rehydrateSnippet(params: {\n workspaceDir: string;\n candidate: DreamingPromotionCandidate;\n}): Promise<{ snippet: string; startLine: number; endLine: number } | null> {\n const fullPath = path.join(params.workspaceDir, params.candidate.path);\n const lines = await readFileLines(fullPath);\n if (!lines) return null;\n\n const startLine = Math.max(1, Math.floor(params.candidate.startLine));\n const endLine = Math.max(startLine, Math.floor(params.candidate.endLine));\n const snippet = sliceRange(lines, startLine, endLine);\n if (!snippet) return null;\n return { snippet, startLine, endLine };\n}\n\n\nfunction buildDeepLastRun(base: {\n runId: string;\n startedAt: string;\n finishedAt: string;\n t0: number;\n ok: boolean;\n reason: string;\n config: DreamingDeepConfig;\n memoryPath: string;\n errorMessage?: string;\n deep: DreamingDeepLastRun['deep'];\n}): DreamingDeepLastRun {\n const durationMs = Math.max(0, Date.now() - base.t0);\n return {\n version: DREAMING_LAST_RUN_FORMAT_VERSION,\n phase: 'deep',\n runId: base.runId,\n startedAt: base.startedAt,\n finishedAt: base.finishedAt,\n durationMs,\n ok: base.ok,\n reason: base.reason,\n config: base.config,\n memoryPath: base.memoryPath,\n ...(base.errorMessage ? { errorMessage: base.errorMessage } : {}),\n deep: base.deep,\n };\n}\n\nexport async function runDreamingDeepPromotion(params: {\n workspaceDir: string;\n dreamingRoot: string;\n config?: Partial<DreamingDeepConfig>;\n memoryManager?: MemoryManager;\n now?: Date;\n}): Promise<{\n ok: boolean;\n reason: string;\n candidates: number;\n applied: number;\n memoryPath: string;\n}> {\n const cfg = resolveDeepDefaults(params.config);\n const now = params.now ?? new Date();\n const startedAt = now.toISOString();\n const runId = `${startedAt}:${process.pid}:${Math.random().toString(16).slice(2)}`;\n const memoryPath = path.join(params.dreamingRoot, MEMORY_MD_FILENAME);\n const t0 = Date.now();\n\n // Early exit for disabled or zero-limit configurations.\n const earlyExitReason = !cfg.enabled ? 'dreaming disabled' : cfg.limit === 0 ? 'dreaming limit=0' : null;\n if (earlyExitReason) {\n const finishedAt = new Date().toISOString();\n const empty = emptyDeepPhaseSkipped();\n await writeDreamingDeepLastRun({\n dreamingRoot: params.dreamingRoot,\n lastRun: buildDeepLastRun({\n runId,\n startedAt,\n finishedAt,\n t0,\n ok: true,\n reason: earlyExitReason,\n config: cfg,\n memoryPath,\n deep: { candidatesRanked: 0, applied: 0, skipped: empty },\n }),\n }).catch(() => undefined);\n return { ok: true, reason: earlyExitReason, candidates: 0, applied: 0, memoryPath };\n }\n\n try {\n const result = await withDreamingPromotionLock(params.dreamingRoot, async () => {\n const { store } = await loadDreamingStore({ dreamingRoot: params.dreamingRoot });\n\n const nowMs = now.getTime();\n\n const all = Object.values(store.entries ?? {}).filter((e): e is DreamingStoreEntry => {\n if (!e || typeof e !== 'object') return false;\n if (e.promotedAt) return false;\n if (!e.path || !e.path.startsWith('memory/')) return false;\n if (e.recallCount < cfg.minRecallCount) return false;\n // Require minimum unique queries to avoid single-query inflation.\n if ((e.queryHashes?.length ?? 0) < cfg.minUniqueQueries) return false;\n // Expire entries older than maxAgeDays since last recall.\n if (isExpiredEntry(e.lastRecalledAt, nowMs, cfg.maxAgeDays)) return false;\n const avg = e.recallCount > 0 ? e.totalScore / e.recallCount : 0;\n return clamp01(avg) >= cfg.minScore;\n });\n\n const ranked: DreamingPromotionCandidate[] = all\n .map((e) => {\n const { avgScore, score, recencyDecay } = computeCandidateScore(e, nowMs, cfg.recencyHalfLifeDays);\n return { ...e, avgScore, score, recencyDecay };\n })\n .sort(compareCandidatesByScore)\n .slice(0, cfg.limit);\n\n if (ranked.length === 0) {\n const z = emptyDeepPhaseSkipped();\n return { ok: true, reason: 'no eligible candidates', candidates: 0, applied: 0, memoryPath, skipped: z };\n }\n\n const existing = await fs.readFile(memoryPath, 'utf-8').catch((err: unknown) => {\n if ((err as NodeJS.ErrnoException | undefined)?.code === 'ENOENT') return '';\n throw err;\n });\n const existingMarkers = extractPromotionMarkers(existing);\n\n const appliedCandidates: Array<{\n key: string;\n hash: string;\n snippet: string;\n path: string;\n startLine: number;\n endLine: number;\n score: number;\n recallCount: number;\n avgScore: number;\n }> = [];\n\n const skipped: DreamingDeepPhaseSkipped = emptyDeepPhaseSkipped();\n for (const candidate of ranked) {\n if (existingMarkers.keys.has(candidate.key)) {\n skipped.alreadyPromotedKey += 1;\n // Treat as already applied; mark promotedAt for idempotency and keep going.\n const entry = store.entries[candidate.key];\n if (entry && !entry.promotedAt) {\n entry.promotedAt = now.toISOString();\n }\n continue;\n }\n const rehydrated = await rehydrateSnippet({ workspaceDir: params.workspaceDir, candidate });\n if (!rehydrated) {\n skipped.rehydrateFailed += 1;\n continue;\n }\n if (isContaminatedSnippet(rehydrated.snippet)) {\n skipped.contaminated += 1;\n continue;\n }\n const hash = snippetHash(rehydrated.snippet);\n if (existingMarkers.hashes.has(hash)) {\n skipped.hashDuplicate += 1;\n // Already promoted (possibly from a different key/line range). Mark promoted for idempotency.\n const entry = store.entries[candidate.key];\n if (entry && !entry.promotedAt) {\n entry.promotedAt = now.toISOString();\n }\n continue;\n }\n appliedCandidates.push({\n key: candidate.key,\n hash,\n snippet: rehydrated.snippet,\n path: candidate.path,\n startLine: rehydrated.startLine,\n endLine: rehydrated.endLine,\n score: candidate.score,\n recallCount: candidate.recallCount,\n avgScore: candidate.avgScore,\n });\n }\n\n if (appliedCandidates.length === 0) {\n await saveDreamingStore({ dreamingRoot: params.dreamingRoot, store });\n return {\n ok: true,\n reason: 'candidates were stale or already applied',\n candidates: ranked.length,\n applied: 0,\n memoryPath,\n skipped,\n };\n }\n\n const day = isoDay(now);\n const header = existing.trim().length > 0 ? '' : '# Long-Term Memory\\n\\n';\n const sectionLines: string[] = ['', `## Promoted From Short-Term Memory (${day})`, ''];\n for (const c of appliedCandidates) {\n const src = `${c.path}:${c.startLine}-${c.endLine}`;\n sectionLines.push(markerForPromotion(c.key, c.hash));\n sectionLines.push(\n `- ${c.snippet} [score=${c.score.toFixed(3)} recalls=${c.recallCount} avg=${c.avgScore.toFixed(3)} source=${src}]`,\n );\n }\n sectionLines.push('');\n\n const next = `${header}${existing.endsWith('\\n') || existing.length === 0 ? existing : `${existing}\\n`}${sectionLines.join('\\n')}`;\n await fs.mkdir(path.dirname(memoryPath), { recursive: true });\n await fs.writeFile(memoryPath, next, 'utf-8');\n\n const nowIso = now.toISOString();\n for (const c of appliedCandidates) {\n params.memoryManager?.recordSignal({\n source: 'dreaming',\n recordId: `dreaming:${c.key}`,\n score: c.score,\n content: c.snippet,\n metadata: {\n path: c.path,\n startLine: c.startLine,\n endLine: c.endLine,\n recallCount: c.recallCount,\n avgScore: c.avgScore,\n },\n });\n const entry = store.entries[c.key];\n if (entry) {\n entry.promotedAt = nowIso;\n entry.snippet = c.snippet;\n entry.startLine = c.startLine;\n entry.endLine = c.endLine;\n }\n }\n store.updatedAt = nowIso;\n await saveDreamingStore({ dreamingRoot: params.dreamingRoot, store });\n\n log.info(\n {\n workspaceDir: params.workspaceDir,\n dreamingRoot: params.dreamingRoot,\n candidates: ranked.length,\n applied: appliedCandidates.length,\n },\n 'Dreaming deep promotion complete',\n );\n\n return {\n ok: true,\n reason: 'applied promotions',\n candidates: ranked.length,\n applied: appliedCandidates.length,\n memoryPath,\n skipped,\n };\n });\n\n const finishedAt = new Date().toISOString();\n const empty = emptyDeepPhaseSkipped();\n const resultSkipped = 'skipped' in result ? result.skipped : empty;\n await writeDreamingDeepLastRun({\n dreamingRoot: params.dreamingRoot,\n lastRun: buildDeepLastRun({\n runId,\n startedAt,\n finishedAt,\n t0,\n ok: result.ok,\n reason: result.reason,\n config: cfg,\n memoryPath: result.memoryPath,\n deep: {\n candidatesRanked: result.candidates,\n applied: result.applied,\n skipped: resultSkipped,\n },\n }),\n }).catch(() => undefined);\n\n return {\n ok: result.ok,\n reason: result.reason,\n candidates: result.candidates,\n applied: result.applied,\n memoryPath: result.memoryPath,\n };\n } catch (err) {\n const finishedAt = new Date().toISOString();\n const em = err instanceof Error ? err.message : String(err);\n const z = emptyDeepPhaseSkipped();\n await writeDreamingDeepLastRun({\n dreamingRoot: params.dreamingRoot,\n lastRun: buildDeepLastRun({\n runId,\n startedAt,\n finishedAt,\n t0,\n ok: false,\n reason: 'error',\n config: cfg,\n memoryPath,\n errorMessage: em,\n deep: { candidatesRanked: 0, applied: 0, skipped: z },\n }),\n }).catch(() => undefined);\n throw err;\n }\n}\n"],"mappings":";;;;;;;;;aAGwD;AA+BxD,MAAM,MAAM,aAAa,gBAAgB;AAazC,SAAS,mBAAmB,KAAa,MAAsB;AAE7D,QAAO,mCAAmC,IAAI,UAAU,KAAK;;AAI/D,eAAe,iBAAiB,QAG4C;CAE1E,MAAM,QAAQ,MAAM,cADH,KAAK,KAAK,OAAO,cAAc,OAAO,UAAU,KACvB,CAAC;AAC3C,KAAI,CAAC,MAAO,QAAO;CAEnB,MAAM,YAAY,KAAK,IAAI,GAAG,KAAK,MAAM,OAAO,UAAU,UAAU,CAAC;CACrE,MAAM,UAAU,KAAK,IAAI,WAAW,KAAK,MAAM,OAAO,UAAU,QAAQ,CAAC;CACzE,MAAM,UAAU,WAAW,OAAO,WAAW,QAAQ;AACrD,KAAI,CAAC,QAAS,QAAO;AACrB,QAAO;EAAE;EAAS;EAAW;EAAS;;AAIxC,SAAS,iBAAiB,MAWF;CACtB,MAAM,aAAa,KAAK,IAAI,GAAG,KAAK,KAAK,GAAG,KAAK,GAAG;AACpD,QAAO;EACL,SAAA;EACA,OAAO;EACP,OAAO,KAAK;EACZ,WAAW,KAAK;EAChB,YAAY,KAAK;EACjB;EACA,IAAI,KAAK;EACT,QAAQ,KAAK;EACb,QAAQ,KAAK;EACb,YAAY,KAAK;EACjB,GAAI,KAAK,eAAe,EAAE,cAAc,KAAK,cAAc,GAAG,EAAE;EAChE,MAAM,KAAK;EACZ;;AAGH,eAAsB,yBAAyB,QAY5C;CACD,MAAM,MAAM,oBAAoB,OAAO,OAAO;CAC9C,MAAM,MAAM,OAAO,uBAAO,IAAI,MAAM;CACpC,MAAM,YAAY,IAAI,aAAa;CACnC,MAAM,QAAQ,GAAG,UAAU,GAAG,QAAQ,IAAI,GAAG,KAAK,QAAQ,CAAC,SAAS,GAAG,CAAC,MAAM,EAAE;CAChF,MAAM,aAAa,KAAK,KAAK,OAAO,cAAc,mBAAmB;CACrE,MAAM,KAAK,KAAK,KAAK;CAGrB,MAAM,kBAAkB,CAAC,IAAI,UAAU,sBAAsB,IAAI,UAAU,IAAI,qBAAqB;AACpG,KAAI,iBAAiB;EACnB,MAAM,8BAAa,IAAI,MAAM,EAAC,aAAa;EAC3C,MAAM,QAAQ,uBAAuB;AACrC,QAAM,yBAAyB;GAC7B,cAAc,OAAO;GACrB,SAAS,iBAAiB;IACxB;IACA;IACA;IACA;IACA,IAAI;IACJ,QAAQ;IACR,QAAQ;IACR;IACA,MAAM;KAAE,kBAAkB;KAAG,SAAS;KAAG,SAAS;KAAO;IAC1D,CAAC;GACH,CAAC,CAAC,YAAY,KAAA,EAAU;AACzB,SAAO;GAAE,IAAI;GAAM,QAAQ;GAAiB,YAAY;GAAG,SAAS;GAAG;GAAY;;AAGrF,KAAI;EACF,MAAM,SAAS,MAAM,0BAA0B,OAAO,cAAc,YAAY;GAC9E,MAAM,EAAE,UAAU,MAAM,kBAAkB,EAAE,cAAc,OAAO,cAAc,CAAC;GAEhF,MAAM,QAAQ,IAAI,SAAS;GAe3B,MAAM,SAbM,OAAO,OAAO,MAAM,WAAW,EAAE,CAAC,CAAC,QAAQ,MAA+B;AACpF,QAAI,CAAC,KAAK,OAAO,MAAM,SAAU,QAAO;AACxC,QAAI,EAAE,WAAY,QAAO;AACzB,QAAI,CAAC,EAAE,QAAQ,CAAC,EAAE,KAAK,WAAW,UAAU,CAAE,QAAO;AACrD,QAAI,EAAE,cAAc,IAAI,eAAgB,QAAO;AAE/C,SAAK,EAAE,aAAa,UAAU,KAAK,IAAI,iBAAkB,QAAO;AAEhE,QAAI,eAAe,EAAE,gBAAgB,OAAO,IAAI,WAAW,CAAE,QAAO;AAEpE,WAAO,QADK,EAAE,cAAc,IAAI,EAAE,aAAa,EAAE,cAAc,EAC5C,IAAI,IAAI;KAGmB,CAC7C,KAAK,MAAM;IACV,MAAM,EAAE,UAAU,OAAO,iBAAiB,sBAAsB,GAAG,OAAO,IAAI,oBAAoB;AAClG,WAAO;KAAE,GAAG;KAAG;KAAU;KAAO;KAAc;KAC9C,CACD,KAAK,yBAAyB,CAC9B,MAAM,GAAG,IAAI,MAAM;AAEtB,OAAI,OAAO,WAAW,EAEpB,QAAO;IAAE,IAAI;IAAM,QAAQ;IAA0B,YAAY;IAAG,SAAS;IAAG;IAAY,SADlF,uBAC4F;IAAE;GAG1G,MAAM,WAAW,MAAM,GAAG,SAAS,YAAY,QAAQ,CAAC,OAAO,QAAiB;AAC9E,QAAK,KAA2C,SAAS,SAAU,QAAO;AAC1E,UAAM;KACN;GACF,MAAM,kBAAkB,wBAAwB,SAAS;GAEzD,MAAM,oBAUD,EAAE;GAEP,MAAM,UAAoC,uBAAuB;AACjE,QAAK,MAAM,aAAa,QAAQ;AAC9B,QAAI,gBAAgB,KAAK,IAAI,UAAU,IAAI,EAAE;AAC3C,aAAQ,sBAAsB;KAE9B,MAAM,QAAQ,MAAM,QAAQ,UAAU;AACtC,SAAI,SAAS,CAAC,MAAM,WAClB,OAAM,aAAa,IAAI,aAAa;AAEtC;;IAEF,MAAM,aAAa,MAAM,iBAAiB;KAAE,cAAc,OAAO;KAAc;KAAW,CAAC;AAC3F,QAAI,CAAC,YAAY;AACf,aAAQ,mBAAmB;AAC3B;;AAEF,QAAI,sBAAsB,WAAW,QAAQ,EAAE;AAC7C,aAAQ,gBAAgB;AACxB;;IAEF,MAAM,OAAO,YAAY,WAAW,QAAQ;AAC5C,QAAI,gBAAgB,OAAO,IAAI,KAAK,EAAE;AACpC,aAAQ,iBAAiB;KAEzB,MAAM,QAAQ,MAAM,QAAQ,UAAU;AACtC,SAAI,SAAS,CAAC,MAAM,WAClB,OAAM,aAAa,IAAI,aAAa;AAEtC;;AAEF,sBAAkB,KAAK;KACrB,KAAK,UAAU;KACf;KACA,SAAS,WAAW;KACpB,MAAM,UAAU;KAChB,WAAW,WAAW;KACtB,SAAS,WAAW;KACpB,OAAO,UAAU;KACjB,aAAa,UAAU;KACvB,UAAU,UAAU;KACrB,CAAC;;AAGJ,OAAI,kBAAkB,WAAW,GAAG;AAClC,UAAM,kBAAkB;KAAE,cAAc,OAAO;KAAc;KAAO,CAAC;AACrE,WAAO;KACL,IAAI;KACJ,QAAQ;KACR,YAAY,OAAO;KACnB,SAAS;KACT;KACA;KACD;;GAGH,MAAM,MAAM,OAAO,IAAI;GACvB,MAAM,SAAS,SAAS,MAAM,CAAC,SAAS,IAAI,KAAK;GACjD,MAAM,eAAyB;IAAC;IAAI,uCAAuC,IAAI;IAAI;IAAG;AACtF,QAAK,MAAM,KAAK,mBAAmB;IACjC,MAAM,MAAM,GAAG,EAAE,KAAK,GAAG,EAAE,UAAU,GAAG,EAAE;AAC1C,iBAAa,KAAK,mBAAmB,EAAE,KAAK,EAAE,KAAK,CAAC;AACpD,iBAAa,KACX,KAAK,EAAE,QAAQ,UAAU,EAAE,MAAM,QAAQ,EAAE,CAAC,WAAW,EAAE,YAAY,OAAO,EAAE,SAAS,QAAQ,EAAE,CAAC,UAAU,IAAI,GACjH;;AAEH,gBAAa,KAAK,GAAG;GAErB,MAAM,OAAO,GAAG,SAAS,SAAS,SAAS,KAAK,IAAI,SAAS,WAAW,IAAI,WAAW,GAAG,SAAS,MAAM,aAAa,KAAK,KAAK;AAChI,SAAM,GAAG,MAAM,KAAK,QAAQ,WAAW,EAAE,EAAE,WAAW,MAAM,CAAC;AAC7D,SAAM,GAAG,UAAU,YAAY,MAAM,QAAQ;GAE7C,MAAM,SAAS,IAAI,aAAa;AAChC,QAAK,MAAM,KAAK,mBAAmB;AACjC,WAAO,eAAe,aAAa;KACjC,QAAQ;KACR,UAAU,YAAY,EAAE;KACxB,OAAO,EAAE;KACT,SAAS,EAAE;KACX,UAAU;MACR,MAAM,EAAE;MACR,WAAW,EAAE;MACb,SAAS,EAAE;MACX,aAAa,EAAE;MACf,UAAU,EAAE;MACb;KACF,CAAC;IACF,MAAM,QAAQ,MAAM,QAAQ,EAAE;AAC9B,QAAI,OAAO;AACT,WAAM,aAAa;AACnB,WAAM,UAAU,EAAE;AAClB,WAAM,YAAY,EAAE;AACpB,WAAM,UAAU,EAAE;;;AAGtB,SAAM,YAAY;AAClB,SAAM,kBAAkB;IAAE,cAAc,OAAO;IAAc;IAAO,CAAC;AAErE,OAAI,KACF;IACE,cAAc,OAAO;IACrB,cAAc,OAAO;IACrB,YAAY,OAAO;IACnB,SAAS,kBAAkB;IAC5B,EACD,mCACD;AAED,UAAO;IACL,IAAI;IACJ,QAAQ;IACR,YAAY,OAAO;IACnB,SAAS,kBAAkB;IAC3B;IACA;IACD;IACD;EAEF,MAAM,8BAAa,IAAI,MAAM,EAAC,aAAa;EAC3C,MAAM,QAAQ,uBAAuB;EACrC,MAAM,gBAAgB,aAAa,SAAS,OAAO,UAAU;AAC7D,QAAM,yBAAyB;GAC7B,cAAc,OAAO;GACrB,SAAS,iBAAiB;IACxB;IACA;IACA;IACA;IACA,IAAI,OAAO;IACX,QAAQ,OAAO;IACf,QAAQ;IACR,YAAY,OAAO;IACnB,MAAM;KACJ,kBAAkB,OAAO;KACzB,SAAS,OAAO;KAChB,SAAS;KACV;IACF,CAAC;GACH,CAAC,CAAC,YAAY,KAAA,EAAU;AAEzB,SAAO;GACL,IAAI,OAAO;GACX,QAAQ,OAAO;GACf,YAAY,OAAO;GACnB,SAAS,OAAO;GAChB,YAAY,OAAO;GACpB;UACM,KAAK;EACZ,MAAM,8BAAa,IAAI,MAAM,EAAC,aAAa;EAC3C,MAAM,KAAK,eAAe,QAAQ,IAAI,UAAU,OAAO,IAAI;EAC3D,MAAM,IAAI,uBAAuB;AACjC,QAAM,yBAAyB;GAC7B,cAAc,OAAO;GACrB,SAAS,iBAAiB;IACxB;IACA;IACA;IACA;IACA,IAAI;IACJ,QAAQ;IACR,QAAQ;IACR;IACA,cAAc;IACd,MAAM;KAAE,kBAAkB;KAAG,SAAS;KAAG,SAAS;KAAG;IACtD,CAAC;GACH,CAAC,CAAC,YAAY,KAAA,EAAU;AACzB,QAAM"}
@@ -24,13 +24,13 @@ export type DreamingRemEvent = DreamingEventBase & {
24
24
  };
25
25
  export type DreamingEvent = DreamingLightEvent | DreamingDeepEvent | DreamingRemEvent;
26
26
  /**
27
- * Append a single event line to `memory/.dreams/events.jsonl`.
27
+ * Append a single event line to an agent's `memories/.dreams/events.jsonl`.
28
28
  * Creates the directory and file if they don't exist.
29
29
  * Failures are silently ignored so audit logging never blocks execution.
30
30
  */
31
- export declare function appendDreamingEvent(workspaceDir: string, event: DreamingEvent): Promise<void>;
31
+ export declare function appendDreamingEvent(dreamingRoot: string, event: DreamingEvent): Promise<void>;
32
32
  /**
33
33
  * Read the most recent N events from the events log.
34
34
  * Returns newest-first. If the file doesn't exist, returns an empty array.
35
35
  */
36
- export declare function readDreamingEvents(workspaceDir: string, limit?: number): Promise<DreamingEvent[]>;
36
+ export declare function readDreamingEvents(dreamingRoot: string, limit?: number): Promise<DreamingEvent[]>;
@@ -3,15 +3,15 @@ import path from "node:path";
3
3
  import fs from "node:fs/promises";
4
4
  //#region src/agent/memory/dreaming/events.ts
5
5
  /**
6
- * Append a single event line to `memory/.dreams/events.jsonl`.
6
+ * Append a single event line to an agent's `memories/.dreams/events.jsonl`.
7
7
  * Creates the directory and file if they don't exist.
8
8
  * Failures are silently ignored so audit logging never blocks execution.
9
9
  */
10
- async function appendDreamingEvent(workspaceDir, event) {
10
+ async function appendDreamingEvent(dreamingRoot, event) {
11
11
  try {
12
- const dirPath = path.join(workspaceDir, DREAMING_DIR_RELATIVE);
12
+ const dirPath = path.join(dreamingRoot, DREAMING_DIR_RELATIVE);
13
13
  await fs.mkdir(dirPath, { recursive: true });
14
- const filePath = path.join(workspaceDir, DREAMING_EVENTS_LOG_RELATIVE);
14
+ const filePath = path.join(dreamingRoot, DREAMING_EVENTS_LOG_RELATIVE);
15
15
  const line = JSON.stringify(event) + "\n";
16
16
  await fs.appendFile(filePath, line, "utf-8");
17
17
  } catch {}
@@ -20,8 +20,8 @@ async function appendDreamingEvent(workspaceDir, event) {
20
20
  * Read the most recent N events from the events log.
21
21
  * Returns newest-first. If the file doesn't exist, returns an empty array.
22
22
  */
23
- async function readDreamingEvents(workspaceDir, limit = 50) {
24
- const filePath = path.join(workspaceDir, DREAMING_EVENTS_LOG_RELATIVE);
23
+ async function readDreamingEvents(dreamingRoot, limit = 50) {
24
+ const filePath = path.join(dreamingRoot, DREAMING_EVENTS_LOG_RELATIVE);
25
25
  let raw;
26
26
  try {
27
27
  raw = await fs.readFile(filePath, "utf-8");
@@ -1 +1 @@
1
- {"version":3,"file":"events.js","names":[],"sources":["../../../../../src/agent/memory/dreaming/events.ts"],"sourcesContent":["import fs from 'node:fs/promises';\nimport path from 'node:path';\n\nimport { DREAMING_DIR_RELATIVE, DREAMING_EVENTS_LOG_RELATIVE, type DreamingPhaseId } from './constants.js';\n\n// ── Event types ────────────────────────────────────────────────────────\n\nexport type DreamingEventBase = {\n timestamp: string;\n phase: DreamingPhaseId;\n ok: boolean;\n reason: string;\n durationMs: number;\n};\n\nexport type DreamingLightEvent = DreamingEventBase & {\n phase: 'light';\n scannedEntries: number;\n newSignals: number;\n deduped: number;\n};\n\nexport type DreamingDeepEvent = DreamingEventBase & {\n phase: 'deep';\n candidates: number;\n applied: number;\n};\n\nexport type DreamingRemEvent = DreamingEventBase & {\n phase: 'rem';\n patternsDiscovered: number;\n entriesAnalyzed: number;\n};\n\nexport type DreamingEvent = DreamingLightEvent | DreamingDeepEvent | DreamingRemEvent;\n\n// ── Write ──────────────────────────────────────────────────────────────\n\n/**\n * Append a single event line to `memory/.dreams/events.jsonl`.\n * Creates the directory and file if they don't exist.\n * Failures are silently ignored so audit logging never blocks execution.\n */\nexport async function appendDreamingEvent(workspaceDir: string, event: DreamingEvent): Promise<void> {\n try {\n const dirPath = path.join(workspaceDir, DREAMING_DIR_RELATIVE);\n await fs.mkdir(dirPath, { recursive: true });\n const filePath = path.join(workspaceDir, DREAMING_EVENTS_LOG_RELATIVE);\n const line = JSON.stringify(event) + '\\n';\n await fs.appendFile(filePath, line, 'utf-8');\n } catch {\n // Audit logging must not block or throw.\n }\n}\n\n// ── Read ───────────────────────────────────────────────────────────────\n\n/**\n * Read the most recent N events from the events log.\n * Returns newest-first. If the file doesn't exist, returns an empty array.\n */\nexport async function readDreamingEvents(\n workspaceDir: string,\n limit = 50,\n): Promise<DreamingEvent[]> {\n const filePath = path.join(workspaceDir, DREAMING_EVENTS_LOG_RELATIVE);\n let raw: string;\n try {\n raw = await fs.readFile(filePath, 'utf-8');\n } catch (err) {\n const code = (err as NodeJS.ErrnoException | undefined)?.code;\n if (code === 'ENOENT') return [];\n throw err;\n }\n\n const lines = raw\n .split('\\n')\n .map((line) => line.trim())\n .filter(Boolean);\n\n // Take the last `limit` lines (newest entries are at the end).\n const tail = lines.slice(-Math.abs(limit));\n\n const events: DreamingEvent[] = [];\n for (const line of tail) {\n try {\n const parsed = JSON.parse(line) as DreamingEvent;\n if (parsed && typeof parsed === 'object' && parsed.timestamp && parsed.phase) {\n events.push(parsed);\n }\n } catch {\n // Skip malformed lines.\n }\n }\n\n // Return newest first.\n events.reverse();\n return events;\n}\n"],"mappings":";;;;;;;;;AA2CA,eAAsB,oBAAoB,cAAsB,OAAqC;AACnG,KAAI;EACF,MAAM,UAAU,KAAK,KAAK,cAAc,sBAAsB;AAC9D,QAAM,GAAG,MAAM,SAAS,EAAE,WAAW,MAAM,CAAC;EAC5C,MAAM,WAAW,KAAK,KAAK,cAAc,6BAA6B;EACtE,MAAM,OAAO,KAAK,UAAU,MAAM,GAAG;AACrC,QAAM,GAAG,WAAW,UAAU,MAAM,QAAQ;SACtC;;;;;;AAWV,eAAsB,mBACpB,cACA,QAAQ,IACkB;CAC1B,MAAM,WAAW,KAAK,KAAK,cAAc,6BAA6B;CACtE,IAAI;AACJ,KAAI;AACF,QAAM,MAAM,GAAG,SAAS,UAAU,QAAQ;UACnC,KAAK;AAEZ,MADc,KAA2C,SAC5C,SAAU,QAAO,EAAE;AAChC,QAAM;;CASR,MAAM,OANQ,IACX,MAAM,KAAK,CACX,KAAK,SAAS,KAAK,MAAM,CAAC,CAC1B,OAAO,QAGQ,CAAC,MAAM,CAAC,KAAK,IAAI,MAAM,CAAC;CAE1C,MAAM,SAA0B,EAAE;AAClC,MAAK,MAAM,QAAQ,KACjB,KAAI;EACF,MAAM,SAAS,KAAK,MAAM,KAAK;AAC/B,MAAI,UAAU,OAAO,WAAW,YAAY,OAAO,aAAa,OAAO,MACrE,QAAO,KAAK,OAAO;SAEf;AAMV,QAAO,SAAS;AAChB,QAAO"}
1
+ {"version":3,"file":"events.js","names":[],"sources":["../../../../../src/agent/memory/dreaming/events.ts"],"sourcesContent":["import fs from 'node:fs/promises';\nimport path from 'node:path';\n\nimport { DREAMING_DIR_RELATIVE, DREAMING_EVENTS_LOG_RELATIVE, type DreamingPhaseId } from './constants.js';\n\n// ── Event types ────────────────────────────────────────────────────────\n\nexport type DreamingEventBase = {\n timestamp: string;\n phase: DreamingPhaseId;\n ok: boolean;\n reason: string;\n durationMs: number;\n};\n\nexport type DreamingLightEvent = DreamingEventBase & {\n phase: 'light';\n scannedEntries: number;\n newSignals: number;\n deduped: number;\n};\n\nexport type DreamingDeepEvent = DreamingEventBase & {\n phase: 'deep';\n candidates: number;\n applied: number;\n};\n\nexport type DreamingRemEvent = DreamingEventBase & {\n phase: 'rem';\n patternsDiscovered: number;\n entriesAnalyzed: number;\n};\n\nexport type DreamingEvent = DreamingLightEvent | DreamingDeepEvent | DreamingRemEvent;\n\n// ── Write ──────────────────────────────────────────────────────────────\n\n/**\n * Append a single event line to an agent's `memories/.dreams/events.jsonl`.\n * Creates the directory and file if they don't exist.\n * Failures are silently ignored so audit logging never blocks execution.\n */\nexport async function appendDreamingEvent(dreamingRoot: string, event: DreamingEvent): Promise<void> {\n try {\n const dirPath = path.join(dreamingRoot, DREAMING_DIR_RELATIVE);\n await fs.mkdir(dirPath, { recursive: true });\n const filePath = path.join(dreamingRoot, DREAMING_EVENTS_LOG_RELATIVE);\n const line = JSON.stringify(event) + '\\n';\n await fs.appendFile(filePath, line, 'utf-8');\n } catch {\n // Audit logging must not block or throw.\n }\n}\n\n// ── Read ───────────────────────────────────────────────────────────────\n\n/**\n * Read the most recent N events from the events log.\n * Returns newest-first. If the file doesn't exist, returns an empty array.\n */\nexport async function readDreamingEvents(\n dreamingRoot: string,\n limit = 50,\n): Promise<DreamingEvent[]> {\n const filePath = path.join(dreamingRoot, DREAMING_EVENTS_LOG_RELATIVE);\n let raw: string;\n try {\n raw = await fs.readFile(filePath, 'utf-8');\n } catch (err) {\n const code = (err as NodeJS.ErrnoException | undefined)?.code;\n if (code === 'ENOENT') return [];\n throw err;\n }\n\n const lines = raw\n .split('\\n')\n .map((line) => line.trim())\n .filter(Boolean);\n\n // Take the last `limit` lines (newest entries are at the end).\n const tail = lines.slice(-Math.abs(limit));\n\n const events: DreamingEvent[] = [];\n for (const line of tail) {\n try {\n const parsed = JSON.parse(line) as DreamingEvent;\n if (parsed && typeof parsed === 'object' && parsed.timestamp && parsed.phase) {\n events.push(parsed);\n }\n } catch {\n // Skip malformed lines.\n }\n }\n\n // Return newest first.\n events.reverse();\n return events;\n}\n"],"mappings":";;;;;;;;;AA2CA,eAAsB,oBAAoB,cAAsB,OAAqC;AACnG,KAAI;EACF,MAAM,UAAU,KAAK,KAAK,cAAc,sBAAsB;AAC9D,QAAM,GAAG,MAAM,SAAS,EAAE,WAAW,MAAM,CAAC;EAC5C,MAAM,WAAW,KAAK,KAAK,cAAc,6BAA6B;EACtE,MAAM,OAAO,KAAK,UAAU,MAAM,GAAG;AACrC,QAAM,GAAG,WAAW,UAAU,MAAM,QAAQ;SACtC;;;;;;AAWV,eAAsB,mBACpB,cACA,QAAQ,IACkB;CAC1B,MAAM,WAAW,KAAK,KAAK,cAAc,6BAA6B;CACtE,IAAI;AACJ,KAAI;AACF,QAAM,MAAM,GAAG,SAAS,UAAU,QAAQ;UACnC,KAAK;AAEZ,MADc,KAA2C,SAC5C,SAAU,QAAO,EAAE;AAChC,QAAM;;CASR,MAAM,OANQ,IACX,MAAM,KAAK,CACX,KAAK,SAAS,KAAK,MAAM,CAAC,CAC1B,OAAO,QAGQ,CAAC,MAAM,CAAC,KAAK,IAAI,MAAM,CAAC;CAE1C,MAAM,SAA0B,EAAE;AAClC,MAAK,MAAM,QAAQ,KACjB,KAAI;EACF,MAAM,SAAS,KAAK,MAAM,KAAK;AAC/B,MAAI,UAAU,OAAO,WAAW,YAAY,OAAO,aAAa,OAAO,MACrE,QAAO,KAAK,OAAO;SAEf;AAMV,QAAO,SAAS;AAChB,QAAO"}
@@ -8,7 +8,7 @@ export type DreamingDeepPhaseSkipped = {
8
8
  hashDuplicate: number;
9
9
  };
10
10
  /**
11
- * On-disk / API shape for `memory/.dreams/last-run.json` (deep promotion sweep).
11
+ * On-disk / API shape for an agent's `memories/.dreams/last-run.json`.
12
12
  */
13
13
  export type DreamingDeepLastRun = {
14
14
  version: typeof DREAMING_LAST_RUN_FORMAT_VERSION;
@@ -75,6 +75,6 @@ export type DreamingLastRun = DreamingDeepLastRun | DreamingLightLastRun | Dream
75
75
  export declare function parseDreamingLastRunFile(raw: unknown): DreamingDeepLastRun | null;
76
76
  export declare function emptyDeepPhaseSkipped(): DreamingDeepPhaseSkipped;
77
77
  export declare function writeDreamingDeepLastRun(params: {
78
- workspaceDir: string;
78
+ dreamingRoot: string;
79
79
  lastRun: DreamingDeepLastRun;
80
80
  }): Promise<void>;
@@ -86,7 +86,7 @@ function emptyDeepPhaseSkipped() {
86
86
  return { ...EMPTY_SKIPPED };
87
87
  }
88
88
  async function writeDreamingDeepLastRun(params) {
89
- const fullPath = path.join(params.workspaceDir, DREAMING_LAST_RUN_RELATIVE);
89
+ const fullPath = path.join(params.dreamingRoot, DREAMING_LAST_RUN_RELATIVE);
90
90
  await fs.mkdir(path.dirname(fullPath), { recursive: true });
91
91
  const tmp = `${fullPath}.${process.pid}.${Date.now()}.tmp`;
92
92
  await fs.writeFile(tmp, `${JSON.stringify(params.lastRun, null, 2)}\n`, "utf-8");
@@ -1 +1 @@
1
- {"version":3,"file":"last-run.js","names":[],"sources":["../../../../../src/agent/memory/dreaming/last-run.ts"],"sourcesContent":["import fs from 'node:fs/promises';\nimport path from 'node:path';\n\nimport { DREAMING_LAST_RUN_RELATIVE } from './constants.js';\nimport type { DreamingDeepConfig, DreamingLightConfig, DreamingRemConfig } from './config.js';\n\nexport const DREAMING_LAST_RUN_FORMAT_VERSION = 2 as const;\n\nexport type { DreamingDeepConfig } from './config.js';\n\nexport type DreamingDeepPhaseSkipped = {\n alreadyPromotedKey: number;\n rehydrateFailed: number;\n contaminated: number;\n hashDuplicate: number;\n};\n\n/**\n * On-disk / API shape for `memory/.dreams/last-run.json` (deep promotion sweep).\n */\nexport type DreamingDeepLastRun = {\n version: typeof DREAMING_LAST_RUN_FORMAT_VERSION;\n phase: 'deep';\n runId: string;\n startedAt: string;\n finishedAt: string;\n durationMs: number;\n ok: boolean;\n reason: string;\n config: DreamingDeepConfig;\n memoryPath: string;\n errorMessage?: string;\n deep: {\n candidatesRanked: number;\n applied: number;\n skipped: DreamingDeepPhaseSkipped;\n };\n};\n\n/**\n * On-disk shape for light sweep last-run.\n */\nexport type DreamingLightLastRun = {\n version: typeof DREAMING_LAST_RUN_FORMAT_VERSION;\n phase: 'light';\n runId: string;\n startedAt: string;\n finishedAt: string;\n durationMs: number;\n ok: boolean;\n reason: string;\n config: DreamingLightConfig;\n light: {\n scannedEntries: number;\n newSignals: number;\n deduped: number;\n };\n errorMessage?: string;\n};\n\n/**\n * On-disk shape for REM pattern last-run.\n */\nexport type DreamingRemLastRun = {\n version: typeof DREAMING_LAST_RUN_FORMAT_VERSION;\n phase: 'rem';\n runId: string;\n startedAt: string;\n finishedAt: string;\n durationMs: number;\n ok: boolean;\n reason: string;\n config: DreamingRemConfig;\n rem: {\n patternsDiscovered: number;\n entriesAnalyzed: number;\n };\n errorMessage?: string;\n};\n\n/** Union of all phase last-run shapes. */\nexport type DreamingLastRun = DreamingDeepLastRun | DreamingLightLastRun | DreamingRemLastRun;\n\nfunction isRecord(v: unknown): v is Record<string, unknown> {\n return v !== null && typeof v === 'object' && !Array.isArray(v);\n}\n\nfunction asNonNegInt(v: unknown): number {\n if (typeof v === 'number' && Number.isFinite(v)) return Math.max(0, Math.floor(v));\n if (typeof v === 'string' && v.trim() && Number.isFinite(Number(v))) {\n return Math.max(0, Math.floor(Number(v)));\n }\n return 0;\n}\n\nfunction asDreamingDeepConfig(v: unknown): DreamingDeepConfig | null {\n if (!isRecord(v)) return null;\n return {\n enabled: v.enabled === true,\n cron: typeof v.cron === 'string' ? v.cron : '0 3 * * *',\n minScore: typeof v.minScore === 'number' && Number.isFinite(v.minScore) ? v.minScore : 0,\n minRecallCount: asNonNegInt(v.minRecallCount) || 1,\n minUniqueQueries: asNonNegInt(v.minUniqueQueries) || 3,\n limit: asNonNegInt(v.limit),\n recencyHalfLifeDays: asNonNegInt(v.recencyHalfLifeDays) || 14,\n maxAgeDays: asNonNegInt(v.maxAgeDays) || 30,\n };\n}\n\nconst EMPTY_SKIPPED: DreamingDeepPhaseSkipped = {\n alreadyPromotedKey: 0,\n rehydrateFailed: 0,\n contaminated: 0,\n hashDuplicate: 0,\n};\n\nfunction parseSkippedStrict(raw: unknown): DreamingDeepPhaseSkipped | null {\n if (!isRecord(raw)) return null;\n if (\n typeof raw.alreadyPromotedKey !== 'number' ||\n !Number.isFinite(raw.alreadyPromotedKey) ||\n typeof raw.rehydrateFailed !== 'number' ||\n !Number.isFinite(raw.rehydrateFailed) ||\n typeof raw.contaminated !== 'number' ||\n !Number.isFinite(raw.contaminated) ||\n typeof raw.hashDuplicate !== 'number' ||\n !Number.isFinite(raw.hashDuplicate)\n ) {\n return null;\n }\n return {\n alreadyPromotedKey: Math.max(0, Math.floor(raw.alreadyPromotedKey)),\n rehydrateFailed: Math.max(0, Math.floor(raw.rehydrateFailed)),\n contaminated: Math.max(0, Math.floor(raw.contaminated)),\n hashDuplicate: Math.max(0, Math.floor(raw.hashDuplicate)),\n };\n}\n\n/**\n * Parse `last-run.json`. Only the current on-disk format (`version: 2`, `phase: 'deep'`) is accepted.\n */\nexport function parseDreamingLastRunFile(raw: unknown): DreamingDeepLastRun | null {\n if (!isRecord(raw)) return null;\n if (raw.version !== DREAMING_LAST_RUN_FORMAT_VERSION || raw.phase !== 'deep') return null;\n\n if (typeof raw.runId !== 'string' || !raw.runId.trim()) return null;\n if (typeof raw.startedAt !== 'string' || typeof raw.finishedAt !== 'string') return null;\n if (!raw.startedAt.trim() || !raw.finishedAt.trim()) return null;\n\n if (typeof raw.durationMs !== 'number' || !Number.isFinite(raw.durationMs) || raw.durationMs < 0) {\n return null;\n }\n if (raw.ok !== true && raw.ok !== false) return null;\n if (typeof raw.reason !== 'string') return null;\n\n const config = asDreamingDeepConfig(raw.config);\n if (!config) return null;\n if (typeof raw.memoryPath !== 'string' || !raw.memoryPath.trim()) return null;\n\n const deepRaw = raw.deep;\n if (!isRecord(deepRaw)) return null;\n if (typeof deepRaw.candidatesRanked !== 'number' || !Number.isFinite(deepRaw.candidatesRanked)) {\n return null;\n }\n if (typeof deepRaw.applied !== 'number' || !Number.isFinite(deepRaw.applied)) return null;\n const skipped = parseSkippedStrict(deepRaw.skipped);\n if (!skipped) return null;\n\n const err = raw.errorMessage;\n const errMsg = typeof err === 'string' && err.trim() ? err.trim() : undefined;\n\n return {\n version: DREAMING_LAST_RUN_FORMAT_VERSION,\n phase: 'deep',\n runId: raw.runId.trim(),\n startedAt: raw.startedAt,\n finishedAt: raw.finishedAt,\n durationMs: Math.max(0, Math.floor(raw.durationMs)),\n ok: raw.ok === true,\n reason: raw.reason,\n config,\n memoryPath: raw.memoryPath,\n ...(errMsg ? { errorMessage: errMsg } : {}),\n deep: {\n candidatesRanked: Math.max(0, Math.floor(deepRaw.candidatesRanked)),\n applied: Math.max(0, Math.floor(deepRaw.applied)),\n skipped,\n },\n };\n}\n\nexport function emptyDeepPhaseSkipped(): DreamingDeepPhaseSkipped {\n return { ...EMPTY_SKIPPED };\n}\n\nexport async function writeDreamingDeepLastRun(params: {\n workspaceDir: string;\n lastRun: DreamingDeepLastRun;\n}): Promise<void> {\n const fullPath = path.join(params.workspaceDir, DREAMING_LAST_RUN_RELATIVE);\n await fs.mkdir(path.dirname(fullPath), { recursive: true });\n const tmp = `${fullPath}.${process.pid}.${Date.now()}.tmp`;\n await fs.writeFile(tmp, `${JSON.stringify(params.lastRun, null, 2)}\\n`, 'utf-8');\n await fs.rename(tmp, fullPath);\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"last-run.js","names":[],"sources":["../../../../../src/agent/memory/dreaming/last-run.ts"],"sourcesContent":["import fs from 'node:fs/promises';\nimport path from 'node:path';\n\nimport { DREAMING_LAST_RUN_RELATIVE } from './constants.js';\nimport type { DreamingDeepConfig, DreamingLightConfig, DreamingRemConfig } from './config.js';\n\nexport const DREAMING_LAST_RUN_FORMAT_VERSION = 2 as const;\n\nexport type { DreamingDeepConfig } from './config.js';\n\nexport type DreamingDeepPhaseSkipped = {\n alreadyPromotedKey: number;\n rehydrateFailed: number;\n contaminated: number;\n hashDuplicate: number;\n};\n\n/**\n * On-disk / API shape for an agent's `memories/.dreams/last-run.json`.\n */\nexport type DreamingDeepLastRun = {\n version: typeof DREAMING_LAST_RUN_FORMAT_VERSION;\n phase: 'deep';\n runId: string;\n startedAt: string;\n finishedAt: string;\n durationMs: number;\n ok: boolean;\n reason: string;\n config: DreamingDeepConfig;\n memoryPath: string;\n errorMessage?: string;\n deep: {\n candidatesRanked: number;\n applied: number;\n skipped: DreamingDeepPhaseSkipped;\n };\n};\n\n/**\n * On-disk shape for light sweep last-run.\n */\nexport type DreamingLightLastRun = {\n version: typeof DREAMING_LAST_RUN_FORMAT_VERSION;\n phase: 'light';\n runId: string;\n startedAt: string;\n finishedAt: string;\n durationMs: number;\n ok: boolean;\n reason: string;\n config: DreamingLightConfig;\n light: {\n scannedEntries: number;\n newSignals: number;\n deduped: number;\n };\n errorMessage?: string;\n};\n\n/**\n * On-disk shape for REM pattern last-run.\n */\nexport type DreamingRemLastRun = {\n version: typeof DREAMING_LAST_RUN_FORMAT_VERSION;\n phase: 'rem';\n runId: string;\n startedAt: string;\n finishedAt: string;\n durationMs: number;\n ok: boolean;\n reason: string;\n config: DreamingRemConfig;\n rem: {\n patternsDiscovered: number;\n entriesAnalyzed: number;\n };\n errorMessage?: string;\n};\n\n/** Union of all phase last-run shapes. */\nexport type DreamingLastRun = DreamingDeepLastRun | DreamingLightLastRun | DreamingRemLastRun;\n\nfunction isRecord(v: unknown): v is Record<string, unknown> {\n return v !== null && typeof v === 'object' && !Array.isArray(v);\n}\n\nfunction asNonNegInt(v: unknown): number {\n if (typeof v === 'number' && Number.isFinite(v)) return Math.max(0, Math.floor(v));\n if (typeof v === 'string' && v.trim() && Number.isFinite(Number(v))) {\n return Math.max(0, Math.floor(Number(v)));\n }\n return 0;\n}\n\nfunction asDreamingDeepConfig(v: unknown): DreamingDeepConfig | null {\n if (!isRecord(v)) return null;\n return {\n enabled: v.enabled === true,\n cron: typeof v.cron === 'string' ? v.cron : '0 3 * * *',\n minScore: typeof v.minScore === 'number' && Number.isFinite(v.minScore) ? v.minScore : 0,\n minRecallCount: asNonNegInt(v.minRecallCount) || 1,\n minUniqueQueries: asNonNegInt(v.minUniqueQueries) || 3,\n limit: asNonNegInt(v.limit),\n recencyHalfLifeDays: asNonNegInt(v.recencyHalfLifeDays) || 14,\n maxAgeDays: asNonNegInt(v.maxAgeDays) || 30,\n };\n}\n\nconst EMPTY_SKIPPED: DreamingDeepPhaseSkipped = {\n alreadyPromotedKey: 0,\n rehydrateFailed: 0,\n contaminated: 0,\n hashDuplicate: 0,\n};\n\nfunction parseSkippedStrict(raw: unknown): DreamingDeepPhaseSkipped | null {\n if (!isRecord(raw)) return null;\n if (\n typeof raw.alreadyPromotedKey !== 'number' ||\n !Number.isFinite(raw.alreadyPromotedKey) ||\n typeof raw.rehydrateFailed !== 'number' ||\n !Number.isFinite(raw.rehydrateFailed) ||\n typeof raw.contaminated !== 'number' ||\n !Number.isFinite(raw.contaminated) ||\n typeof raw.hashDuplicate !== 'number' ||\n !Number.isFinite(raw.hashDuplicate)\n ) {\n return null;\n }\n return {\n alreadyPromotedKey: Math.max(0, Math.floor(raw.alreadyPromotedKey)),\n rehydrateFailed: Math.max(0, Math.floor(raw.rehydrateFailed)),\n contaminated: Math.max(0, Math.floor(raw.contaminated)),\n hashDuplicate: Math.max(0, Math.floor(raw.hashDuplicate)),\n };\n}\n\n/**\n * Parse `last-run.json`. Only the current on-disk format (`version: 2`, `phase: 'deep'`) is accepted.\n */\nexport function parseDreamingLastRunFile(raw: unknown): DreamingDeepLastRun | null {\n if (!isRecord(raw)) return null;\n if (raw.version !== DREAMING_LAST_RUN_FORMAT_VERSION || raw.phase !== 'deep') return null;\n\n if (typeof raw.runId !== 'string' || !raw.runId.trim()) return null;\n if (typeof raw.startedAt !== 'string' || typeof raw.finishedAt !== 'string') return null;\n if (!raw.startedAt.trim() || !raw.finishedAt.trim()) return null;\n\n if (typeof raw.durationMs !== 'number' || !Number.isFinite(raw.durationMs) || raw.durationMs < 0) {\n return null;\n }\n if (raw.ok !== true && raw.ok !== false) return null;\n if (typeof raw.reason !== 'string') return null;\n\n const config = asDreamingDeepConfig(raw.config);\n if (!config) return null;\n if (typeof raw.memoryPath !== 'string' || !raw.memoryPath.trim()) return null;\n\n const deepRaw = raw.deep;\n if (!isRecord(deepRaw)) return null;\n if (typeof deepRaw.candidatesRanked !== 'number' || !Number.isFinite(deepRaw.candidatesRanked)) {\n return null;\n }\n if (typeof deepRaw.applied !== 'number' || !Number.isFinite(deepRaw.applied)) return null;\n const skipped = parseSkippedStrict(deepRaw.skipped);\n if (!skipped) return null;\n\n const err = raw.errorMessage;\n const errMsg = typeof err === 'string' && err.trim() ? err.trim() : undefined;\n\n return {\n version: DREAMING_LAST_RUN_FORMAT_VERSION,\n phase: 'deep',\n runId: raw.runId.trim(),\n startedAt: raw.startedAt,\n finishedAt: raw.finishedAt,\n durationMs: Math.max(0, Math.floor(raw.durationMs)),\n ok: raw.ok === true,\n reason: raw.reason,\n config,\n memoryPath: raw.memoryPath,\n ...(errMsg ? { errorMessage: errMsg } : {}),\n deep: {\n candidatesRanked: Math.max(0, Math.floor(deepRaw.candidatesRanked)),\n applied: Math.max(0, Math.floor(deepRaw.applied)),\n skipped,\n },\n };\n}\n\nexport function emptyDeepPhaseSkipped(): DreamingDeepPhaseSkipped {\n return { ...EMPTY_SKIPPED };\n}\n\nexport async function writeDreamingDeepLastRun(params: {\n dreamingRoot: string;\n lastRun: DreamingDeepLastRun;\n}): Promise<void> {\n const fullPath = path.join(params.dreamingRoot, DREAMING_LAST_RUN_RELATIVE);\n await fs.mkdir(path.dirname(fullPath), { recursive: true });\n const tmp = `${fullPath}.${process.pid}.${Date.now()}.tmp`;\n await fs.writeFile(tmp, `${JSON.stringify(params.lastRun, null, 2)}\\n`, 'utf-8');\n await fs.rename(tmp, fullPath);\n}\n"],"mappings":"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"}
@@ -1,6 +1,6 @@
1
1
  import type { DreamingLightConfig } from './config.js';
2
2
  export declare function runLightSweep(params: {
3
- workspaceDir: string;
3
+ dreamingRoot: string;
4
4
  config?: Partial<DreamingLightConfig>;
5
5
  now?: Date;
6
6
  }): Promise<{
@@ -18,7 +18,7 @@ async function runLightSweep(params) {
18
18
  const runId = `light:${startedAt}:${process.pid}`;
19
19
  const startMs = Date.now();
20
20
  const reason = cfg.enabled ? "light sweep disabled: no implicit file source" : "light sweep disabled";
21
- await writeLastRun(params.workspaceDir, {
21
+ await writeLastRun(params.dreamingRoot, {
22
22
  runId,
23
23
  startedAt,
24
24
  cfg,
@@ -39,7 +39,7 @@ async function runLightSweep(params) {
39
39
  deduped: 0
40
40
  };
41
41
  }
42
- async function writeLastRun(workspaceDir, params) {
42
+ async function writeLastRun(dreamingRoot, params) {
43
43
  const finishedAt = (/* @__PURE__ */ new Date()).toISOString();
44
44
  const durationMs = Math.max(0, Date.now() - params.startMs);
45
45
  const lastRun = {
@@ -55,7 +55,7 @@ async function writeLastRun(workspaceDir, params) {
55
55
  light: params.light,
56
56
  ...params.errorMessage ? { errorMessage: params.errorMessage } : {}
57
57
  };
58
- const lastRunPath = path.join(workspaceDir, DREAMING_DIR_RELATIVE, "last-run-light.json");
58
+ const lastRunPath = path.join(dreamingRoot, DREAMING_DIR_RELATIVE, "last-run-light.json");
59
59
  await fs.mkdir(path.dirname(lastRunPath), { recursive: true });
60
60
  const tmp = `${lastRunPath}.${process.pid}.${Date.now()}.tmp`;
61
61
  await fs.writeFile(tmp, `${JSON.stringify(lastRun, null, 2)}\n`, "utf-8");
@@ -1 +1 @@
1
- {"version":3,"file":"light-sweep.js","names":[],"sources":["../../../../../src/agent/memory/dreaming/light-sweep.ts"],"sourcesContent":["import fs from 'node:fs/promises';\nimport path from 'node:path';\n\nimport { DREAMING_DIR_RELATIVE } from './constants.js';\nimport type { DreamingLightConfig } from './config.js';\nimport {\n DREAMING_LAST_RUN_FORMAT_VERSION,\n type DreamingLightLastRun,\n} from './last-run.js';\n\nfunction resolveConfig(overrides?: Partial<DreamingLightConfig>): DreamingLightConfig {\n return {\n enabled: overrides?.enabled === true,\n cron: typeof overrides?.cron === 'string' ? overrides.cron : '0 */6 * * *',\n lookbackDays: Math.max(1, Math.floor(Number(overrides?.lookbackDays) || 2)),\n limit: Math.max(0, Math.floor(Number(overrides?.limit) || 100)),\n dedupeSimilarity: Math.max(0, Math.min(1, Number(overrides?.dedupeSimilarity) || 0.9)),\n };\n}\n\nexport async function runLightSweep(params: {\n workspaceDir: string;\n config?: Partial<DreamingLightConfig>;\n now?: Date;\n}): Promise<{\n ok: boolean;\n reason: string;\n scannedEntries: number;\n newSignals: number;\n deduped: number;\n}> {\n const cfg = resolveConfig(params.config);\n const now = params.now ?? new Date();\n const startedAt = now.toISOString();\n const runId = `light:${startedAt}:${process.pid}`;\n const startMs = Date.now();\n const reason = cfg.enabled\n ? 'light sweep disabled: no implicit file source'\n : 'light sweep disabled';\n\n await writeLastRun(params.workspaceDir, {\n runId, startedAt, cfg, ok: true, reason, startMs,\n light: { scannedEntries: 0, newSignals: 0, deduped: 0 },\n });\n return { ok: true, reason, scannedEntries: 0, newSignals: 0, deduped: 0 };\n}\n\n// ── Last-run writer ────────────────────────────────────────────────────\n\nasync function writeLastRun(\n workspaceDir: string,\n params: {\n runId: string;\n startedAt: string;\n cfg: DreamingLightConfig;\n ok: boolean;\n reason: string;\n startMs: number;\n light: DreamingLightLastRun['light'];\n errorMessage?: string;\n },\n): Promise<void> {\n const finishedAt = new Date().toISOString();\n const durationMs = Math.max(0, Date.now() - params.startMs);\n\n const lastRun: DreamingLightLastRun = {\n version: DREAMING_LAST_RUN_FORMAT_VERSION,\n phase: 'light',\n runId: params.runId,\n startedAt: params.startedAt,\n finishedAt,\n durationMs,\n ok: params.ok,\n reason: params.reason,\n config: params.cfg,\n light: params.light,\n ...(params.errorMessage ? { errorMessage: params.errorMessage } : {}),\n };\n\n const lastRunPath = path.join(workspaceDir, DREAMING_DIR_RELATIVE, 'last-run-light.json');\n await fs.mkdir(path.dirname(lastRunPath), { recursive: true });\n const tmp = `${lastRunPath}.${process.pid}.${Date.now()}.tmp`;\n await fs.writeFile(tmp, `${JSON.stringify(lastRun, null, 2)}\\n`, 'utf-8');\n await fs.rename(tmp, lastRunPath);\n}\n"],"mappings":";;;;;AAUA,SAAS,cAAc,WAA+D;AACpF,QAAO;EACL,SAAS,WAAW,YAAY;EAChC,MAAM,OAAO,WAAW,SAAS,WAAW,UAAU,OAAO;EAC7D,cAAc,KAAK,IAAI,GAAG,KAAK,MAAM,OAAO,WAAW,aAAa,IAAI,EAAE,CAAC;EAC3E,OAAO,KAAK,IAAI,GAAG,KAAK,MAAM,OAAO,WAAW,MAAM,IAAI,IAAI,CAAC;EAC/D,kBAAkB,KAAK,IAAI,GAAG,KAAK,IAAI,GAAG,OAAO,WAAW,iBAAiB,IAAI,GAAI,CAAC;EACvF;;AAGH,eAAsB,cAAc,QAUjC;CACD,MAAM,MAAM,cAAc,OAAO,OAAO;CAExC,MAAM,aADM,OAAO,uBAAO,IAAI,MAAM,EACd,aAAa;CACnC,MAAM,QAAQ,SAAS,UAAU,GAAG,QAAQ;CAC5C,MAAM,UAAU,KAAK,KAAK;CAC1B,MAAM,SAAS,IAAI,UACf,kDACA;AAEJ,OAAM,aAAa,OAAO,cAAc;EACtC;EAAO;EAAW;EAAK,IAAI;EAAM;EAAQ;EACzC,OAAO;GAAE,gBAAgB;GAAG,YAAY;GAAG,SAAS;GAAG;EACxD,CAAC;AACF,QAAO;EAAE,IAAI;EAAM;EAAQ,gBAAgB;EAAG,YAAY;EAAG,SAAS;EAAG;;AAK3E,eAAe,aACb,cACA,QAUe;CACf,MAAM,8BAAa,IAAI,MAAM,EAAC,aAAa;CAC3C,MAAM,aAAa,KAAK,IAAI,GAAG,KAAK,KAAK,GAAG,OAAO,QAAQ;CAE3D,MAAM,UAAgC;EACpC,SAAA;EACA,OAAO;EACP,OAAO,OAAO;EACd,WAAW,OAAO;EAClB;EACA;EACA,IAAI,OAAO;EACX,QAAQ,OAAO;EACf,QAAQ,OAAO;EACf,OAAO,OAAO;EACd,GAAI,OAAO,eAAe,EAAE,cAAc,OAAO,cAAc,GAAG,EAAE;EACrE;CAED,MAAM,cAAc,KAAK,KAAK,cAAc,uBAAuB,sBAAsB;AACzF,OAAM,GAAG,MAAM,KAAK,QAAQ,YAAY,EAAE,EAAE,WAAW,MAAM,CAAC;CAC9D,MAAM,MAAM,GAAG,YAAY,GAAG,QAAQ,IAAI,GAAG,KAAK,KAAK,CAAC;AACxD,OAAM,GAAG,UAAU,KAAK,GAAG,KAAK,UAAU,SAAS,MAAM,EAAE,CAAC,KAAK,QAAQ;AACzE,OAAM,GAAG,OAAO,KAAK,YAAY"}
1
+ {"version":3,"file":"light-sweep.js","names":[],"sources":["../../../../../src/agent/memory/dreaming/light-sweep.ts"],"sourcesContent":["import fs from 'node:fs/promises';\nimport path from 'node:path';\n\nimport { DREAMING_DIR_RELATIVE } from './constants.js';\nimport type { DreamingLightConfig } from './config.js';\nimport {\n DREAMING_LAST_RUN_FORMAT_VERSION,\n type DreamingLightLastRun,\n} from './last-run.js';\n\nfunction resolveConfig(overrides?: Partial<DreamingLightConfig>): DreamingLightConfig {\n return {\n enabled: overrides?.enabled === true,\n cron: typeof overrides?.cron === 'string' ? overrides.cron : '0 */6 * * *',\n lookbackDays: Math.max(1, Math.floor(Number(overrides?.lookbackDays) || 2)),\n limit: Math.max(0, Math.floor(Number(overrides?.limit) || 100)),\n dedupeSimilarity: Math.max(0, Math.min(1, Number(overrides?.dedupeSimilarity) || 0.9)),\n };\n}\n\nexport async function runLightSweep(params: {\n dreamingRoot: string;\n config?: Partial<DreamingLightConfig>;\n now?: Date;\n}): Promise<{\n ok: boolean;\n reason: string;\n scannedEntries: number;\n newSignals: number;\n deduped: number;\n}> {\n const cfg = resolveConfig(params.config);\n const now = params.now ?? new Date();\n const startedAt = now.toISOString();\n const runId = `light:${startedAt}:${process.pid}`;\n const startMs = Date.now();\n const reason = cfg.enabled\n ? 'light sweep disabled: no implicit file source'\n : 'light sweep disabled';\n\n await writeLastRun(params.dreamingRoot, {\n runId, startedAt, cfg, ok: true, reason, startMs,\n light: { scannedEntries: 0, newSignals: 0, deduped: 0 },\n });\n return { ok: true, reason, scannedEntries: 0, newSignals: 0, deduped: 0 };\n}\n\n// ── Last-run writer ────────────────────────────────────────────────────\n\nasync function writeLastRun(\n dreamingRoot: string,\n params: {\n runId: string;\n startedAt: string;\n cfg: DreamingLightConfig;\n ok: boolean;\n reason: string;\n startMs: number;\n light: DreamingLightLastRun['light'];\n errorMessage?: string;\n },\n): Promise<void> {\n const finishedAt = new Date().toISOString();\n const durationMs = Math.max(0, Date.now() - params.startMs);\n\n const lastRun: DreamingLightLastRun = {\n version: DREAMING_LAST_RUN_FORMAT_VERSION,\n phase: 'light',\n runId: params.runId,\n startedAt: params.startedAt,\n finishedAt,\n durationMs,\n ok: params.ok,\n reason: params.reason,\n config: params.cfg,\n light: params.light,\n ...(params.errorMessage ? { errorMessage: params.errorMessage } : {}),\n };\n\n const lastRunPath = path.join(dreamingRoot, DREAMING_DIR_RELATIVE, 'last-run-light.json');\n await fs.mkdir(path.dirname(lastRunPath), { recursive: true });\n const tmp = `${lastRunPath}.${process.pid}.${Date.now()}.tmp`;\n await fs.writeFile(tmp, `${JSON.stringify(lastRun, null, 2)}\\n`, 'utf-8');\n await fs.rename(tmp, lastRunPath);\n}\n"],"mappings":";;;;;AAUA,SAAS,cAAc,WAA+D;AACpF,QAAO;EACL,SAAS,WAAW,YAAY;EAChC,MAAM,OAAO,WAAW,SAAS,WAAW,UAAU,OAAO;EAC7D,cAAc,KAAK,IAAI,GAAG,KAAK,MAAM,OAAO,WAAW,aAAa,IAAI,EAAE,CAAC;EAC3E,OAAO,KAAK,IAAI,GAAG,KAAK,MAAM,OAAO,WAAW,MAAM,IAAI,IAAI,CAAC;EAC/D,kBAAkB,KAAK,IAAI,GAAG,KAAK,IAAI,GAAG,OAAO,WAAW,iBAAiB,IAAI,GAAI,CAAC;EACvF;;AAGH,eAAsB,cAAc,QAUjC;CACD,MAAM,MAAM,cAAc,OAAO,OAAO;CAExC,MAAM,aADM,OAAO,uBAAO,IAAI,MAAM,EACd,aAAa;CACnC,MAAM,QAAQ,SAAS,UAAU,GAAG,QAAQ;CAC5C,MAAM,UAAU,KAAK,KAAK;CAC1B,MAAM,SAAS,IAAI,UACf,kDACA;AAEJ,OAAM,aAAa,OAAO,cAAc;EACtC;EAAO;EAAW;EAAK,IAAI;EAAM;EAAQ;EACzC,OAAO;GAAE,gBAAgB;GAAG,YAAY;GAAG,SAAS;GAAG;EACxD,CAAC;AACF,QAAO;EAAE,IAAI;EAAM;EAAQ,gBAAgB;EAAG,YAAY;EAAG,SAAS;EAAG;;AAK3E,eAAe,aACb,cACA,QAUe;CACf,MAAM,8BAAa,IAAI,MAAM,EAAC,aAAa;CAC3C,MAAM,aAAa,KAAK,IAAI,GAAG,KAAK,KAAK,GAAG,OAAO,QAAQ;CAE3D,MAAM,UAAgC;EACpC,SAAA;EACA,OAAO;EACP,OAAO,OAAO;EACd,WAAW,OAAO;EAClB;EACA;EACA,IAAI,OAAO;EACX,QAAQ,OAAO;EACf,QAAQ,OAAO;EACf,OAAO,OAAO;EACd,GAAI,OAAO,eAAe,EAAE,cAAc,OAAO,cAAc,GAAG,EAAE;EACrE;CAED,MAAM,cAAc,KAAK,KAAK,cAAc,uBAAuB,sBAAsB;AACzF,OAAM,GAAG,MAAM,KAAK,QAAQ,YAAY,EAAE,EAAE,WAAW,MAAM,CAAC;CAC9D,MAAM,MAAM,GAAG,YAAY,GAAG,QAAQ,IAAI,GAAG,KAAK,KAAK,CAAC;AACxD,OAAM,GAAG,UAAU,KAAK,GAAG,KAAK,UAAU,SAAS,MAAM,EAAE,CAAC,KAAK,QAAQ;AACzE,OAAM,GAAG,OAAO,KAAK,YAAY"}
@@ -16,6 +16,7 @@ type PreviewItem = {
16
16
  };
17
17
  export declare function previewDreamingDeepPromotion(params: {
18
18
  workspaceDir: string;
19
+ dreamingRoot: string;
19
20
  config?: Partial<DreamingDeepConfig>;
20
21
  limit?: number;
21
22
  now?: Date;
@@ -6,14 +6,14 @@ import fs from "node:fs/promises";
6
6
  //#region src/agent/memory/dreaming/preview.ts
7
7
  async function previewDreamingDeepPromotion(params) {
8
8
  const cfg = resolveDeepDefaults(params.config);
9
- const memoryPath = path.join(params.workspaceDir, MEMORY_MD_FILENAME);
9
+ const memoryPath = path.join(params.dreamingRoot, MEMORY_MD_FILENAME);
10
10
  if (!cfg.enabled) return {
11
11
  ok: true,
12
12
  reason: "dreaming disabled",
13
13
  items: [],
14
14
  memoryPath
15
15
  };
16
- const { store } = await loadDreamingStore({ workspaceDir: params.workspaceDir });
16
+ const { store } = await loadDreamingStore({ dreamingRoot: params.dreamingRoot });
17
17
  const nowMs = (params.now ?? /* @__PURE__ */ new Date()).getTime();
18
18
  const ranked = Object.values(store.entries ?? {}).filter((e) => {
19
19
  if (!e || typeof e !== "object") return false;
@@ -1 +1 @@
1
- {"version":3,"file":"preview.js","names":[],"sources":["../../../../../src/agent/memory/dreaming/preview.ts"],"sourcesContent":["import fs from 'node:fs/promises';\nimport path from 'node:path';\n\nimport type { DreamingDeepConfig } from './config.js';\nimport { MEMORY_MD_FILENAME } from './constants.js';\nimport { loadDreamingStore, type DreamingStoreEntry } from './short-term-store.js';\nimport {\n clamp01,\n compareCandidatesByScore,\n computeCandidateScore,\n extractPromotionMarkers,\n isContaminatedSnippet,\n isExpiredEntry,\n readFileLines,\n resolveDeepDefaults,\n sliceRange,\n snippetHash,\n} from './utils.js';\n\ntype PreviewItem = {\n key: string;\n hash: string;\n snippet: string;\n path: string;\n startLine: number;\n endLine: number;\n score: number;\n avgScore: number;\n recallCount: number;\n recencyDecay: number;\n alreadyPromotedByKey: boolean;\n alreadyPromotedByHash: boolean;\n skippedReason: string | null;\n};\n\nexport async function previewDreamingDeepPromotion(params: {\n workspaceDir: string;\n config?: Partial<DreamingDeepConfig>;\n limit?: number;\n now?: Date;\n}): Promise<{ ok: boolean; reason: string; items: PreviewItem[]; memoryPath: string }> {\n const cfg = resolveDeepDefaults(params.config);\n const memoryPath = path.join(params.workspaceDir, MEMORY_MD_FILENAME);\n if (!cfg.enabled) return { ok: true, reason: 'dreaming disabled', items: [], memoryPath };\n\n const { store } = await loadDreamingStore({ workspaceDir: params.workspaceDir });\n const nowMs = (params.now ?? new Date()).getTime();\n\n const all = Object.values(store.entries ?? {}).filter((e): e is DreamingStoreEntry => {\n if (!e || typeof e !== 'object') return false;\n if (e.promotedAt) return false;\n if (!e.path || !e.path.startsWith('memory/')) return false;\n if (e.recallCount < cfg.minRecallCount) return false;\n if ((e.queryHashes?.length ?? 0) < cfg.minUniqueQueries) return false;\n if (isExpiredEntry(e.lastRecalledAt, nowMs, cfg.maxAgeDays)) return false;\n const avg = e.recallCount > 0 ? e.totalScore / e.recallCount : 0;\n return clamp01(avg) >= cfg.minScore;\n });\n\n const ranked = all\n .map((e) => {\n const { avgScore, score, recencyDecay } = computeCandidateScore(e, nowMs, cfg.recencyHalfLifeDays);\n return { ...e, avgScore, score, recencyDecay };\n })\n .sort(compareCandidatesByScore);\n\n const existing = await fs.readFile(memoryPath, 'utf-8').catch((err: unknown) => {\n if ((err as NodeJS.ErrnoException | undefined)?.code === 'ENOENT') return '';\n throw err;\n });\n const markers = extractPromotionMarkers(existing);\n\n const limit = Math.min(Math.max(params.limit ?? 20, 1), 50);\n const out: PreviewItem[] = [];\n\n // Scan more than limit so filtering doesn't yield empty previews.\n const scanCap = Math.min(ranked.length, Math.max(limit * 3, limit));\n for (const candidate of ranked.slice(0, scanCap)) {\n const alreadyPromotedByKey = markers.keys.has(candidate.key);\n if (alreadyPromotedByKey) {\n out.push({\n key: candidate.key,\n hash: '',\n snippet: '',\n path: candidate.path,\n startLine: candidate.startLine,\n endLine: candidate.endLine,\n score: candidate.score,\n avgScore: candidate.avgScore,\n recallCount: candidate.recallCount,\n recencyDecay: candidate.recencyDecay,\n alreadyPromotedByKey: true,\n alreadyPromotedByHash: false,\n skippedReason: 'already promoted (key)',\n });\n continue;\n }\n\n const fullPath = path.join(params.workspaceDir, candidate.path);\n const lines = await readFileLines(fullPath);\n if (!lines) continue;\n const startLine = Math.max(1, Math.floor(candidate.startLine));\n const endLine = Math.max(startLine, Math.floor(candidate.endLine));\n const snippet = sliceRange(lines, startLine, endLine);\n if (!snippet) continue;\n if (isContaminatedSnippet(snippet)) continue;\n const hash = snippetHash(snippet);\n const alreadyPromotedByHash = markers.hashes.has(hash);\n out.push({\n key: candidate.key,\n hash,\n snippet,\n path: candidate.path,\n startLine,\n endLine,\n score: candidate.score,\n avgScore: candidate.avgScore,\n recallCount: candidate.recallCount,\n recencyDecay: candidate.recencyDecay,\n alreadyPromotedByKey: false,\n alreadyPromotedByHash,\n skippedReason: alreadyPromotedByHash ? 'already promoted (hash)' : null,\n });\n if (out.filter((x) => !x.skippedReason).length >= limit) break;\n }\n\n return { ok: true, reason: 'ok', items: out, memoryPath };\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"preview.js","names":[],"sources":["../../../../../src/agent/memory/dreaming/preview.ts"],"sourcesContent":["import fs from 'node:fs/promises';\nimport path from 'node:path';\n\nimport type { DreamingDeepConfig } from './config.js';\nimport { MEMORY_MD_FILENAME } from './constants.js';\nimport { loadDreamingStore, type DreamingStoreEntry } from './short-term-store.js';\nimport {\n clamp01,\n compareCandidatesByScore,\n computeCandidateScore,\n extractPromotionMarkers,\n isContaminatedSnippet,\n isExpiredEntry,\n readFileLines,\n resolveDeepDefaults,\n sliceRange,\n snippetHash,\n} from './utils.js';\n\ntype PreviewItem = {\n key: string;\n hash: string;\n snippet: string;\n path: string;\n startLine: number;\n endLine: number;\n score: number;\n avgScore: number;\n recallCount: number;\n recencyDecay: number;\n alreadyPromotedByKey: boolean;\n alreadyPromotedByHash: boolean;\n skippedReason: string | null;\n};\n\nexport async function previewDreamingDeepPromotion(params: {\n workspaceDir: string;\n dreamingRoot: string;\n config?: Partial<DreamingDeepConfig>;\n limit?: number;\n now?: Date;\n}): Promise<{ ok: boolean; reason: string; items: PreviewItem[]; memoryPath: string }> {\n const cfg = resolveDeepDefaults(params.config);\n const memoryPath = path.join(params.dreamingRoot, MEMORY_MD_FILENAME);\n if (!cfg.enabled) return { ok: true, reason: 'dreaming disabled', items: [], memoryPath };\n\n const { store } = await loadDreamingStore({ dreamingRoot: params.dreamingRoot });\n const nowMs = (params.now ?? new Date()).getTime();\n\n const all = Object.values(store.entries ?? {}).filter((e): e is DreamingStoreEntry => {\n if (!e || typeof e !== 'object') return false;\n if (e.promotedAt) return false;\n if (!e.path || !e.path.startsWith('memory/')) return false;\n if (e.recallCount < cfg.minRecallCount) return false;\n if ((e.queryHashes?.length ?? 0) < cfg.minUniqueQueries) return false;\n if (isExpiredEntry(e.lastRecalledAt, nowMs, cfg.maxAgeDays)) return false;\n const avg = e.recallCount > 0 ? e.totalScore / e.recallCount : 0;\n return clamp01(avg) >= cfg.minScore;\n });\n\n const ranked = all\n .map((e) => {\n const { avgScore, score, recencyDecay } = computeCandidateScore(e, nowMs, cfg.recencyHalfLifeDays);\n return { ...e, avgScore, score, recencyDecay };\n })\n .sort(compareCandidatesByScore);\n\n const existing = await fs.readFile(memoryPath, 'utf-8').catch((err: unknown) => {\n if ((err as NodeJS.ErrnoException | undefined)?.code === 'ENOENT') return '';\n throw err;\n });\n const markers = extractPromotionMarkers(existing);\n\n const limit = Math.min(Math.max(params.limit ?? 20, 1), 50);\n const out: PreviewItem[] = [];\n\n // Scan more than limit so filtering doesn't yield empty previews.\n const scanCap = Math.min(ranked.length, Math.max(limit * 3, limit));\n for (const candidate of ranked.slice(0, scanCap)) {\n const alreadyPromotedByKey = markers.keys.has(candidate.key);\n if (alreadyPromotedByKey) {\n out.push({\n key: candidate.key,\n hash: '',\n snippet: '',\n path: candidate.path,\n startLine: candidate.startLine,\n endLine: candidate.endLine,\n score: candidate.score,\n avgScore: candidate.avgScore,\n recallCount: candidate.recallCount,\n recencyDecay: candidate.recencyDecay,\n alreadyPromotedByKey: true,\n alreadyPromotedByHash: false,\n skippedReason: 'already promoted (key)',\n });\n continue;\n }\n\n const fullPath = path.join(params.workspaceDir, candidate.path);\n const lines = await readFileLines(fullPath);\n if (!lines) continue;\n const startLine = Math.max(1, Math.floor(candidate.startLine));\n const endLine = Math.max(startLine, Math.floor(candidate.endLine));\n const snippet = sliceRange(lines, startLine, endLine);\n if (!snippet) continue;\n if (isContaminatedSnippet(snippet)) continue;\n const hash = snippetHash(snippet);\n const alreadyPromotedByHash = markers.hashes.has(hash);\n out.push({\n key: candidate.key,\n hash,\n snippet,\n path: candidate.path,\n startLine,\n endLine,\n score: candidate.score,\n avgScore: candidate.avgScore,\n recallCount: candidate.recallCount,\n recencyDecay: candidate.recencyDecay,\n alreadyPromotedByKey: false,\n alreadyPromotedByHash,\n skippedReason: alreadyPromotedByHash ? 'already promoted (hash)' : null,\n });\n if (out.filter((x) => !x.skippedReason).length >= limit) break;\n }\n\n return { ok: true, reason: 'ok', items: out, memoryPath };\n}\n"],"mappings":"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"}
@@ -10,7 +10,7 @@ import type { DreamingRemConfig } from './config.js';
10
10
  * Runs weekly; expensive but insightful.
11
11
  */
12
12
  export declare function runRemPatterns(params: {
13
- workspaceDir: string;
13
+ dreamingRoot: string;
14
14
  config?: Partial<DreamingRemConfig>;
15
15
  now?: Date;
16
16
  }): Promise<{
@@ -36,7 +36,7 @@ async function runRemPatterns(params) {
36
36
  const startMs = Date.now();
37
37
  const nowMs = now.getTime();
38
38
  if (!cfg.enabled) {
39
- await writeLastRun(params.workspaceDir, {
39
+ await writeLastRun(params.dreamingRoot, {
40
40
  runId,
41
41
  startedAt,
42
42
  cfg,
@@ -56,7 +56,7 @@ async function runRemPatterns(params) {
56
56
  };
57
57
  }
58
58
  try {
59
- const { store } = await loadDreamingStore({ workspaceDir: params.workspaceDir });
59
+ const { store } = await loadDreamingStore({ dreamingRoot: params.dreamingRoot });
60
60
  const cutoffMs = nowMs - cfg.lookbackDays * MS_PER_DAY;
61
61
  const recentEntries = Object.values(store.entries ?? {}).filter((entry) => {
62
62
  if (!entry || typeof entry !== "object") return false;
@@ -65,7 +65,7 @@ async function runRemPatterns(params) {
65
65
  return Number.isFinite(lastMs) && lastMs >= cutoffMs;
66
66
  });
67
67
  if (recentEntries.length < 2) {
68
- await writeLastRun(params.workspaceDir, {
68
+ await writeLastRun(params.dreamingRoot, {
69
69
  runId,
70
70
  startedAt,
71
71
  cfg,
@@ -93,17 +93,17 @@ async function runRemPatterns(params) {
93
93
  }
94
94
  store.updatedAt = now.toISOString();
95
95
  await saveDreamingStore({
96
- workspaceDir: params.workspaceDir,
96
+ dreamingRoot: params.dreamingRoot,
97
97
  store
98
98
  });
99
- if (topClusters.length > 0) await appendPatternSummary(params.workspaceDir, topClusters, now);
99
+ if (topClusters.length > 0) await appendPatternSummary(params.dreamingRoot, topClusters, now);
100
100
  log.info({
101
- workspaceDir: params.workspaceDir,
101
+ dreamingRoot: params.dreamingRoot,
102
102
  patterns: topClusters.length,
103
103
  entriesAnalyzed: recentEntries.length,
104
104
  touched: touchedKeys.size
105
105
  }, "REM pattern discovery complete");
106
- await writeLastRun(params.workspaceDir, {
106
+ await writeLastRun(params.dreamingRoot, {
107
107
  runId,
108
108
  startedAt,
109
109
  cfg,
@@ -126,9 +126,9 @@ async function runRemPatterns(params) {
126
126
  log.error({
127
127
  err,
128
128
  errorMessage,
129
- workspaceDir: params.workspaceDir
129
+ dreamingRoot: params.dreamingRoot
130
130
  }, `REM pattern discovery failed: ${errorMessage}`);
131
- await writeLastRun(params.workspaceDir, {
131
+ await writeLastRun(params.dreamingRoot, {
132
132
  runId,
133
133
  startedAt,
134
134
  cfg,
@@ -230,8 +230,8 @@ function discoverPatternClusters(entries, minStrength) {
230
230
  });
231
231
  return scoredClusters;
232
232
  }
233
- async function appendPatternSummary(workspaceDir, clusters, now) {
234
- const dreamsPath = path.join(workspaceDir, DREAMS_MD_FILENAME);
233
+ async function appendPatternSummary(dreamingRoot, clusters, now) {
234
+ const dreamsPath = path.join(dreamingRoot, DREAMS_MD_FILENAME);
235
235
  const existing = await fs.readFile(dreamsPath, "utf-8").catch((err) => {
236
236
  if (err?.code === "ENOENT") return "";
237
237
  throw err;
@@ -258,7 +258,7 @@ async function appendPatternSummary(workspaceDir, clusters, now) {
258
258
  const next = `${existing}${existing.trim().length > 0 && !existing.endsWith("\n") ? "\n" : ""}${lines.join("\n")}`;
259
259
  await fs.writeFile(dreamsPath, next, "utf-8");
260
260
  }
261
- async function writeLastRun(workspaceDir, params) {
261
+ async function writeLastRun(dreamingRoot, params) {
262
262
  const finishedAt = (/* @__PURE__ */ new Date()).toISOString();
263
263
  const durationMs = Math.max(0, Date.now() - params.startMs);
264
264
  const lastRun = {
@@ -274,7 +274,7 @@ async function writeLastRun(workspaceDir, params) {
274
274
  rem: params.rem,
275
275
  ...params.errorMessage ? { errorMessage: params.errorMessage } : {}
276
276
  };
277
- const lastRunPath = path.join(workspaceDir, DREAMING_DIR_RELATIVE, "last-run-rem.json");
277
+ const lastRunPath = path.join(dreamingRoot, DREAMING_DIR_RELATIVE, "last-run-rem.json");
278
278
  await fs.mkdir(path.dirname(lastRunPath), { recursive: true });
279
279
  const tmp = `${lastRunPath}.${process.pid}.${Date.now()}.tmp`;
280
280
  await fs.writeFile(tmp, `${JSON.stringify(lastRun, null, 2)}\n`, "utf-8");