@xopcai/xopc 0.0.227 → 0.0.229

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 (249) hide show
  1. package/dist/browser-ext/manifest.json +1 -1
  2. package/dist/extensions/telegram/xopc.extension.json +1 -1
  3. package/dist/gateway/static/root/assets/{activity-store-BevwE16n.js → activity-store-M0nAY5XB.js} +1 -1
  4. package/dist/gateway/static/root/assets/{agent-avatar-dicebear-BggVQrEZ.js → agent-avatar-dicebear-CsFAJTIN.js} +1 -1
  5. package/dist/gateway/static/root/assets/agents-DA4b6_0C.js +68 -0
  6. package/dist/gateway/static/root/assets/{api-Bx_BpIt8.js → api-BywYxpaS.js} +1 -1
  7. package/dist/gateway/static/root/assets/{app-management-settings-panel-BtKP9n2r.js → app-management-settings-panel-7KcMWuah.js} +1 -1
  8. package/dist/gateway/static/root/assets/{appearance-settings-BoH2NAUX.js → appearance-settings-Cqlw7Fif.js} +1 -1
  9. package/dist/gateway/static/root/assets/apps-page-CsnhdGZ2.js +1 -0
  10. package/dist/gateway/static/root/assets/{archive-plugin-DnceUyxm.js → archive-plugin-7_DXaMTP.js} +1 -1
  11. package/dist/gateway/static/root/assets/{attachment-load-Bh8_9gkr.js → attachment-load-q4pDpqkF.js} +1 -1
  12. package/dist/gateway/static/root/assets/{automations-page-ZKeAAVxD.js → automations-page-BuTqjKGX.js} +1 -1
  13. package/dist/gateway/static/root/assets/automations-workspace-CD0E2ThS.js +6 -0
  14. package/dist/gateway/static/root/assets/{binary-plugins-Cy9er6w-.js → binary-plugins-DUce1Bsc.js} +1 -1
  15. package/dist/gateway/static/root/assets/{block-editor-Cc0wWvNX.js → block-editor-D8Ejp-QR.js} +3 -3
  16. package/dist/gateway/static/root/assets/browser-settings-page-CY1k3MMd.js +8 -0
  17. package/dist/gateway/static/root/assets/{browser-workflow-inputs-BS7rpLLl.js → browser-workflow-inputs-8NC2qDRF.js} +1 -1
  18. package/dist/gateway/static/root/assets/{browser-workflows-page-BdBVUZXm.js → browser-workflows-page-BDvZbR9v.js} +2 -2
  19. package/dist/gateway/static/root/assets/capabilities-settings-panel-D1VfotHQ.js +7 -0
  20. package/dist/gateway/static/root/assets/{capability-presets-api-D1Lqz0Tt.js → capability-presets-api-o0y9WgAI.js} +1 -1
  21. package/dist/gateway/static/root/assets/capability-presets-settings-panel-DXHqRLpU.js +3 -0
  22. package/dist/gateway/static/root/assets/{channel-recipient-api-CGuEl-l2.js → channel-recipient-api-C5ABr73b.js} +1 -1
  23. package/dist/gateway/static/root/assets/channels-settings-DrFL57M_.js +1 -0
  24. package/dist/gateway/static/root/assets/channels-status-swr-38FsOnR0.js +1 -0
  25. package/dist/gateway/static/root/assets/{chat-terminal-dock-CdX_7aQh.js → chat-terminal-dock-h1CKexNz.js} +2 -2
  26. package/dist/gateway/static/root/assets/connectors-page-DUAyfFCF.js +2 -0
  27. package/dist/gateway/static/root/assets/{cron-expression-BnSQc4Ek.js → cron-expression-DlaQQOId.js} +1 -1
  28. package/dist/gateway/static/root/assets/{date-picker-BbuG7zQ_.js → date-picker-8R1sXJKb.js} +1 -1
  29. package/dist/gateway/static/root/assets/{dependency-picker-snZeqOmG.js → dependency-picker-CWur0821.js} +1 -1
  30. package/dist/gateway/static/root/assets/{desktop-pet-DJQ8JoR1.js → desktop-pet-Knl-zNDU.js} +1 -1
  31. package/dist/gateway/static/root/assets/{desktop-pet-settings-B9txsRtv.js → desktop-pet-settings-CAQMLVtd.js} +1 -1
  32. package/dist/gateway/static/root/assets/{directory-picker-path-field-D7WKWkNB.js → directory-picker-path-field-Caaz4Rw5.js} +1 -1
  33. package/dist/gateway/static/root/assets/{extension-debug-page-D_7cOCj2.js → extension-debug-page-B965Mc15.js} +1 -1
  34. package/dist/gateway/static/root/assets/{extension-page-Bwu47iUb.js → extension-page-C0UnkBi5.js} +1 -1
  35. package/dist/gateway/static/root/assets/{extension-settings-page-Dwg4dSZM.js → extension-settings-page-BUSIAZCR.js} +1 -1
  36. package/dist/gateway/static/root/assets/{gateway-config-api-jURUSte_.js → gateway-config-api-DkH0eEgy.js} +1 -1
  37. package/dist/gateway/static/root/assets/{gateway-config-swr-6SQXF1yR.js → gateway-config-swr-BWGjnmDl.js} +1 -1
  38. package/dist/gateway/static/root/assets/{gateway-settings-UklJOMLX.js → gateway-settings-BBgLDm6I.js} +1 -1
  39. package/dist/gateway/static/root/assets/{gateway-startup-retry-DqWaxyvZ.js → gateway-startup-retry-B_zrtccP.js} +1 -1
  40. package/dist/gateway/static/root/assets/{heartbeat-settings-Djs_nduD.js → heartbeat-settings-BtEHVXWD.js} +1 -1
  41. package/dist/gateway/static/root/assets/home-page-5SU2TNJj.js +1 -0
  42. package/dist/gateway/static/root/assets/{image-generation-api-Bxmt6LEr.js → image-generation-api-YKP2me5Z.js} +1 -1
  43. package/dist/gateway/static/root/assets/index-BNWhgmjs.js +70 -0
  44. package/dist/gateway/static/root/assets/index-D_hrEKXM.css +2 -0
  45. package/dist/gateway/static/root/assets/{keyboard-shortcuts-settings-ByVsCH3d.js → keyboard-shortcuts-settings-CsRz8NrS.js} +1 -1
  46. package/dist/gateway/static/root/assets/local-app-workbench-page-DYPEUgpP.js +2 -0
  47. package/dist/gateway/static/root/assets/{local-apps-page-D19R-xsz.js → local-apps-page-CTBNUG4a.js} +1 -1
  48. package/dist/gateway/static/root/assets/{locale-store-Ci1Qi0Q-.js → locale-store-CXhjfe4q.js} +1 -1
  49. package/dist/gateway/static/root/assets/logs-page-B0P7rG2B.js +2 -0
  50. package/dist/gateway/static/root/assets/{management-settings-G0y7zmfY.js → management-settings-YqUAEwQo.js} +1 -1
  51. package/dist/gateway/static/root/assets/{markdown-split-B69d2HWt.js → markdown-split-dxpSCXb8.js} +1 -1
  52. package/dist/gateway/static/root/assets/{markdown-view-DD_PgVue.css → markdown-view-CLzTdVLW.css} +1 -1
  53. package/dist/gateway/static/root/assets/markdown-view-DvM5PWEH.js +201 -0
  54. package/dist/gateway/static/root/assets/{media-plugins-6TWEQgN_.js → media-plugins-CJ00i1Lg.js} +1 -1
  55. package/dist/gateway/static/root/assets/messages-BMdD0LWk.js +3 -0
  56. package/dist/gateway/static/root/assets/{notes-api-DLsnnZCS.js → notes-api-BFsOGYkd.js} +1 -1
  57. package/dist/gateway/static/root/assets/{notes-page-CkRJJKDm.js → notes-page-DEnbnkIt.js} +1 -1
  58. package/dist/gateway/static/root/assets/notes-workbench-DmVYu_Oc.js +4 -0
  59. package/dist/gateway/static/root/assets/{product-open-page-HxArIvoN.js → product-open-page-BHxo9U95.js} +1 -1
  60. package/dist/gateway/static/root/assets/project-detail-page-DV2nGmsq.js +1 -0
  61. package/dist/gateway/static/root/assets/projects-page-BNIFwFfc.js +1 -0
  62. package/dist/gateway/static/root/assets/{registry-api-lEar5FOV.js → registry-api-BFZrVYfy.js} +1 -1
  63. package/dist/gateway/static/root/assets/remote-access-hub-DLXqKiA_.js +1 -0
  64. package/dist/gateway/static/root/assets/{runtime-tools-settings-panel-Bf03UNGD.js → runtime-tools-settings-panel-BpQ2GI-0.js} +1 -1
  65. package/dist/gateway/static/root/assets/{schema-form-CIXMBgx5.js → schema-form-HE1G26Lx.js} +1 -1
  66. package/dist/gateway/static/root/assets/sessions-page-DWaXf_25.js +1 -0
  67. package/dist/gateway/static/root/assets/settings-advanced-gate-JFCbnCL2.js +1 -0
  68. package/dist/gateway/static/root/assets/{settings-form-section-DgdB26mE.js → settings-form-section-CXAn0Xhy.js} +1 -1
  69. package/dist/gateway/static/root/assets/{settings-loading-skeleton-efk5W6lG.js → settings-loading-skeleton-DsFu7Bcv.js} +1 -1
  70. package/dist/gateway/static/root/assets/{settings-page-BHVf4gEP.js → settings-page-C4iib9nO.js} +1 -1
  71. package/dist/gateway/static/root/assets/{setup-status-panel-WK0dGNMv.js → setup-status-panel-BA83Wr1d.js} +1 -1
  72. package/dist/gateway/static/root/assets/{share-preview-page-Cod-w2qm.js → share-preview-page-BOGl3s6M.js} +1 -1
  73. package/dist/gateway/static/root/assets/{shares-settings-CUqQ31gt.js → shares-settings-Q2MdGaBi.js} +1 -1
  74. package/dist/gateway/static/root/assets/skill-reload-api-cFtfVeFU.js +1 -0
  75. package/dist/gateway/static/root/assets/{skills-page-DwCcipqK.js → skills-page-CdaFtNw9.js} +1 -1
  76. package/dist/gateway/static/root/assets/{skills-page.utils-3WSbtl3S.js → skills-page.utils-DYaAddUL.js} +1 -1
  77. package/dist/gateway/static/root/assets/{system-settings-panel-C5VxqC_s.js → system-settings-panel-Co7gilRd.js} +1 -1
  78. package/dist/gateway/static/root/assets/task-detail-page-5B1pswu8.js +1 -0
  79. package/dist/gateway/static/root/assets/{theme-store-Dd89g_ki.js → theme-store-DOdCjyuw.js} +1 -1
  80. package/dist/gateway/static/root/assets/{use-autosave-CeV8VJh2.js → use-autosave-DnnZtMpA.js} +1 -1
  81. package/dist/gateway/static/root/assets/user-context-page-Dr1FKjXv.js +1 -0
  82. package/dist/gateway/static/root/assets/{voice-api-key-field-EmJ-8aZu.js → voice-api-key-field-wetUpi3i.js} +1 -1
  83. package/dist/gateway/static/root/assets/{work-discovery-overlay-zsk6E3Mi.js → work-discovery-overlay-tbTWASJJ.js} +1 -1
  84. package/dist/gateway/static/root/assets/workflow-run-setup-panel-Dy0fDs8w.js +3 -0
  85. package/dist/gateway/static/root/assets/workflows-page-IVP3GSkI.js +5 -0
  86. package/dist/gateway/static/root/index.html +12 -12
  87. package/dist/gateway/static/root/notification-sw.js +1 -1
  88. package/dist/package.js +1 -1
  89. package/dist/packages/gateway-contract/src/notifications.js +56 -0
  90. package/dist/packages/gateway-contract/src/turn-outcome.js +114 -0
  91. package/dist/src/agent/agent-instance-gateway.d.ts +1 -1
  92. package/dist/src/agent/agent-manager.d.ts +1 -1
  93. package/dist/src/agent/agent-manager.js +18 -3
  94. package/dist/src/agent/background-review/prompts.d.ts +8 -2
  95. package/dist/src/agent/background-review/prompts.js +25 -12
  96. package/dist/src/agent/background-review/run-background-review.d.ts +7 -2
  97. package/dist/src/agent/background-review/run-background-review.js +175 -160
  98. package/dist/src/agent/lifecycle/timeout-wrapper.d.ts +1 -0
  99. package/dist/src/agent/lifecycle/timeout-wrapper.js +7 -6
  100. package/dist/src/agent/mcp/mcp-transport-config.d.ts +1 -1
  101. package/dist/src/agent/mcp/mcp-transport-config.js +1 -1
  102. package/dist/src/agent/memory/index.d.ts +1 -1
  103. package/dist/src/agent/memory/index.js +2 -2
  104. package/dist/src/agent/memory/manager.d.ts +1 -11
  105. package/dist/src/agent/memory/manager.js +0 -16
  106. package/dist/src/agent/memory/understanding/service.d.ts +0 -11
  107. package/dist/src/agent/memory/understanding/service.js +7 -173
  108. package/dist/src/agent/memory/user-context-coordinator.d.ts +1 -3
  109. package/dist/src/agent/memory/user-context-coordinator.js +3 -66
  110. package/dist/src/agent/orchestration/agent-orchestrator.js +1 -1
  111. package/dist/src/agent/orchestration/run-agent-turn-with-timeout.d.ts +2 -2
  112. package/dist/src/agent/orchestration/run-agent-turn-with-timeout.js +4 -4
  113. package/dist/src/agent/service/direct-turn-helpers.js +1 -1
  114. package/dist/src/agent/tools/create-share-tool.js +14 -1
  115. package/dist/src/agent/tools/exec-command.js +3 -3
  116. package/dist/src/agent/tools/execute-code-tool.js +1 -1
  117. package/dist/src/agent/tools/executor.js +2 -2
  118. package/dist/src/agent/tools/image-generate-tool.js +12 -0
  119. package/dist/src/agent/tools/send-media.js +11 -0
  120. package/dist/src/agent/tools/xopc-use-tool.js +1 -1
  121. package/dist/src/cli/command-loaders.js +1 -0
  122. package/dist/src/cli/command-manifest.js +4 -0
  123. package/dist/src/cli/commands/doctor/checks/database-schema.js +1 -1
  124. package/dist/src/cli/commands/history.d.ts +1 -0
  125. package/dist/src/cli/commands/history.js +50 -0
  126. package/dist/src/config/agent-profile.js +1 -1
  127. package/dist/src/config/schema.d.ts +4 -0
  128. package/dist/src/config/schema.js +1 -0
  129. package/dist/src/connectors/connected-source-understanding.js +35 -21
  130. package/dist/src/connectors/learning-coordinator.js +1 -42
  131. package/dist/src/gateway/agents-admin.js +1 -1
  132. package/dist/src/gateway/chat-stream/mapper.d.ts +2 -0
  133. package/dist/src/gateway/chat-stream/mapper.js +5 -0
  134. package/dist/src/gateway/chat-stream/protocol.d.ts +3 -2
  135. package/dist/src/gateway/chat-stream/turn-outcome-collector.d.ts +16 -0
  136. package/dist/src/gateway/chat-stream/turn-outcome-collector.js +111 -0
  137. package/dist/src/gateway/hono/lib/static-ui.js +7 -5
  138. package/dist/src/gateway/hono/routes/index.js +2 -0
  139. package/dist/src/gateway/hono/routes/mobile.js +18 -40
  140. package/dist/src/gateway/hono/routes/notifications.d.ts +3 -0
  141. package/dist/src/gateway/hono/routes/notifications.js +45 -0
  142. package/dist/src/gateway/hono/routes/sessions.js +31 -0
  143. package/dist/src/gateway/hono/routes/tasks.js +1 -1
  144. package/dist/src/gateway/hono/routes/understanding-sources.js +4 -1
  145. package/dist/src/gateway/hono/routes/you.js +29 -11
  146. package/dist/src/gateway/service/agent-runner.js +6 -2
  147. package/dist/src/gateway/service/run-gateway-agent.js +58 -2
  148. package/dist/src/gateway/service/sessions-api.d.ts +6 -0
  149. package/dist/src/gateway/service/sessions-api.js +60 -3
  150. package/dist/src/gateway/service.d.ts +2 -2
  151. package/dist/src/gateway/service.js +8 -7
  152. package/dist/src/history/ctx/exporter.d.ts +14 -0
  153. package/dist/src/history/ctx/exporter.js +99 -0
  154. package/dist/src/history/ctx/format.d.ts +25 -0
  155. package/dist/src/history/ctx/format.js +282 -0
  156. package/dist/src/knowledge/index.d.ts +0 -1
  157. package/dist/src/knowledge/index.js +1 -2
  158. package/dist/src/media/session-references.d.ts +6 -0
  159. package/dist/src/media/session-references.js +24 -3
  160. package/dist/src/notifications/device-store.d.ts +16 -0
  161. package/dist/src/notifications/device-store.js +96 -0
  162. package/dist/src/notifications/planner.d.ts +6 -0
  163. package/dist/src/notifications/planner.js +160 -0
  164. package/dist/src/notifications/service.d.ts +18 -0
  165. package/dist/src/notifications/service.js +184 -0
  166. package/dist/src/notifications/store.d.ts +53 -0
  167. package/dist/src/notifications/store.js +184 -0
  168. package/dist/src/notifications/types.d.ts +29 -0
  169. package/dist/src/notifications/types.js +14 -0
  170. package/dist/src/session/client-history.d.ts +3 -1
  171. package/dist/src/session/client-history.js +13 -0
  172. package/dist/src/session/index.d.ts +1 -1
  173. package/dist/src/session/manager.d.ts +1 -0
  174. package/dist/src/session/manager.js +6 -0
  175. package/dist/src/session/store.d.ts +15 -0
  176. package/dist/src/session/store.js +58 -0
  177. package/dist/src/storage/sqlite/index.d.ts +2 -2
  178. package/dist/src/storage/sqlite/index.js +3 -3
  179. package/dist/src/storage/sqlite/migrations/136_product_notifications.sql +79 -0
  180. package/dist/src/storage/sqlite/migrations/137_understanding_status_audit.sql +71 -0
  181. package/dist/src/storage/sqlite/migrations/runner.d.ts +1 -1
  182. package/dist/src/storage/sqlite/migrations/runner.js +3 -3
  183. package/dist/src/storage/sqlite/migrations/runner.ts +1 -1
  184. package/dist/src/storage/sqlite/schema.js +1 -1
  185. package/dist/src/storage/sqlite/session-input-repository.d.ts +5 -0
  186. package/dist/src/storage/sqlite/session-input-repository.js +9 -1
  187. package/dist/src/storage/sqlite/user-context-repository.d.ts +16 -4
  188. package/dist/src/storage/sqlite/user-context-repository.js +56 -12
  189. package/dist/src/tasks/index.js +2 -2
  190. package/dist/src/tasks/task-application-service.js +42 -6
  191. package/dist/src/tasks/task-change-events.d.ts +9 -0
  192. package/dist/src/tasks/task-change-events.js +17 -1
  193. package/dist/src/tasks/task-outbox-dispatcher.js +5 -1
  194. package/dist/src/tasks/task-run-dispatcher.js +4 -2
  195. package/dist/src/tasks/task-run-repository.js +13 -0
  196. package/dist/src/user-context/config.d.ts +8 -0
  197. package/dist/src/user-context/config.js +3 -0
  198. package/dist/src/user-context/consolidation.js +16 -4
  199. package/dist/src/user-context/extraction/executor.d.ts +22 -0
  200. package/dist/src/user-context/extraction/executor.js +142 -0
  201. package/dist/src/user-context/extraction/registry.d.ts +1 -1
  202. package/dist/src/user-context/extraction/registry.js +5 -34
  203. package/dist/src/user-context/extraction/repair.js +4 -1
  204. package/dist/src/user-context/extraction/semantic.d.ts +18 -0
  205. package/dist/src/user-context/extraction/semantic.js +148 -0
  206. package/dist/src/user-context/understandingQuality.js +4 -0
  207. package/dist/src/work-discovery/analyzer.js +9 -4
  208. package/dist/src/work-discovery/service.d.ts +1 -0
  209. package/dist/src/work-discovery/service.js +5 -4
  210. package/dist/src/work-discovery/types.d.ts +1 -0
  211. package/package.json +14 -8
  212. package/dist/gateway/static/root/assets/agents-TJpjRHnr.js +0 -68
  213. package/dist/gateway/static/root/assets/apps-page-CZ4Da51l.js +0 -1
  214. package/dist/gateway/static/root/assets/automations-workspace-2Y00PvJU.js +0 -6
  215. package/dist/gateway/static/root/assets/browser-settings-page-CbJD27_j.js +0 -8
  216. package/dist/gateway/static/root/assets/capabilities-settings-panel-Dv8y6OuP.js +0 -7
  217. package/dist/gateway/static/root/assets/capability-presets-settings-panel-TZmjzWzt.js +0 -3
  218. package/dist/gateway/static/root/assets/channels-settings-g-68dutA.js +0 -1
  219. package/dist/gateway/static/root/assets/channels-status-swr-D7KsAeWh.js +0 -1
  220. package/dist/gateway/static/root/assets/connectors-page-DXA0rAvQ.js +0 -2
  221. package/dist/gateway/static/root/assets/home-page-i6bXCHdo.js +0 -1
  222. package/dist/gateway/static/root/assets/index-BBBE89vm.css +0 -2
  223. package/dist/gateway/static/root/assets/index-BsD5wygl.js +0 -74
  224. package/dist/gateway/static/root/assets/local-app-workbench-page-BCKEDMlP.js +0 -2
  225. package/dist/gateway/static/root/assets/logs-page-Cy9YQK7j.js +0 -2
  226. package/dist/gateway/static/root/assets/markdown-view-CBM-v2ph.js +0 -69
  227. package/dist/gateway/static/root/assets/mermaid-render-BbqDc_LQ.js +0 -134
  228. package/dist/gateway/static/root/assets/messages-CtOJwGW3.js +0 -3
  229. package/dist/gateway/static/root/assets/notes-workbench-B10T3hGX.js +0 -4
  230. package/dist/gateway/static/root/assets/project-detail-page-DsqRlgsy.js +0 -1
  231. package/dist/gateway/static/root/assets/projects-page-Bu2PN8OK.js +0 -1
  232. package/dist/gateway/static/root/assets/remote-access-hub-CXACdJ2f.js +0 -1
  233. package/dist/gateway/static/root/assets/sessions-page-CS2knWDT.js +0 -1
  234. package/dist/gateway/static/root/assets/settings-advanced-gate-ByFGk0q_.js +0 -1
  235. package/dist/gateway/static/root/assets/skill-reload-api-DweAPjI8.js +0 -1
  236. package/dist/gateway/static/root/assets/task-detail-page-DEj-BFMP.js +0 -1
  237. package/dist/gateway/static/root/assets/user-context-page-f7yh7aD5.js +0 -1
  238. package/dist/gateway/static/root/assets/workflow-run-setup-panel-CBAYvm3G.js +0 -3
  239. package/dist/gateway/static/root/assets/workflows-page-BN0JmHrG.js +0 -5
  240. package/dist/src/agent/memory/understanding/correction.d.ts +0 -3
  241. package/dist/src/agent/memory/understanding/correction.js +0 -39
  242. package/dist/src/knowledge/connected-understanding-pipeline.d.ts +0 -17
  243. package/dist/src/knowledge/connected-understanding-pipeline.js +0 -278
  244. package/dist/src/mobile/notification-service.d.ts +0 -9
  245. package/dist/src/mobile/notification-service.js +0 -156
  246. package/dist/src/mobile/notification-store.d.ts +0 -28
  247. package/dist/src/mobile/notification-store.js +0 -132
  248. package/dist/src/mobile/notification-types.d.ts +0 -37
  249. package/dist/src/mobile/notification-types.js +0 -9
