@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
@@ -10,9 +10,9 @@ import { claimContextExtractionRun, finishContextExtractionRun, getContextExtrac
10
10
  import { closeTemporalAssertions, createTemporalAssertion, linkContextObjects, listContextObjectRelations, listTemporalAssertions } from "./context-relation-repository.js";
11
11
  import { finishContextConsolidationRun, getContextConsolidationRun, listContextConsolidationDecisions, listContextConsolidationRuns, recordContextConsolidationDecision, startContextConsolidationRun } from "./context-consolidation-repository.js";
12
12
  import { summarizeUnderstandingFeedback, summarizeUserUnderstandingQuality } from "./user-context-quality-repository.js";
13
- import { closeUnderstandingValidity, consumeContextConsent, createCollaborationRule, createContextEvidence, createUnderstanding, decideContextConsent, deleteCollaborationRule, deleteUnderstanding, ensureContextConsent, getCollaborationRule, getTurnPersonalization, getUnderstanding, getUserProfile, hasContextConsent, isUnderstandingSuppressed, linkUnderstandingEvidence, listCollaborationRules, listUnderstandingEvidence, listUnderstandings, recordContextFeedback, recordContextRun, rejectUnderstanding, reviseCollaborationRule, reviseUnderstanding, searchActiveUnderstandings, setCollaborationRuleStatus, setUnderstandingStatus, updateUserProfile } from "./user-context-repository.js";
13
+ import { closeUnderstandingValidity, consumeContextConsent, createCollaborationRule, createContextEvidence, createUnderstanding, decideContextConsent, deleteCollaborationRule, deleteUnderstanding, ensureContextConsent, getCollaborationRule, getTurnPersonalization, getUnderstanding, getUserProfile, hasContextConsent, isUnderstandingSuppressed, linkUnderstandingEvidence, listCollaborationRules, listUnderstandingEvidence, listUnderstandingStatusEvents, listUnderstandings, recordContextFeedback, recordContextRun, rejectUnderstanding, reviseCollaborationRule, reviseUnderstanding, searchActiveUnderstandings, setCollaborationRuleStatus, setUnderstandingStatus, updateUserProfile } from "./user-context-repository.js";
14
14
  import { getUserPeopleIndexState, getUserPerson, listUserPeople, mergeUserPeople, replaceUserPeopleIndex, summarizeUserPeople, updateUserPerson } from "./user-people-repository.js";
15
- import { cancelQueuedSessionInput, claimNextSessionInput, findSessionInput, finishSessionInputRun, getSessionInputById, getSessionInputState, insertSessionInput, mutateQueuedSessionInput, recoverSessionInputState, setSessionInputStatus } from "./session-input-repository.js";
15
+ import { cancelQueuedSessionInput, claimNextSessionInput, findSessionInput, finishSessionInputRun, getSessionInputById, getSessionInputState, insertSessionInput, listActiveSessionInputRuns, mutateQueuedSessionInput, recoverSessionInputState, setSessionInputStatus } from "./session-input-repository.js";
16
16
  import { buildDefaultSessionMetadata } from "./session-metadata.js";
17
17
  import { buildGlobalSessionStats, classifyStoredRow, estimateTokensFromMessages, extractFtsContent, metadataToSessionInsert, sessionConfigRowToConfig, sessionRowToMetadata, transcriptEntryRowToStoredRow } from "./row-mappers.js";
18
18
  import { replaceLatestSessionTurnAndQueueInput, validateLatestSessionTurnTarget } from "./session-turn-replace-repository.js";
@@ -36,4 +36,4 @@ import { appendConnectorExecutionAudit, claimConnectorWebhookDelivery, completeC
36
36
  import { getConnectorAccount, listConnectorAccounts, reconcileConnectorAccount, refreshConnectorAccountCurrent } from "./connector-account-repository.js";
37
37
  import { getConnectorSyncPolicy, getConnectorSyncPolicyForConnection, listConnectorSyncPolicies, upsertConnectorSyncPolicy } from "./connector-sync-policy-repository.js";
38
38
  import { getUserTrustPolicy, setUserTrustPolicy } from "./user-trust-repository.js";
39
- export { COMPOSER_INPUT_HISTORY_LIMIT, DatabaseSchemaMigrationGapError, DatabaseSchemaTooNewError, SCHEMA_META_SCHEMA_VERSION_KEY, XOPC_DB_BASELINE_SCHEMA_VERSION, XOPC_DB_FILENAME, XOPC_DB_SCHEMA_VERSION, acknowledgeHomeAttention, appendCompactionBoundaryIfUnchanged, appendComposerInputHistory, appendConnectorExecutionAudit, appendMemorySignal, appendMemoryTraceEvent, appendTranscriptEntry, applyPendingMigrations, attachMemoryEvidence, bindEndpointPrincipal, buildDefaultSessionMetadata, buildGlobalSessionStats, buildRelationshipPrompt, cancelQueuedSessionInput, claimConnectorWebhookDelivery, claimContextExtractionRun, claimKnowledgeSourceItems, claimNextConnectorLearningJob, claimNextSessionInput, classifyStoredRow, clearComposerInputHistory, closeTemporalAssertions, closeUnderstandingValidity, closeXopcDatabase, completeConnectorWebhookDelivery, completeKnowledgeSourceItemSynthesis, consumeConnectorApproval, consumeContextConsent, countKnowledgeSourceItems, countMemoryRecordsBySourceInstanceId, createCollaborationRule, createConnectorApproval, createContextEvidence, createEndpointPrincipal, createObjectLinkRecord, createTemporalAssertion, createUnderstanding, decideConnectorApproval, decideContextConsent, deleteCollaborationRule, deleteConnectorConnection, deleteConnectorInstallation, deleteKnowledgeSourceItems, deleteMemoryEvidenceForRecord, deleteMemoryRecord, deleteMemoryRecordsBySourceInstanceId, deleteNoteAgentContextRecord, deleteNoteRecord, deleteObjectLinkRecord, deleteSessionConfig, deleteSessionRecord, deleteUnderstanding, discoverSqlMigrations, enqueueConnectorLearningJob, ensureContextConsent, ensureSessionRecord, ensureXopcDatabaseSchema, estimateTokensFromMessages, extractFtsContent, findSessionInput, findSessionKeyBySessionId, finishContextConsolidationRun, finishContextExtractionRun, finishEndpointToolInvocationAudit, finishKnowledgeSyncRun, finishSessionInputRun, getActivityEventRecord, getCachedConnectorCatalogEntry, getCollaborationRule, getConnectorAccount, getConnectorApproval, getConnectorConnection, getConnectorInstallation, getConnectorSyncPolicy, getConnectorSyncPolicyForConnection, getContextConsolidationRun, getContextExtractionRun, getCurrentSessionId, getEndpointPrincipal, getGlobalSessionStats, getInteractionState, getKnowledgeConsumerWatermark, getKnowledgeSourceCursor, getKnowledgeSourceItem, getMemoryProviderState, getMemoryRecord, getMemoryTurnFeedback, getNoteAgentContextRecord, getNoteRecord, getRelationshipSettings, getSessionConfig, getSessionInputById, getSessionInputState, getSessionMetadata, getSessionPersistedLevels, getSessionTaskPlan, getSqliteDatabase, getTurnPersonalization, getUnderstanding, getUserPeopleIndexState, getUserPerson, getUserProfile, getUserTrustPolicy, getXopcDatabase, hasContextConsent, hasIndependentExtractionOutput, hasSessionConfig, hasUnresolvedMemoryConflict, incrementSessionStatsOnAppend, insertSessionInput, inspectSchemaMigrationStatus, isHomeAttentionAcknowledged, isProactiveSupportAllowed, isUnderstandingSuppressed, isXopcDatabaseOpen, linkContextObjects, linkUnderstandingEvidence, listActivityRecords, listCachedConnectorCatalogEntries, listCollaborationRules, listCompactionBoundaries, listComposerInputHistory, listConnectorAccounts, listConnectorActionMetadata, listConnectorApprovals, listConnectorConnections, listConnectorExecutionAudit, listConnectorInstallations, listConnectorLearningJobs, listConnectorSyncPolicies, listContextConsolidationDecisions, listContextConsolidationRuns, listContextExtractionOutputs, listContextExtractionRuns, listContextObjectRelations, listEndpointPrincipals, listEndpointToolInvocationAudits, listKnowledgeSourceChanges, listKnowledgeSourceItems, listKnowledgeSyncRuns, listMemoryEvidence, listMemoryRecords, listMemorySignals, listMemoryTraceEvents, listNoteRecords, listObjectActivityRecords, listObjectLinkRecords, listProjectActivityRecords, listRegisteredMigrationTargets, listSessionMetadata, listSessionsByAgent, listTemporalAssertions, listUnderstandingEvidence, listUnderstandings, listUserPeople, loadCompactionSourceSnapshot, loadLlmMessagesForSession, loadTranscriptHistoryRowsForSession, loadTranscriptRows, loadTranscriptRowsForSession, markMemoryRecordsConflicted, mergeUserPeople, metadataToSessionInsert, mutateQueuedSessionInput, openXopcDatabase, paginateTranscriptMessages, patchSessionMetadata, pruneBoundedKnowledgeSourceItems, readSchemaVersion, readSchemaVersionForTest, reconcileConnectorAccount, recordActivityEvent, recordContextConsolidationDecision, recordContextFeedback, recordContextRun, recoverSessionInputState, recoverStaleConnectorLearningJobs, refreshConnectorAccountCurrent, rejectUnderstanding, releaseConnectorWebhookDelivery, replaceConnectorCatalogEntries, replaceLatestSessionTurnAndQueueInput, replaceTranscriptRows, replaceUserPeopleIndex, requireXopcDatabase, resetSessionRecord, resetXopcDatabaseSingletonForTest, resolveMigrationsDir, resolveSessionAgentId, resolveXopcDatabasePath, restoreBeforeCompactionBoundary, reviseCollaborationRule, reviseUnderstanding, revokeEndpointPrincipal, runSqliteWriteTransaction, searchActiveUnderstandings, searchMemoryRecords, searchSessionTranscript, sessionConfigRowToConfig, sessionRowToMetadata, setCollaborationRuleStatus, setConnectorLearningPaused, setInteractionState, setKnowledgeConsumerWatermark, setKnowledgeSourceCursor, setKnowledgeSourceItemSynthesisStatus, setMemoryProviderState, setMemoryRecordStatus, setMemoryTurnFeedback, setSessionConfig, setSessionInputStatus, setSessionTaskPlan, setUnderstandingStatus, setUserTrustPolicy, startContextConsolidationRun, startEndpointToolInvocationAudit, startKnowledgeSyncRun, summarizeMemoryRecallFeedback, summarizeUnderstandingFeedback, summarizeUserPeople, summarizeUserUnderstandingQuality, touchEndpointPrincipal, transcriptEntryRowToStoredRow, updateConnectorLearningJob, updateInteractionStateFromMessage, updateRelationshipSettings, updateSessionConfig, updateSessionStats, updateUserPerson, updateUserProfile, upsertConnectorActionMetadata, upsertConnectorCatalogEntry, upsertConnectorConnection, upsertConnectorInstallation, upsertConnectorSyncPolicy, upsertKnowledgeSourceItems, upsertMemoryRecord, upsertNoteAgentContextRecord, upsertNoteRecord, validateLatestSessionTurnTarget };
39
+ export { COMPOSER_INPUT_HISTORY_LIMIT, DatabaseSchemaMigrationGapError, DatabaseSchemaTooNewError, SCHEMA_META_SCHEMA_VERSION_KEY, XOPC_DB_BASELINE_SCHEMA_VERSION, XOPC_DB_FILENAME, XOPC_DB_SCHEMA_VERSION, acknowledgeHomeAttention, appendCompactionBoundaryIfUnchanged, appendComposerInputHistory, appendConnectorExecutionAudit, appendMemorySignal, appendMemoryTraceEvent, appendTranscriptEntry, applyPendingMigrations, attachMemoryEvidence, bindEndpointPrincipal, buildDefaultSessionMetadata, buildGlobalSessionStats, buildRelationshipPrompt, cancelQueuedSessionInput, claimConnectorWebhookDelivery, claimContextExtractionRun, claimKnowledgeSourceItems, claimNextConnectorLearningJob, claimNextSessionInput, classifyStoredRow, clearComposerInputHistory, closeTemporalAssertions, closeUnderstandingValidity, closeXopcDatabase, completeConnectorWebhookDelivery, completeKnowledgeSourceItemSynthesis, consumeConnectorApproval, consumeContextConsent, countKnowledgeSourceItems, countMemoryRecordsBySourceInstanceId, createCollaborationRule, createConnectorApproval, createContextEvidence, createEndpointPrincipal, createObjectLinkRecord, createTemporalAssertion, createUnderstanding, decideConnectorApproval, decideContextConsent, deleteCollaborationRule, deleteConnectorConnection, deleteConnectorInstallation, deleteKnowledgeSourceItems, deleteMemoryEvidenceForRecord, deleteMemoryRecord, deleteMemoryRecordsBySourceInstanceId, deleteNoteAgentContextRecord, deleteNoteRecord, deleteObjectLinkRecord, deleteSessionConfig, deleteSessionRecord, deleteUnderstanding, discoverSqlMigrations, enqueueConnectorLearningJob, ensureContextConsent, ensureSessionRecord, ensureXopcDatabaseSchema, estimateTokensFromMessages, extractFtsContent, findSessionInput, findSessionKeyBySessionId, finishContextConsolidationRun, finishContextExtractionRun, finishEndpointToolInvocationAudit, finishKnowledgeSyncRun, finishSessionInputRun, getActivityEventRecord, getCachedConnectorCatalogEntry, getCollaborationRule, getConnectorAccount, getConnectorApproval, getConnectorConnection, getConnectorInstallation, getConnectorSyncPolicy, getConnectorSyncPolicyForConnection, getContextConsolidationRun, getContextExtractionRun, getCurrentSessionId, getEndpointPrincipal, getGlobalSessionStats, getInteractionState, getKnowledgeConsumerWatermark, getKnowledgeSourceCursor, getKnowledgeSourceItem, getMemoryProviderState, getMemoryRecord, getMemoryTurnFeedback, getNoteAgentContextRecord, getNoteRecord, getRelationshipSettings, getSessionConfig, getSessionInputById, getSessionInputState, getSessionMetadata, getSessionPersistedLevels, getSessionTaskPlan, getSqliteDatabase, getTurnPersonalization, getUnderstanding, getUserPeopleIndexState, getUserPerson, getUserProfile, getUserTrustPolicy, getXopcDatabase, hasContextConsent, hasIndependentExtractionOutput, hasSessionConfig, hasUnresolvedMemoryConflict, incrementSessionStatsOnAppend, insertSessionInput, inspectSchemaMigrationStatus, isHomeAttentionAcknowledged, isProactiveSupportAllowed, isUnderstandingSuppressed, isXopcDatabaseOpen, linkContextObjects, linkUnderstandingEvidence, listActiveSessionInputRuns, listActivityRecords, listCachedConnectorCatalogEntries, listCollaborationRules, listCompactionBoundaries, listComposerInputHistory, listConnectorAccounts, listConnectorActionMetadata, listConnectorApprovals, listConnectorConnections, listConnectorExecutionAudit, listConnectorInstallations, listConnectorLearningJobs, listConnectorSyncPolicies, listContextConsolidationDecisions, listContextConsolidationRuns, listContextExtractionOutputs, listContextExtractionRuns, listContextObjectRelations, listEndpointPrincipals, listEndpointToolInvocationAudits, listKnowledgeSourceChanges, listKnowledgeSourceItems, listKnowledgeSyncRuns, listMemoryEvidence, listMemoryRecords, listMemorySignals, listMemoryTraceEvents, listNoteRecords, listObjectActivityRecords, listObjectLinkRecords, listProjectActivityRecords, listRegisteredMigrationTargets, listSessionMetadata, listSessionsByAgent, listTemporalAssertions, listUnderstandingEvidence, listUnderstandingStatusEvents, listUnderstandings, listUserPeople, loadCompactionSourceSnapshot, loadLlmMessagesForSession, loadTranscriptHistoryRowsForSession, loadTranscriptRows, loadTranscriptRowsForSession, markMemoryRecordsConflicted, mergeUserPeople, metadataToSessionInsert, mutateQueuedSessionInput, openXopcDatabase, paginateTranscriptMessages, patchSessionMetadata, pruneBoundedKnowledgeSourceItems, readSchemaVersion, readSchemaVersionForTest, reconcileConnectorAccount, recordActivityEvent, recordContextConsolidationDecision, recordContextFeedback, recordContextRun, recoverSessionInputState, recoverStaleConnectorLearningJobs, refreshConnectorAccountCurrent, rejectUnderstanding, releaseConnectorWebhookDelivery, replaceConnectorCatalogEntries, replaceLatestSessionTurnAndQueueInput, replaceTranscriptRows, replaceUserPeopleIndex, requireXopcDatabase, resetSessionRecord, resetXopcDatabaseSingletonForTest, resolveMigrationsDir, resolveSessionAgentId, resolveXopcDatabasePath, restoreBeforeCompactionBoundary, reviseCollaborationRule, reviseUnderstanding, revokeEndpointPrincipal, runSqliteWriteTransaction, searchActiveUnderstandings, searchMemoryRecords, searchSessionTranscript, sessionConfigRowToConfig, sessionRowToMetadata, setCollaborationRuleStatus, setConnectorLearningPaused, setInteractionState, setKnowledgeConsumerWatermark, setKnowledgeSourceCursor, setKnowledgeSourceItemSynthesisStatus, setMemoryProviderState, setMemoryRecordStatus, setMemoryTurnFeedback, setSessionConfig, setSessionInputStatus, setSessionTaskPlan, setUnderstandingStatus, setUserTrustPolicy, startContextConsolidationRun, startEndpointToolInvocationAudit, startKnowledgeSyncRun, summarizeMemoryRecallFeedback, summarizeUnderstandingFeedback, summarizeUserPeople, summarizeUserUnderstandingQuality, touchEndpointPrincipal, transcriptEntryRowToStoredRow, updateConnectorLearningJob, updateInteractionStateFromMessage, updateRelationshipSettings, updateSessionConfig, updateSessionStats, updateUserPerson, updateUserProfile, upsertConnectorActionMetadata, upsertConnectorCatalogEntry, upsertConnectorConnection, upsertConnectorInstallation, upsertConnectorSyncPolicy, upsertKnowledgeSourceItems, upsertMemoryRecord, upsertNoteAgentContextRecord, upsertNoteRecord, validateLatestSessionTurnTarget };
@@ -0,0 +1,79 @@
1
+ CREATE TABLE notification_devices (
2
+ device_id TEXT PRIMARY KEY,
3
+ platform TEXT NOT NULL CHECK (platform IN ('ios', 'android')),
4
+ push_token TEXT NOT NULL,
5
+ push_provider TEXT NOT NULL DEFAULT 'expo',
6
+ enabled INTEGER NOT NULL DEFAULT 1 CHECK (enabled IN (0, 1)),
7
+ permissions TEXT NOT NULL DEFAULT 'unknown' CHECK (permissions IN ('granted', 'denied', 'unknown')),
8
+ preferences_json TEXT NOT NULL DEFAULT '{}',
9
+ locale TEXT NOT NULL DEFAULT 'en' CHECK (locale IN ('en', 'zh')),
10
+ app_version TEXT,
11
+ lease_expires_at INTEGER NOT NULL,
12
+ last_seen_at INTEGER NOT NULL,
13
+ created_at INTEGER NOT NULL,
14
+ updated_at INTEGER NOT NULL
15
+ );
16
+
17
+ INSERT INTO notification_devices (
18
+ device_id, platform, push_token, push_provider, enabled, permissions,
19
+ preferences_json, locale, app_version, lease_expires_at,
20
+ last_seen_at, created_at, updated_at
21
+ )
22
+ SELECT
23
+ device_id, platform, push_token, push_provider, enabled, permissions,
24
+ preferences_json, 'en', app_version,
25
+ (unixepoch() * 1000) + 604800000,
26
+ last_seen_at, created_at, updated_at
27
+ FROM mobile_devices;
28
+
29
+ CREATE UNIQUE INDEX idx_notification_devices_push_token
30
+ ON notification_devices(push_provider, push_token);
31
+ CREATE INDEX idx_notification_devices_delivery
32
+ ON notification_devices(enabled, permissions, lease_expires_at);
33
+
34
+ CREATE TABLE notification_events (
35
+ event_id TEXT PRIMARY KEY,
36
+ dedupe_key TEXT NOT NULL UNIQUE,
37
+ event_type TEXT NOT NULL,
38
+ target_json TEXT NOT NULL,
39
+ priority TEXT NOT NULL CHECK (priority IN ('normal', 'high')),
40
+ title_en TEXT NOT NULL,
41
+ title_zh TEXT NOT NULL,
42
+ body_en TEXT,
43
+ body_zh TEXT,
44
+ payload_json TEXT NOT NULL DEFAULT '{}',
45
+ created_at INTEGER NOT NULL
46
+ );
47
+
48
+ CREATE INDEX idx_notification_events_created
49
+ ON notification_events(created_at, event_id);
50
+
51
+ CREATE TABLE notification_deliveries (
52
+ event_id TEXT NOT NULL,
53
+ device_id TEXT NOT NULL,
54
+ status TEXT NOT NULL CHECK (status IN ('pending', 'accepted', 'delivered', 'dead')),
55
+ attempts INTEGER NOT NULL DEFAULT 0,
56
+ next_attempt_at INTEGER NOT NULL,
57
+ provider_ticket_id TEXT,
58
+ last_error TEXT,
59
+ updated_at INTEGER NOT NULL,
60
+ PRIMARY KEY (event_id, device_id),
61
+ FOREIGN KEY (event_id) REFERENCES notification_events(event_id) ON DELETE CASCADE,
62
+ FOREIGN KEY (device_id) REFERENCES notification_devices(device_id) ON DELETE CASCADE
63
+ );
64
+
65
+ CREATE INDEX idx_notification_deliveries_due
66
+ ON notification_deliveries(status, next_attempt_at);
67
+
68
+ CREATE TABLE notification_acknowledgements (
69
+ event_id TEXT NOT NULL,
70
+ consumer_id TEXT NOT NULL,
71
+ surface TEXT NOT NULL CHECK (surface IN ('web', 'electron', 'mobile')),
72
+ acknowledged_at INTEGER NOT NULL,
73
+ PRIMARY KEY (event_id, consumer_id),
74
+ FOREIGN KEY (event_id) REFERENCES notification_events(event_id) ON DELETE CASCADE
75
+ );
76
+
77
+ DROP TABLE mobile_activity_acknowledgements;
78
+ DROP TABLE mobile_activity_events;
79
+ DROP TABLE mobile_devices;
@@ -0,0 +1,71 @@
1
+ CREATE TABLE understanding_status_events (
2
+ event_id TEXT PRIMARY KEY,
3
+ understanding_id TEXT NOT NULL REFERENCES user_understandings(understanding_id) ON DELETE CASCADE,
4
+ from_status TEXT CHECK (from_status IS NULL OR from_status IN (
5
+ 'candidate', 'active', 'needs_review', 'stale', 'archived', 'rejected'
6
+ )),
7
+ to_status TEXT NOT NULL CHECK (to_status IN (
8
+ 'candidate', 'active', 'needs_review', 'stale', 'archived', 'rejected'
9
+ )),
10
+ actor_type TEXT NOT NULL CHECK (actor_type IN ('user', 'runtime', 'migration')),
11
+ source TEXT NOT NULL,
12
+ created_at INTEGER NOT NULL
13
+ );
14
+
15
+ CREATE INDEX idx_understanding_status_events_item
16
+ ON understanding_status_events(understanding_id, created_at DESC);
17
+
18
+ INSERT INTO understanding_status_events (
19
+ event_id, understanding_id, from_status, to_status, actor_type, source, created_at
20
+ )
21
+ SELECT
22
+ lower(hex(randomblob(16))), understanding_id, NULL, status, 'migration', 'status-audit-baseline', updated_at
23
+ FROM user_understandings;
24
+
25
+ INSERT INTO understanding_status_events (
26
+ event_id, understanding_id, from_status, to_status, actor_type, source, created_at
27
+ )
28
+ SELECT
29
+ lower(hex(randomblob(16))), u.understanding_id, u.status, 'needs_review', 'migration',
30
+ 'repair-untrusted-portrait-v1', CAST(strftime('%s', 'now') AS INTEGER) * 1000
31
+ FROM user_understandings u
32
+ JOIN user_understanding_versions v ON v.version_id = u.current_version_id
33
+ WHERE u.status = 'active'
34
+ AND (
35
+ u.canonical_key LIKE 'connected:%'
36
+ OR u.canonical_key LIKE 'connected-semantic:%'
37
+ OR (u.canonical_key LIKE 'work-discovery:%' AND v.created_by <> 'user')
38
+ OR EXISTS (
39
+ SELECT 1
40
+ FROM understanding_evidence_links l
41
+ JOIN context_evidence e ON e.evidence_id = l.evidence_id
42
+ WHERE l.version_id = u.current_version_id
43
+ AND e.extractor_id IN ('connector-structural', 'connector-semantic', 'explicit-command')
44
+ )
45
+ OR (u.kind = 'task_lesson' AND length(v.statement) > 240)
46
+ OR (u.kind = 'boundary' AND (
47
+ v.statement LIKE '%不要再问%'
48
+ OR v.statement LIKE '%直接执行%'
49
+ OR lower(v.statement) LIKE '%do not ask%'
50
+ OR lower(v.statement) LIKE '%just do it%'
51
+ ))
52
+ );
53
+
54
+ UPDATE user_understandings
55
+ SET status = 'needs_review',
56
+ updated_at = CAST(strftime('%s', 'now') AS INTEGER) * 1000
57
+ WHERE understanding_id IN (
58
+ SELECT understanding_id
59
+ FROM understanding_status_events
60
+ WHERE source = 'repair-untrusted-portrait-v1'
61
+ );
62
+
63
+ UPDATE context_temporal_assertions
64
+ SET status = 'candidate',
65
+ updated_at = CAST(strftime('%s', 'now') AS INTEGER) * 1000
66
+ WHERE object_type = 'understanding'
67
+ AND object_id IN (
68
+ SELECT understanding_id
69
+ FROM understanding_status_events
70
+ WHERE source = 'repair-untrusted-portrait-v1'
71
+ );
@@ -3,7 +3,7 @@ import type { ApplyMigrationsOptions } from './types.js';
3
3
  /** Baseline schema version applied from schema.sql on first open. */
4
4
  export declare const XOPC_DB_BASELINE_SCHEMA_VERSION = 11;
5
5
  /** Latest schema version this release supports (increment when adding migrations). */
6
- export declare const XOPC_DB_SCHEMA_VERSION = 135;
6
+ export declare const XOPC_DB_SCHEMA_VERSION = 137;
7
7
  export declare function resolveMigrationsDir(override?: string): string;
8
8
  /**
9
9
  * Apply sequential SQL migrations from (currentVersion + 1) through targetVersion.
@@ -12,7 +12,7 @@ const log = createLogger("Sqlite:Migrations");
12
12
  /** Baseline schema version applied from schema.sql on first open. */
13
13
  const XOPC_DB_BASELINE_SCHEMA_VERSION = 11;
14
14
  /** Latest schema version this release supports (increment when adding migrations). */
15
- const XOPC_DB_SCHEMA_VERSION = 135;
15
+ const XOPC_DB_SCHEMA_VERSION = 137;
16
16
  const MODULE_DIR = dirname(fileURLToPath(import.meta.url));
17
17
  function backupBeforeTaskCutover(db, databasePath) {
18
18
  db.exec("PRAGMA wal_checkpoint(FULL)");
@@ -57,7 +57,7 @@ function applySingleMigration(db, migration) {
57
57
  * Each step runs in its own transaction and updates schema_meta on success.
58
58
  */
59
59
  function applyPendingMigrations(db, options = {}) {
60
- const targetVersion = options.targetVersion ?? 135;
60
+ const targetVersion = options.targetVersion ?? 137;
61
61
  let currentVersion = readSchemaVersion(db);
62
62
  if (currentVersion > targetVersion) throw new DatabaseSchemaTooNewError(currentVersion, targetVersion);
63
63
  if (currentVersion >= targetVersion) return currentVersion;
@@ -94,7 +94,7 @@ function applyPendingMigrations(db, options = {}) {
94
94
  }
95
95
  /** Inspect schema version without mutating the database. */
96
96
  function inspectSchemaMigrationStatus(db, options = {}) {
97
- const appVersion = options.targetVersion ?? 135;
97
+ const appVersion = options.targetVersion ?? 137;
98
98
  const dbVersion = readSchemaVersion(db);
99
99
  if (dbVersion > appVersion) return {
100
100
  dbVersion,
@@ -19,7 +19,7 @@ const log = createLogger('Sqlite:Migrations');
19
19
  export const XOPC_DB_BASELINE_SCHEMA_VERSION = 11;
20
20
 
21
21
  /** Latest schema version this release supports (increment when adding migrations). */
22
- export const XOPC_DB_SCHEMA_VERSION = 135;
22
+ export const XOPC_DB_SCHEMA_VERSION = 137;
23
23
 
24
24
  const MODULE_DIR = dirname(fileURLToPath(import.meta.url));
25
25
 
@@ -32,7 +32,7 @@ function ensureXopcDatabaseSchema(db, options = {}) {
32
32
  currentVersion = 11;
33
33
  }
34
34
  applyPendingMigrations(db, {
35
- targetVersion: 135,
35
+ targetVersion: 137,
36
36
  databasePath: options.databasePath
37
37
  });
38
38
  }
@@ -31,6 +31,11 @@ export type SessionInputState = {
31
31
  inputs: SessionInput[];
32
32
  };
33
33
  export declare function getSessionInputState(sessionKey: string): SessionInputState;
34
+ /** Durable active webchat runs claimed by the session-input coordinator. */
35
+ export declare function listActiveSessionInputRuns(): Array<{
36
+ sessionKey: string;
37
+ runId: string;
38
+ }>;
34
39
  export declare function findSessionInput(sessionKey: string, clientMessageId: string): SessionInput | undefined;
35
40
  export declare function getSessionInputById(sessionKey: string, id: string): SessionInput | undefined;
36
41
  export declare function insertSessionInput(input: {
@@ -56,6 +56,14 @@ function getSessionInputState(sessionKey) {
56
56
  })
57
57
  };
58
58
  }
59
+ /** Durable active webchat runs claimed by the session-input coordinator. */
60
+ function listActiveSessionInputRuns() {
61
+ return getSqliteDatabase().prepare(`SELECT session_key, active_run_id
62
+ FROM session_input_runtime WHERE active_run_id IS NOT NULL`).all().map((row) => ({
63
+ sessionKey: row.session_key,
64
+ runId: row.active_run_id
65
+ }));
66
+ }
59
67
  function findSessionInput(sessionKey, clientMessageId) {
60
68
  const row = getSqliteDatabase().prepare(`${SELECT_INPUTS} WHERE session_key = ? AND client_message_id = ?`).get(sessionKey, clientMessageId);
61
69
  return row ? mapInput(row) : void 0;
@@ -158,4 +166,4 @@ function recoverSessionInputState() {
158
166
  });
159
167
  }
160
168
  //#endregion
161
- export { cancelQueuedSessionInput, claimNextSessionInput, findSessionInput, finishSessionInputRun, getSessionInputById, getSessionInputState, insertSessionInput, mutateQueuedSessionInput, recoverSessionInputState, setSessionInputStatus };
169
+ export { cancelQueuedSessionInput, claimNextSessionInput, findSessionInput, finishSessionInputRun, getSessionInputById, getSessionInputState, insertSessionInput, listActiveSessionInputRuns, mutateQueuedSessionInput, recoverSessionInputState, setSessionInputStatus };
@@ -1,4 +1,13 @@
1
1
  import { type CollaborationRule, type ContextEvidence, type PersonalizationItem, type UnderstandingStatus, type UserContextScope, type UserProfile, type UserUnderstanding } from '../../user-context/domain.js';
2
+ export type UnderstandingStatusEvent = {
3
+ id: string;
4
+ understandingId: string;
5
+ fromStatus?: UnderstandingStatus;
6
+ toStatus: UnderstandingStatus;
7
+ actorType: 'user' | 'runtime' | 'migration';
8
+ source: string;
9
+ createdAt: number;
10
+ };
2
11
  export declare function getUserProfile(principalId?: string): UserProfile;
3
12
  export declare function updateUserProfile(patch: Partial<Pick<UserProfile, 'callName' | 'role' | 'primaryGoal' | 'pronouns' | 'timezone' | 'locale' | 'accessibility'>>, principalId?: string): UserProfile;
4
13
  export type CreateUnderstandingInput = Omit<UserUnderstanding, 'id' | 'versionId' | 'createdAt' | 'updatedAt' | 'statement' | 'payload'> & {
@@ -21,12 +30,15 @@ export declare function reviseUnderstanding(id: string, statement: string, optio
21
30
  confidence?: number;
22
31
  changeReason: string;
23
32
  }): UserUnderstanding;
24
- export declare function setUnderstandingStatus(id: string, status: UnderstandingStatus, confirmation?: {
25
- explicitness: UserUnderstanding['explicitness'];
26
- confidence: number;
33
+ export declare function setUnderstandingStatus(id: string, status: UnderstandingStatus, options?: {
34
+ explicitness?: UserUnderstanding['explicitness'];
35
+ confidence?: number;
36
+ actorType?: UnderstandingStatusEvent['actorType'];
37
+ source?: string;
27
38
  }): UserUnderstanding;
28
39
  export declare function closeUnderstandingValidity(id: string, validTo?: number): UserUnderstanding;
29
- export declare function rejectUnderstanding(id: string, reason: string): UserUnderstanding;
40
+ export declare function rejectUnderstanding(id: string, reason: string, actorType?: UnderstandingStatusEvent['actorType']): UserUnderstanding;
41
+ export declare function listUnderstandingStatusEvents(id: string): UnderstandingStatusEvent[];
30
42
  export declare function deleteUnderstanding(id: string): boolean;
31
43
  export declare function isUnderstandingSuppressed(canonicalKey: string, scope: UserContextScope, principalId?: string): boolean;
32
44
  export declare function createCollaborationRule(input: Pick<CollaborationRule, 'category' | 'priority' | 'scope' | 'conditions' | 'statement'>, principalId?: string): CollaborationRule;
@@ -4,6 +4,11 @@ import { retrievalQueryAuditValue } from "../../retrieval/audit.js";
4
4
  import { buildFts5SearchQuery, fts5RankToScore } from "./fts.js";
5
5
  import { createHash, randomUUID } from "node:crypto";
6
6
  //#region src/storage/sqlite/user-context-repository.ts
7
+ function insertUnderstandingStatusEvent(db, input) {
8
+ db.prepare(`INSERT INTO understanding_status_events (
9
+ event_id, understanding_id, from_status, to_status, actor_type, source, created_at
10
+ ) VALUES (?, ?, ?, ?, ?, ?, ?)`).run(randomUUID(), input.understandingId, input.fromStatus ?? null, input.toStatus, input.actorType, input.source, input.createdAt);
11
+ }
7
12
  function evidenceFromRow(row) {
8
13
  return {
9
14
  id: row.evidence_id,
@@ -144,6 +149,13 @@ function createUnderstanding(input, principalId = USER_CONTEXT_PRINCIPAL_ID) {
144
149
  version_id, understanding_id, statement, payload_json, created_by, change_reason, created_at
145
150
  ) VALUES (?, ?, ?, ?, ?, ?, ?)`).run(versionId, id, input.statement.trim(), JSON.stringify(input.payload ?? {}), input.createdBy, input.changeReason, now);
146
151
  db.prepare("INSERT INTO user_understanding_fts (statement, understanding_id, version_id) VALUES (?, ?, ?)").run(input.statement.trim(), id, versionId);
152
+ insertUnderstandingStatusEvent(db, {
153
+ understandingId: id,
154
+ toStatus: input.status,
155
+ actorType: input.createdBy === "user" ? "user" : "runtime",
156
+ source: `create:${input.changeReason}`,
157
+ createdAt: now
158
+ });
147
159
  });
148
160
  return getUnderstanding(id);
149
161
  }
@@ -197,17 +209,29 @@ function reviseUnderstanding(id, statement, options) {
197
209
  });
198
210
  return getUnderstanding(id);
199
211
  }
200
- function setUnderstandingStatus(id, status, confirmation) {
212
+ function setUnderstandingStatus(id, status, options) {
213
+ const current = getUnderstanding(id);
214
+ if (!current) throw new Error(`User understanding not found: ${id}`);
201
215
  const now = Date.now();
202
- getSqliteDatabase().prepare(`UPDATE user_understandings
203
- SET status = ?,
204
- explicitness = COALESCE(?, explicitness),
205
- confidence = COALESCE(?, confidence),
206
- updated_at = ?
207
- WHERE understanding_id = ?`).run(status, confirmation?.explicitness ?? null, confirmation?.confidence ?? null, now, id);
208
- const assertionStatus = status === "active" ? "active" : status === "archived" ? "closed" : status === "rejected" ? "rejected" : "candidate";
209
- getSqliteDatabase().prepare(`UPDATE context_temporal_assertions
210
- SET status = ?, updated_at = ? WHERE object_type = 'understanding' AND object_id = ?`).run(assertionStatus, now, id);
216
+ runSqliteWriteTransaction((db) => {
217
+ db.prepare(`UPDATE user_understandings
218
+ SET status = ?,
219
+ explicitness = COALESCE(?, explicitness),
220
+ confidence = COALESCE(?, confidence),
221
+ updated_at = ?
222
+ WHERE understanding_id = ?`).run(status, options?.explicitness ?? null, options?.confidence ?? null, now, id);
223
+ const assertionStatus = status === "active" ? "active" : status === "archived" ? "closed" : status === "rejected" ? "rejected" : "candidate";
224
+ db.prepare(`UPDATE context_temporal_assertions
225
+ SET status = ?, updated_at = ? WHERE object_type = 'understanding' AND object_id = ?`).run(assertionStatus, now, id);
226
+ if (current.status !== status) insertUnderstandingStatusEvent(db, {
227
+ understandingId: id,
228
+ fromStatus: current.status,
229
+ toStatus: status,
230
+ actorType: options?.actorType ?? "runtime",
231
+ source: options?.source ?? "repository-status-change",
232
+ createdAt: now
233
+ });
234
+ });
211
235
  const result = getUnderstanding(id);
212
236
  if (!result) throw new Error(`User understanding not found: ${id}`);
213
237
  return result;
@@ -219,12 +243,20 @@ function closeUnderstandingValidity(id, validTo = Date.now()) {
219
243
  if (!result) throw new Error(`User understanding not found: ${id}`);
220
244
  return result;
221
245
  }
222
- function rejectUnderstanding(id, reason) {
246
+ function rejectUnderstanding(id, reason, actorType = "runtime") {
223
247
  const current = getUnderstanding(id);
224
248
  if (!current) throw new Error(`User understanding not found: ${id}`);
225
249
  const now = Date.now();
226
250
  runSqliteWriteTransaction((db) => {
227
251
  db.prepare("UPDATE user_understandings SET status = 'rejected', updated_at = ? WHERE understanding_id = ?").run(now, id);
252
+ if (current.status !== "rejected") insertUnderstandingStatusEvent(db, {
253
+ understandingId: id,
254
+ fromStatus: current.status,
255
+ toStatus: "rejected",
256
+ actorType,
257
+ source: reason,
258
+ createdAt: now
259
+ });
228
260
  db.prepare(`INSERT INTO context_suppressions (
229
261
  suppression_id, principal_id, canonical_key, scope_type, scope_id, reason, expires_at, created_at
230
262
  ) VALUES (?, ?, ?, ?, ?, ?, NULL, ?)
@@ -232,6 +264,18 @@ function rejectUnderstanding(id, reason) {
232
264
  });
233
265
  return getUnderstanding(id);
234
266
  }
267
+ function listUnderstandingStatusEvents(id) {
268
+ return getSqliteDatabase().prepare(`SELECT * FROM understanding_status_events
269
+ WHERE understanding_id = ? ORDER BY created_at DESC, rowid DESC`).all(id).map((row) => ({
270
+ id: row.event_id,
271
+ understandingId: row.understanding_id,
272
+ ...row.from_status ? { fromStatus: row.from_status } : {},
273
+ toStatus: row.to_status,
274
+ actorType: row.actor_type,
275
+ source: row.source,
276
+ createdAt: row.created_at
277
+ }));
278
+ }
235
279
  function deleteUnderstanding(id) {
236
280
  return runSqliteWriteTransaction((db) => {
237
281
  db.prepare("DELETE FROM user_understanding_fts WHERE understanding_id = ?").run(id);
@@ -442,4 +486,4 @@ function decideContextConsent(id, decision) {
442
486
  return Number(result.changes) > 0;
443
487
  }
444
488
  //#endregion
445
- export { closeUnderstandingValidity, consumeContextConsent, createCollaborationRule, createContextEvidence, createUnderstanding, decideContextConsent, deleteCollaborationRule, deleteUnderstanding, ensureContextConsent, getCollaborationRule, getTurnPersonalization, getUnderstanding, getUserProfile, hasContextConsent, isUnderstandingSuppressed, linkUnderstandingEvidence, listCollaborationRules, listUnderstandingEvidence, listUnderstandings, recordContextFeedback, recordContextRun, rejectUnderstanding, reviseCollaborationRule, reviseUnderstanding, searchActiveUnderstandings, setCollaborationRuleStatus, setUnderstandingStatus, updateUserProfile };
489
+ export { closeUnderstandingValidity, consumeContextConsent, createCollaborationRule, createContextEvidence, createUnderstanding, decideContextConsent, deleteCollaborationRule, deleteUnderstanding, ensureContextConsent, getCollaborationRule, getTurnPersonalization, getUnderstanding, getUserProfile, hasContextConsent, isUnderstandingSuppressed, linkUnderstandingEvidence, listCollaborationRules, listUnderstandingEvidence, listUnderstandingStatusEvents, listUnderstandings, recordContextFeedback, recordContextRun, rejectUnderstanding, reviseCollaborationRule, reviseUnderstanding, searchActiveUnderstandings, setCollaborationRuleStatus, setUnderstandingStatus, updateUserProfile };
@@ -1,12 +1,12 @@
1
1
  import { TaskRepository } from "./task-repository.js";
2
2
  import { TaskConversationConflictError, TaskConversationRepository } from "./task-conversation-repository.js";
3
+ import { enqueueTaskAttentionRequiredEvent, enqueueTaskChanged, enqueueTaskChangedEvent } from "./task-change-events.js";
3
4
  import { TaskRunRepository } from "./task-run-repository.js";
4
5
  import { TaskReadModelProjector } from "./task-read-model-projector.js";
5
6
  import { resolveExecutionContext } from "./execution-context.js";
6
7
  import { AttentionGovernor } from "./attention-governor.js";
7
8
  import { HomeQueryService, buildHomeWorkbench, decisionFromTask } from "./home-query-service.js";
8
9
  import { TaskContextRepository } from "./task-context-repository.js";
9
- import { enqueueTaskChanged, enqueueTaskChangedEvent } from "./task-change-events.js";
10
10
  import { TaskDependencyError, TaskDependencyService } from "./task-dependency-service.js";
11
11
  import { TaskApplicationService } from "./task-application-service.js";
12
12
  import { TaskWorkflowCoordinator } from "./task-workflow-coordinator.js";
@@ -22,4 +22,4 @@ import { TaskDeletionService } from "./task-deletion-service.js";
22
22
  import { TaskOutboxDispatcher } from "./task-outbox-dispatcher.js";
23
23
  import { TaskRunDispatcher } from "./task-run-dispatcher.js";
24
24
  import { TaskSignalService } from "./task-signal-service.js";
25
- export { AttentionGovernor, HomeQueryService, ModelTaskContractPlanner, ProjectMonitoringService, ProjectOperatingViewService, TaskApplicationService, TaskContextRepository, TaskConversationConflictError, TaskConversationRepository, TaskDeletionService, TaskDependencyError, TaskDependencyService, TaskHandoffService, TaskOutboxDispatcher, TaskReadModelProjector, TaskRepository, TaskRunCoordinator, TaskRunDispatcher, TaskRunRepository, TaskSignalService, TaskValueMetricsService, TaskWorkflowCoordinator, assembleTaskContext, buildHomeWorkbench, buildTaskExecutionDirective, decideProactiveDisposition, decisionFromTask, defineTaskContract, enqueueTaskChanged, enqueueTaskChangedEvent, getTaskContextManifest, getTaskExecutionBrief, isInQuietHours, nextQuietHoursEnd, parseTaskContractResponse, proactiveDispositionReason, resolveExecutionContext, summarizeProjectOperatingView };
25
+ export { AttentionGovernor, HomeQueryService, ModelTaskContractPlanner, ProjectMonitoringService, ProjectOperatingViewService, TaskApplicationService, TaskContextRepository, TaskConversationConflictError, TaskConversationRepository, TaskDeletionService, TaskDependencyError, TaskDependencyService, TaskHandoffService, TaskOutboxDispatcher, TaskReadModelProjector, TaskRepository, TaskRunCoordinator, TaskRunDispatcher, TaskRunRepository, TaskSignalService, TaskValueMetricsService, TaskWorkflowCoordinator, assembleTaskContext, buildHomeWorkbench, buildTaskExecutionDirective, decideProactiveDisposition, decisionFromTask, defineTaskContract, enqueueTaskAttentionRequiredEvent, enqueueTaskChanged, enqueueTaskChangedEvent, getTaskContextManifest, getTaskExecutionBrief, isInQuietHours, nextQuietHoursEnd, parseTaskContractResponse, proactiveDispositionReason, resolveExecutionContext, summarizeProjectOperatingView };
@@ -1,9 +1,9 @@
1
1
  import { getSqliteDatabase, runSqliteWriteTransaction } from "../storage/sqlite/transaction.js";
2
2
  import { TaskRepository } from "./task-repository.js";
3
+ import { enqueueTaskAttentionRequiredEvent, enqueueTaskChangedEvent } from "./task-change-events.js";
3
4
  import { TaskRunRepository } from "./task-run-repository.js";
4
5
  import { TaskReadModelProjector } from "./task-read-model-projector.js";
5
6
  import { TaskContextRepository } from "./task-context-repository.js";
6
- import { enqueueTaskChangedEvent } from "./task-change-events.js";
7
7
  import { TaskDependencyService } from "./task-dependency-service.js";
8
8
  import { createHash, randomUUID } from "node:crypto";
9
9
  //#region src/tasks/task-application-service.ts
@@ -153,6 +153,15 @@ var TaskApplicationService = class {
153
153
  ],
154
154
  actor
155
155
  });
156
+ else if (started.ok === false && started.reason === "blocked") {
157
+ if (!this.#runs.listActiveWaits(current.id).some((wait) => wait.kind === "approval" || wait.kind === "user_input")) enqueueTaskAttentionRequiredEvent(db, {
158
+ taskId: current.id,
159
+ taskTitle: current.title,
160
+ ...current.projectId ? { projectId: current.projectId } : {},
161
+ reason: "blocked",
162
+ correlationId: input.idempotencyKey
163
+ });
164
+ }
156
165
  return started;
157
166
  });
158
167
  }
@@ -275,11 +284,15 @@ var TaskApplicationService = class {
275
284
  }
276
285
  }
277
286
  if (result.ok === false) {
278
- if (result.reason === "blocked") this.enqueueEvent(db, "task.attention_required.v2", task.id, input.idempotencyKey, {
279
- taskId: task.id,
280
- reason: "blocked",
281
- projectId: task.projectId
282
- });
287
+ if (result.reason === "blocked") {
288
+ if (!this.#runs.listActiveWaits(task.id).some((wait) => wait.kind === "approval" || wait.kind === "user_input")) enqueueTaskAttentionRequiredEvent(db, {
289
+ taskId: task.id,
290
+ taskTitle: task.title,
291
+ ...task.projectId ? { projectId: task.projectId } : {},
292
+ reason: "blocked",
293
+ correlationId: input.idempotencyKey
294
+ });
295
+ }
283
296
  return result;
284
297
  }
285
298
  this.recordCommand(db, {
@@ -301,6 +314,10 @@ var TaskApplicationService = class {
301
314
  runId: result.runId
302
315
  });
303
316
  if (result.model.task.phase !== task.phase) this.enqueueEvent(db, "task.phase_changed.v2", task.id, input.idempotencyKey, {
317
+ task: {
318
+ id: result.model.task.id,
319
+ title: result.model.task.title
320
+ },
304
321
  taskId: task.id,
305
322
  from: task.phase,
306
323
  to: result.model.task.phase,
@@ -344,6 +361,14 @@ var TaskApplicationService = class {
344
361
  const task = this.#tasks.require(run.taskId);
345
362
  if (input.receipt.status !== "succeeded") {
346
363
  const model = this.#projector.project(task);
364
+ enqueueTaskAttentionRequiredEvent(db, {
365
+ taskId: task.id,
366
+ taskTitle: task.title,
367
+ ...task.projectId ? { projectId: task.projectId } : {},
368
+ reason: "failed",
369
+ detail: input.terminalMessage ?? input.receipt.summary,
370
+ correlationId: run.id
371
+ });
347
372
  enqueueTaskChangedEvent(db, {
348
373
  taskId: task.id,
349
374
  projectId: task.projectId,
@@ -370,6 +395,17 @@ var TaskApplicationService = class {
370
395
  ...phase === "closed" ? { resolution: "done" } : {}
371
396
  });
372
397
  if (!updated) throw new Error("Task changed while its run was being finalized");
398
+ this.enqueueEvent(db, "task.phase_changed.v2", updated.id, run.id, {
399
+ task: {
400
+ id: updated.id,
401
+ title: updated.title
402
+ },
403
+ taskId: updated.id,
404
+ from: task.phase,
405
+ to: updated.phase,
406
+ resolution: updated.resolution,
407
+ projectId: updated.projectId
408
+ });
373
409
  enqueueTaskChangedEvent(db, {
374
410
  taskId: updated.id,
375
411
  projectId: updated.projectId,
@@ -10,4 +10,13 @@ export type TaskChangeInput = {
10
10
  occurredAt?: number;
11
11
  };
12
12
  export declare function enqueueTaskChangedEvent(db: DatabaseSync, input: TaskChangeInput): void;
13
+ export declare function enqueueTaskAttentionRequiredEvent(db: DatabaseSync, input: {
14
+ taskId: string;
15
+ taskTitle: string;
16
+ projectId?: string;
17
+ reason: 'blocked' | 'failed' | 'user_input' | 'approval';
18
+ detail?: string;
19
+ correlationId: string;
20
+ occurredAt?: number;
21
+ }): void;
13
22
  export declare function enqueueTaskChanged(input: TaskChangeInput): void;
@@ -22,8 +22,24 @@ function enqueueTaskChangedEvent(db, input) {
22
22
  occurredAt
23
23
  }), occurredAt);
24
24
  }
25
+ function enqueueTaskAttentionRequiredEvent(db, input) {
26
+ const occurredAt = input.occurredAt ?? Date.now();
27
+ db.prepare(`INSERT INTO domain_outbox (
28
+ event_id, event_type, subject_kind, subject_id, correlation_id,
29
+ payload_json, created_at
30
+ ) VALUES (?, 'task.attention_required.v2', 'task', ?, ?, ?, ?)`).run(randomUUID(), input.taskId, input.correlationId, JSON.stringify({
31
+ task: {
32
+ id: input.taskId,
33
+ title: input.taskTitle
34
+ },
35
+ taskId: input.taskId,
36
+ reason: input.reason,
37
+ ...input.detail ? { detail: input.detail } : {},
38
+ ...input.projectId ? { projectId: input.projectId } : {}
39
+ }), occurredAt);
40
+ }
25
41
  function enqueueTaskChanged(input) {
26
42
  runSqliteWriteTransaction((db) => enqueueTaskChangedEvent(db, input));
27
43
  }
28
44
  //#endregion
29
- export { enqueueTaskChanged, enqueueTaskChangedEvent };
45
+ export { enqueueTaskAttentionRequiredEvent, enqueueTaskChanged, enqueueTaskChangedEvent };
@@ -10,10 +10,14 @@ var TaskOutboxDispatcher = class {
10
10
  ORDER BY created_at, event_id LIMIT ?`).all(Math.max(1, Math.min(500, Math.floor(limit))));
11
11
  let published = 0;
12
12
  for (const row of rows) try {
13
+ const payload = JSON.parse(row.payload_json);
13
14
  this.publish({
14
15
  type: row.event_type,
15
16
  source: "tasks",
16
- payload: JSON.parse(row.payload_json),
17
+ payload: {
18
+ ...payload,
19
+ sourceEventId: row.event_id
20
+ },
17
21
  occurredAtMs: row.created_at
18
22
  });
19
23
  runSqliteWriteTransaction((db) => {
@@ -2,12 +2,14 @@ import { createLogger } from "../utils/logger/index.js";
2
2
  import { init_logger } from "../utils/logger.js";
3
3
  import { TaskRepository } from "./task-repository.js";
4
4
  import { TaskRunRepository } from "./task-run-repository.js";
5
+ import { TaskApplicationService } from "./task-application-service.js";
5
6
  //#region src/tasks/task-run-dispatcher.ts
6
7
  init_logger();
7
8
  const log = createLogger("TaskRunDispatcher");
8
9
  var TaskRunDispatcher = class {
9
10
  #runs = new TaskRunRepository();
10
11
  #tasks = new TaskRepository();
12
+ #application = new TaskApplicationService();
11
13
  #draining = /* @__PURE__ */ new Set();
12
14
  constructor(deps) {
13
15
  this.deps = deps;
@@ -49,9 +51,9 @@ var TaskRunDispatcher = class {
49
51
  "running",
50
52
  "waiting",
51
53
  "verifying"
52
- ].includes(current.status)) this.#runs.finalize({
54
+ ].includes(current.status)) this.#application.completeRun({
53
55
  runId: current.id,
54
- expectedVersion: current.version,
56
+ expectedRunVersion: current.version,
55
57
  terminalCode: "dispatch_failed",
56
58
  terminalMessage: error instanceof Error ? error.message : String(error),
57
59
  receipt: {