@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
@@ -404,6 +404,147 @@ CREATE INDEX IF NOT EXISTS idx_goals_agent_updated
404
404
  CREATE INDEX IF NOT EXISTS idx_goals_active_session
405
405
  ON goals(active_session_key);
406
406
 
407
+ CREATE TABLE IF NOT EXISTS work_items (
408
+ id TEXT PRIMARY KEY,
409
+ project_id TEXT NOT NULL,
410
+ title TEXT NOT NULL,
411
+ description TEXT,
412
+ status TEXT NOT NULL,
413
+ priority TEXT NOT NULL DEFAULT 'normal',
414
+ owner_agent_id TEXT,
415
+ next_action TEXT,
416
+ blocked_reason TEXT,
417
+ due_at INTEGER,
418
+ completed_at INTEGER,
419
+ archived_at INTEGER,
420
+ created_at INTEGER NOT NULL,
421
+ updated_at INTEGER NOT NULL
422
+ );
423
+
424
+ CREATE INDEX IF NOT EXISTS idx_work_items_project_status
425
+ ON work_items(project_id, status, archived_at, updated_at DESC);
426
+
427
+ CREATE TABLE IF NOT EXISTS work_item_links (
428
+ id TEXT PRIMARY KEY,
429
+ work_item_id TEXT NOT NULL,
430
+ kind TEXT NOT NULL,
431
+ target_id TEXT NOT NULL,
432
+ title TEXT,
433
+ status_snapshot TEXT,
434
+ created_at INTEGER NOT NULL
435
+ );
436
+
437
+ CREATE INDEX IF NOT EXISTS idx_work_item_links_item
438
+ ON work_item_links(work_item_id, created_at DESC);
439
+
440
+ CREATE TABLE IF NOT EXISTS work_item_events (
441
+ id TEXT PRIMARY KEY,
442
+ work_item_id TEXT NOT NULL,
443
+ type TEXT NOT NULL,
444
+ payload_json TEXT,
445
+ created_at INTEGER NOT NULL
446
+ );
447
+
448
+ CREATE INDEX IF NOT EXISTS idx_work_item_events_item
449
+ ON work_item_events(work_item_id, created_at DESC);
450
+
451
+ CREATE TABLE IF NOT EXISTS work_item_attachments (
452
+ id TEXT PRIMARY KEY,
453
+ work_item_id TEXT NOT NULL,
454
+ media_uri TEXT NOT NULL,
455
+ media_id TEXT NOT NULL,
456
+ bucket TEXT NOT NULL,
457
+ type TEXT NOT NULL,
458
+ mime_type TEXT NOT NULL,
459
+ file_name TEXT NOT NULL,
460
+ size INTEGER NOT NULL,
461
+ created_at INTEGER NOT NULL
462
+ );
463
+
464
+ CREATE INDEX IF NOT EXISTS idx_work_item_attachments_item
465
+ ON work_item_attachments(work_item_id, created_at DESC);
466
+
467
+ CREATE TABLE IF NOT EXISTS work_item_update_suggestions (
468
+ id TEXT PRIMARY KEY,
469
+ work_item_id TEXT NOT NULL,
470
+ source_kind TEXT NOT NULL,
471
+ source_id TEXT NOT NULL,
472
+ status TEXT NOT NULL,
473
+ patch_json TEXT NOT NULL DEFAULT '{}',
474
+ progress_note TEXT,
475
+ rationale TEXT,
476
+ confidence REAL,
477
+ created_at INTEGER NOT NULL,
478
+ applied_at INTEGER,
479
+ dismissed_at INTEGER
480
+ );
481
+
482
+ CREATE INDEX IF NOT EXISTS idx_work_item_update_suggestions_item
483
+ ON work_item_update_suggestions(work_item_id, status, created_at DESC);
484
+
485
+ CREATE TABLE IF NOT EXISTS activity_events (
486
+ id TEXT PRIMARY KEY,
487
+ type TEXT NOT NULL,
488
+ primary_object_kind TEXT NOT NULL,
489
+ primary_object_id TEXT NOT NULL,
490
+ primary_object_title TEXT,
491
+ actor_json TEXT NOT NULL,
492
+ initiator_json TEXT,
493
+ source_json TEXT NOT NULL,
494
+ payload_json TEXT NOT NULL DEFAULT '{}',
495
+ visibility TEXT NOT NULL,
496
+ importance TEXT NOT NULL,
497
+ created_at INTEGER NOT NULL
498
+ );
499
+
500
+ CREATE INDEX IF NOT EXISTS idx_activity_events_created
501
+ ON activity_events(created_at DESC);
502
+
503
+ CREATE INDEX IF NOT EXISTS idx_activity_events_object_created
504
+ ON activity_events(primary_object_kind, primary_object_id, created_at DESC);
505
+
506
+ CREATE TABLE IF NOT EXISTS activity_scopes (
507
+ activity_id TEXT NOT NULL,
508
+ scope_kind TEXT NOT NULL,
509
+ scope_id TEXT NOT NULL,
510
+ reason TEXT NOT NULL,
511
+ PRIMARY KEY (activity_id, scope_kind, scope_id, reason)
512
+ );
513
+
514
+ CREATE INDEX IF NOT EXISTS idx_activity_scopes_scope
515
+ ON activity_scopes(scope_kind, scope_id, activity_id);
516
+
517
+ CREATE TABLE IF NOT EXISTS object_links (
518
+ id TEXT PRIMARY KEY,
519
+ from_kind TEXT NOT NULL,
520
+ from_id TEXT NOT NULL,
521
+ from_title TEXT,
522
+ to_kind TEXT NOT NULL,
523
+ to_id TEXT NOT NULL,
524
+ to_title TEXT,
525
+ relation TEXT NOT NULL,
526
+ source TEXT NOT NULL,
527
+ created_at INTEGER NOT NULL
528
+ );
529
+
530
+ CREATE INDEX IF NOT EXISTS idx_object_links_from
531
+ ON object_links(from_kind, from_id);
532
+
533
+ CREATE INDEX IF NOT EXISTS idx_object_links_to
534
+ ON object_links(to_kind, to_id);
535
+
536
+ CREATE TABLE IF NOT EXISTS activity_related_projects (
537
+ activity_id TEXT NOT NULL,
538
+ project_id TEXT NOT NULL,
539
+ reason TEXT NOT NULL,
540
+ confidence REAL NOT NULL,
541
+ computed_at INTEGER NOT NULL,
542
+ PRIMARY KEY (activity_id, project_id, reason)
543
+ );
544
+
545
+ CREATE INDEX IF NOT EXISTS idx_activity_related_projects_project
546
+ ON activity_related_projects(project_id, activity_id);
547
+
407
548
  CREATE TABLE IF NOT EXISTS goal_context_messages (
408
549
  goal_id TEXT PRIMARY KEY,
409
550
  text TEXT NOT NULL DEFAULT '',
@@ -93,6 +93,17 @@ function listSessionMetadata(query = {}) {
93
93
  if (query.projectId) {
94
94
  conditions.push(`s.project_id = ?`);
95
95
  params.push(query.projectId);
96
+ } else if (query.unassigned) conditions.push(`(s.project_id IS NULL OR s.project_id = '')`);
97
+ if (query.updatedAfter !== void 0) {
98
+ const clauses = [`s.updated_at >= ?`];
99
+ params.push(query.updatedAfter);
100
+ if (query.includePinned) clauses.push(`s.status = 'pinned'`);
101
+ const includeSessionKey = query.includeSessionKey?.trim();
102
+ if (includeSessionKey) {
103
+ clauses.push(`s.session_key = ?`);
104
+ params.push(includeSessionKey);
105
+ }
106
+ conditions.push(`(${clauses.join(" OR ")})`);
96
107
  }
97
108
  if (query.channel) {
98
109
  const rawChannels = query.channel.split(",").map((c) => c.trim().toLowerCase()).filter(Boolean);
@@ -1 +1 @@
1
- {"version":3,"file":"session-repository.js","names":[],"sources":["../../../../src/storage/sqlite/session-repository.ts"],"sourcesContent":["import { randomUUID } from 'node:crypto';\nimport type { DatabaseSync } from 'node:sqlite';\n\nimport { validateSessionId } from '../../session/session-id.js';\nimport type { SessionListQuery, SessionMetadata, PaginatedResult } from '../../session/types.js';\nimport { buildDefaultSessionMetadata, type SessionMetadataSeed } from './session-metadata.js';\nimport {\n buildGlobalSessionStats,\n metadataToSessionInsert,\n sessionRowToMetadata,\n type SessionRow,\n} from './row-mappers.js';\nimport { getSqliteDatabase, runSqliteWriteTransaction } from './transaction.js';\n\nconst SESSION_COLUMNS = `\n s.session_key, s.agent_id, s.session_id, s.status, s.name, s.tags_json,\n s.created_at, s.updated_at, s.last_accessed_at, s.session_started_at, s.last_interaction_at,\n s.source_channel, s.source_chat_id, s.session_type, s.hidden_from_session_list,\n s.parent_session_key, s.workflow_run_id, s.workflow_definition_id, s.workflow_agent_id, s.workflow_agent_label,\n s.project_id, s.routing_json, s.custom_data_json,\n s.abort_cutoff_timestamp, s.message_count, s.estimated_tokens, s.compacted_count,\n s.last_flushed_at, s.flush_count,\n s.thinking_level, s.verbose_level,\n t.cwd AS cwd\n`;\n\nimport { escapeFts5Query } from './fts.js';\n\nconst SESSION_FROM_JOIN = `\n FROM sessions s\n LEFT JOIN transcripts t ON t.session_id = s.session_id\n`;\n\nconst SELECT_SESSION = `SELECT ${SESSION_COLUMNS} ${SESSION_FROM_JOIN} WHERE s.session_key = ?`;\n\nfunction readSessionRow(db: DatabaseSync, sessionKey: string): SessionRow | undefined {\n return db.prepare(SELECT_SESSION).get(sessionKey) as SessionRow | undefined;\n}\n\nfunction insertSessionAndTranscript(\n db: DatabaseSync,\n sessionKey: string,\n sessionId: string,\n cwd: string,\n metadata: SessionMetadata,\n): void {\n const row = metadataToSessionInsert(sessionKey, sessionId, metadata);\n db.prepare(\n `INSERT INTO sessions (\n session_key, agent_id, session_id, status, name, tags_json,\n created_at, updated_at, last_accessed_at, session_started_at, last_interaction_at,\n source_channel, source_chat_id, session_type, hidden_from_session_list,\n parent_session_key, workflow_run_id, workflow_definition_id, workflow_agent_id, workflow_agent_label,\n project_id, routing_json, custom_data_json,\n abort_cutoff_timestamp, message_count, estimated_tokens, compacted_count,\n last_flushed_at, flush_count,\n thinking_level, verbose_level\n ) VALUES (\n ?, ?, ?, ?, ?, ?,\n ?, ?, ?, ?, ?,\n ?, ?, ?, ?,\n ?, ?, ?, ?, ?,\n ?, ?, ?,\n ?, ?, ?, ?, ?, ?,\n ?, ?\n )`,\n ).run(\n row.sessionKey,\n row.agentId,\n row.sessionId,\n row.status,\n row.name,\n row.tagsJson,\n row.createdAt,\n row.updatedAt,\n row.lastAccessedAt,\n row.sessionStartedAt,\n row.lastInteractionAt,\n row.sourceChannel,\n row.sourceChatId,\n row.sessionType,\n row.hiddenFromSessionList,\n row.parentSessionKey,\n row.workflowRunId,\n row.workflowDefinitionId,\n row.workflowAgentId,\n row.workflowAgentLabel,\n row.projectId,\n row.routingJson,\n row.customDataJson,\n row.abortCutoffTimestamp,\n row.messageCount,\n row.estimatedTokens,\n row.compactedCount,\n row.lastFlushedAt,\n row.flushCount,\n row.thinkingLevel,\n row.verboseLevel,\n );\n\n const now = Date.now();\n db.prepare(\n `INSERT INTO transcripts (session_id, session_key, status, created_at, cwd)\n VALUES (?, ?, 'active', ?, ?)`,\n ).run(sessionId, sessionKey, now, cwd);\n}\n\nexport function ensureSessionInTransaction(\n db: DatabaseSync,\n sessionKey: string,\n cwd: string,\n seed?: SessionMetadataSeed,\n): SessionMetadata {\n const existing = readSessionRow(db, sessionKey);\n if (existing) {\n return sessionRowToMetadata(sessionKey, existing);\n }\n\n const sessionId = validateSessionId(randomUUID());\n const metadata = buildDefaultSessionMetadata(sessionKey, seed);\n metadata.sessionId = sessionId;\n insertSessionAndTranscript(db, sessionKey, sessionId, cwd, metadata);\n const row = readSessionRow(db, sessionKey);\n if (!row) {\n throw new Error(`Failed to create session: ${sessionKey}`);\n }\n return sessionRowToMetadata(sessionKey, row);\n}\n\nexport function ensureSessionRecord(\n sessionKey: string,\n cwd: string,\n seed?: SessionMetadataSeed,\n): SessionMetadata {\n return runSqliteWriteTransaction((db) => ensureSessionInTransaction(db, sessionKey, cwd, seed));\n}\n\nexport function readCurrentSessionId(db: DatabaseSync, sessionKey: string): string | null {\n const row = db\n .prepare(`SELECT session_id FROM sessions WHERE session_key = ?`)\n .get(sessionKey) as { session_id?: string } | undefined;\n return row?.session_id ?? null;\n}\n\nexport function getSessionMetadata(sessionKey: string): SessionMetadata | null {\n const db = getSqliteDatabase();\n const row = readSessionRow(db, sessionKey);\n if (!row) {\n return null;\n }\n return sessionRowToMetadata(sessionKey, row);\n}\n\nexport function getCurrentSessionId(sessionKey: string): string | null {\n return readCurrentSessionId(getSqliteDatabase(), sessionKey);\n}\n\nexport function listSessionMetadata(query: SessionListQuery = {}): PaginatedResult<SessionMetadata> {\n const db = getSqliteDatabase();\n const conditions: string[] = [];\n const params: Array<string | number> = [];\n\n if (!query.includeHidden) {\n conditions.push(`s.hidden_from_session_list = 0`);\n }\n\n if (query.sessionTypes?.length) {\n conditions.push(`s.session_type IN (${query.sessionTypes.map(() => '?').join(', ')})`);\n params.push(...query.sessionTypes);\n } else if (!query.includeHidden) {\n conditions.push(`s.session_type = ?`);\n params.push('chat');\n }\n\n if (query.status) {\n const statuses = Array.isArray(query.status) ? query.status : [query.status];\n conditions.push(`s.status IN (${statuses.map(() => '?').join(', ')})`);\n params.push(...statuses);\n }\n\n if (query.projectId) {\n conditions.push(`s.project_id = ?`);\n params.push(query.projectId);\n }\n\n if (query.channel) {\n const rawChannels = query.channel\n .split(',')\n .map((c) => c.trim().toLowerCase())\n .filter(Boolean);\n const channels = [\n ...new Set(\n rawChannels.flatMap((c) => {\n if (c === 'webchat') return ['webchat', 'ui'];\n if (c === 'gateway') return ['gateway', 'webui'];\n return [c];\n }),\n ),\n ];\n if (channels.length === 0) {\n return { items: [], total: 0, limit: query.limit ?? 50, offset: query.offset ?? 0, hasMore: false };\n }\n conditions.push(`LOWER(s.source_channel) IN (${channels.map(() => '?').join(', ')})`);\n params.push(...channels);\n }\n\n if (query.tags?.length) {\n for (const tag of query.tags) {\n conditions.push(`s.tags_json LIKE ?`);\n params.push(`%\"${tag}\"%`);\n }\n }\n\n let searchKeys: string[] | null = null;\n if (query.search?.trim()) {\n const rawSearch = query.search.trim();\n const ftsQuery = escapeFts5Query(rawSearch);\n const ftsRows = db\n .prepare(\n `SELECT DISTINCT session_key FROM transcript_fts WHERE transcript_fts MATCH ? LIMIT 500`,\n )\n .all(ftsQuery) as Array<{ session_key: string }>;\n const ftsKeys = new Set(ftsRows.map((r) => r.session_key));\n const like = `%${rawSearch.toLowerCase()}%`;\n const metaRows = db\n .prepare(\n `SELECT session_key FROM sessions\n WHERE LOWER(session_key) LIKE ?\n OR LOWER(COALESCE(name, '')) LIKE ?\n OR LOWER(source_channel) LIKE ?\n OR LOWER(source_chat_id) LIKE ?\n OR LOWER(tags_json) LIKE ?`,\n )\n .all(like, like, like, like, like) as Array<{ session_key: string }>;\n searchKeys = [...new Set([...ftsKeys, ...metaRows.map((r) => r.session_key)])];\n if (searchKeys.length === 0) {\n return { items: [], total: 0, limit: query.limit ?? 50, offset: query.offset ?? 0, hasMore: false };\n }\n conditions.push(`s.session_key IN (${searchKeys.map(() => '?').join(', ')})`);\n params.push(...searchKeys);\n }\n\n const where = conditions.length > 0 ? `WHERE ${conditions.join(' AND ')}` : '';\n const sortColumn = sessionSortColumn(query.sortBy);\n const sortOrder = query.sortOrder === 'asc' ? 'ASC' : 'DESC';\n\n const countRow = db\n .prepare(`SELECT COUNT(*) AS total FROM sessions s ${where}`)\n .get(...params) as { total: number };\n const total = countRow.total;\n\n const limit = query.limit ?? 50;\n const offset = query.offset ?? 0;\n const rows = db\n .prepare(\n `SELECT ${SESSION_COLUMNS} ${SESSION_FROM_JOIN} ${where}\n ORDER BY ${sortColumn} ${sortOrder}\n LIMIT ? OFFSET ?`,\n )\n .all(...params, limit, offset) as SessionRow[];\n\n const items = rows.map((row) => sessionRowToMetadata(row.session_key, row));\n return { items, total, limit, offset, hasMore: offset + limit < total };\n}\n\nfunction sessionSortColumn(sortBy: SessionListQuery['sortBy']): string {\n switch (sortBy) {\n case 'createdAt':\n return 's.created_at';\n case 'messageCount':\n return 's.message_count';\n case 'lastAccessedAt':\n return 's.last_accessed_at';\n case 'updatedAt':\n default:\n return 's.updated_at';\n }\n}\n\nexport function patchSessionMetadata(\n sessionKey: string,\n updates: Partial<SessionMetadata>,\n): SessionMetadata {\n return runSqliteWriteTransaction((db) => {\n const existing = readSessionRow(db, sessionKey);\n if (!existing) {\n throw new Error(`Session not found: ${sessionKey}`);\n }\n\n const current = sessionRowToMetadata(sessionKey, existing);\n const merged = { ...current, ...updates, key: sessionKey };\n const now = Date.now();\n\n db.prepare(\n `UPDATE sessions SET\n status = ?,\n name = ?,\n tags_json = ?,\n updated_at = ?,\n last_accessed_at = ?,\n session_started_at = ?,\n last_interaction_at = ?,\n source_channel = ?,\n source_chat_id = ?,\n session_type = ?,\n hidden_from_session_list = ?,\n parent_session_key = ?,\n workflow_run_id = ?,\n workflow_definition_id = ?,\n workflow_agent_id = ?,\n workflow_agent_label = ?,\n project_id = ?,\n routing_json = ?,\n custom_data_json = ?,\n abort_cutoff_timestamp = ?,\n message_count = ?,\n estimated_tokens = ?,\n compacted_count = ?,\n last_flushed_at = ?,\n flush_count = ?,\n thinking_level = ?,\n verbose_level = ?\n WHERE session_key = ?`,\n ).run(\n merged.status,\n merged.name ?? null,\n JSON.stringify(merged.tags ?? []),\n Date.parse(merged.updatedAt) || now,\n Date.parse(merged.lastAccessedAt) || now,\n merged.sessionStartedAt ? Date.parse(merged.sessionStartedAt) : existing.session_started_at,\n merged.lastInteractionAt ? Date.parse(merged.lastInteractionAt) : existing.last_interaction_at,\n merged.sourceChannel,\n merged.sourceChatId,\n merged.sessionType,\n merged.hiddenFromSessionList ? 1 : 0,\n merged.parentSessionKey ?? null,\n merged.workflowRunId ?? null,\n merged.workflowDefinitionId ?? null,\n merged.workflowAgentId ?? null,\n merged.workflowAgentLabel ?? null,\n merged.projectId ?? null,\n merged.routing ? JSON.stringify(merged.routing) : null,\n merged.customData ? JSON.stringify(merged.customData) : null,\n merged.abortCutoffTimestamp ?? null,\n merged.messageCount,\n merged.estimatedTokens,\n merged.compactedCount,\n merged.lastFlushedAt ?? null,\n merged.flushCount ?? 0,\n existing.thinking_level,\n existing.verbose_level,\n sessionKey,\n );\n\n const row = readSessionRow(db, sessionKey);\n if (!row) {\n throw new Error(`Session not found after patch: ${sessionKey}`);\n }\n return sessionRowToMetadata(sessionKey, row);\n });\n}\n\nexport function updateSessionStats(\n sessionKey: string,\n stats: { messageCount: number; estimatedTokens: number; lastInteractionAt?: number },\n): void {\n runSqliteWriteTransaction((db) => {\n const now = stats.lastInteractionAt ?? Date.now();\n db.prepare(\n `UPDATE sessions SET\n message_count = ?,\n estimated_tokens = ?,\n updated_at = ?,\n last_accessed_at = ?,\n last_interaction_at = ?\n WHERE session_key = ?`,\n ).run(stats.messageCount, stats.estimatedTokens, now, now, now, sessionKey);\n });\n}\n\nexport function incrementSessionStatsOnAppend(sessionKey: string, tokenDelta = 0): void {\n runSqliteWriteTransaction((db) => {\n const now = Date.now();\n db.prepare(\n `UPDATE sessions SET\n message_count = message_count + 1,\n estimated_tokens = estimated_tokens + ?,\n updated_at = ?,\n last_accessed_at = ?,\n last_interaction_at = ?\n WHERE session_key = ?`,\n ).run(tokenDelta, now, now, now, sessionKey);\n });\n}\n\nexport function resetSessionRecord(\n sessionKey: string,\n cwd: string,\n): { sessionId: string; previousSessionId: string } | null {\n return runSqliteWriteTransaction((db) => {\n const existing = readSessionRow(db, sessionKey);\n if (!existing) {\n return null;\n }\n\n const previousSessionId = existing.session_id;\n const now = Date.now();\n db.prepare(\n `UPDATE transcripts SET status = 'archived', archive_reason = 'reset', archived_at = ?\n WHERE session_id = ?`,\n ).run(now, previousSessionId);\n\n const newSessionId = validateSessionId(randomUUID());\n db.prepare(\n `INSERT INTO transcripts (session_id, session_key, status, created_at, cwd)\n VALUES (?, ?, 'active', ?, ?)`,\n ).run(newSessionId, sessionKey, now, cwd);\n\n db.prepare(\n `UPDATE sessions SET\n session_id = ?,\n updated_at = ?,\n session_started_at = ?,\n last_interaction_at = NULL,\n message_count = 0,\n estimated_tokens = 0\n WHERE session_key = ?`,\n ).run(newSessionId, now, now, sessionKey);\n\n return { sessionId: newSessionId, previousSessionId };\n });\n}\n\nexport function deleteSessionRecord(sessionKey: string): boolean {\n return runSqliteWriteTransaction((db) => {\n const existing = readSessionRow(db, sessionKey);\n if (!existing) {\n return false;\n }\n\n const now = Date.now();\n db.prepare(\n `UPDATE transcripts SET status = 'archived', archive_reason = 'delete', archived_at = ?\n WHERE session_id = ?`,\n ).run(now, existing.session_id);\n\n db.prepare(`DELETE FROM sessions WHERE session_key = ?`).run(sessionKey);\n return true;\n });\n}\n\nexport function listSessionsByAgent(agentId: string): SessionMetadata[] {\n const db = getSqliteDatabase();\n const rows = db\n .prepare(\n `SELECT ${SESSION_COLUMNS} ${SESSION_FROM_JOIN}\n WHERE s.agent_id = ?\n ORDER BY s.updated_at DESC`,\n )\n .all(agentId.toLowerCase()) as SessionRow[];\n return rows.map((row) => sessionRowToMetadata(row.session_key, row));\n}\n\nexport function getSessionPersistedLevels(sessionKey: string): {\n thinkingLevel: string | null;\n verboseLevel: string | null;\n} | null {\n const db = getSqliteDatabase();\n const row = db\n .prepare(`SELECT thinking_level, verbose_level FROM sessions WHERE session_key = ?`)\n .get(sessionKey) as { thinking_level: string | null; verbose_level: string | null } | undefined;\n if (!row) {\n return null;\n }\n return { thinkingLevel: row.thinking_level, verboseLevel: row.verbose_level };\n}\n\nexport function findSessionKeyBySessionId(sessionId: string): string | null {\n const db = getSqliteDatabase();\n const row = db\n .prepare(`SELECT session_key FROM sessions WHERE session_id = ?`)\n .get(sessionId) as { session_key?: string } | undefined;\n return row?.session_key ?? null;\n}\n\nexport function getGlobalSessionStats(): ReturnType<typeof buildGlobalSessionStats> {\n const all = listSessionMetadata({ limit: 100_000, offset: 0 });\n return buildGlobalSessionStats(all.items);\n}\n\nexport function resolveSessionAgentId(sessionKey: string): string {\n return getSessionMetadata(sessionKey)?.routing?.agentId ?? 'main';\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"session-repository.js","names":[],"sources":["../../../../src/storage/sqlite/session-repository.ts"],"sourcesContent":["import { randomUUID } from 'node:crypto';\nimport type { DatabaseSync } from 'node:sqlite';\n\nimport { validateSessionId } from '../../session/session-id.js';\nimport type { SessionListQuery, SessionMetadata, PaginatedResult } from '../../session/types.js';\nimport { buildDefaultSessionMetadata, type SessionMetadataSeed } from './session-metadata.js';\nimport {\n buildGlobalSessionStats,\n metadataToSessionInsert,\n sessionRowToMetadata,\n type SessionRow,\n} from './row-mappers.js';\nimport { getSqliteDatabase, runSqliteWriteTransaction } from './transaction.js';\n\nconst SESSION_COLUMNS = `\n s.session_key, s.agent_id, s.session_id, s.status, s.name, s.tags_json,\n s.created_at, s.updated_at, s.last_accessed_at, s.session_started_at, s.last_interaction_at,\n s.source_channel, s.source_chat_id, s.session_type, s.hidden_from_session_list,\n s.parent_session_key, s.workflow_run_id, s.workflow_definition_id, s.workflow_agent_id, s.workflow_agent_label,\n s.project_id, s.routing_json, s.custom_data_json,\n s.abort_cutoff_timestamp, s.message_count, s.estimated_tokens, s.compacted_count,\n s.last_flushed_at, s.flush_count,\n s.thinking_level, s.verbose_level,\n t.cwd AS cwd\n`;\n\nimport { escapeFts5Query } from './fts.js';\n\nconst SESSION_FROM_JOIN = `\n FROM sessions s\n LEFT JOIN transcripts t ON t.session_id = s.session_id\n`;\n\nconst SELECT_SESSION = `SELECT ${SESSION_COLUMNS} ${SESSION_FROM_JOIN} WHERE s.session_key = ?`;\n\nfunction readSessionRow(db: DatabaseSync, sessionKey: string): SessionRow | undefined {\n return db.prepare(SELECT_SESSION).get(sessionKey) as SessionRow | undefined;\n}\n\nfunction insertSessionAndTranscript(\n db: DatabaseSync,\n sessionKey: string,\n sessionId: string,\n cwd: string,\n metadata: SessionMetadata,\n): void {\n const row = metadataToSessionInsert(sessionKey, sessionId, metadata);\n db.prepare(\n `INSERT INTO sessions (\n session_key, agent_id, session_id, status, name, tags_json,\n created_at, updated_at, last_accessed_at, session_started_at, last_interaction_at,\n source_channel, source_chat_id, session_type, hidden_from_session_list,\n parent_session_key, workflow_run_id, workflow_definition_id, workflow_agent_id, workflow_agent_label,\n project_id, routing_json, custom_data_json,\n abort_cutoff_timestamp, message_count, estimated_tokens, compacted_count,\n last_flushed_at, flush_count,\n thinking_level, verbose_level\n ) VALUES (\n ?, ?, ?, ?, ?, ?,\n ?, ?, ?, ?, ?,\n ?, ?, ?, ?,\n ?, ?, ?, ?, ?,\n ?, ?, ?,\n ?, ?, ?, ?, ?, ?,\n ?, ?\n )`,\n ).run(\n row.sessionKey,\n row.agentId,\n row.sessionId,\n row.status,\n row.name,\n row.tagsJson,\n row.createdAt,\n row.updatedAt,\n row.lastAccessedAt,\n row.sessionStartedAt,\n row.lastInteractionAt,\n row.sourceChannel,\n row.sourceChatId,\n row.sessionType,\n row.hiddenFromSessionList,\n row.parentSessionKey,\n row.workflowRunId,\n row.workflowDefinitionId,\n row.workflowAgentId,\n row.workflowAgentLabel,\n row.projectId,\n row.routingJson,\n row.customDataJson,\n row.abortCutoffTimestamp,\n row.messageCount,\n row.estimatedTokens,\n row.compactedCount,\n row.lastFlushedAt,\n row.flushCount,\n row.thinkingLevel,\n row.verboseLevel,\n );\n\n const now = Date.now();\n db.prepare(\n `INSERT INTO transcripts (session_id, session_key, status, created_at, cwd)\n VALUES (?, ?, 'active', ?, ?)`,\n ).run(sessionId, sessionKey, now, cwd);\n}\n\nexport function ensureSessionInTransaction(\n db: DatabaseSync,\n sessionKey: string,\n cwd: string,\n seed?: SessionMetadataSeed,\n): SessionMetadata {\n const existing = readSessionRow(db, sessionKey);\n if (existing) {\n return sessionRowToMetadata(sessionKey, existing);\n }\n\n const sessionId = validateSessionId(randomUUID());\n const metadata = buildDefaultSessionMetadata(sessionKey, seed);\n metadata.sessionId = sessionId;\n insertSessionAndTranscript(db, sessionKey, sessionId, cwd, metadata);\n const row = readSessionRow(db, sessionKey);\n if (!row) {\n throw new Error(`Failed to create session: ${sessionKey}`);\n }\n return sessionRowToMetadata(sessionKey, row);\n}\n\nexport function ensureSessionRecord(\n sessionKey: string,\n cwd: string,\n seed?: SessionMetadataSeed,\n): SessionMetadata {\n return runSqliteWriteTransaction((db) => ensureSessionInTransaction(db, sessionKey, cwd, seed));\n}\n\nexport function readCurrentSessionId(db: DatabaseSync, sessionKey: string): string | null {\n const row = db\n .prepare(`SELECT session_id FROM sessions WHERE session_key = ?`)\n .get(sessionKey) as { session_id?: string } | undefined;\n return row?.session_id ?? null;\n}\n\nexport function getSessionMetadata(sessionKey: string): SessionMetadata | null {\n const db = getSqliteDatabase();\n const row = readSessionRow(db, sessionKey);\n if (!row) {\n return null;\n }\n return sessionRowToMetadata(sessionKey, row);\n}\n\nexport function getCurrentSessionId(sessionKey: string): string | null {\n return readCurrentSessionId(getSqliteDatabase(), sessionKey);\n}\n\nexport function listSessionMetadata(query: SessionListQuery = {}): PaginatedResult<SessionMetadata> {\n const db = getSqliteDatabase();\n const conditions: string[] = [];\n const params: Array<string | number> = [];\n\n if (!query.includeHidden) {\n conditions.push(`s.hidden_from_session_list = 0`);\n }\n\n if (query.sessionTypes?.length) {\n conditions.push(`s.session_type IN (${query.sessionTypes.map(() => '?').join(', ')})`);\n params.push(...query.sessionTypes);\n } else if (!query.includeHidden) {\n conditions.push(`s.session_type = ?`);\n params.push('chat');\n }\n\n if (query.status) {\n const statuses = Array.isArray(query.status) ? query.status : [query.status];\n conditions.push(`s.status IN (${statuses.map(() => '?').join(', ')})`);\n params.push(...statuses);\n }\n\n if (query.projectId) {\n conditions.push(`s.project_id = ?`);\n params.push(query.projectId);\n } else if (query.unassigned) {\n conditions.push(`(s.project_id IS NULL OR s.project_id = '')`);\n }\n\n if (query.updatedAfter !== undefined) {\n const clauses = [`s.updated_at >= ?`];\n params.push(query.updatedAfter);\n if (query.includePinned) {\n clauses.push(`s.status = 'pinned'`);\n }\n const includeSessionKey = query.includeSessionKey?.trim();\n if (includeSessionKey) {\n clauses.push(`s.session_key = ?`);\n params.push(includeSessionKey);\n }\n conditions.push(`(${clauses.join(' OR ')})`);\n }\n\n if (query.channel) {\n const rawChannels = query.channel\n .split(',')\n .map((c) => c.trim().toLowerCase())\n .filter(Boolean);\n const channels = [\n ...new Set(\n rawChannels.flatMap((c) => {\n if (c === 'webchat') return ['webchat', 'ui'];\n if (c === 'gateway') return ['gateway', 'webui'];\n return [c];\n }),\n ),\n ];\n if (channels.length === 0) {\n return { items: [], total: 0, limit: query.limit ?? 50, offset: query.offset ?? 0, hasMore: false };\n }\n conditions.push(`LOWER(s.source_channel) IN (${channels.map(() => '?').join(', ')})`);\n params.push(...channels);\n }\n\n if (query.tags?.length) {\n for (const tag of query.tags) {\n conditions.push(`s.tags_json LIKE ?`);\n params.push(`%\"${tag}\"%`);\n }\n }\n\n let searchKeys: string[] | null = null;\n if (query.search?.trim()) {\n const rawSearch = query.search.trim();\n const ftsQuery = escapeFts5Query(rawSearch);\n const ftsRows = db\n .prepare(\n `SELECT DISTINCT session_key FROM transcript_fts WHERE transcript_fts MATCH ? LIMIT 500`,\n )\n .all(ftsQuery) as Array<{ session_key: string }>;\n const ftsKeys = new Set(ftsRows.map((r) => r.session_key));\n const like = `%${rawSearch.toLowerCase()}%`;\n const metaRows = db\n .prepare(\n `SELECT session_key FROM sessions\n WHERE LOWER(session_key) LIKE ?\n OR LOWER(COALESCE(name, '')) LIKE ?\n OR LOWER(source_channel) LIKE ?\n OR LOWER(source_chat_id) LIKE ?\n OR LOWER(tags_json) LIKE ?`,\n )\n .all(like, like, like, like, like) as Array<{ session_key: string }>;\n searchKeys = [...new Set([...ftsKeys, ...metaRows.map((r) => r.session_key)])];\n if (searchKeys.length === 0) {\n return { items: [], total: 0, limit: query.limit ?? 50, offset: query.offset ?? 0, hasMore: false };\n }\n conditions.push(`s.session_key IN (${searchKeys.map(() => '?').join(', ')})`);\n params.push(...searchKeys);\n }\n\n const where = conditions.length > 0 ? `WHERE ${conditions.join(' AND ')}` : '';\n const sortColumn = sessionSortColumn(query.sortBy);\n const sortOrder = query.sortOrder === 'asc' ? 'ASC' : 'DESC';\n\n const countRow = db\n .prepare(`SELECT COUNT(*) AS total FROM sessions s ${where}`)\n .get(...params) as { total: number };\n const total = countRow.total;\n\n const limit = query.limit ?? 50;\n const offset = query.offset ?? 0;\n const rows = db\n .prepare(\n `SELECT ${SESSION_COLUMNS} ${SESSION_FROM_JOIN} ${where}\n ORDER BY ${sortColumn} ${sortOrder}\n LIMIT ? OFFSET ?`,\n )\n .all(...params, limit, offset) as SessionRow[];\n\n const items = rows.map((row) => sessionRowToMetadata(row.session_key, row));\n return { items, total, limit, offset, hasMore: offset + limit < total };\n}\n\nfunction sessionSortColumn(sortBy: SessionListQuery['sortBy']): string {\n switch (sortBy) {\n case 'createdAt':\n return 's.created_at';\n case 'messageCount':\n return 's.message_count';\n case 'lastAccessedAt':\n return 's.last_accessed_at';\n case 'updatedAt':\n default:\n return 's.updated_at';\n }\n}\n\nexport function patchSessionMetadata(\n sessionKey: string,\n updates: Partial<SessionMetadata>,\n): SessionMetadata {\n return runSqliteWriteTransaction((db) => {\n const existing = readSessionRow(db, sessionKey);\n if (!existing) {\n throw new Error(`Session not found: ${sessionKey}`);\n }\n\n const current = sessionRowToMetadata(sessionKey, existing);\n const merged = { ...current, ...updates, key: sessionKey };\n const now = Date.now();\n\n db.prepare(\n `UPDATE sessions SET\n status = ?,\n name = ?,\n tags_json = ?,\n updated_at = ?,\n last_accessed_at = ?,\n session_started_at = ?,\n last_interaction_at = ?,\n source_channel = ?,\n source_chat_id = ?,\n session_type = ?,\n hidden_from_session_list = ?,\n parent_session_key = ?,\n workflow_run_id = ?,\n workflow_definition_id = ?,\n workflow_agent_id = ?,\n workflow_agent_label = ?,\n project_id = ?,\n routing_json = ?,\n custom_data_json = ?,\n abort_cutoff_timestamp = ?,\n message_count = ?,\n estimated_tokens = ?,\n compacted_count = ?,\n last_flushed_at = ?,\n flush_count = ?,\n thinking_level = ?,\n verbose_level = ?\n WHERE session_key = ?`,\n ).run(\n merged.status,\n merged.name ?? null,\n JSON.stringify(merged.tags ?? []),\n Date.parse(merged.updatedAt) || now,\n Date.parse(merged.lastAccessedAt) || now,\n merged.sessionStartedAt ? Date.parse(merged.sessionStartedAt) : existing.session_started_at,\n merged.lastInteractionAt ? Date.parse(merged.lastInteractionAt) : existing.last_interaction_at,\n merged.sourceChannel,\n merged.sourceChatId,\n merged.sessionType,\n merged.hiddenFromSessionList ? 1 : 0,\n merged.parentSessionKey ?? null,\n merged.workflowRunId ?? null,\n merged.workflowDefinitionId ?? null,\n merged.workflowAgentId ?? null,\n merged.workflowAgentLabel ?? null,\n merged.projectId ?? null,\n merged.routing ? JSON.stringify(merged.routing) : null,\n merged.customData ? JSON.stringify(merged.customData) : null,\n merged.abortCutoffTimestamp ?? null,\n merged.messageCount,\n merged.estimatedTokens,\n merged.compactedCount,\n merged.lastFlushedAt ?? null,\n merged.flushCount ?? 0,\n existing.thinking_level,\n existing.verbose_level,\n sessionKey,\n );\n\n const row = readSessionRow(db, sessionKey);\n if (!row) {\n throw new Error(`Session not found after patch: ${sessionKey}`);\n }\n return sessionRowToMetadata(sessionKey, row);\n });\n}\n\nexport function updateSessionStats(\n sessionKey: string,\n stats: { messageCount: number; estimatedTokens: number; lastInteractionAt?: number },\n): void {\n runSqliteWriteTransaction((db) => {\n const now = stats.lastInteractionAt ?? Date.now();\n db.prepare(\n `UPDATE sessions SET\n message_count = ?,\n estimated_tokens = ?,\n updated_at = ?,\n last_accessed_at = ?,\n last_interaction_at = ?\n WHERE session_key = ?`,\n ).run(stats.messageCount, stats.estimatedTokens, now, now, now, sessionKey);\n });\n}\n\nexport function incrementSessionStatsOnAppend(sessionKey: string, tokenDelta = 0): void {\n runSqliteWriteTransaction((db) => {\n const now = Date.now();\n db.prepare(\n `UPDATE sessions SET\n message_count = message_count + 1,\n estimated_tokens = estimated_tokens + ?,\n updated_at = ?,\n last_accessed_at = ?,\n last_interaction_at = ?\n WHERE session_key = ?`,\n ).run(tokenDelta, now, now, now, sessionKey);\n });\n}\n\nexport function resetSessionRecord(\n sessionKey: string,\n cwd: string,\n): { sessionId: string; previousSessionId: string } | null {\n return runSqliteWriteTransaction((db) => {\n const existing = readSessionRow(db, sessionKey);\n if (!existing) {\n return null;\n }\n\n const previousSessionId = existing.session_id;\n const now = Date.now();\n db.prepare(\n `UPDATE transcripts SET status = 'archived', archive_reason = 'reset', archived_at = ?\n WHERE session_id = ?`,\n ).run(now, previousSessionId);\n\n const newSessionId = validateSessionId(randomUUID());\n db.prepare(\n `INSERT INTO transcripts (session_id, session_key, status, created_at, cwd)\n VALUES (?, ?, 'active', ?, ?)`,\n ).run(newSessionId, sessionKey, now, cwd);\n\n db.prepare(\n `UPDATE sessions SET\n session_id = ?,\n updated_at = ?,\n session_started_at = ?,\n last_interaction_at = NULL,\n message_count = 0,\n estimated_tokens = 0\n WHERE session_key = ?`,\n ).run(newSessionId, now, now, sessionKey);\n\n return { sessionId: newSessionId, previousSessionId };\n });\n}\n\nexport function deleteSessionRecord(sessionKey: string): boolean {\n return runSqliteWriteTransaction((db) => {\n const existing = readSessionRow(db, sessionKey);\n if (!existing) {\n return false;\n }\n\n const now = Date.now();\n db.prepare(\n `UPDATE transcripts SET status = 'archived', archive_reason = 'delete', archived_at = ?\n WHERE session_id = ?`,\n ).run(now, existing.session_id);\n\n db.prepare(`DELETE FROM sessions WHERE session_key = ?`).run(sessionKey);\n return true;\n });\n}\n\nexport function listSessionsByAgent(agentId: string): SessionMetadata[] {\n const db = getSqliteDatabase();\n const rows = db\n .prepare(\n `SELECT ${SESSION_COLUMNS} ${SESSION_FROM_JOIN}\n WHERE s.agent_id = ?\n ORDER BY s.updated_at DESC`,\n )\n .all(agentId.toLowerCase()) as SessionRow[];\n return rows.map((row) => sessionRowToMetadata(row.session_key, row));\n}\n\nexport function getSessionPersistedLevels(sessionKey: string): {\n thinkingLevel: string | null;\n verboseLevel: string | null;\n} | null {\n const db = getSqliteDatabase();\n const row = db\n .prepare(`SELECT thinking_level, verbose_level FROM sessions WHERE session_key = ?`)\n .get(sessionKey) as { thinking_level: string | null; verbose_level: string | null } | undefined;\n if (!row) {\n return null;\n }\n return { thinkingLevel: row.thinking_level, verboseLevel: row.verbose_level };\n}\n\nexport function findSessionKeyBySessionId(sessionId: string): string | null {\n const db = getSqliteDatabase();\n const row = db\n .prepare(`SELECT session_key FROM sessions WHERE session_id = ?`)\n .get(sessionId) as { session_key?: string } | undefined;\n return row?.session_key ?? null;\n}\n\nexport function getGlobalSessionStats(): ReturnType<typeof buildGlobalSessionStats> {\n const all = listSessionMetadata({ limit: 100_000, offset: 0 });\n return buildGlobalSessionStats(all.items);\n}\n\nexport function resolveSessionAgentId(sessionKey: string): string {\n return getSessionMetadata(sessionKey)?.routing?.agentId ?? 'main';\n}\n"],"mappings":"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"}
@@ -1,4 +1,5 @@
1
1
  import type { ExtensionRegistryImpl } from '../../extensions/loader.js';
2
+ import { type SessionTimelineItem } from '../../session/transcript-outline.js';
2
3
  import { type Config } from '../../config/schema.js';
3
4
  import type { ExportFormat } from '../../session/types.js';
4
5
  import type { ChatSendOptions, HistoryMessage, TuiBackend, TuiCompactionResult, TuiEvent, TuiModelChoice, TuiShareRequest, TuiShareResult, TuiSessionStats, TuiSessionItem, TuiTranscriptTreeEntry, TuiAgentInfo, TuiWorkspaceFileSearchEntry, TuiWorkflowRunStartRequest, TuiWorkflowRunStartResult, TuiStartupProjectResult } from '../tui-backend.js';
@@ -72,7 +73,19 @@ export declare class EmbeddedBackend implements TuiBackend {
72
73
  }): Promise<{
73
74
  messages: HistoryMessage[];
74
75
  }>;
76
+ loadHistoryWindow(opts: {
77
+ sessionKey: string;
78
+ rowNumber: number;
79
+ before?: number;
80
+ after?: number;
81
+ }): Promise<{
82
+ messages: import("../../session/client-history.js").ClientHistoryMessage[];
83
+ startRowNumber: number;
84
+ endRowNumber: number;
85
+ totalRows: number;
86
+ }>;
75
87
  loadTranscriptTree(sessionKey: string): Promise<TuiTranscriptTreeEntry[]>;
88
+ loadTimeline(sessionKey: string): Promise<SessionTimelineItem[]>;
76
89
  getSessionStats(sessionKey: string): Promise<TuiSessionStats>;
77
90
  listSessions(): Promise<TuiSessionItem[]>;
78
91
  listAgents(): Promise<TuiAgentInfo[]>;
@@ -1,17 +1,21 @@
1
- import { getAgentDefaultModelRef, init_schema } from "../../config/schema.js";
2
- import { init_agent_scope, listAgentEntries, normalizeAgentId } from "../../agent/agent-scope.js";
3
- import { init_agent_session_key, resolveAgentIdFromSessionKey } from "../../routing/agent-session-key.js";
4
1
  import { createLogger } from "../../utils/logger/index.js";
5
2
  import { init_logger } from "../../utils/logger.js";
6
- import { loadConfig, saveConfig } from "../../config/loader.js";
7
3
  import { openXopcDatabase } from "../../storage/sqlite/connection.js";
4
+ import { init_agent_session_key, resolveAgentIdFromSessionKey } from "../../routing/agent-session-key.js";
8
5
  import { getSessionMetadata } from "../../storage/sqlite/session-repository.js";
9
6
  import "../../storage/sqlite/index.js";
7
+ import { getAgentDefaultModelRef, init_schema } from "../../config/schema.js";
8
+ import { init_agent_scope, listAgentEntries, normalizeAgentId } from "../../agent/agent-scope.js";
9
+ import { loadConfig, saveConfig } from "../../config/loader.js";
10
10
  import { effectiveWorkspacePathForSession } from "../../session/session-workspace.js";
11
11
  import { createCreateShareTool, isShareToolAvailable } from "../../agent/tools/create-share-tool.js";
12
+ import { ProjectService } from "../../projects/project-service.js";
13
+ import { inferSuggestedProjectDefaultAgentId } from "../../projects/project-agent-suggestion.js";
14
+ import "../../projects/index.js";
12
15
  import { evictEmbeddedSessionRunner } from "../../agent/embedded/session-runner.js";
13
16
  import { prependEnvelopeTimestamp } from "../../channels/envelope-timestamp.js";
14
17
  import { SessionIndex } from "../../session/manager.js";
18
+ import { buildSessionTimeline } from "../../session/transcript-outline.js";
15
19
  import { transcriptRowsToClientHistory } from "../../session/client-history.js";
16
20
  import "../../session/index.js";
17
21
  import { parseModelRef } from "../../agent/models/selection.js";
@@ -24,9 +28,6 @@ import "../../config/index.js";
24
28
  import { buildWorkflowChildTools } from "../../agent/workflow/workflow-child-tools.js";
25
29
  import { WorkflowRunService } from "../../workflows/service/workflow-run-service.js";
26
30
  import { WorkflowSessionBridge } from "../../workflows/service/workflow-session-bridge.js";
27
- import { ProjectService } from "../../projects/project-service.js";
28
- import { inferSuggestedProjectDefaultAgentId } from "../../projects/project-agent-suggestion.js";
29
- import "../../projects/index.js";
30
31
  import { ChatStreamMapper } from "../../gateway/chat-stream/mapper.js";
31
32
  import { fuzzySearchWorkspaceFiles } from "../../gateway/workspace-file-search.js";
32
33
  import { sessionMetadataToTuiItem } from "../tui-session-format.js";
@@ -40,6 +41,11 @@ init_agent_session_key();
40
41
  init_schema();
41
42
  init_logger();
42
43
  const log = createLogger("TUI:Embedded");
44
+ function clampHistoryWindowSpan(value, fallback) {
45
+ const parsed = Math.trunc(value ?? fallback);
46
+ if (!Number.isFinite(parsed)) return fallback;
47
+ return Math.min(200, Math.max(0, parsed));
48
+ }
43
49
  function isPathSameOrInside(parentDir, childDir) {
44
50
  const rel = relative(resolve(parentDir), resolve(childDir));
45
51
  return rel === "" || !!rel && !rel.startsWith("..") && !isAbsolute(rel);
@@ -104,6 +110,9 @@ var EmbeddedBackend = class {
104
110
  async ensureAgent() {
105
111
  if (this.agent) return this.agent;
106
112
  if (this.agentLoading) return this.agentLoading;
113
+ if (!this.config || !this.sessionIndex) {
114
+ if (!this.running) this.start();
115
+ }
107
116
  if (!this.config || !this.sessionIndex) throw new Error("Embedded backend not started");
108
117
  this.agentLoading = this.createAgent(this.config, this.sessionIndex);
109
118
  try {
@@ -335,6 +344,52 @@ var EmbeddedBackend = class {
335
344
  return { messages: [] };
336
345
  }
337
346
  }
347
+ async loadHistoryWindow(opts) {
348
+ if (!this.agent) return {
349
+ messages: [],
350
+ startRowNumber: 0,
351
+ endRowNumber: 0,
352
+ totalRows: 0
353
+ };
354
+ try {
355
+ const rows = await this.agent.sessionStore.loadTranscriptRows(opts.sessionKey);
356
+ const totalRows = rows.length;
357
+ if (totalRows === 0) return {
358
+ messages: [],
359
+ startRowNumber: 0,
360
+ endRowNumber: 0,
361
+ totalRows
362
+ };
363
+ const targetRowNumber = Math.min(totalRows, Math.max(1, Math.trunc(opts.rowNumber)));
364
+ const before = clampHistoryWindowSpan(opts.before, 80);
365
+ const after = clampHistoryWindowSpan(opts.after, 120);
366
+ const startRowNumber = Math.max(1, targetRowNumber - before);
367
+ const endRowNumber = Math.min(totalRows, targetRowNumber + after);
368
+ return {
369
+ messages: transcriptRowsToClientHistory(rows, {
370
+ startRowNumber,
371
+ endRowNumber
372
+ }),
373
+ startRowNumber,
374
+ endRowNumber,
375
+ totalRows
376
+ };
377
+ } catch (error) {
378
+ const errorMessage = error instanceof Error ? error.message : String(error);
379
+ log.warn({
380
+ err: error,
381
+ sessionKey: opts.sessionKey,
382
+ rowNumber: opts.rowNumber,
383
+ errorMessage
384
+ }, `Embedded loadHistoryWindow failed: ${errorMessage}`);
385
+ return {
386
+ messages: [],
387
+ startRowNumber: 0,
388
+ endRowNumber: 0,
389
+ totalRows: 0
390
+ };
391
+ }
392
+ }
338
393
  async loadTranscriptTree(sessionKey) {
339
394
  if (!this.agent) return [];
340
395
  try {
@@ -349,6 +404,20 @@ var EmbeddedBackend = class {
349
404
  return [];
350
405
  }
351
406
  }
407
+ async loadTimeline(sessionKey) {
408
+ if (!this.agent) return [];
409
+ try {
410
+ return buildSessionTimeline(await this.agent.sessionStore.loadTranscriptRows(sessionKey));
411
+ } catch (error) {
412
+ const errorMessage = error instanceof Error ? error.message : String(error);
413
+ log.warn({
414
+ err: error,
415
+ sessionKey,
416
+ errorMessage
417
+ }, `Embedded loadTimeline failed: ${errorMessage}`);
418
+ return [];
419
+ }
420
+ }
352
421
  async getSessionStats(sessionKey) {
353
422
  if (!this.agent) return computeTuiSessionStats([]);
354
423
  try {