@@ -1,7 +1,7 @@
1
1
  import { UNDERSTANDING_KINDS } from "../../../user-context/domain.js";
2
2
  import { listContextExtractionRuns } from "../../../storage/sqlite/context-extraction-repository.js";
3
3
  import { listContextConsolidationRuns } from "../../../storage/sqlite/context-consolidation-repository.js";
4
- import { createCollaborationRule, createUnderstanding, decideContextConsent, deleteCollaborationRule, deleteUnderstanding, getCollaborationRule, getTurnPersonalization, getUnderstanding, getUserProfile, listCollaborationRules, listUnderstandingEvidence, listUnderstandings, recordContextFeedback, rejectUnderstanding, reviseCollaborationRule, reviseUnderstanding, setCollaborationRuleStatus, setUnderstandingStatus, updateUserProfile } from "../../../storage/sqlite/user-context-repository.js";
4
+ import { createCollaborationRule, createUnderstanding, decideContextConsent, deleteCollaborationRule, deleteUnderstanding, getCollaborationRule, getTurnPersonalization, getUnderstanding, getUserProfile, listCollaborationRules, listUnderstandingEvidence, listUnderstandingStatusEvents, listUnderstandings, recordContextFeedback, rejectUnderstanding, reviseCollaborationRule, reviseUnderstanding, setCollaborationRuleStatus, setUnderstandingStatus, updateUserProfile } from "../../../storage/sqlite/user-context-repository.js";
5
5
  import "../../../storage/sqlite/index.js";
