@xopcai/xopc 0.0.113 → 0.0.115

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 (567) hide show
  1. package/dist/browser-ext/manifest.json +1 -1
  2. package/dist/extensions/feishu/src/outbound/media-load.js +1 -1
  3. package/dist/extensions/feishu/src/workflow-progress.js +1 -1
  4. package/dist/extensions/telegram/src/adapters/streaming-adapter.js +1 -1
  5. package/dist/extensions/telegram/src/inbound-processor.js +1 -1
  6. package/dist/extensions/telegram/src/plugin.js +1 -1
  7. package/dist/extensions/telegram/src/routing-integration.js +2 -2
  8. package/dist/extensions/telegram/src/update-offset-store.js +1 -1
  9. package/dist/extensions/telegram/src/workflow-progress.js +1 -1
  10. package/dist/extensions/telegram/xopc.extension.json +1 -1
  11. package/dist/extensions/weixin/src/api/api.js +2 -2
  12. package/dist/extensions/weixin/src/auth/accounts.js +1 -1
  13. package/dist/extensions/weixin/src/cdn/upload.js +1 -1
  14. package/dist/extensions/weixin/src/media/data-url.js +1 -1
  15. package/dist/extensions/weixin/src/messaging/debug-mode.js +1 -1
  16. package/dist/extensions/weixin/src/messaging/inbound.js +1 -1
  17. package/dist/extensions/weixin/src/messaging/process-message.js +1 -1
  18. package/dist/extensions/weixin/src/plugin.js +1 -1
  19. package/dist/extensions/weixin/src/storage/sync-buf.js +1 -1
  20. package/dist/extensions/weixin/src/workflow-progress.js +1 -1
  21. package/dist/gateway/static/root/assets/{agent-avatar-dicebear-CBlklyNr.js → agent-avatar-dicebear-DVnBfANm.js} +1 -1
  22. package/dist/gateway/static/root/assets/agent-browser-settings-page-DPXc4hz8.js +6 -0
  23. package/dist/gateway/static/root/assets/agent-defaults-tabbed-page-CTJ0YnRQ.js +1 -0
  24. package/dist/gateway/static/root/assets/agents-zJXQfJ_W.js +71 -0
  25. package/dist/gateway/static/root/assets/{app-management-settings-panel-28E_WfMe.js → app-management-settings-panel-DzGbdr04.js} +1 -1
  26. package/dist/gateway/static/root/assets/{appearance-settings-Do1z0XgJ.js → appearance-settings-BQpPSTHD.js} +1 -1
  27. package/dist/gateway/static/root/assets/apps-page-CPjfyzSD.js +1 -0
  28. package/dist/gateway/static/root/assets/{archive-plugin-BAFlsov_.js → archive-plugin-CXu-Csep.js} +1 -1
  29. package/dist/gateway/static/root/assets/{attachment-load-V3qGPC3x.js → attachment-load-BAjgOoGY.js} +1 -1
  30. package/dist/gateway/static/root/assets/{binary-plugins-DT8NvA6W.js → binary-plugins-BSBgB2hO.js} +1 -1
  31. package/dist/gateway/static/root/assets/{block-editor-CdLMEcHd.js → block-editor-BpXw9TTR.js} +3 -3
  32. package/dist/gateway/static/root/assets/channels-settings-BbPUpzWB.js +1 -0
  33. package/dist/gateway/static/root/assets/{config-api-Bf5mjpu7.js → config-api-NOoPiIYz.js} +1 -1
  34. package/dist/gateway/static/root/assets/connectors-settings-CAXYMOdp.js +2 -0
  35. package/dist/gateway/static/root/assets/{cron-api--pAB_rps.js → cron-api-C9BOqAXd.js} +1 -1
  36. package/dist/gateway/static/root/assets/cron-page-DuUbBeKI.js +3 -0
  37. package/dist/gateway/static/root/assets/{dreaming-settings-6UZE1FSK.js → dreaming-settings-DQ4DtiK1.js} +1 -1
  38. package/dist/gateway/static/root/assets/{extension-debug-page-BGhE7msg.js → extension-debug-page-D9kgUHCc.js} +1 -1
  39. package/dist/gateway/static/root/assets/{extension-page-CvpI45WG.js → extension-page-CGyhXqzR.js} +1 -1
  40. package/dist/gateway/static/root/assets/{extension-settings-page-DAmR5FUe.js → extension-settings-page-DL8Xquqd.js} +1 -1
  41. package/dist/gateway/static/root/assets/{fetch-NZmjSXLl.js → fetch-D0VXA932.js} +1 -1
  42. package/dist/gateway/static/root/assets/{format-interval-label-qhth3BMV.js → format-interval-label-Be8SmgUw.js} +1 -1
  43. package/dist/gateway/static/root/assets/{gateway-config-api-CaXBt-9R.js → gateway-config-api-C-xjn__h.js} +1 -1
  44. package/dist/gateway/static/root/assets/{gateway-settings-DphpbLBc.js → gateway-settings-BMPwIjKI.js} +1 -1
  45. package/dist/gateway/static/root/assets/{gateway-startup-retry-Be1omjh3.js → gateway-startup-retry-DERUH61L.js} +1 -1
  46. package/dist/gateway/static/root/assets/goal-detail-page-BJsyjJnF.js +1 -0
  47. package/dist/gateway/static/root/assets/goals-config-api-BPmqWk90.js +1 -0
  48. package/dist/gateway/static/root/assets/goals-page-BerDgIhw.js +2 -0
  49. package/dist/gateway/static/root/assets/goals-settings-ByTjeAto.js +1 -0
  50. package/dist/gateway/static/root/assets/{heartbeat-config-api-BzO6G4fD.js → heartbeat-config-api-Bfdzr8oV.js} +1 -1
  51. package/dist/gateway/static/root/assets/{heartbeat-settings-DCST9-du.js → heartbeat-settings-TbHgcjTn.js} +1 -1
  52. package/dist/gateway/static/root/assets/index-AkTrf6Pb.js +122 -0
  53. package/dist/gateway/static/root/assets/index-fh5sXTj9.css +1 -0
  54. package/dist/gateway/static/root/assets/{interval-presets-DJmshV8n.js → interval-presets-utKbuCRY.js} +1 -1
  55. package/dist/gateway/static/root/assets/{keyboard-shortcuts-settings-9AUUlQ5Q.js → keyboard-shortcuts-settings-CjqS6c6V.js} +1 -1
  56. package/dist/gateway/static/root/assets/logs-page-DGXuPf5B.js +2 -0
  57. package/dist/gateway/static/root/assets/{markdown-split-CYYELqAr.js → markdown-split-DW8C47iB.js} +1 -1
  58. package/dist/gateway/static/root/assets/{media-plugins-BEcMR2M8.js → media-plugins-D6HwDhDT.js} +1 -1
  59. package/dist/gateway/static/root/assets/messages-upgxw6Ub.js +3 -0
  60. package/dist/gateway/static/root/assets/models-hub-panel-Bot16nn7.js +2 -0
  61. package/dist/gateway/static/root/assets/note-detail-page-Brlyou8M.js +2 -0
  62. package/dist/gateway/static/root/assets/{note-image-lightbox-DNAoPcmm.js → note-image-lightbox-pJM35Pz5.js} +1 -1
  63. package/dist/gateway/static/root/assets/notes-page-DvZ4pwc-.js +1 -0
  64. package/dist/gateway/static/root/assets/{preview-open-alternatives-BPLz0AIv.js → preview-open-alternatives-CVwHuyN6.js} +1 -1
  65. package/dist/gateway/static/root/assets/remote-access-hub-BZEDmxbZ.js +1 -0
  66. package/dist/gateway/static/root/assets/{save-bar-controls-CrWwWRVK.js → save-bar-controls-Ba-UEk7x.js} +1 -1
  67. package/dist/gateway/static/root/assets/{schedule-field-CF2sadvN.js → schedule-field-CNN9595U.js} +1 -1
  68. package/dist/gateway/static/root/assets/{schema-form-Di5cKjYE.js → schema-form-DnNMmtD5.js} +1 -1
  69. package/dist/gateway/static/root/assets/sessions-page-DdGGlsfn.js +1 -0
  70. package/dist/gateway/static/root/assets/settings-advanced-gate-DlkEkPf9.js +1 -0
  71. package/dist/gateway/static/root/assets/{settings-collapsible-section-Chh282jW.js → settings-collapsible-section-CmOz80i5.js} +1 -1
  72. package/dist/gateway/static/root/assets/{settings-form-section-Dq-83cQd.js → settings-form-section-BmK7JJOV.js} +1 -1
  73. package/dist/gateway/static/root/assets/settings-page-DFPTrsPF.js +1 -0
  74. package/dist/gateway/static/root/assets/setup-status-panel-CYCCfgh4.js +1 -0
  75. package/dist/gateway/static/root/assets/{share-preview-page-0FXYnSUA.js → share-preview-page-Dp2qGrHC.js} +1 -1
  76. package/dist/gateway/static/root/assets/shares-settings-Bff1pGd0.js +1 -0
  77. package/dist/gateway/static/root/assets/skill-reload-api-CJGKpBur.js +1 -0
  78. package/dist/gateway/static/root/assets/skills-page-C6ocduTD.js +2 -0
  79. package/dist/gateway/static/root/assets/{system-settings-panel-W1pTcojB.js → system-settings-panel-5jrIEr5b.js} +1 -1
  80. package/dist/gateway/static/root/assets/{use-agent-defaults-form-BVRvkK7m.js → use-agent-defaults-form-BuiXLIs5.js} +1 -1
  81. package/dist/gateway/static/root/assets/{use-channel-catalog-CgJibfMM.js → use-channel-catalog-CHlO8J9G.js} +1 -1
  82. package/dist/gateway/static/root/assets/{use-settings-tab-guard-Bw_qkRQE.js → use-settings-tab-guard-CW5JORnl.js} +1 -1
  83. package/dist/gateway/static/root/assets/voice-api-key-field-DDoQyghO.js +1 -0
  84. package/dist/gateway/static/root/assets/{voice-player-store-C7lziaAx.js → voice-player-store-DDDWYHvg.js} +1 -1
  85. package/dist/gateway/static/root/assets/workflow-page.utils-CKjeEGqx.js +1 -0
  86. package/dist/gateway/static/root/assets/workflows-page-B604ehHG.js +18 -0
  87. package/dist/gateway/static/root/index.html +5 -5
  88. package/dist/gateway/static/root/logo.svg +4 -3
  89. package/dist/package.js +1 -1
  90. package/dist/src/agent/agent-manager.d.ts +8 -0
  91. package/dist/src/agent/agent-manager.js +63 -28
  92. package/dist/src/agent/agent-manager.js.map +1 -1
  93. package/dist/src/agent/agent-scope.js +1 -1
  94. package/dist/src/agent/bootstrap/load-bootstrap-files.js +1 -1
  95. package/dist/src/agent/bootstrap/project-agents-context.d.ts +2 -0
  96. package/dist/src/agent/bootstrap/project-agents-context.js +32 -0
  97. package/dist/src/agent/bootstrap/project-agents-context.js.map +1 -0
  98. package/dist/src/agent/context/workspace-seed.js +2 -2
  99. package/dist/src/agent/context/workspace-state.js +1 -1
  100. package/dist/src/agent/context/workspace.js +1 -1
  101. package/dist/src/agent/embedded/session-tool-result-guard.js +8 -1
  102. package/dist/src/agent/embedded/session-tool-result-guard.js.map +1 -1
  103. package/dist/src/agent/goals/checklist-judge.d.ts +1 -0
  104. package/dist/src/agent/goals/checklist-judge.js +3 -2
  105. package/dist/src/agent/goals/checklist-judge.js.map +1 -1
  106. package/dist/src/agent/goals/evaluate-turn.d.ts +1 -1
  107. package/dist/src/agent/goals/evaluate-turn.js +1 -0
  108. package/dist/src/agent/goals/evaluate-turn.js.map +1 -1
  109. package/dist/src/agent/goals/goal-locale.js +2 -2
  110. package/dist/src/agent/goals/persistent-goal-service.js +2 -4
  111. package/dist/src/agent/goals/persistent-goal-service.js.map +1 -1
  112. package/dist/src/agent/goals/post-turn.d.ts +6 -1
  113. package/dist/src/agent/goals/post-turn.js +15 -6
  114. package/dist/src/agent/goals/post-turn.js.map +1 -1
  115. package/dist/src/agent/image/load-image-media.js +2 -2
  116. package/dist/src/agent/inbound/inbound-loop.js +5 -1
  117. package/dist/src/agent/inbound/inbound-loop.js.map +1 -1
  118. package/dist/src/agent/inbound/turn-dispatcher.d.ts +2 -2
  119. package/dist/src/agent/inbound/turn-dispatcher.js +2 -2
  120. package/dist/src/agent/inbound/turn-dispatcher.js.map +1 -1
  121. package/dist/src/agent/ipc/inbox.js +3 -3
  122. package/dist/src/agent/ipc/socket.js +1 -1
  123. package/dist/src/agent/mcp/bundle-mcp-materialize.d.ts +27 -0
  124. package/dist/src/agent/mcp/bundle-mcp-materialize.js +50 -2
  125. package/dist/src/agent/mcp/bundle-mcp-materialize.js.map +1 -1
  126. package/dist/src/agent/mcp/bundle-mcp-runtime.js +79 -4
  127. package/dist/src/agent/mcp/bundle-mcp-runtime.js.map +1 -1
  128. package/dist/src/agent/mcp/bundle-mcp-types.d.ts +19 -0
  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/builtin-memory-store.js +1 -1
  132. package/dist/src/agent/memory/dreaming/deep-promotion.js +1 -1
  133. package/dist/src/agent/memory/dreaming/events.js +1 -1
  134. package/dist/src/agent/memory/dreaming/last-run.js +1 -1
  135. package/dist/src/agent/memory/dreaming/light-sweep.js +1 -1
  136. package/dist/src/agent/memory/dreaming/preview.js +1 -1
  137. package/dist/src/agent/memory/dreaming/rem-patterns.js +1 -1
  138. package/dist/src/agent/memory/dreaming/short-term-store.js +1 -1
  139. package/dist/src/agent/memory/dreaming/utils.js +1 -1
  140. package/dist/src/agent/memory/memory-flush.js +1 -1
  141. package/dist/src/agent/memory/plugin-discovery.js +1 -1
  142. package/dist/src/agent/models/manager.js +1 -1
  143. package/dist/src/agent/prompt/memory/index.js +1 -1
  144. package/dist/src/agent/prompt/service-prompt-builder.js +2 -2
  145. package/dist/src/agent/reply/post-compaction-context.js +1 -1
  146. package/dist/src/agent/reply/workspace-boundary-read.js +1 -1
  147. package/dist/src/agent/sandbox/path-policy.js +2 -2
  148. package/dist/src/agent/service/btw-query.js +11 -3
  149. package/dist/src/agent/service/btw-query.js.map +1 -1
  150. package/dist/src/agent/service/parse-outbound-session-key.js +13 -8
  151. package/dist/src/agent/service/parse-outbound-session-key.js.map +1 -1
  152. package/dist/src/agent/service/process-direct-one-shot.d.ts +2 -2
  153. package/dist/src/agent/service/process-direct-one-shot.js +1 -1
  154. package/dist/src/agent/service/process-direct-one-shot.js.map +1 -1
  155. package/dist/src/agent/service/process-direct-streaming.d.ts +2 -2
  156. package/dist/src/agent/service/process-direct-streaming.js +1 -1
  157. package/dist/src/agent/service/process-direct-streaming.js.map +1 -1
  158. package/dist/src/agent/service.d.ts +1 -1
  159. package/dist/src/agent/service.js +13 -9
  160. package/dist/src/agent/service.js.map +1 -1
  161. package/dist/src/agent/service.types.d.ts +5 -0
  162. package/dist/src/agent/session/session-inspector.js +1 -1
  163. package/dist/src/agent/skills/config.js +2 -2
  164. package/dist/src/agent/skills/filesystem-watcher.js +5 -4
  165. package/dist/src/agent/skills/filesystem-watcher.js.map +1 -1
  166. package/dist/src/agent/skills/hub-hash.js +2 -2
  167. package/dist/src/agent/skills/hub-lock.js +1 -1
  168. package/dist/src/agent/skills/hub-pull.js +2 -2
  169. package/dist/src/agent/skills/index.js +4 -3
  170. package/dist/src/agent/skills/index.js.map +1 -1
  171. package/dist/src/agent/skills/installer.js +2 -2
  172. package/dist/src/agent/skills/managed-store.js +1 -1
  173. package/dist/src/agent/skills/skill-manage-ops.js +3 -2
  174. package/dist/src/agent/skills/skill-manage-ops.js.map +1 -1
  175. package/dist/src/agent/skills/skill-manager.js +1 -1
  176. package/dist/src/agent/skills/skill-view-path.js +1 -1
  177. package/dist/src/agent/skills/test-framework.js +1 -1
  178. package/dist/src/agent/skills/types.d.ts +1 -1
  179. package/dist/src/agent/skills/watcher.js +2 -5
  180. package/dist/src/agent/skills/watcher.js.map +1 -1
  181. package/dist/src/agent/skills/workspace-skills-dir.d.ts +1 -0
  182. package/dist/src/agent/skills/workspace-skills-dir.js +11 -0
  183. package/dist/src/agent/skills/workspace-skills-dir.js.map +1 -0
  184. package/dist/src/agent/starter-agents.js +1 -1
  185. package/dist/src/agent/tool-manuals/browser.d.ts +1 -1
  186. package/dist/src/agent/tool-manuals/browser.js +62 -3
  187. package/dist/src/agent/tool-manuals/browser.js.map +1 -1
  188. package/dist/src/agent/tools/browser/tool/browser-use-tool.d.ts +4 -1
  189. package/dist/src/agent/tools/browser/tool/browser-use-tool.js +13 -4
  190. package/dist/src/agent/tools/browser/tool/browser-use-tool.js.map +1 -1
  191. package/dist/src/agent/tools/browser/tool/schemas.d.ts +0 -2
  192. package/dist/src/agent/tools/browser/tool/schemas.js +1 -2
  193. package/dist/src/agent/tools/browser/tool/schemas.js.map +1 -1
  194. package/dist/src/agent/tools/dreaming-tool.js +1 -1
  195. package/dist/src/agent/tools/factory.js +1 -10
  196. package/dist/src/agent/tools/factory.js.map +1 -1
  197. package/dist/src/agent/tools/find.js +1 -1
  198. package/dist/src/agent/tools/grep.js +1 -1
  199. package/dist/src/agent/tools/image-generate-tool.js +1 -1
  200. package/dist/src/agent/tools/skill-manage-tool.js +2 -2
  201. package/dist/src/agent/tools/skill-manage-tool.js.map +1 -1
  202. package/dist/src/agent/tools/workflow-tool.js +1 -1
  203. package/dist/src/agent/workflow/catalog.js +1 -1
  204. package/dist/src/agent/workflow/snapshot.d.ts +10 -0
  205. package/dist/src/agent/workflow/snapshot.js +136 -1
  206. package/dist/src/agent/workflow/snapshot.js.map +1 -1
  207. package/dist/src/agent/workflow/subagent-runner.js +18 -1
  208. package/dist/src/agent/workflow/subagent-runner.js.map +1 -1
  209. package/dist/src/ai-assist/text-assist.js +1 -1
  210. package/dist/src/auth/credentials.js +2 -2
  211. package/dist/src/auth/profiles/store.js +2 -2
  212. package/dist/src/auth/sync-provider-auth.js +1 -1
  213. package/dist/src/browser/actions/extension-registry-bridge.js +91 -7
  214. package/dist/src/browser/actions/extension-registry-bridge.js.map +1 -1
  215. package/dist/src/browser/actions/registry.js +383 -7
  216. package/dist/src/browser/actions/registry.js.map +1 -1
  217. package/dist/src/browser/actions/types.d.ts +11 -3
  218. package/dist/src/browser/cache-dir-policy.js +1 -1
  219. package/dist/src/browser/cdp-local-launcher.js +2 -2
  220. package/dist/src/browser/index.js +2 -2
  221. package/dist/src/browser/pipeline/output.d.ts +18 -16
  222. package/dist/src/browser/pipeline/output.js +28 -20
  223. package/dist/src/browser/pipeline/output.js.map +1 -1
  224. package/dist/src/browser/pipeline/runner.d.ts +7 -14
  225. package/dist/src/browser/pipeline/runner.js +349 -102
  226. package/dist/src/browser/pipeline/runner.js.map +1 -1
  227. package/dist/src/browser/pipeline/schema.d.ts +1 -0
  228. package/dist/src/browser/pipeline/schema.js +35 -58
  229. package/dist/src/browser/pipeline/schema.js.map +1 -1
  230. package/dist/src/browser/pipeline/source.d.ts +2 -0
  231. package/dist/src/browser/pipeline/source.js +10 -1
  232. package/dist/src/browser/pipeline/source.js.map +1 -1
  233. package/dist/src/browser/pipeline/template.d.ts +10 -2
  234. package/dist/src/browser/pipeline/template.js +50 -8
  235. package/dist/src/browser/pipeline/template.js.map +1 -1
  236. package/dist/src/browser/providers/browser-ext-install.js +4 -4
  237. package/dist/src/browser/providers/cloakbrowser.js +5 -5
  238. package/dist/src/browser/providers/playwright-doctor.js +1 -1
  239. package/dist/src/browser/stealth.js +1 -1
  240. package/dist/src/channels/catalog/channel-catalog-service.d.ts +2 -1
  241. package/dist/src/channels/catalog/channel-catalog-service.js +133 -16
  242. package/dist/src/channels/catalog/channel-catalog-service.js.map +1 -1
  243. package/dist/src/channels/catalog/channel-catalog-types.d.ts +13 -0
  244. package/dist/src/channels/outbound/persist-store.js +1 -1
  245. package/dist/src/channels/pairing/allow-from-file.js +1 -1
  246. package/dist/src/channels/pairing/pairing-store.js +2 -2
  247. package/dist/src/chat-commands/agent-edit.js +2 -2
  248. package/dist/src/chat-commands/builtins/config.js +5 -7
  249. package/dist/src/chat-commands/builtins/config.js.map +1 -1
  250. package/dist/src/chat-commands/context.d.ts +5 -0
  251. package/dist/src/chat-commands/context.js +18 -9
  252. package/dist/src/chat-commands/context.js.map +1 -1
  253. package/dist/src/chat-commands/index.d.ts +1 -1
  254. package/dist/src/chat-commands/index.js +2 -2
  255. package/dist/src/chat-commands/index.js.map +1 -1
  256. package/dist/src/chat-commands/processor.js +22 -21
  257. package/dist/src/chat-commands/processor.js.map +1 -1
  258. package/dist/src/chat-commands/session-key.d.ts +3 -15
  259. package/dist/src/chat-commands/session-key.js +3 -49
  260. package/dist/src/chat-commands/session-key.js.map +1 -1
  261. package/dist/src/chat-commands/types.d.ts +4 -0
  262. package/dist/src/cli/commands/browser-cli-helpers.js +11 -5
  263. package/dist/src/cli/commands/browser-cli-helpers.js.map +1 -1
  264. package/dist/src/cli/commands/config.js +1 -1
  265. package/dist/src/cli/commands/doctor/checks/channel-config.js +14 -1
  266. package/dist/src/cli/commands/doctor/checks/channel-config.js.map +1 -1
  267. package/dist/src/cli/commands/doctor/checks/config-health.js +1 -1
  268. package/dist/src/cli/commands/doctor/checks/database-schema.js +1 -1
  269. package/dist/src/cli/commands/doctor/checks/provider-auth.js +1 -1
  270. package/dist/src/cli/commands/doctor/checks/session-integrity.js +8 -8
  271. package/dist/src/cli/commands/doctor/checks/session-integrity.js.map +1 -1
  272. package/dist/src/cli/commands/doctor/checks/state-integrity.js +1 -1
  273. package/dist/src/cli/commands/doctor/checks/workspace-status.js +1 -1
  274. package/dist/src/cli/commands/extension-create.js +1 -1
  275. package/dist/src/cli/commands/extension-dev.js +2 -2
  276. package/dist/src/cli/commands/extension-marketplace.js +2 -2
  277. package/dist/src/cli/commands/extension-pack.js +2 -2
  278. package/dist/src/cli/commands/extension.js +3 -3
  279. package/dist/src/cli/commands/gateway/logs.js +1 -1
  280. package/dist/src/cli/commands/image.js +1 -1
  281. package/dist/src/cli/commands/init.js +2 -2
  282. package/dist/src/cli/commands/models.js +1 -1
  283. package/dist/src/cli/commands/skills-test.js +1 -1
  284. package/dist/src/cli/templates.js +1 -1
  285. package/dist/src/cli/utils/gateway-client.js +1 -1
  286. package/dist/src/cli/utils/init-workspace-core.js +2 -2
  287. package/dist/src/config/agent-profile.js +1 -1
  288. package/dist/src/config/agent-typed-models.js +1 -1
  289. package/dist/src/config/gateway-bind.js +1 -1
  290. package/dist/src/config/index.js +7 -7
  291. package/dist/src/config/loader.js +4 -4
  292. package/dist/src/config/models-json.js +2 -2
  293. package/dist/src/config/paths-state.js +1 -1
  294. package/dist/src/config/paths.js +1 -1
  295. package/dist/src/config/profile.js +1 -1
  296. package/dist/src/config/reload.js +1 -1
  297. package/dist/src/config/rules.js +5 -0
  298. package/dist/src/config/rules.js.map +1 -1
  299. package/dist/src/config/schema.d.ts +8 -0
  300. package/dist/src/config/schema.js +7 -0
  301. package/dist/src/config/schema.js.map +1 -1
  302. package/dist/src/config/web-patch.d.ts +1 -0
  303. package/dist/src/config/web-patch.js +1 -0
  304. package/dist/src/config/web-patch.js.map +1 -1
  305. package/dist/src/config/workspace-path.js +1 -1
  306. package/dist/src/connectors/builtin-catalog.js +180 -1
  307. package/dist/src/connectors/builtin-catalog.js.map +1 -1
  308. package/dist/src/connectors/health.js +18 -9
  309. package/dist/src/connectors/health.js.map +1 -1
  310. package/dist/src/connectors/types.d.ts +19 -0
  311. package/dist/src/connectors/usage.js +12 -4
  312. package/dist/src/connectors/usage.js.map +1 -1
  313. package/dist/src/cron/executor.js +1 -1
  314. package/dist/src/cron/service.js +1 -1
  315. package/dist/src/daemon/constants.js +1 -1
  316. package/dist/src/daemon/install-plan.js +2 -2
  317. package/dist/src/daemon/launchd.js +2 -2
  318. package/dist/src/daemon/schtasks.js +2 -2
  319. package/dist/src/daemon/systemd.js +2 -2
  320. package/dist/src/extensions/bundle-mcp.js +1 -1
  321. package/dist/src/extensions/discover-extensions.js +2 -2
  322. package/dist/src/extensions/health.js +1 -1
  323. package/dist/src/extensions/install.js +2 -2
  324. package/dist/src/extensions/loader.js +2 -2
  325. package/dist/src/extensions/lockfile.js +3 -3
  326. package/dist/src/extensions/security.js +1 -1
  327. package/dist/src/extensions/types/tui.d.ts +2 -0
  328. package/dist/src/extensions/update.js +2 -2
  329. package/dist/src/gateway/agents-admin.js +2 -2
  330. package/dist/src/gateway/file-path-classifier.js +2 -2
  331. package/dist/src/gateway/heartbeat/service.js +13 -1
  332. package/dist/src/gateway/heartbeat/service.js.map +1 -1
  333. package/dist/src/gateway/hono/app.js +18 -5
  334. package/dist/src/gateway/hono/app.js.map +1 -1
  335. package/dist/src/gateway/hono/lib/config-payload.d.ts +3 -1
  336. package/dist/src/gateway/hono/lib/config-payload.js +7 -4
  337. package/dist/src/gateway/hono/lib/config-payload.js.map +1 -1
  338. package/dist/src/gateway/hono/lib/extension-store.js +2 -2
  339. package/dist/src/gateway/hono/lib/static-ui.js +2 -2
  340. package/dist/src/gateway/hono/middleware/strict-rate-limit.d.ts +4 -0
  341. package/dist/src/gateway/hono/middleware/strict-rate-limit.js +19 -5
  342. package/dist/src/gateway/hono/middleware/strict-rate-limit.js.map +1 -1
  343. package/dist/src/gateway/hono/oauth-async.js +1 -1
  344. package/dist/src/gateway/hono/routes/agent-stream.js +6 -6
  345. package/dist/src/gateway/hono/routes/agent-stream.js.map +1 -1
  346. package/dist/src/gateway/hono/routes/agents.js +1 -1
  347. package/dist/src/gateway/hono/routes/auth-registry-extensions.js +1 -1
  348. package/dist/src/gateway/hono/routes/channels.js +18 -14
  349. package/dist/src/gateway/hono/routes/channels.js.map +1 -1
  350. package/dist/src/gateway/hono/routes/config-patch/gateway.d.ts +1 -1
  351. package/dist/src/gateway/hono/routes/config-patch/gateway.js +6 -0
  352. package/dist/src/gateway/hono/routes/config-patch/gateway.js.map +1 -1
  353. package/dist/src/gateway/hono/routes/config-patch/misc.js +1 -1
  354. package/dist/src/gateway/hono/routes/deps.d.ts +1 -0
  355. package/dist/src/gateway/hono/routes/dreaming.js +1 -1
  356. package/dist/src/gateway/hono/routes/goals.js +16 -3
  357. package/dist/src/gateway/hono/routes/goals.js.map +1 -1
  358. package/dist/src/gateway/hono/routes/host-fs.js +2 -2
  359. package/dist/src/gateway/hono/routes/logs.js +1 -0
  360. package/dist/src/gateway/hono/routes/logs.js.map +1 -1
  361. package/dist/src/gateway/hono/routes/mcp.js +27 -8
  362. package/dist/src/gateway/hono/routes/mcp.js.map +1 -1
  363. package/dist/src/gateway/hono/routes/models.js +1 -1
  364. package/dist/src/gateway/hono/routes/notes.js +14 -2
  365. package/dist/src/gateway/hono/routes/notes.js.map +1 -1
  366. package/dist/src/gateway/hono/routes/sessions.js +62 -4
  367. package/dist/src/gateway/hono/routes/sessions.js.map +1 -1
  368. package/dist/src/gateway/hono/routes/shares.js +1 -1
  369. package/dist/src/gateway/hono/routes/workflows.js +1 -1
  370. package/dist/src/gateway/hono/routes/workspace.js +5 -68
  371. package/dist/src/gateway/hono/routes/workspace.js.map +1 -1
  372. package/dist/src/gateway/hono/sse.d.ts +2 -2
  373. package/dist/src/gateway/hono/sse.js +7 -15
  374. package/dist/src/gateway/hono/sse.js.map +1 -1
  375. package/dist/src/gateway/lock.js +3 -3
  376. package/dist/src/gateway/ports.js +1 -1
  377. package/dist/src/gateway/rate-limit/buckets.d.ts +3 -0
  378. package/dist/src/gateway/rate-limit/buckets.js +12 -0
  379. package/dist/src/gateway/rate-limit/buckets.js.map +1 -1
  380. package/dist/src/gateway/resolve-webchat-session-key.d.ts +2 -6
  381. package/dist/src/gateway/resolve-webchat-session-key.js +5 -31
  382. package/dist/src/gateway/resolve-webchat-session-key.js.map +1 -1
  383. package/dist/src/gateway/service/agent-runner.d.ts +2 -3
  384. package/dist/src/gateway/service/agent-runner.js +9 -22
  385. package/dist/src/gateway/service/agent-runner.js.map +1 -1
  386. package/dist/src/gateway/service/config-coordinator.js +1 -1
  387. package/dist/src/gateway/service/marketplace-service.js +2 -2
  388. package/dist/src/gateway/service/run-gateway-agent.js +9 -7
  389. package/dist/src/gateway/service/run-gateway-agent.js.map +1 -1
  390. package/dist/src/gateway/service/sessions-api.d.ts +9 -0
  391. package/dist/src/gateway/service/sessions-api.js +11 -0
  392. package/dist/src/gateway/service/sessions-api.js.map +1 -1
  393. package/dist/src/gateway/service.d.ts +1 -1
  394. package/dist/src/gateway/service.js +23 -9
  395. package/dist/src/gateway/service.js.map +1 -1
  396. package/dist/src/gateway/workspace-file-search.d.ts +9 -0
  397. package/dist/src/gateway/workspace-file-search.js +76 -0
  398. package/dist/src/gateway/workspace-file-search.js.map +1 -0
  399. package/dist/src/gateway/workspace-fs-file-list.js +1 -1
  400. package/dist/src/goals/goal-notifications.d.ts +2 -0
  401. package/dist/src/goals/goal-notifications.js +16 -11
  402. package/dist/src/goals/goal-notifications.js.map +1 -1
  403. package/dist/src/goals/goal-service.js +1 -6
  404. package/dist/src/goals/goal-service.js.map +1 -1
  405. package/dist/src/goals/goal-workflow-judge.js +2 -2
  406. package/dist/src/i18n/goals-bundle.js +1 -1
  407. package/dist/src/i18n/index.js +1 -1
  408. package/dist/src/i18n/share-tool-bundle.js +2 -2
  409. package/dist/src/infra/brew.js +1 -1
  410. package/dist/src/infra/package-json.js +1 -1
  411. package/dist/src/infra/package-update-steps.js +1 -1
  412. package/dist/src/infra/path-env.js +2 -2
  413. package/dist/src/infra/restart.js +1 -1
  414. package/dist/src/infra/stable-node-path.js +1 -1
  415. package/dist/src/infra/update-check.js +1 -1
  416. package/dist/src/infra/update-global.js +1 -1
  417. package/dist/src/infra/update-lock.js +2 -2
  418. package/dist/src/infra/update-restart.js +1 -1
  419. package/dist/src/infra/update-runner.js +1 -1
  420. package/dist/src/infra/update-startup.js +1 -1
  421. package/dist/src/infra/write-file-atomic.js +2 -2
  422. package/dist/src/media/store.js +1 -1
  423. package/dist/src/notes/agent-context.js +1 -1
  424. package/dist/src/notes/service.js +1 -1
  425. package/dist/src/notes/store.js +2 -2
  426. package/dist/src/project-trust/trust-store.js +4 -2
  427. package/dist/src/project-trust/trust-store.js.map +1 -1
  428. package/dist/src/providers/auth-runtime/auth-profile-store.js +1 -1
  429. package/dist/src/providers/index.js +1 -1
  430. package/dist/src/providers/model-registry.js +4 -4
  431. package/dist/src/session/index.d.ts +1 -1
  432. package/dist/src/session/index.js +2 -2
  433. package/dist/src/session/init-session-turn.js +7 -10
  434. package/dist/src/session/init-session-turn.js.map +1 -1
  435. package/dist/src/session/manager.d.ts +5 -1
  436. package/dist/src/session/manager.js +5 -2
  437. package/dist/src/session/manager.js.map +1 -1
  438. package/dist/src/session/reset-type.d.ts +0 -2
  439. package/dist/src/session/reset-type.js +3 -9
  440. package/dist/src/session/reset-type.js.map +1 -1
  441. package/dist/src/session/resolve-session.js +10 -21
  442. package/dist/src/session/resolve-session.js.map +1 -1
  443. package/dist/src/session/session-title.js +2 -2
  444. package/dist/src/session/store.d.ts +11 -3
  445. package/dist/src/session/store.js +30 -14
  446. package/dist/src/session/store.js.map +1 -1
  447. package/dist/src/session/types.d.ts +2 -4
  448. package/dist/src/session/types.js.map +1 -1
  449. package/dist/src/share/share-auto.js +2 -2
  450. package/dist/src/share/share-store.js +3 -3
  451. package/dist/src/share/share-thumbnail.js +2 -2
  452. package/dist/src/share/share-zip.js +1 -1
  453. package/dist/src/share/site-share-store.js +3 -3
  454. package/dist/src/share/site-static-serve.js +1 -1
  455. package/dist/src/storage/sqlite/connection.js +1 -1
  456. package/dist/src/storage/sqlite/index.d.ts +2 -2
  457. package/dist/src/storage/sqlite/index.js +3 -3
  458. package/dist/src/storage/sqlite/memory-index-repository.js +2 -2
  459. package/dist/src/storage/sqlite/migrations/010_session_id_identity.sql +30 -0
  460. package/dist/src/storage/sqlite/migrations/discover.js +1 -1
  461. package/dist/src/storage/sqlite/migrations/runner.d.ts +2 -2
  462. package/dist/src/storage/sqlite/migrations/runner.js +5 -5
  463. package/dist/src/storage/sqlite/migrations/runner.js.map +1 -1
  464. package/dist/src/storage/sqlite/migrations/runner.ts +2 -2
  465. package/dist/src/storage/sqlite/row-mappers.d.ts +4 -4
  466. package/dist/src/storage/sqlite/row-mappers.js +11 -14
  467. package/dist/src/storage/sqlite/row-mappers.js.map +1 -1
  468. package/dist/src/storage/sqlite/schema.js +4 -4
  469. package/dist/src/storage/sqlite/schema.js.map +1 -1
  470. package/dist/src/storage/sqlite/schema.sql +37 -10
  471. package/dist/src/storage/sqlite/session-metadata.d.ts +2 -7
  472. package/dist/src/storage/sqlite/session-metadata.js +18 -72
  473. package/dist/src/storage/sqlite/session-metadata.js.map +1 -1
  474. package/dist/src/storage/sqlite/session-repository.d.ts +6 -5
  475. package/dist/src/storage/sqlite/session-repository.js +34 -40
  476. package/dist/src/storage/sqlite/session-repository.js.map +1 -1
  477. package/dist/src/storage/sqlite/transcript-repository.d.ts +2 -2
  478. package/dist/src/storage/sqlite/transcript-repository.js +52 -52
  479. package/dist/src/storage/sqlite/transcript-repository.js.map +1 -1
  480. package/dist/src/tui/backends/embedded-backend.d.ts +18 -4
  481. package/dist/src/tui/backends/embedded-backend.js +100 -1
  482. package/dist/src/tui/backends/embedded-backend.js.map +1 -1
  483. package/dist/src/tui/backends/gateway-sse-backend.d.ts +5 -1
  484. package/dist/src/tui/backends/gateway-sse-backend.js +45 -2
  485. package/dist/src/tui/backends/gateway-sse-backend.js.map +1 -1
  486. package/dist/src/tui/clipboard-image.js +3 -3
  487. package/dist/src/tui/components/chat-log.d.ts +2 -0
  488. package/dist/src/tui/components/chat-log.js +19 -0
  489. package/dist/src/tui/components/chat-log.js.map +1 -1
  490. package/dist/src/tui/extension-host/autocomplete.d.ts +3 -2
  491. package/dist/src/tui/extension-host/autocomplete.js +29 -12
  492. package/dist/src/tui/extension-host/autocomplete.js.map +1 -1
  493. package/dist/src/tui/extension-host/load-extensions.js +1 -1
  494. package/dist/src/tui/extension-host/runtime.d.ts +12 -0
  495. package/dist/src/tui/extension-host/runtime.js +6 -4
  496. package/dist/src/tui/extension-host/runtime.js.map +1 -1
  497. package/dist/src/tui/theme-manager.js +1 -1
  498. package/dist/src/tui/tui-backend.d.ts +23 -0
  499. package/dist/src/tui/tui-command-formatters.js +4 -4
  500. package/dist/src/tui/tui-commands.d.ts +16 -3
  501. package/dist/src/tui/tui-commands.js +134 -27
  502. package/dist/src/tui/tui-commands.js.map +1 -1
  503. package/dist/src/tui/tui-file-autocomplete.d.ts +5 -0
  504. package/dist/src/tui/tui-file-autocomplete.js +26 -0
  505. package/dist/src/tui/tui-file-autocomplete.js.map +1 -0
  506. package/dist/src/tui/tui-keybindings-file.js +1 -1
  507. package/dist/src/tui/tui-picker-overlay.js +1 -1
  508. package/dist/src/tui/tui-scoped-models.js +2 -2
  509. package/dist/src/tui/tui-settings.js +1 -1
  510. package/dist/src/tui/tui-startup-resources.js +1 -1
  511. package/dist/src/tui/tui-startup-text.js +1 -1
  512. package/dist/src/tui/tui-startup-text.js.map +1 -1
  513. package/dist/src/tui/tui.js +106 -17
  514. package/dist/src/tui/tui.js.map +1 -1
  515. package/dist/src/tunnel/frpc-binary.js +4 -4
  516. package/dist/src/tunnel/frpc-config.js +1 -1
  517. package/dist/src/tunnel/frpc-extract.js +1 -1
  518. package/dist/src/tunnel/tunnel-state.js +1 -1
  519. package/dist/src/utils/logger/audit.js +1 -1
  520. package/dist/src/utils/logger/context.d.ts +2 -2
  521. package/dist/src/utils/logger/context.js +2 -1
  522. package/dist/src/utils/logger/context.js.map +1 -1
  523. package/dist/src/utils/logger/log-store.js +2 -1
  524. package/dist/src/utils/logger/log-store.js.map +1 -1
  525. package/dist/src/utils/logger/pino-record.js +3 -0
  526. package/dist/src/utils/logger/pino-record.js.map +1 -1
  527. package/dist/src/utils/logger/rotation.js +1 -1
  528. package/dist/src/utils/logger/streams.js +1 -1
  529. package/dist/src/utils/logger/types.d.ts +5 -0
  530. package/dist/src/utils/logger/types.js.map +1 -1
  531. package/dist/src/voice/tts/audio.js +1 -1
  532. package/dist/src/voice/tts/providers/edge-speech.js +2 -2
  533. package/dist/src/workflows/draft/workflow-draft-service.js +1 -1
  534. package/dist/src/workflows/service/workflow-run-service.js +1 -1
  535. package/dist/src/workflows/service/workflow-session-bridge.js +13 -1
  536. package/dist/src/workflows/service/workflow-session-bridge.js.map +1 -1
  537. package/dist/src/workflows/store/event-store.js +1 -1
  538. package/dist/src/workflows/store/run-store.js +1 -1
  539. package/package.json +1 -1
  540. package/dist/gateway/static/root/assets/agent-browser-settings-page-rGbKc2Hh.js +0 -6
  541. package/dist/gateway/static/root/assets/agent-defaults-tabbed-page-CtwVbjOA.js +0 -1
  542. package/dist/gateway/static/root/assets/agents-CCBmGcwc.js +0 -71
  543. package/dist/gateway/static/root/assets/apps-page-xwCsJS15.js +0 -1
  544. package/dist/gateway/static/root/assets/channels-settings-C044DcYk.js +0 -1
  545. package/dist/gateway/static/root/assets/connectors-settings-8VEWUOTj.js +0 -2
  546. package/dist/gateway/static/root/assets/cron-page-DqmNGNOy.js +0 -3
  547. package/dist/gateway/static/root/assets/goal-detail-page-bv0VRDaf.js +0 -1
  548. package/dist/gateway/static/root/assets/goals-page-1Ywnt4Cb.js +0 -2
  549. package/dist/gateway/static/root/assets/goals-settings-ceEBjnfc.js +0 -1
  550. package/dist/gateway/static/root/assets/index-Cxm6xsps.js +0 -122
  551. package/dist/gateway/static/root/assets/index-b_R4tKqt.css +0 -1
  552. package/dist/gateway/static/root/assets/logs-page-B_wrxhee.js +0 -2
  553. package/dist/gateway/static/root/assets/messages-CkT-lcgP.js +0 -3
  554. package/dist/gateway/static/root/assets/models-hub-panel-D0JDSbNu.js +0 -2
  555. package/dist/gateway/static/root/assets/note-detail-page-DpFV-EO6.js +0 -2
  556. package/dist/gateway/static/root/assets/notes-page-CdkjTch8.js +0 -1
  557. package/dist/gateway/static/root/assets/remote-access-hub-DSYVAi96.js +0 -1
  558. package/dist/gateway/static/root/assets/sessions-page-CenkcVjF.js +0 -1
  559. package/dist/gateway/static/root/assets/settings-advanced-gate-D9sva86V.js +0 -1
  560. package/dist/gateway/static/root/assets/settings-page-DL35U0x0.js +0 -1
  561. package/dist/gateway/static/root/assets/setup-status-panel-Ctwbp9Er.js +0 -1
  562. package/dist/gateway/static/root/assets/shares-settings-DIM3JNsr.js +0 -1
  563. package/dist/gateway/static/root/assets/skill-reload-api-DAlNaNzL.js +0 -1
  564. package/dist/gateway/static/root/assets/skills-page-CLrHVzAt.js +0 -2
  565. package/dist/gateway/static/root/assets/voice-api-key-field-vYAO71Gn.js +0 -1
  566. package/dist/gateway/static/root/assets/workflow-page.utils-sgHjOXOm.js +0 -1
  567. package/dist/gateway/static/root/assets/workflows-page-DYyOTmFx.js +0 -18