6
6
  import { listUserFocuses, updateUserFocus } from "../../../user-context/sources/repository.js";
7
7
  import { canonicalUnderstandingKey, findDuplicateUnderstanding } from "../../../user-context/understanding.js";
@@ -199,8 +199,13 @@ function registerYouRoutes(authenticated, deps) {
199
199
  const objects = normalized.map(({ objectType, objectId, action }) => {
200
200
  if (objectType === "understanding") return action === "accept" ? setUnderstandingStatus(objectId, "active", {
201
201
  explicitness: "explicit",
202
- confidence: 1
203
- }) : action === "reject" ? rejectUnderstanding(objectId, "Rejected during context review") : setUnderstandingStatus(objectId, "needs_review");
202
+ confidence: 1,
203
+ actorType: "user",
204
+ source: "context-review"
205
+ }) : action === "reject" ? rejectUnderstanding(objectId, "Rejected during context review", "user") : setUnderstandingStatus(objectId, "needs_review", {
206
+ actorType: "user",
207
+ source: "context-review-later"
208
+ });
204
209
  return updateUserFocus(objectId, { status: action === "accept" ? "active" : action === "reject" ? "rejected" : "paused" });
205
210
  });
206
211
  return c.json({ objects });
@@ -271,7 +276,10 @@ function registerYouRoutes(authenticated, deps) {
271
276
  authenticated.get("/api/you/understandings/:id/evidence", (c) => {
272
277
  const understanding = getUnderstanding(c.req.param("id"));
273
278
  if (!understanding) return c.json({ error: "Understanding not found" }, 404);
274
- return c.json({ evidence: listUnderstandingEvidence(understanding.id) });
279
+ return c.json({
280
+ evidence: listUnderstandingEvidence(understanding.id),
281
+ statusEvents: listUnderstandingStatusEvents(understanding.id)
282
+ });
275
283
  });
276
284
  authenticated.patch("/api/you/understandings/:id", write, async (c) => {
277
285
  const id = c.req.param("id");
@@ -299,10 +307,14 @@ function registerYouRoutes(authenticated, deps) {
299
307
  }
300
308
  if (body.status !== void 0) {
301
309
  if (!UNDERSTANDING_STATUSES.has(body.status)) return c.json({ error: "Invalid status" }, 400);
302
- understanding = body.status === "rejected" ? rejectUnderstanding(id, nonEmptyString(body.reason, 500) ?? "Rejected by user") : setUnderstandingStatus(id, body.status, body.status === "active" ? {
303
- explicitness: "explicit",
304
- confidence: 1
305
- } : void 0);
310
+ understanding = body.status === "rejected" ? rejectUnderstanding(id, nonEmptyString(body.reason, 500) ?? "Rejected by user", "user") : setUnderstandingStatus(id, body.status, {
311
+ ...body.status === "active" ? {
312
+ explicitness: "explicit",
313
+ confidence: 1
314
+ } : {},
315
+ actorType: "user",
316
+ source: "understanding-edit"
317
+ });
306
318
  }
307
319
  return c.json({ understanding });
308
320
  });
@@ -374,9 +386,15 @@ function registerYouRoutes(authenticated, deps) {
374
386
  ...typeof body.reason === "string" ? { reason: body.reason.slice(0, 500) } : {}
375
387
  });
376
388
  if (objectType === "understanding" && typeof objectId === "string") {
377
- if (rating === "wrong") rejectUnderstanding(objectId, "Marked wrong from turn feedback");
378
- if (rating === "stale") setUnderstandingStatus(objectId, "stale");
379
- if (rating === "sensitive") setUnderstandingStatus(objectId, "needs_review");
389
+ if (rating === "wrong") rejectUnderstanding(objectId, "Marked wrong from turn feedback", "user");
390
+ if (rating === "stale") setUnderstandingStatus(objectId, "stale", {
391
+ actorType: "user",
392
+ source: "turn-feedback-stale"
393
+ });
394
+ if (rating === "sensitive") setUnderstandingStatus(objectId, "needs_review", {
395
+ actorType: "user",
396
+ source: "turn-feedback-sensitive"
397
+ });
380
398
  }
381
399
  if (objectType === "focus" && typeof objectId === "string") {
382
400
  if (rating === "wrong") updateUserFocus(objectId, { status: "rejected" });
@@ -1,5 +1,7 @@
1
1
  import { createLogger } from "../../utils/logger/index.js";
2
2
  import { init_logger } from "../../utils/logger.js";
3
+ import { listActiveSessionInputRuns } from "../../storage/sqlite/session-input-repository.js";
4
+ import "../../storage/sqlite/index.js";
3
5
  import { ClarifyBridge } from "../clarify-bridge.js";
4
6
  import { runGatewayAgent } from "./run-gateway-agent.js";
5
7
  import { fitSourceContextsToBudget } from "../../agent/source-context/budget.js";
@@ -75,10 +77,12 @@ var GatewayAgentRunner = class {
75
77
  return this.activeWebchatRunBySession.has(sessionKey);
76
78
  }
77
79
  getActiveRunId(sessionKey) {
78
- return this.activeWebchatRunBySession.get(sessionKey);
80
+ return this.activeWebchatRunBySession.get(sessionKey) ?? this.inputs.snapshot(sessionKey).activeRunId;
79
81
  }
80
82
  listActiveRuns() {
81
- return [...this.activeWebchatRunBySession.entries()].map(([sessionKey, runId]) => ({
83
+ const runs = new Map(listActiveSessionInputRuns().map(({ sessionKey, runId }) => [sessionKey, runId]));
84
+ for (const [sessionKey, runId] of this.activeWebchatRunBySession) runs.set(sessionKey, runId);
85
+ return [...runs].map(([sessionKey, runId]) => ({
82
86
  sessionKey,
83
87
  runId
84
88
  }));
@@ -13,6 +13,7 @@ import { ChatStreamMapper } from "../chat-stream/mapper.js";
13
13
  import { resolveWebchatSessionKey } from "../resolve-webchat-session-key.js";
14
14
  import { recordExplicitRelationshipFollowUp } from "../../user-context/relationship-continuity.js";
15
15
  import { coalesceThinkingDeltas } from "../chat-stream/thinking-delta-coalescer.js";
16
+ import { TurnOutcomeCollector } from "../chat-stream/turn-outcome-collector.js";
16
17
  import crypto from "crypto";
17
18
  //#region src/gateway/service/run-gateway-agent.ts
18
19
  init_logger();
@@ -34,9 +35,11 @@ async function* runGatewayAgent(deps, message, channel, chatId, origin, attachme
34
35
  let taskRunStatus = "failed";
35
36
  let taskRunSummary = "Agent run ended unexpectedly";
36
37
  let terminalStatus = "error";
38
+ let runTopicCompleted = false;
37
39
  let webchatSessionKey;
38
40
  let webchatSessionId;
39
41
  let webchatMetadata;
42
+ let outcomeEnvironment = "workspace";
40
43
  if (channel === "webchat") {
41
44
  const resolved = resolveWebchatSessionKey({ sessionKey: chatId });
42
45
  if (resolved.ok === false) throw new Error(resolved.error);
@@ -65,6 +68,8 @@ async function* runGatewayAgent(deps, message, channel, chatId, origin, attachme
65
68
  channel,
66
69
  metadata: webchatMetadata
67
70
  });
71
+ if (/remote/i.test(executionContext.strategy ?? "")) outcomeEnvironment = "remote_runtime";
72
+ else if (/worktree/i.test(executionContext.strategy ?? "")) outcomeEnvironment = "worktree";
68
73
  taskRun = TaskRunCoordinator.start({
69
74
  runId,
70
75
  context: executionContext,
@@ -76,8 +81,11 @@ async function* runGatewayAgent(deps, message, channel, chatId, origin, attachme
76
81
  sessionKey: streamSessionKey,
77
82
  channel
78
83
  });
84
+ const outcomeCollector = new TurnOutcomeCollector(runId, outcomeEnvironment);
85
+ let outcomeFinalized = false;
79
86
  let registeredActiveWebchatRun = false;
80
87
  const captureTaskEvent = (event) => {
88
+ outcomeCollector.capture(event);
81
89
  if (event.type === "task_plan_updated") {
82
90
  taskRun?.capturePlan(event.payload.items);
83
91
  return;
@@ -102,6 +110,30 @@ async function* runGatewayAgent(deps, message, channel, chatId, origin, attachme
102
110
  yield event;
103
111
  }
104
112
  };
113
+ const finalizeOutcome = async (status, summary) => {
114
+ if (outcomeFinalized) return [];
115
+ outcomeFinalized = true;
116
+ const outcome = outcomeCollector.finalize(status, summary);
117
+ if (webchatSessionKey) try {
118
+ await sessionIndex.appendTranscriptCustomEntry(webchatSessionKey, {
119
+ customType: "turn_outcome",
120
+ data: outcome
121
+ });
122
+ } catch (err) {
123
+ log.warn({
124
+ err,
125
+ runId,
126
+ sessionKey: webchatSessionKey
127
+ }, `Turn outcome persistence failed: ${err instanceof Error ? err.message : String(err)}`);
128
+ }
129
+ return [{
130
+ type: "turn_outcome",
131
+ runId,
132
+ sessionKey: streamSessionKey,
133
+ timestamp: Date.now(),
134
+ payload: outcome
135
+ }];
136
+ };
105
137
  try {
106
138
  yield* emitAndYield(mapper.start());
107
139
  if (channel === "webchat" && webchatSessionKey) {
@@ -141,8 +173,10 @@ async function* runGatewayAgent(deps, message, channel, chatId, origin, attachme
141
173
  taskRunStatus = mergedSignal.aborted ? "cancelled" : "succeeded";
142
174
  terminalStatus = endStatus;
143
175
  taskRunSummary = endSummary;
176
+ yield* emitAndYield(await finalizeOutcome(endStatus, endSummary));
144
177
  yield* emitAndYield(mapper.end(endStatus, endSummary));
145
178
  completeRealtimeTopic(`run:${runId}`);
179
+ runTopicCompleted = true;
146
180
  return {
147
181
  status: mergedSignal.aborted ? "aborted" : "ok",
148
182
  summary: mergedSignal.aborted ? "Interrupted" : "Message processed successfully"
@@ -163,8 +197,10 @@ async function* runGatewayAgent(deps, message, channel, chatId, origin, attachme
163
197
  taskRunSummary = em;
164
198
  const errorContent = formatAgentRunErrorForClient(streamError);
165
199
  yield* emitAndYield(mapper.error(errorContent));
200
+ yield* emitAndYield(await finalizeOutcome("error", streamError));
166
201
  yield* emitAndYield(mapper.end("error", streamError));
167
202
  completeRealtimeTopic(`run:${runId}`);
203
+ runTopicCompleted = true;
168
204
  return {
169
205
  status: "error",
170
206
  summary: streamError
@@ -247,6 +283,7 @@ async function* runGatewayAgent(deps, message, channel, chatId, origin, attachme
247
283
  presentation: "answer"
248
284
  }
249
285
  }]);
286
+ yield* emitAndYield(await finalizeOutcome("success", "Message processed"));
250
287
  yield* emitAndYield(mapper.end("success", "Message processed"));
251
288
  taskRunStatus = "succeeded";
252
289
  taskRunSummary = "Message processed";
@@ -257,6 +294,7 @@ async function* runGatewayAgent(deps, message, channel, chatId, origin, attachme
257
294
  } catch (error) {
258
295
  const em = error instanceof Error ? error.message : String(error);
259
296
  taskRunStatus = "failed";
297
+ terminalStatus = "error";
260
298
  taskRunSummary = em;
261
299
  log.error({
262
300
  err: error,
@@ -266,6 +304,17 @@ async function* runGatewayAgent(deps, message, channel, chatId, origin, attachme
266
304
  channel,
267
305
  chatId
268
306
  }, `Agent run failed: ${em}`);
307
+ if (channel === "webchat" && !runTopicCompleted) {
308
+ yield* emitAndYield(mapper.error(formatAgentRunErrorForClient(em)));
309
+ yield* emitAndYield(await finalizeOutcome("error", em));
310
+ yield* emitAndYield(mapper.end("error", em));
311
+ completeRealtimeTopic(`run:${runId}`);
312
+ runTopicCompleted = true;
313
+ return {
314
+ status: "error",
315
+ summary: em
316
+ };
317
+ }
269
318
  throw error;
270
319
  } finally {
271
320
  if (taskRun) try {
@@ -282,6 +331,9 @@ async function* runGatewayAgent(deps, message, channel, chatId, origin, attachme
282
331
  }
283
332
  if (webchatSessionKey) {
284
333
  const metaAfter = await sessionIndex.getSessionMetadata(webchatSessionKey).catch(() => void 0);
334
+ const normalizedResponse = terminalStatus === "success" ? mapper.getLastAssistantText().replace(/\s+/g, " ").trim() : "";
335
+ const responseCharacters = Array.from(normalizedResponse);
336
+ const responsePreview = responseCharacters.length > 180 ? `${responseCharacters.slice(0, 179).join("")}…` : normalizedResponse;
285
337
  if (metaAfter?.name) emit("session.updated", {
286
338
  key: webchatSessionKey,
287
339
  name: metaAfter.name
@@ -292,9 +344,13 @@ async function* runGatewayAgent(deps, message, channel, chatId, origin, attachme
292
344
  sessionKey: webchatSessionKey,
293
345
  status: terminalStatus,
294
346
  completedAtMs: Date.now(),
295
- route: `/chat/${encodeURIComponent(webchatSessionKey)}`,
347
+ target: {
348
+ kind: "chat",
349
+ sessionKey: webchatSessionKey
350
+ },
296
351
  source: "webchat",
297
- ...metaAfter?.name?.trim() ? { sessionTitle: metaAfter.name.trim().slice(0, 100) } : {}
352
+ ...metaAfter?.name?.trim() ? { sessionTitle: metaAfter.name.trim().slice(0, 100) } : {},
353
+ ...responsePreview ? { responsePreview } : {}
298
354
  });
299
355
  }
300
356
  }
@@ -159,6 +159,12 @@ export declare class GatewaySessionsApi {
159
159
  sessionKey: string;
160
160
  rowCount: number;
161
161
  }>;
162
+ forkAtTurn(sourceKey: string, lastTurnId: string): Promise<{
163
+ sessionKey: string;
164
+ rowCount: number;
165
+ lastTurnId: string;
166
+ session: NonNullable<Awaited<ReturnType<GatewaySessionsApi['getSession']>>>;
167
+ }>;
162
168
  btwQuery(sessionKey: string, question: string): Promise<{
163
169
  text: string;
164
170
  error?: string;
@@ -1,11 +1,28 @@
1
+ import { init_agent_session_key, resolveAgentIdFromSessionKey } from "../../routing/agent-session-key.js";
2
+ import { buildSessionKey, init_session_key } from "../../routing/session-key.js";
1
3
  import { retireSessionMcpRuntimeForSessionKey } from "../../agent/mcp/bundle-mcp-runtime.js";
2
4
  import "../../agent/mcp/bundle-mcp-tools.js";
3
5
  import { buildSessionTimeline } from "../../session/transcript-outline.js";
4
6
  import { transcriptRowsToClientHistory } from "../../session/client-history.js";
5
- import { collectMediaUrisFromMessages, deleteMediaUris } from "../../media/session-references.js";
7
+ import { collectMediaUrisFromValues, deleteMediaUris } from "../../media/session-references.js";
6
8
  import { getDistinctSessionChatIds } from "./session-chat-ids.js";
7
9
  import { performSessionReset } from "../session-reset-service.js";
10
+ import { randomUUID } from "node:crypto";
8
11
  //#region src/gateway/service/sessions-api.ts
12
+ /**
13
+ * GatewaySessionsApi — session CRUD, search, compaction, tag/pin/archive,
14
+ * stats, and chat-id grouping for the gateway REST surface.
15
+ *
16
+ * Twenty-four methods, previously sitting on `GatewayService` as a mix of
17
+ * one-line `sessionIndex.*` delegations and small composite operations (e.g.
18
+ * `restoreCheckpoint` also evicts the in-memory agent, `runCompaction` also
19
+ * appends a transcript context entry). Centralising them here lets routes
20
+ * depend on the narrow `GatewaySessionsApi` surface instead of the full
21
+ * `GatewayService`, and keeps the gateway composition root focused on
22
+ * lifecycle + wiring.
23
+ */
24
+ init_session_key();
25
+ init_agent_session_key();
9
26
  function clampWindowSpan(value, fallback) {
10
27
  const parsed = Math.trunc(value ?? fallback);
11
28
  if (!Number.isFinite(parsed)) return fallback;
@@ -117,10 +134,10 @@ var GatewaySessionsApi = class {
117
134
  return result;
118
135
  }
119
136
  async delete(key) {
120
- const messages = await this.opts.sessionIndex.loadMessages(key).catch(() => []);
137
+ const transcriptRows = await this.opts.sessionIndex.getStore().loadTranscriptHistoryRows(key).catch(() => []);
121
138
  const result = await this.opts.sessionIndex.deleteSession(key);
122
139
  if (result) {
123
- await deleteMediaUris(collectMediaUrisFromMessages(messages));
140
+ await deleteMediaUris(collectMediaUrisFromValues(transcriptRows));
124
141
  this.opts.getAgentService().evictSessionAgent(key);
125
142
  await retireSessionMcpRuntimeForSessionKey({
126
143
  sessionKey: key,
@@ -185,6 +202,46 @@ var GatewaySessionsApi = class {
185
202
  forkRows(key, targetKey, options = {}) {
186
203
  return this.opts.sessionIndex.forkSessionRows(key, targetKey, options);
187
204
  }
205
+ async forkAtTurn(sourceKey, lastTurnId) {
206
+ const source = await this.opts.sessionIndex.getSessionMetadata(sourceKey);
207
+ if (!source) throw new Error(`Session not found: ${sourceKey}`);
208
+ if (source.sessionType !== "chat") throw new Error("Only chat sessions can be forked");
209
+ const normalizedTurnId = lastTurnId.trim();
210
+ if (!normalizedTurnId) throw new Error("lastTurnId is required");
211
+ if (this.opts.getActiveWebchatRunId(sourceKey)?.trim() === normalizedTurnId) throw new Error("Cannot fork a turn that is still running");
212
+ const agentId = source.routing?.agentId?.trim() || resolveAgentIdFromSessionKey(sourceKey);
213
+ const chatId = `chat_${randomUUID()}`;
214
+ const targetKey = buildSessionKey({
215
+ agentId,
216
+ source: "webchat",
217
+ accountId: "default",
218
+ peerKind: "direct",
219
+ peerId: chatId
220
+ });
221
+ const result = await this.opts.sessionIndex.forkSessionAtTurn(sourceKey, {
222
+ targetKey,
223
+ lastTurnId: normalizedTurnId,
224
+ targetMetadata: {
225
+ sourceChannel: "webchat",
226
+ sourceChatId: `default:direct:${chatId}`,
227
+ sessionType: "chat",
228
+ routing: {
229
+ agentId,
230
+ source: "webchat",
231
+ accountId: "default",
232
+ peerKind: "direct",
233
+ peerId: chatId
234
+ }
235
+ }
236
+ });
237
+ const session = await this.getSession(result.sessionKey);
238
+ if (!session) throw new Error(`Forked session not found: ${result.sessionKey}`);
239
+ return {
240
+ ...result,
241
+ lastTurnId: normalizedTurnId,
242
+ session
243
+ };
244
+ }
188
245
  btwQuery(sessionKey, question) {
189
246
  return this.opts.getAgentService().sessionInspector.btwQuery(sessionKey, question);
190
247
  }
@@ -68,7 +68,7 @@ export declare class GatewayService {
68
68
  private taskRunDispatcher;
69
69
  private taskRunDispatchTimer;
70
70
  private managedComposioEventPoller?;
71
- private mobileNotifications;
71
+ private notificationService;
72
72
  private connectorSupervisor;
73
73
  private connectorLearningCoordinator;
74
74
  private connectedSourceChangePublisher;
@@ -120,7 +120,7 @@ export declare class GatewayService {
120
120
  private ensureAgentService;
121
121
  private ensureHeartbeatService;
122
122
  private createTaskRunDispatcher;
123
- private createMobileNotificationService;
123
+ private createNotificationService;
124
124
  dispatchTaskRuns(): void;
125
125
  ensureTaskConversation(taskId: string, options?: {
126
126
  runId?: string;
@@ -92,7 +92,7 @@ import { auditGatewayConfig } from "./security/audit.js";
92
92
  import { getXopcCloudCatalogCoordinator } from "../providers/xopc-cloud-catalog-coordinator.js";
93
93
  import { ModelCatalogSyncService } from "../providers/model-catalog-sync-service.js";
94
94
  import { runBootstrapMigrationsSync } from "../migrations/runner.js";
95
- import { MobileNotificationService } from "../mobile/notification-service.js";
95
+ import { NotificationService } from "../notifications/service.js";
96
96
  import { LocalAppService } from "../local-apps/service.js";
97
97
  import "../local-apps/index.js";
98
98
  import { createRuntimeBrowserRecipeService } from "../browser/recipes/runtime-service.js";
@@ -185,7 +185,7 @@ var GatewayService = class {
185
185
  taskRunDispatcher = null;
186
186
  taskRunDispatchTimer = null;
187
187
  managedComposioEventPoller;
188
- mobileNotifications = null;
188
+ notificationService = null;
189
189
  connectorSupervisor = null;
190
190
  connectorLearningCoordinator = null;
191
191
  connectedSourceChangePublisher = null;
@@ -239,7 +239,6 @@ var GatewayService = class {
239
239
  this.proactiveTemporalWorker = new ProactiveTemporalWorker(this.proactive);
240
240
  this.proactiveInboxWorker = new ProactiveInboxWorker({ deliver: async ({ inboxItem }) => {
241
241
  this.emit("proactive.inbox.created", inboxItem);
242
- await this.createMobileNotificationService().deliverGatewayEvent("proactive.inbox.created", inboxItem);
243
242
  } });
244
243
  let bootstrapConfigChanged = initializeVoiceDefaults(this.config, inferProductLanguageFromEnvironment());
245
244
  const starterResult = ensureStarterAgentsInitialized(this.config);
@@ -574,9 +573,9 @@ var GatewayService = class {
574
573
  });
575
574
  return this.taskRunDispatcher;
576
575
  }
577
- createMobileNotificationService() {
578
- if (!this.mobileNotifications) this.mobileNotifications = new MobileNotificationService();
579
- return this.mobileNotifications;
576
+ createNotificationService() {
577
+ if (!this.notificationService) this.notificationService = new NotificationService({ publish: (type, payload) => this.realtime.broker.publish("gateway", type, payload) });
578
+ return this.notificationService;
580
579
  }
581
580
  dispatchTaskRuns() {
582
581
  new TaskSignalService().tick();
@@ -798,6 +797,7 @@ var GatewayService = class {
798
797
  });
799
798
  log.debug("Starting gateway service...");
800
799
  openXopcDatabase();
800
+ this.createNotificationService().start();
801
801
  this.startTime = Date.now();
802
802
  this.running = true;
803
803
  this.taskRunDispatchTimer = setInterval(() => this.dispatchTaskRuns(), 1e3);
@@ -1103,6 +1103,7 @@ var GatewayService = class {
1103
1103
  await this.discussionLiveWorker.stop();
1104
1104
  this.proactiveTemporalWorker.stop();
1105
1105
  await this.proactiveInboxWorker.stop();
1106
+ this.notificationService?.stop();
1106
1107
  if (this.taskRunDispatchTimer) {
1107
1108
  clearInterval(this.taskRunDispatchTimer);
1108
1109
  this.taskRunDispatchTimer = null;
@@ -1543,7 +1544,7 @@ var GatewayService = class {
1543
1544
  }
1544
1545
  emit(type, payload) {
1545
1546
  this.realtime.broker.publish("gateway", type, payload);
1546
- this.createMobileNotificationService().handleGatewayEvent(type, payload);
1547
+ this.createNotificationService().handleGatewayEvent(type, payload);
1547
1548
  }
1548
1549
  handleAutomationRunCompleted(run) {
1549
1550
  this.automationService.get(run.automationId).then((automation) => {
@@ -0,0 +1,14 @@
1
+ import type { DatabaseSync } from 'node:sqlite';
2
+ export interface CtxHistoryExportResult {
3
+ outputDir: string;
4
+ historyPath: string;
5
+ manifestPath: string;
6
+ sessionCount: number;
7
+ eventCount: number;
8
+ changed: boolean;
9
+ }
10
+ export declare function resolveDefaultCtxHistoryExportDir(env?: NodeJS.ProcessEnv): string;
11
+ export declare function exportCtxHistory(db: DatabaseSync, options?: {
12
+ outputDir?: string;
13
+ env?: NodeJS.ProcessEnv;
14
+ }): Promise<CtxHistoryExportResult>;
@@ -0,0 +1,99 @@
1
+ import { init_paths_state, resolveStateDir } from "../../config/paths-state.js";
2
+ import { init_write_file_atomic, writeTextAtomic } from "../../infra/write-file-atomic.js";
3
+ import { buildCtxHistoryJsonl, buildCtxPluginManifest } from "./format.js";
4
+ import { join, resolve } from "node:path";
5
+ import { mkdir, readFile } from "node:fs/promises";
6
+ //#region src/history/ctx/exporter.ts
7
+ init_paths_state();
8
+ init_write_file_atomic();
9
+ function readSnapshot(db) {
10
+ db.exec("BEGIN");
11
+ try {
12
+ const transcripts = db.prepare(`SELECT
13
+ t.session_id,
14
+ t.status,
15
+ t.created_at,
16
+ t.archived_at,
17
+ t.cwd,
18
+ s.agent_id,
19
+ s.session_type
20
+ FROM transcripts t
21
+ JOIN sessions s ON s.session_key = t.session_key
22
+ WHERE t.status = 'active' OR t.archive_reason IN ('reset', 'stale')
23
+ ORDER BY t.created_at ASC, t.session_id ASC`).all();
24
+ const entries = db.prepare(`SELECT e.entry_id, e.session_id, e.seq, e.payload_json, e.created_at
25
+ FROM transcript_entries e
26
+ JOIN transcripts t ON t.session_id = e.session_id
27
+ JOIN sessions s ON s.session_key = t.session_key
28
+ WHERE t.status = 'active' OR t.archive_reason IN ('reset', 'stale')
29
+ ORDER BY t.created_at ASC, t.session_id ASC, e.seq ASC, e.entry_id ASC`).all();
30
+ db.exec("COMMIT");
31
+ const entriesBySession = /* @__PURE__ */ new Map();
32
+ for (const entry of entries) {
33
+ const bucket = entriesBySession.get(entry.session_id) ?? [];
34
+ bucket.push({
35
+ entryId: entry.entry_id,
36
+ seq: entry.seq,
37
+ createdAt: entry.created_at,
38
+ payloadJson: entry.payload_json
39
+ });
40
+ entriesBySession.set(entry.session_id, bucket);
41
+ }
42
+ return transcripts.map((transcript) => ({
43
+ sessionId: transcript.session_id,
44
+ status: transcript.status,
45
+ createdAt: transcript.created_at,
46
+ archivedAt: transcript.archived_at,
47
+ cwd: transcript.cwd,
48
+ agentId: transcript.agent_id,
49
+ sessionType: transcript.session_type,
50
+ entries: entriesBySession.get(transcript.session_id) ?? []
51
+ }));
52
+ } catch (error) {
53
+ try {
54
+ db.exec("ROLLBACK");
55
+ } catch {}
56
+ throw error;
57
+ }
58
+ }
59
+ async function writeIfChanged(path, contents) {
60
+ let existing = null;
61
+ try {
62
+ existing = await readFile(path, "utf8");
63
+ } catch (error) {
64
+ if (error.code !== "ENOENT") throw error;
65
+ }
66
+ if (existing === contents) return false;
67
+ await writeTextAtomic(path, contents, {
68
+ mode: 384,
69
+ ensureDirMode: 448
70
+ });
71
+ return true;
72
+ }
73
+ function resolveDefaultCtxHistoryExportDir(env = process.env) {
74
+ return join(resolveStateDir(env), "exports", "ctx");
75
+ }
76
+ async function exportCtxHistory(db, options = {}) {
77
+ const outputDir = resolve(options.outputDir ?? resolveDefaultCtxHistoryExportDir(options.env));
78
+ const historyPath = join(outputDir, "history.jsonl");
79
+ const manifestPath = join(outputDir, "ctx-history-plugin.json");
80
+ const sessions = readSnapshot(db);
81
+ const history = buildCtxHistoryJsonl(sessions);
82
+ const manifest = buildCtxPluginManifest();
83
+ await mkdir(outputDir, {
84
+ recursive: true,
85
+ mode: 448
86
+ });
87
+ const historyChanged = await writeIfChanged(historyPath, history.contents);
88
+ const manifestChanged = await writeIfChanged(manifestPath, manifest);
89
+ return {
90
+ outputDir,
91
+ historyPath,
92
+ manifestPath,
93
+ sessionCount: sessions.length,
94
+ eventCount: history.eventCount,
95
+ changed: historyChanged || manifestChanged
96
+ };
97
+ }
98
+ //#endregion
99
+ export { exportCtxHistory, resolveDefaultCtxHistoryExportDir };
@@ -0,0 +1,25 @@
1
+ export declare const CTX_HISTORY_SCHEMA_VERSION = "ctx-history-jsonl-v2";
2
+ export declare const CTX_PROVIDER_KEY = "xopc";
3
+ export declare const CTX_SOURCE_ID = "default";
4
+ export declare const CTX_SOURCE_FORMAT = "xopc-session-history-v1";
5
+ export interface XopcHistorySession {
6
+ sessionId: string;
7
+ status: string;
8
+ createdAt: number;
9
+ archivedAt: number | null;
10
+ cwd: string;
11
+ agentId: string;
12
+ sessionType: string | null;
13
+ entries: XopcHistoryEntry[];
14
+ }
15
+ export interface XopcHistoryEntry {
16
+ entryId: string;
17
+ seq: number;
18
+ createdAt: number;
19
+ payloadJson: string;
20
+ }
21
+ export declare function buildCtxHistoryJsonl(sessions: XopcHistorySession[]): {
22
+ contents: string;
23
+ eventCount: number;
24
+ };
25
+ export declare function buildCtxPluginManifest(): string;