@@ -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 {\n buildDefaultSessionMetadata,\n resolveAgentIdFromSessionKey,\n} 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.current_transcript_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.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.transcript_id = s.current_transcript_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 transcriptId: string,\n cwd: string,\n metadata: SessionMetadata,\n): void {\n const row = metadataToSessionInsert(sessionKey, transcriptId, metadata);\n db.prepare(\n `INSERT INTO sessions (\n session_key, agent_id, current_transcript_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 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.transcriptId,\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.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 (transcript_id, session_key, status, created_at, cwd)\n VALUES (?, ?, 'active', ?, ?)`,\n ).run(transcriptId, sessionKey, now, cwd);\n}\n\nexport function ensureSessionInTransaction(\n db: DatabaseSync,\n sessionKey: string,\n cwd: string,\n): SessionMetadata {\n const existing = readSessionRow(db, sessionKey);\n if (existing) {\n return sessionRowToMetadata(sessionKey, existing);\n }\n\n const transcriptId = validateSessionId(randomUUID());\n const metadata = buildDefaultSessionMetadata(sessionKey);\n metadata.transcriptId = transcriptId;\n insertSessionAndTranscript(db, sessionKey, transcriptId, 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(sessionKey: string, cwd: string): SessionMetadata {\n return runSqliteWriteTransaction((db) => ensureSessionInTransaction(db, sessionKey, cwd));\n}\n\nexport function readCurrentTranscriptId(db: DatabaseSync, sessionKey: string): string | null {\n const row = db\n .prepare(`SELECT current_transcript_id FROM sessions WHERE session_key = ?`)\n .get(sessionKey) as { current_transcript_id?: string } | undefined;\n return row?.current_transcript_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 getCurrentTranscriptId(sessionKey: string): string | null {\n return readCurrentTranscriptId(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.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 const directMatch = `LOWER(s.source_channel) IN (${channels.map(() => '?').join(', ')})`;\n const keyPatterns = new Set<string>();\n for (const c of channels) {\n if (c === 'webchat' || c === 'ui') {\n keyPatterns.add(`s.session_key LIKE 'agent:%:webchat:%'`);\n } else if (c === 'gateway' || c === 'webui') {\n keyPatterns.add(`s.session_key LIKE 'agent:%:gateway:%'`);\n } else {\n keyPatterns.add(`s.session_key LIKE 'agent:%:${c.replace(/'/g, \"''\")}:%'`);\n }\n }\n const keyFallback =\n keyPatterns.size > 0\n ? `(TRIM(COALESCE(s.source_channel, '')) = '' AND (${[...keyPatterns].join(' OR ')}))`\n : '';\n conditions.push(keyFallback ? `(${directMatch} OR ${keyFallback})` : directMatch);\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 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.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.current_transcript_id;\n const now = Date.now();\n db.prepare(\n `UPDATE transcripts SET status = 'archived', archive_reason = 'reset', archived_at = ?\n WHERE transcript_id = ?`,\n ).run(now, previousSessionId);\n\n const newTranscriptId = validateSessionId(randomUUID());\n db.prepare(\n `INSERT INTO transcripts (transcript_id, session_key, status, created_at, cwd)\n VALUES (?, ?, 'active', ?, ?)`,\n ).run(newTranscriptId, sessionKey, now, cwd);\n\n db.prepare(\n `UPDATE sessions SET\n current_transcript_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(newTranscriptId, now, now, sessionKey);\n\n return { sessionId: newTranscriptId, 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 transcript_id = ?`,\n ).run(now, existing.current_transcript_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 findSessionKeyByTranscriptId(transcriptId: string): string | null {\n const db = getSqliteDatabase();\n const row = db\n .prepare(`SELECT session_key FROM sessions WHERE current_transcript_id = ?`)\n .get(transcriptId) 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 resolveAgentIdFromSessionKey(sessionKey);\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.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 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.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.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 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.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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"}
@@ -4,11 +4,11 @@ import type { TranscriptCompactionRecord } from '../../session/transcript-format
4
4
  import { type TranscriptStoredRow } from '../../session/session-context-for-llm.js';
5
5
  import { type TranscriptEntryRow } from './row-mappers.js';
6
6
  export declare function appendTranscriptEntry(sessionKey: string, row: TranscriptStoredRow, opts?: {
7
- transcriptId?: string;
7
+ sessionId?: string;
8
8
  tokenDelta?: number;
9
9
  }): TranscriptEntryRow;
10
10
  export declare function loadTranscriptRowsForSession(sessionKey: string): TranscriptStoredRow[];
11
- export declare function loadTranscriptRows(transcriptId: string): TranscriptStoredRow[];
11
+ export declare function loadTranscriptRows(sessionId: string): TranscriptStoredRow[];
12
12
  export declare function loadLlmMessagesForSession(sessionKey: string): AgentMessage[];
13
13
  export declare function replaceTranscriptRows(sessionKey: string, rows: TranscriptStoredRow[], opts?: {
14
14
  appendCompaction?: TranscriptCompactionRecord;
@@ -1,27 +1,27 @@
1
1
  import { getSqliteDatabase, runSqliteWriteTransaction } from "./transaction.js";
2
2
  import { buildSessionContextForLlm } from "../../session/session-context-for-llm.js";
3
3
  import { classifyStoredRow, estimateTokensFromMessages, extractFtsContent, transcriptEntryRowToStoredRow } from "./row-mappers.js";
4
- import { getCurrentTranscriptId, readCurrentTranscriptId } from "./session-repository.js";
4
+ import { getCurrentSessionId, readCurrentSessionId } from "./session-repository.js";
5
5
  import { randomUUID } from "node:crypto";
6
6
  //#region src/storage/sqlite/transcript-repository.ts
7
7
  const MAX_CHECKPOINTS_PER_TRANSCRIPT = 15;
8
- function nextSeq(db, transcriptId) {
9
- return (db.prepare(`SELECT COALESCE(MAX(seq), 0) AS max_seq FROM transcript_entries WHERE transcript_id = ?`).get(transcriptId).max_seq ?? 0) + 1;
8
+ function nextSeq(db, sessionId) {
9
+ return (db.prepare(`SELECT COALESCE(MAX(seq), 0) AS max_seq FROM transcript_entries WHERE session_id = ?`).get(sessionId).max_seq ?? 0) + 1;
10
10
  }
11
11
  function insertEntry(db, params) {
12
12
  const { entryKind, role } = classifyStoredRow(params.row);
13
13
  const entryId = params.entryId ?? randomUUID();
14
- const seq = nextSeq(db, params.transcriptId);
14
+ const seq = nextSeq(db, params.sessionId);
15
15
  const createdAt = params.createdAt ?? Date.now();
16
16
  const payloadJson = JSON.stringify(params.row);
17
- db.prepare(`INSERT INTO transcript_entries (entry_id, transcript_id, seq, entry_kind, role, payload_json, created_at)
18
- VALUES (?, ?, ?, ?, ?, ?, ?)`).run(entryId, params.transcriptId, seq, entryKind, role, payloadJson, createdAt);
17
+ db.prepare(`INSERT INTO transcript_entries (entry_id, session_id, seq, entry_kind, role, payload_json, created_at)
18
+ VALUES (?, ?, ?, ?, ?, ?, ?)`).run(entryId, params.sessionId, seq, entryKind, role, payloadJson, createdAt);
19
19
  const content = extractFtsContent(params.row);
20
- if (content.trim()) db.prepare(`INSERT INTO transcript_fts (content, session_key, transcript_id, entry_id)
21
- VALUES (?, ?, ?, ?)`).run(content, params.sessionKey, params.transcriptId, entryId);
20
+ if (content.trim()) db.prepare(`INSERT INTO transcript_fts (content, session_key, session_id, entry_id)
21
+ VALUES (?, ?, ?, ?)`).run(content, params.sessionKey, params.sessionId, entryId);
22
22
  return {
23
23
  entry_id: entryId,
24
- transcript_id: params.transcriptId,
24
+ session_id: params.sessionId,
25
25
  seq,
26
26
  entry_kind: entryKind,
27
27
  role,
@@ -31,10 +31,10 @@ function insertEntry(db, params) {
31
31
  }
32
32
  function appendTranscriptEntry(sessionKey, row, opts) {
33
33
  return runSqliteWriteTransaction((db) => {
34
- const transcriptId = opts?.transcriptId ?? readCurrentTranscriptId(db, sessionKey);
35
- if (!transcriptId) throw new Error(`Session not found: ${sessionKey}`);
34
+ const sessionId = opts?.sessionId ?? readCurrentSessionId(db, sessionKey);
35
+ if (!sessionId) throw new Error(`Session not found: ${sessionKey}`);
36
36
  const inserted = insertEntry(db, {
37
- transcriptId,
37
+ sessionId,
38
38
  sessionKey,
39
39
  row
40
40
  });
@@ -53,32 +53,32 @@ function appendTranscriptEntry(sessionKey, row, opts) {
53
53
  });
54
54
  }
55
55
  function loadTranscriptRowsForSession(sessionKey) {
56
- const transcriptId = getCurrentTranscriptId(sessionKey);
57
- if (!transcriptId) return [];
58
- return loadTranscriptRows(transcriptId);
56
+ const sessionId = getCurrentSessionId(sessionKey);
57
+ if (!sessionId) return [];
58
+ return loadTranscriptRows(sessionId);
59
59
  }
60
- function loadTranscriptRows(transcriptId) {
61
- return getSqliteDatabase().prepare(`SELECT entry_id, transcript_id, seq, entry_kind, role, payload_json, created_at
60
+ function loadTranscriptRows(sessionId) {
61
+ return getSqliteDatabase().prepare(`SELECT entry_id, session_id, seq, entry_kind, role, payload_json, created_at
62
62
  FROM transcript_entries
63
- WHERE transcript_id = ?
64
- ORDER BY seq ASC`).all(transcriptId).map(transcriptEntryRowToStoredRow);
63
+ WHERE session_id = ?
64
+ ORDER BY seq ASC`).all(sessionId).map(transcriptEntryRowToStoredRow);
65
65
  }
66
66
  function loadLlmMessagesForSession(sessionKey) {
67
67
  return buildSessionContextForLlm(loadTranscriptRowsForSession(sessionKey));
68
68
  }
69
69
  function replaceTranscriptRows(sessionKey, rows, opts) {
70
70
  runSqliteWriteTransaction((db) => {
71
- const transcriptId = readCurrentTranscriptId(db, sessionKey);
72
- if (!transcriptId) throw new Error(`Session not found: ${sessionKey}`);
73
- db.prepare(`DELETE FROM transcript_fts WHERE transcript_id = ?`).run(transcriptId);
74
- db.prepare(`DELETE FROM transcript_entries WHERE transcript_id = ?`).run(transcriptId);
71
+ const sessionId = readCurrentSessionId(db, sessionKey);
72
+ if (!sessionId) throw new Error(`Session not found: ${sessionKey}`);
73
+ db.prepare(`DELETE FROM transcript_fts WHERE session_id = ?`).run(sessionId);
74
+ db.prepare(`DELETE FROM transcript_entries WHERE session_id = ?`).run(sessionId);
75
75
  const toWrite = [...rows];
76
76
  if (opts?.appendCompaction) toWrite.push({
77
77
  type: "compaction",
78
78
  ...opts.appendCompaction
79
79
  });
80
80
  for (const row of toWrite) insertEntry(db, {
81
- transcriptId,
81
+ sessionId,
82
82
  sessionKey,
83
83
  row
84
84
  });
@@ -102,8 +102,8 @@ function loadCheckpointRows(sessionKey, checkpointId) {
102
102
  ORDER BY seq ASC`).all(checkpointId).map((entry) => JSON.parse(entry.payload_json));
103
103
  }
104
104
  function paginateTranscriptMessages(sessionKey, options = {}) {
105
- const transcriptId = getCurrentTranscriptId(sessionKey);
106
- if (!transcriptId) return {
105
+ const sessionId = getCurrentSessionId(sessionKey);
106
+ if (!sessionId) return {
107
107
  rows: [],
108
108
  messages: [],
109
109
  total: 0,
@@ -114,35 +114,35 @@ function paginateTranscriptMessages(sessionKey, options = {}) {
114
114
  const kinds = options.includeContext ? ["message", "context"] : ["message"];
115
115
  const kindPlaceholders = kinds.map(() => "?").join(", ");
116
116
  const total = db.prepare(`SELECT COUNT(*) AS total FROM transcript_entries
117
- WHERE transcript_id = ? AND entry_kind IN (${kindPlaceholders})`).get(transcriptId, ...kinds).total;
117
+ WHERE session_id = ? AND entry_kind IN (${kindPlaceholders})`).get(sessionId, ...kinds).total;
118
118
  const limit = Math.min(200, Math.max(1, Math.trunc(options.limit ?? 50)));
119
119
  const offset = Math.max(0, Math.trunc(options.offset ?? 0));
120
120
  let rows;
121
121
  if (options.beforeEndIndex !== void 0 && Number.isFinite(options.beforeEndIndex)) {
122
122
  const endExclusive = Math.min(total, Math.max(0, Math.trunc(options.beforeEndIndex)));
123
123
  const startInclusive = Math.max(0, endExclusive - limit);
124
- rows = db.prepare(`SELECT entry_id, transcript_id, seq, entry_kind, role, payload_json, created_at
124
+ rows = db.prepare(`SELECT entry_id, session_id, seq, entry_kind, role, payload_json, created_at
125
125
  FROM (
126
- SELECT entry_id, transcript_id, seq, entry_kind, role, payload_json, created_at,
126
+ SELECT entry_id, session_id, seq, entry_kind, role, payload_json, created_at,
127
127
  ROW_NUMBER() OVER (ORDER BY seq ASC) - 1 AS idx
128
128
  FROM transcript_entries
129
- WHERE transcript_id = ? AND entry_kind IN (${kindPlaceholders})
129
+ WHERE session_id = ? AND entry_kind IN (${kindPlaceholders})
130
130
  )
131
131
  WHERE idx >= ? AND idx < ?
132
- ORDER BY seq ASC`).all(transcriptId, ...kinds, startInclusive, endExclusive);
132
+ ORDER BY seq ASC`).all(sessionId, ...kinds, startInclusive, endExclusive);
133
133
  } else if (options.beforeSeq !== void 0 && Number.isFinite(options.beforeSeq)) {
134
- rows = db.prepare(`SELECT entry_id, transcript_id, seq, entry_kind, role, payload_json, created_at
134
+ rows = db.prepare(`SELECT entry_id, session_id, seq, entry_kind, role, payload_json, created_at
135
135
  FROM transcript_entries
136
- WHERE transcript_id = ? AND entry_kind IN (${kindPlaceholders}) AND seq < ?
136
+ WHERE session_id = ? AND entry_kind IN (${kindPlaceholders}) AND seq < ?
137
137
  ORDER BY seq DESC
138
- LIMIT ?`).all(transcriptId, ...kinds, options.beforeSeq, limit);
138
+ LIMIT ?`).all(sessionId, ...kinds, options.beforeSeq, limit);
139
139
  rows.reverse();
140
140
  } else {
141
- rows = db.prepare(`SELECT entry_id, transcript_id, seq, entry_kind, role, payload_json, created_at
141
+ rows = db.prepare(`SELECT entry_id, session_id, seq, entry_kind, role, payload_json, created_at
142
142
  FROM transcript_entries
143
- WHERE transcript_id = ? AND entry_kind IN (${kindPlaceholders})
143
+ WHERE session_id = ? AND entry_kind IN (${kindPlaceholders})
144
144
  ORDER BY seq DESC
145
- LIMIT ? OFFSET ?`).all(transcriptId, ...kinds, limit, offset);
145
+ LIMIT ? OFFSET ?`).all(sessionId, ...kinds, limit, offset);
146
146
  rows.reverse();
147
147
  }
148
148
  const storedRows = rows.map(transcriptEntryRowToStoredRow);
@@ -156,29 +156,29 @@ function paginateTranscriptMessages(sessionKey, options = {}) {
156
156
  }
157
157
  function captureCompactionCheckpoint(sessionKey) {
158
158
  return runSqliteWriteTransaction((db) => {
159
- const transcriptId = readCurrentTranscriptId(db, sessionKey);
160
- if (!transcriptId) return null;
161
- const entries = db.prepare(`SELECT entry_id, transcript_id, seq, entry_kind, role, payload_json, created_at
162
- FROM transcript_entries WHERE transcript_id = ? ORDER BY seq ASC`).all(transcriptId);
159
+ const sessionId = readCurrentSessionId(db, sessionKey);
160
+ if (!sessionId) return null;
161
+ const entries = db.prepare(`SELECT entry_id, session_id, seq, entry_kind, role, payload_json, created_at
162
+ FROM transcript_entries WHERE session_id = ? ORDER BY seq ASC`).all(sessionId);
163
163
  if (entries.length === 0) return null;
164
164
  const checkpointId = randomUUID();
165
165
  const now = Date.now();
166
166
  const messageCount = entries.filter((e) => e.entry_kind === "message").length;
167
167
  const sizeBytes = entries.reduce((sum, e) => sum + e.payload_json.length, 0);
168
168
  db.prepare(`INSERT INTO compaction_checkpoints
169
- (checkpoint_id, transcript_id, session_key, created_at, message_count, size_bytes)
170
- VALUES (?, ?, ?, ?, ?, ?)`).run(checkpointId, transcriptId, sessionKey, now, messageCount, sizeBytes);
169
+ (checkpoint_id, session_id, session_key, created_at, message_count, size_bytes)
170
+ VALUES (?, ?, ?, ?, ?, ?)`).run(checkpointId, sessionId, sessionKey, now, messageCount, sizeBytes);
171
171
  const insertCheckpointEntry = db.prepare(`INSERT INTO checkpoint_entries (checkpoint_id, seq, entry_kind, role, payload_json)
172
172
  VALUES (?, ?, ?, ?, ?)`);
173
173
  for (const entry of entries) insertCheckpointEntry.run(checkpointId, entry.seq, entry.entry_kind, entry.role, entry.payload_json);
174
- pruneCompactionCheckpoints(db, transcriptId);
174
+ pruneCompactionCheckpoints(db, sessionId);
175
175
  return checkpointId;
176
176
  });
177
177
  }
178
- function pruneCompactionCheckpoints(db, transcriptId) {
178
+ function pruneCompactionCheckpoints(db, sessionId) {
179
179
  const rows = db.prepare(`SELECT checkpoint_id FROM compaction_checkpoints
180
- WHERE transcript_id = ?
181
- ORDER BY created_at ASC`).all(transcriptId);
180
+ WHERE session_id = ?
181
+ ORDER BY created_at ASC`).all(sessionId);
182
182
  if (rows.length <= MAX_CHECKPOINTS_PER_TRANSCRIPT) return;
183
183
  const toDelete = rows.slice(0, rows.length - MAX_CHECKPOINTS_PER_TRANSCRIPT);
184
184
  const del = db.prepare(`DELETE FROM compaction_checkpoints WHERE checkpoint_id = ?`);
@@ -208,18 +208,18 @@ function getCompactionCheckpointDetail(sessionKey, checkpointId) {
208
208
  }
209
209
  function restoreCompactionCheckpoint(sessionKey, checkpointId) {
210
210
  runSqliteWriteTransaction((db) => {
211
- const transcriptId = readCurrentTranscriptId(db, sessionKey);
212
- if (!transcriptId) throw new Error(`Session not found: ${sessionKey}`);
211
+ const sessionId = readCurrentSessionId(db, sessionKey);
212
+ if (!sessionId) throw new Error(`Session not found: ${sessionKey}`);
213
213
  if (!db.prepare(`SELECT checkpoint_id FROM compaction_checkpoints
214
214
  WHERE session_key = ? AND checkpoint_id = ?`).get(sessionKey, checkpointId)) throw new Error(`Checkpoint not found: ${checkpointId}`);
215
215
  const entries = db.prepare(`SELECT seq, entry_kind, role, payload_json
216
216
  FROM checkpoint_entries
217
217
  WHERE checkpoint_id = ?
218
218
  ORDER BY seq ASC`).all(checkpointId);
219
- db.prepare(`DELETE FROM transcript_fts WHERE transcript_id = ?`).run(transcriptId);
220
- db.prepare(`DELETE FROM transcript_entries WHERE transcript_id = ?`).run(transcriptId);
219
+ db.prepare(`DELETE FROM transcript_fts WHERE session_id = ?`).run(sessionId);
220
+ db.prepare(`DELETE FROM transcript_entries WHERE session_id = ?`).run(sessionId);
221
221
  for (const entry of entries) insertEntry(db, {
222
- transcriptId,
222
+ sessionId,
223
223
  sessionKey,
224
224
  row: JSON.parse(entry.payload_json),
225
225
  createdAt: Date.now()
@@ -1 +1 @@
1
- {"version":3,"file":"transcript-repository.js","names":[],"sources":["../../../../src/storage/sqlite/transcript-repository.ts"],"sourcesContent":["import { randomUUID } from 'node:crypto';\nimport type { DatabaseSync } from 'node:sqlite';\n\nimport type { AgentMessage } from '@earendil-works/pi-agent-core';\n\nimport type { CompactionCheckpointDetail, CompactionCheckpointSummary } from '../../session/types.js';\nimport type { TranscriptCompactionRecord } from '../../session/transcript-format.js';\nimport {\n buildSessionContextForLlm,\n type TranscriptStoredRow,\n} from '../../session/session-context-for-llm.js';\nimport {\n classifyStoredRow,\n estimateTokensFromMessages,\n extractFtsContent,\n transcriptEntryRowToStoredRow,\n type TranscriptEntryRow,\n} from './row-mappers.js';\nimport { getCurrentTranscriptId, readCurrentTranscriptId } from './session-repository.js';\nimport { getSqliteDatabase, runSqliteWriteTransaction } from './transaction.js';\n\nconst MAX_CHECKPOINTS_PER_TRANSCRIPT = 15;\n\nfunction nextSeq(db: DatabaseSync, transcriptId: string): number {\n const row = db\n .prepare(`SELECT COALESCE(MAX(seq), 0) AS max_seq FROM transcript_entries WHERE transcript_id = ?`)\n .get(transcriptId) as { max_seq: number };\n return (row.max_seq ?? 0) + 1;\n}\n\nfunction insertEntry(\n db: DatabaseSync,\n params: {\n transcriptId: string;\n sessionKey: string;\n row: TranscriptStoredRow;\n entryId?: string;\n createdAt?: number;\n },\n): TranscriptEntryRow {\n const { entryKind, role } = classifyStoredRow(params.row);\n const entryId = params.entryId ?? randomUUID();\n const seq = nextSeq(db, params.transcriptId);\n const createdAt = params.createdAt ?? Date.now();\n const payloadJson = JSON.stringify(params.row);\n\n db.prepare(\n `INSERT INTO transcript_entries (entry_id, transcript_id, seq, entry_kind, role, payload_json, created_at)\n VALUES (?, ?, ?, ?, ?, ?, ?)`,\n ).run(entryId, params.transcriptId, seq, entryKind, role, payloadJson, createdAt);\n\n const content = extractFtsContent(params.row);\n if (content.trim()) {\n db.prepare(\n `INSERT INTO transcript_fts (content, session_key, transcript_id, entry_id)\n VALUES (?, ?, ?, ?)`,\n ).run(content, params.sessionKey, params.transcriptId, entryId);\n }\n\n return {\n entry_id: entryId,\n transcript_id: params.transcriptId,\n seq,\n entry_kind: entryKind,\n role,\n payload_json: payloadJson,\n created_at: createdAt,\n };\n}\n\nexport function appendTranscriptEntry(\n sessionKey: string,\n row: TranscriptStoredRow,\n opts?: { transcriptId?: string; tokenDelta?: number },\n): TranscriptEntryRow {\n return runSqliteWriteTransaction((db) => {\n const transcriptId = opts?.transcriptId ?? readCurrentTranscriptId(db, sessionKey);\n if (!transcriptId) {\n throw new Error(`Session not found: ${sessionKey}`);\n }\n const inserted = insertEntry(db, { transcriptId, sessionKey, row });\n if (classifyStoredRow(row).entryKind === 'message') {\n const tokenDelta = opts?.tokenDelta ?? 0;\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 return inserted;\n });\n}\n\nexport function loadTranscriptRowsForSession(sessionKey: string): TranscriptStoredRow[] {\n const transcriptId = getCurrentTranscriptId(sessionKey);\n if (!transcriptId) {\n return [];\n }\n return loadTranscriptRows(transcriptId);\n}\n\nexport function loadTranscriptRows(transcriptId: string): TranscriptStoredRow[] {\n const db = getSqliteDatabase();\n const rows = db\n .prepare(\n `SELECT entry_id, transcript_id, seq, entry_kind, role, payload_json, created_at\n FROM transcript_entries\n WHERE transcript_id = ?\n ORDER BY seq ASC`,\n )\n .all(transcriptId) as TranscriptEntryRow[];\n return rows.map(transcriptEntryRowToStoredRow);\n}\n\nexport function loadLlmMessagesForSession(sessionKey: string): AgentMessage[] {\n const rows = loadTranscriptRowsForSession(sessionKey);\n return buildSessionContextForLlm(rows);\n}\n\nexport function replaceTranscriptRows(\n sessionKey: string,\n rows: TranscriptStoredRow[],\n opts?: { appendCompaction?: TranscriptCompactionRecord },\n): void {\n runSqliteWriteTransaction((db) => {\n const transcriptId = readCurrentTranscriptId(db, sessionKey);\n if (!transcriptId) {\n throw new Error(`Session not found: ${sessionKey}`);\n }\n\n db.prepare(`DELETE FROM transcript_fts WHERE transcript_id = ?`).run(transcriptId);\n db.prepare(`DELETE FROM transcript_entries WHERE transcript_id = ?`).run(transcriptId);\n\n const toWrite = [...rows];\n if (opts?.appendCompaction) {\n toWrite.push({\n type: 'compaction',\n ...opts.appendCompaction,\n } as unknown as TranscriptStoredRow);\n }\n\n for (const row of toWrite) {\n insertEntry(db, { transcriptId, sessionKey, row });\n }\n\n const llm = buildSessionContextForLlm(toWrite);\n const now = 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(llm.length, estimateTokensFromMessages(llm), now, now, now, sessionKey);\n });\n}\n\nexport function loadCheckpointRows(sessionKey: string, checkpointId: string): TranscriptStoredRow[] {\n const db = getSqliteDatabase();\n const checkpoint = db\n .prepare(\n `SELECT checkpoint_id FROM compaction_checkpoints\n WHERE session_key = ? AND checkpoint_id = ?`,\n )\n .get(sessionKey, checkpointId) as { checkpoint_id: string } | undefined;\n if (!checkpoint) {\n return [];\n }\n const entries = db\n .prepare(\n `SELECT payload_json FROM checkpoint_entries\n WHERE checkpoint_id = ?\n ORDER BY seq ASC`,\n )\n .all(checkpointId) as Array<{ payload_json: string }>;\n return entries.map((entry) => JSON.parse(entry.payload_json) as TranscriptStoredRow);\n}\n\nexport function paginateTranscriptMessages(\n sessionKey: string,\n options: {\n offset?: number;\n limit?: number;\n beforeSeq?: number;\n /** 0-based exclusive end index (legacy cursor from gateway UI). */\n beforeEndIndex?: number;\n includeContext?: boolean;\n } = {},\n): {\n rows: TranscriptStoredRow[];\n messages: AgentMessage[];\n total: number;\n startSeq: number;\n endSeq: number;\n} {\n const transcriptId = getCurrentTranscriptId(sessionKey);\n if (!transcriptId) {\n return { rows: [], messages: [], total: 0, startSeq: 0, endSeq: 0 };\n }\n\n const db = getSqliteDatabase();\n const kinds = options.includeContext ? ['message', 'context'] : ['message'];\n const kindPlaceholders = kinds.map(() => '?').join(', ');\n\n const countRow = db\n .prepare(\n `SELECT COUNT(*) AS total FROM transcript_entries\n WHERE transcript_id = ? AND entry_kind IN (${kindPlaceholders})`,\n )\n .get(transcriptId, ...kinds) as { total: number };\n const total = countRow.total;\n\n const limit = Math.min(200, Math.max(1, Math.trunc(options.limit ?? 50)));\n const offset = Math.max(0, Math.trunc(options.offset ?? 0));\n\n let rows: TranscriptEntryRow[];\n if (options.beforeEndIndex !== undefined && Number.isFinite(options.beforeEndIndex)) {\n const endExclusive = Math.min(total, Math.max(0, Math.trunc(options.beforeEndIndex)));\n const startInclusive = Math.max(0, endExclusive - limit);\n rows = db\n .prepare(\n `SELECT entry_id, transcript_id, seq, entry_kind, role, payload_json, created_at\n FROM (\n SELECT entry_id, transcript_id, seq, entry_kind, role, payload_json, created_at,\n ROW_NUMBER() OVER (ORDER BY seq ASC) - 1 AS idx\n FROM transcript_entries\n WHERE transcript_id = ? AND entry_kind IN (${kindPlaceholders})\n )\n WHERE idx >= ? AND idx < ?\n ORDER BY seq ASC`,\n )\n .all(transcriptId, ...kinds, startInclusive, endExclusive) as TranscriptEntryRow[];\n } else if (options.beforeSeq !== undefined && Number.isFinite(options.beforeSeq)) {\n rows = db\n .prepare(\n `SELECT entry_id, transcript_id, seq, entry_kind, role, payload_json, created_at\n FROM transcript_entries\n WHERE transcript_id = ? AND entry_kind IN (${kindPlaceholders}) AND seq < ?\n ORDER BY seq DESC\n LIMIT ?`,\n )\n .all(transcriptId, ...kinds, options.beforeSeq, limit) as TranscriptEntryRow[];\n rows.reverse();\n } else {\n rows = db\n .prepare(\n `SELECT entry_id, transcript_id, seq, entry_kind, role, payload_json, created_at\n FROM transcript_entries\n WHERE transcript_id = ? AND entry_kind IN (${kindPlaceholders})\n ORDER BY seq DESC\n LIMIT ? OFFSET ?`,\n )\n .all(transcriptId, ...kinds, limit, offset) as TranscriptEntryRow[];\n rows.reverse();\n }\n\n const storedRows = rows.map(transcriptEntryRowToStoredRow);\n const messages = buildSessionContextForLlm(storedRows);\n const startSeq = rows[0]?.seq ?? 0;\n const endSeq = rows[rows.length - 1]?.seq ?? 0;\n return { rows: storedRows, messages, total, startSeq, endSeq };\n}\n\nexport function captureCompactionCheckpoint(sessionKey: string): string | null {\n return runSqliteWriteTransaction((db) => {\n const transcriptId = readCurrentTranscriptId(db, sessionKey);\n if (!transcriptId) {\n return null;\n }\n\n const entries = db\n .prepare(\n `SELECT entry_id, transcript_id, seq, entry_kind, role, payload_json, created_at\n FROM transcript_entries WHERE transcript_id = ? ORDER BY seq ASC`,\n )\n .all(transcriptId) as TranscriptEntryRow[];\n if (entries.length === 0) {\n return null;\n }\n\n const checkpointId = randomUUID();\n const now = Date.now();\n const messageCount = entries.filter((e) => e.entry_kind === 'message').length;\n const sizeBytes = entries.reduce((sum, e) => sum + e.payload_json.length, 0);\n\n db.prepare(\n `INSERT INTO compaction_checkpoints\n (checkpoint_id, transcript_id, session_key, created_at, message_count, size_bytes)\n VALUES (?, ?, ?, ?, ?, ?)`,\n ).run(checkpointId, transcriptId, sessionKey, now, messageCount, sizeBytes);\n\n const insertCheckpointEntry = db.prepare(\n `INSERT INTO checkpoint_entries (checkpoint_id, seq, entry_kind, role, payload_json)\n VALUES (?, ?, ?, ?, ?)`,\n );\n for (const entry of entries) {\n insertCheckpointEntry.run(\n checkpointId,\n entry.seq,\n entry.entry_kind,\n entry.role,\n entry.payload_json,\n );\n }\n\n pruneCompactionCheckpoints(db, transcriptId);\n return checkpointId;\n });\n}\n\nfunction pruneCompactionCheckpoints(db: DatabaseSync, transcriptId: string): void {\n const rows = db\n .prepare(\n `SELECT checkpoint_id FROM compaction_checkpoints\n WHERE transcript_id = ?\n ORDER BY created_at ASC`,\n )\n .all(transcriptId) as Array<{ checkpoint_id: string }>;\n if (rows.length <= MAX_CHECKPOINTS_PER_TRANSCRIPT) {\n return;\n }\n const toDelete = rows.slice(0, rows.length - MAX_CHECKPOINTS_PER_TRANSCRIPT);\n const del = db.prepare(`DELETE FROM compaction_checkpoints WHERE checkpoint_id = ?`);\n for (const row of toDelete) {\n del.run(row.checkpoint_id);\n }\n}\n\nexport function listCompactionCheckpoints(sessionKey: string): CompactionCheckpointSummary[] {\n const db = getSqliteDatabase();\n const rows = db\n .prepare(\n `SELECT checkpoint_id, created_at, message_count, size_bytes\n FROM compaction_checkpoints\n WHERE session_key = ?\n ORDER BY created_at DESC`,\n )\n .all(sessionKey) as Array<{\n checkpoint_id: string;\n created_at: number;\n message_count: number;\n size_bytes: number;\n }>;\n\n return rows.map((row) => ({\n id: row.checkpoint_id,\n sizeBytes: row.size_bytes,\n modifiedAt: new Date(row.created_at).toISOString(),\n }));\n}\n\nexport function getCompactionCheckpointDetail(\n sessionKey: string,\n checkpointId: string,\n): CompactionCheckpointDetail | null {\n const db = getSqliteDatabase();\n const row = db\n .prepare(\n `SELECT checkpoint_id, created_at, message_count, size_bytes\n FROM compaction_checkpoints\n WHERE session_key = ? AND checkpoint_id = ?`,\n )\n .get(sessionKey, checkpointId) as\n | {\n checkpoint_id: string;\n created_at: number;\n message_count: number;\n size_bytes: number;\n }\n | undefined;\n if (!row) {\n return null;\n }\n return {\n id: row.checkpoint_id,\n sizeBytes: row.size_bytes,\n modifiedAt: new Date(row.created_at).toISOString(),\n messageCount: row.message_count,\n };\n}\n\nexport function restoreCompactionCheckpoint(sessionKey: string, checkpointId: string): void {\n runSqliteWriteTransaction((db) => {\n const transcriptId = readCurrentTranscriptId(db, sessionKey);\n if (!transcriptId) {\n throw new Error(`Session not found: ${sessionKey}`);\n }\n\n const checkpoint = db\n .prepare(\n `SELECT checkpoint_id FROM compaction_checkpoints\n WHERE session_key = ? AND checkpoint_id = ?`,\n )\n .get(sessionKey, checkpointId) as { checkpoint_id: string } | undefined;\n if (!checkpoint) {\n throw new Error(`Checkpoint not found: ${checkpointId}`);\n }\n\n const entries = db\n .prepare(\n `SELECT seq, entry_kind, role, payload_json\n FROM checkpoint_entries\n WHERE checkpoint_id = ?\n ORDER BY seq ASC`,\n )\n .all(checkpointId) as Array<{\n seq: number;\n entry_kind: string;\n role: string | null;\n payload_json: string;\n }>;\n\n db.prepare(`DELETE FROM transcript_fts WHERE transcript_id = ?`).run(transcriptId);\n db.prepare(`DELETE FROM transcript_entries WHERE transcript_id = ?`).run(transcriptId);\n\n for (const entry of entries) {\n const payload = JSON.parse(entry.payload_json) as TranscriptStoredRow;\n insertEntry(db, {\n transcriptId,\n sessionKey,\n row: payload,\n createdAt: Date.now(),\n });\n }\n\n const llm = buildSessionContextForLlm(entries.map((e) => JSON.parse(e.payload_json) as TranscriptStoredRow));\n const now = 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(llm.length, estimateTokensFromMessages(llm), now, now, now, sessionKey);\n });\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"transcript-repository.js","names":[],"sources":["../../../../src/storage/sqlite/transcript-repository.ts"],"sourcesContent":["import { randomUUID } from 'node:crypto';\nimport type { DatabaseSync } from 'node:sqlite';\n\nimport type { AgentMessage } from '@earendil-works/pi-agent-core';\n\nimport type { CompactionCheckpointDetail, CompactionCheckpointSummary } from '../../session/types.js';\nimport type { TranscriptCompactionRecord } from '../../session/transcript-format.js';\nimport {\n buildSessionContextForLlm,\n type TranscriptStoredRow,\n} from '../../session/session-context-for-llm.js';\nimport {\n classifyStoredRow,\n estimateTokensFromMessages,\n extractFtsContent,\n transcriptEntryRowToStoredRow,\n type TranscriptEntryRow,\n} from './row-mappers.js';\nimport { getCurrentSessionId, readCurrentSessionId } from './session-repository.js';\nimport { getSqliteDatabase, runSqliteWriteTransaction } from './transaction.js';\n\nconst MAX_CHECKPOINTS_PER_TRANSCRIPT = 15;\n\nfunction nextSeq(db: DatabaseSync, sessionId: string): number {\n const row = db\n .prepare(`SELECT COALESCE(MAX(seq), 0) AS max_seq FROM transcript_entries WHERE session_id = ?`)\n .get(sessionId) as { max_seq: number };\n return (row.max_seq ?? 0) + 1;\n}\n\nfunction insertEntry(\n db: DatabaseSync,\n params: {\n sessionId: string;\n sessionKey: string;\n row: TranscriptStoredRow;\n entryId?: string;\n createdAt?: number;\n },\n): TranscriptEntryRow {\n const { entryKind, role } = classifyStoredRow(params.row);\n const entryId = params.entryId ?? randomUUID();\n const seq = nextSeq(db, params.sessionId);\n const createdAt = params.createdAt ?? Date.now();\n const payloadJson = JSON.stringify(params.row);\n\n db.prepare(\n `INSERT INTO transcript_entries (entry_id, session_id, seq, entry_kind, role, payload_json, created_at)\n VALUES (?, ?, ?, ?, ?, ?, ?)`,\n ).run(entryId, params.sessionId, seq, entryKind, role, payloadJson, createdAt);\n\n const content = extractFtsContent(params.row);\n if (content.trim()) {\n db.prepare(\n `INSERT INTO transcript_fts (content, session_key, session_id, entry_id)\n VALUES (?, ?, ?, ?)`,\n ).run(content, params.sessionKey, params.sessionId, entryId);\n }\n\n return {\n entry_id: entryId,\n session_id: params.sessionId,\n seq,\n entry_kind: entryKind,\n role,\n payload_json: payloadJson,\n created_at: createdAt,\n };\n}\n\nexport function appendTranscriptEntry(\n sessionKey: string,\n row: TranscriptStoredRow,\n opts?: { sessionId?: string; tokenDelta?: number },\n): TranscriptEntryRow {\n return runSqliteWriteTransaction((db) => {\n const sessionId = opts?.sessionId ?? readCurrentSessionId(db, sessionKey);\n if (!sessionId) {\n throw new Error(`Session not found: ${sessionKey}`);\n }\n const inserted = insertEntry(db, { sessionId, sessionKey, row });\n if (classifyStoredRow(row).entryKind === 'message') {\n const tokenDelta = opts?.tokenDelta ?? 0;\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 return inserted;\n });\n}\n\nexport function loadTranscriptRowsForSession(sessionKey: string): TranscriptStoredRow[] {\n const sessionId = getCurrentSessionId(sessionKey);\n if (!sessionId) {\n return [];\n }\n return loadTranscriptRows(sessionId);\n}\n\nexport function loadTranscriptRows(sessionId: string): TranscriptStoredRow[] {\n const db = getSqliteDatabase();\n const rows = db\n .prepare(\n `SELECT entry_id, session_id, seq, entry_kind, role, payload_json, created_at\n FROM transcript_entries\n WHERE session_id = ?\n ORDER BY seq ASC`,\n )\n .all(sessionId) as TranscriptEntryRow[];\n return rows.map(transcriptEntryRowToStoredRow);\n}\n\nexport function loadLlmMessagesForSession(sessionKey: string): AgentMessage[] {\n const rows = loadTranscriptRowsForSession(sessionKey);\n return buildSessionContextForLlm(rows);\n}\n\nexport function replaceTranscriptRows(\n sessionKey: string,\n rows: TranscriptStoredRow[],\n opts?: { appendCompaction?: TranscriptCompactionRecord },\n): void {\n runSqliteWriteTransaction((db) => {\n const sessionId = readCurrentSessionId(db, sessionKey);\n if (!sessionId) {\n throw new Error(`Session not found: ${sessionKey}`);\n }\n\n db.prepare(`DELETE FROM transcript_fts WHERE session_id = ?`).run(sessionId);\n db.prepare(`DELETE FROM transcript_entries WHERE session_id = ?`).run(sessionId);\n\n const toWrite = [...rows];\n if (opts?.appendCompaction) {\n toWrite.push({\n type: 'compaction',\n ...opts.appendCompaction,\n } as unknown as TranscriptStoredRow);\n }\n\n for (const row of toWrite) {\n insertEntry(db, { sessionId, sessionKey, row });\n }\n\n const llm = buildSessionContextForLlm(toWrite);\n const now = 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(llm.length, estimateTokensFromMessages(llm), now, now, now, sessionKey);\n });\n}\n\nexport function loadCheckpointRows(sessionKey: string, checkpointId: string): TranscriptStoredRow[] {\n const db = getSqliteDatabase();\n const checkpoint = db\n .prepare(\n `SELECT checkpoint_id FROM compaction_checkpoints\n WHERE session_key = ? AND checkpoint_id = ?`,\n )\n .get(sessionKey, checkpointId) as { checkpoint_id: string } | undefined;\n if (!checkpoint) {\n return [];\n }\n const entries = db\n .prepare(\n `SELECT payload_json FROM checkpoint_entries\n WHERE checkpoint_id = ?\n ORDER BY seq ASC`,\n )\n .all(checkpointId) as Array<{ payload_json: string }>;\n return entries.map((entry) => JSON.parse(entry.payload_json) as TranscriptStoredRow);\n}\n\nexport function paginateTranscriptMessages(\n sessionKey: string,\n options: {\n offset?: number;\n limit?: number;\n beforeSeq?: number;\n /** 0-based exclusive end index (legacy cursor from gateway UI). */\n beforeEndIndex?: number;\n includeContext?: boolean;\n } = {},\n): {\n rows: TranscriptStoredRow[];\n messages: AgentMessage[];\n total: number;\n startSeq: number;\n endSeq: number;\n} {\n const sessionId = getCurrentSessionId(sessionKey);\n if (!sessionId) {\n return { rows: [], messages: [], total: 0, startSeq: 0, endSeq: 0 };\n }\n\n const db = getSqliteDatabase();\n const kinds = options.includeContext ? ['message', 'context'] : ['message'];\n const kindPlaceholders = kinds.map(() => '?').join(', ');\n\n const countRow = db\n .prepare(\n `SELECT COUNT(*) AS total FROM transcript_entries\n WHERE session_id = ? AND entry_kind IN (${kindPlaceholders})`,\n )\n .get(sessionId, ...kinds) as { total: number };\n const total = countRow.total;\n\n const limit = Math.min(200, Math.max(1, Math.trunc(options.limit ?? 50)));\n const offset = Math.max(0, Math.trunc(options.offset ?? 0));\n\n let rows: TranscriptEntryRow[];\n if (options.beforeEndIndex !== undefined && Number.isFinite(options.beforeEndIndex)) {\n const endExclusive = Math.min(total, Math.max(0, Math.trunc(options.beforeEndIndex)));\n const startInclusive = Math.max(0, endExclusive - limit);\n rows = db\n .prepare(\n `SELECT entry_id, session_id, seq, entry_kind, role, payload_json, created_at\n FROM (\n SELECT entry_id, session_id, seq, entry_kind, role, payload_json, created_at,\n ROW_NUMBER() OVER (ORDER BY seq ASC) - 1 AS idx\n FROM transcript_entries\n WHERE session_id = ? AND entry_kind IN (${kindPlaceholders})\n )\n WHERE idx >= ? AND idx < ?\n ORDER BY seq ASC`,\n )\n .all(sessionId, ...kinds, startInclusive, endExclusive) as TranscriptEntryRow[];\n } else if (options.beforeSeq !== undefined && Number.isFinite(options.beforeSeq)) {\n rows = db\n .prepare(\n `SELECT entry_id, session_id, seq, entry_kind, role, payload_json, created_at\n FROM transcript_entries\n WHERE session_id = ? AND entry_kind IN (${kindPlaceholders}) AND seq < ?\n ORDER BY seq DESC\n LIMIT ?`,\n )\n .all(sessionId, ...kinds, options.beforeSeq, limit) as TranscriptEntryRow[];\n rows.reverse();\n } else {\n rows = db\n .prepare(\n `SELECT entry_id, session_id, seq, entry_kind, role, payload_json, created_at\n FROM transcript_entries\n WHERE session_id = ? AND entry_kind IN (${kindPlaceholders})\n ORDER BY seq DESC\n LIMIT ? OFFSET ?`,\n )\n .all(sessionId, ...kinds, limit, offset) as TranscriptEntryRow[];\n rows.reverse();\n }\n\n const storedRows = rows.map(transcriptEntryRowToStoredRow);\n const messages = buildSessionContextForLlm(storedRows);\n const startSeq = rows[0]?.seq ?? 0;\n const endSeq = rows[rows.length - 1]?.seq ?? 0;\n return { rows: storedRows, messages, total, startSeq, endSeq };\n}\n\nexport function captureCompactionCheckpoint(sessionKey: string): string | null {\n return runSqliteWriteTransaction((db) => {\n const sessionId = readCurrentSessionId(db, sessionKey);\n if (!sessionId) {\n return null;\n }\n\n const entries = db\n .prepare(\n `SELECT entry_id, session_id, seq, entry_kind, role, payload_json, created_at\n FROM transcript_entries WHERE session_id = ? ORDER BY seq ASC`,\n )\n .all(sessionId) as TranscriptEntryRow[];\n if (entries.length === 0) {\n return null;\n }\n\n const checkpointId = randomUUID();\n const now = Date.now();\n const messageCount = entries.filter((e) => e.entry_kind === 'message').length;\n const sizeBytes = entries.reduce((sum, e) => sum + e.payload_json.length, 0);\n\n db.prepare(\n `INSERT INTO compaction_checkpoints\n (checkpoint_id, session_id, session_key, created_at, message_count, size_bytes)\n VALUES (?, ?, ?, ?, ?, ?)`,\n ).run(checkpointId, sessionId, sessionKey, now, messageCount, sizeBytes);\n\n const insertCheckpointEntry = db.prepare(\n `INSERT INTO checkpoint_entries (checkpoint_id, seq, entry_kind, role, payload_json)\n VALUES (?, ?, ?, ?, ?)`,\n );\n for (const entry of entries) {\n insertCheckpointEntry.run(\n checkpointId,\n entry.seq,\n entry.entry_kind,\n entry.role,\n entry.payload_json,\n );\n }\n\n pruneCompactionCheckpoints(db, sessionId);\n return checkpointId;\n });\n}\n\nfunction pruneCompactionCheckpoints(db: DatabaseSync, sessionId: string): void {\n const rows = db\n .prepare(\n `SELECT checkpoint_id FROM compaction_checkpoints\n WHERE session_id = ?\n ORDER BY created_at ASC`,\n )\n .all(sessionId) as Array<{ checkpoint_id: string }>;\n if (rows.length <= MAX_CHECKPOINTS_PER_TRANSCRIPT) {\n return;\n }\n const toDelete = rows.slice(0, rows.length - MAX_CHECKPOINTS_PER_TRANSCRIPT);\n const del = db.prepare(`DELETE FROM compaction_checkpoints WHERE checkpoint_id = ?`);\n for (const row of toDelete) {\n del.run(row.checkpoint_id);\n }\n}\n\nexport function listCompactionCheckpoints(sessionKey: string): CompactionCheckpointSummary[] {\n const db = getSqliteDatabase();\n const rows = db\n .prepare(\n `SELECT checkpoint_id, created_at, message_count, size_bytes\n FROM compaction_checkpoints\n WHERE session_key = ?\n ORDER BY created_at DESC`,\n )\n .all(sessionKey) as Array<{\n checkpoint_id: string;\n created_at: number;\n message_count: number;\n size_bytes: number;\n }>;\n\n return rows.map((row) => ({\n id: row.checkpoint_id,\n sizeBytes: row.size_bytes,\n modifiedAt: new Date(row.created_at).toISOString(),\n }));\n}\n\nexport function getCompactionCheckpointDetail(\n sessionKey: string,\n checkpointId: string,\n): CompactionCheckpointDetail | null {\n const db = getSqliteDatabase();\n const row = db\n .prepare(\n `SELECT checkpoint_id, created_at, message_count, size_bytes\n FROM compaction_checkpoints\n WHERE session_key = ? AND checkpoint_id = ?`,\n )\n .get(sessionKey, checkpointId) as\n | {\n checkpoint_id: string;\n created_at: number;\n message_count: number;\n size_bytes: number;\n }\n | undefined;\n if (!row) {\n return null;\n }\n return {\n id: row.checkpoint_id,\n sizeBytes: row.size_bytes,\n modifiedAt: new Date(row.created_at).toISOString(),\n messageCount: row.message_count,\n };\n}\n\nexport function restoreCompactionCheckpoint(sessionKey: string, checkpointId: string): void {\n runSqliteWriteTransaction((db) => {\n const sessionId = readCurrentSessionId(db, sessionKey);\n if (!sessionId) {\n throw new Error(`Session not found: ${sessionKey}`);\n }\n\n const checkpoint = db\n .prepare(\n `SELECT checkpoint_id FROM compaction_checkpoints\n WHERE session_key = ? AND checkpoint_id = ?`,\n )\n .get(sessionKey, checkpointId) as { checkpoint_id: string } | undefined;\n if (!checkpoint) {\n throw new Error(`Checkpoint not found: ${checkpointId}`);\n }\n\n const entries = db\n .prepare(\n `SELECT seq, entry_kind, role, payload_json\n FROM checkpoint_entries\n WHERE checkpoint_id = ?\n ORDER BY seq ASC`,\n )\n .all(checkpointId) as Array<{\n seq: number;\n entry_kind: string;\n role: string | null;\n payload_json: string;\n }>;\n\n db.prepare(`DELETE FROM transcript_fts WHERE session_id = ?`).run(sessionId);\n db.prepare(`DELETE FROM transcript_entries WHERE session_id = ?`).run(sessionId);\n\n for (const entry of entries) {\n const payload = JSON.parse(entry.payload_json) as TranscriptStoredRow;\n insertEntry(db, {\n sessionId,\n sessionKey,\n row: payload,\n createdAt: Date.now(),\n });\n }\n\n const llm = buildSessionContextForLlm(entries.map((e) => JSON.parse(e.payload_json) as TranscriptStoredRow));\n const now = 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(llm.length, estimateTokensFromMessages(llm), now, now, now, sessionKey);\n });\n}\n"],"mappings":"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"}
@@ -1,7 +1,12 @@
1
1
  import type { ExtensionRegistryImpl } from '../../extensions/loader.js';
2
2
  import type { ExportFormat } from '../../session/types.js';
3
- import type { ChatSendOptions, HistoryMessage, TuiBackend, TuiCompactionResult, TuiEvent, TuiModelChoice, TuiShareRequest, TuiShareResult, TuiSessionStats, TuiSessionItem, TuiTranscriptTreeEntry, TuiAgentInfo } from '../tui-backend.js';
3
+ import type { ChatSendOptions, HistoryMessage, TuiBackend, TuiCompactionResult, TuiEvent, TuiModelChoice, TuiShareRequest, TuiShareResult, TuiSessionStats, TuiSessionItem, TuiTranscriptTreeEntry, TuiAgentInfo, TuiWorkspaceFileSearchEntry, TuiWorkflowRunStartRequest, TuiWorkflowRunStartResult } from '../tui-backend.js';
4
4
  import type { SessionInfo } from '../tui-types.js';
5
+ interface EmbeddedBackendOptions {
6
+ extensionRegistry?: ExtensionRegistryImpl;
7
+ implicitTrustedWorkspace?: string;
8
+ isWorkspaceTrusted?: (workspaceDir: string) => boolean | null | undefined;
9
+ }
5
10
  /**
6
11
  * TUI backend that runs the agent in-process (no gateway required).
7
12
  *
@@ -12,19 +17,27 @@ export declare class EmbeddedBackend implements TuiBackend {
12
17
  private readonly opts?;
13
18
  private bus;
14
19
  private agent;
20
+ private config;
21
+ private workspace;
22
+ private sessionIndex;
23
+ private sessionIndexReady;
24
+ private workflowRunService;
15
25
  private running;
16
26
  private chatAbort;
17
27
  onEvent?: (evt: TuiEvent) => void;
18
28
  onConnected?: () => void;
19
29
  onDisconnected?: (reason: string) => void;
20
- constructor(opts?: {
21
- extensionRegistry?: ExtensionRegistryImpl;
22
- });
30
+ constructor(opts?: EmbeddedBackendOptions);
23
31
  get connectionLabel(): string;
24
32
  start(): void;
25
33
  stop(): void;
26
34
  getActiveSignal(): AbortSignal | undefined;
35
+ private getWorkflowRunService;
27
36
  getStartupResources(sessionKey: string): Promise<import("../tui-backend.js").TuiStartupResources>;
37
+ startWorkflowRun(opts: TuiWorkflowRunStartRequest): Promise<TuiWorkflowRunStartResult>;
38
+ searchWorkspaceFiles(sessionKey: string, query: string, options?: {
39
+ limit?: number;
40
+ }): Promise<TuiWorkspaceFileSearchEntry[]>;
28
41
  sendChat(opts: ChatSendOptions): Promise<{
29
42
  runId: string;
30
43
  }>;
@@ -111,3 +124,4 @@ export declare class EmbeddedBackend implements TuiBackend {
111
124
  }>;
112
125
  private processOutbound;
113
126
  }
127
+ export {};