@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,278 +0,0 @@
1
- import { listKnowledgeSourceItems } from "../storage/sqlite/knowledge-repository.js";
2
- import "../storage/sqlite/index.js";
3
- import { clusterUnderstandingSignals } from "../user-context/sources/signal-clustering.js";
4
- import { personIdForIdentity, personIdentityKey, rebuildUserPeopleIndex } from "../user-context/relationships/indexer.js";
5
- //#region src/knowledge/connected-understanding-pipeline.ts
6
- function logicalEventKey(item) {
7
- const value = item.metadata.logicalEventKey;
8
- return typeof value === "string" && value.trim() ? value.trim() : void 0;
9
- }
10
- function eventTime(item) {
11
- if (!item.occurredAt) return void 0;
12
- const value = Date.parse(item.occurredAt);
13
- return Number.isFinite(value) ? value : void 0;
14
- }
15
- function normalizedRecord(item) {
16
- if (!item.normalizedText) return {};
17
- try {
18
- const value = JSON.parse(item.normalizedText);
19
- return value && typeof value === "object" && !Array.isArray(value) ? value : {};
20
- } catch {
21
- return {};
22
- }
23
- }
24
- function textField(record, ...fields) {
25
- for (const field of fields) {
26
- const value = record[field];
27
- if (typeof value === "string" && value.trim()) return value.trim();
28
- if (value && typeof value === "object" && !Array.isArray(value)) {
29
- const nested = value;
30
- for (const nestedField of [
31
- "name",
32
- "full_name",
33
- "fullName",
34
- "title"
35
- ]) {
36
- const nestedValue = nested[nestedField];
37
- if (typeof nestedValue === "string" && nestedValue.trim()) return nestedValue.trim();
38
- }
39
- }
40
- }
41
- }
42
- function normalizeConversationTitle(value) {
43
- return value.replace(/^(?:(?:re|fwd?|回复|转发)\s*[::]\s*)+/i, "").trim();
44
- }
45
- function projectSignal(item) {
46
- if (item.metadata.actorAttributed !== true) return void 0;
47
- const observationKind = item.metadata.observationKind;
48
- if (![
49
- "activity",
50
- "message",
51
- "calendar_event",
52
- "external_task",
53
- "document_metadata"
54
- ].includes(String(observationKind))) return;
55
- const title = textField(normalizedRecord(item), "subject", "title", "repository", "project", "fullName", "full_name", "name");
56
- const subjectKey = typeof item.metadata.subjectKey === "string" && item.metadata.subjectKey.trim() ? item.metadata.subjectKey.trim() : void 0;
57
- const displayTitle = title ? normalizeConversationTitle(title) : subjectKey;
58
- if (!displayTitle) return void 0;
59
- return {
60
- evidenceRef: item.id,
61
- sourceId: item.sourceInstanceId,
62
- title: displayTitle,
63
- group: typeof item.metadata.toolkit === "string" ? item.metadata.toolkit : void 0,
64
- subjectKey,
65
- occurredAt: eventTime(item)
66
- };
67
- }
68
- function recent(items, days) {
69
- const now = Date.now();
70
- const cutoff = now - days * 864e5;
71
- return items.filter((item) => {
72
- const time = eventTime(item);
73
- return time !== void 0 && time >= cutoff && time <= now + 3e5 && logicalEventKey(item);
74
- });
75
- }
76
- function person(value) {
77
- if (!value || typeof value !== "object" || Array.isArray(value)) return void 0;
78
- const row = value;
79
- const read = (field) => typeof row[field] === "string" && row[field].trim() ? row[field].trim().slice(0, 160) : void 0;
80
- const result = {
81
- name: read("name"),
82
- email: read("email"),
83
- username: read("username")
84
- };
85
- return result.name || result.email || result.username ? result : void 0;
86
- }
87
- function relationshipObservations(items) {
88
- const grouped = /* @__PURE__ */ new Map();
89
- for (const item of recent(items, 90)) {
90
- if (item.metadata.actorAttributed !== true) continue;
91
- const owners = new Set(Array.isArray(item.metadata.ownerIdentities) ? item.metadata.ownerIdentities.filter((value) => typeof value === "string").map((value) => value.toLowerCase()) : []);
92
- const values = item.metadata.personEntities;
93
- if (!Array.isArray(values)) continue;
94
- for (const value of values) {
95
- const signal = person(value);
96
- if (!signal) continue;
97
- const strongIdentity = (signal.email ?? signal.username)?.toLowerCase();
98
- if (strongIdentity && owners.has(strongIdentity)) continue;
99
- const label = signal.name ?? signal.email ?? signal.username;
100
- const identityKey = personIdentityKey(signal, item.sourceInstanceId);
101
- const personId = personIdForIdentity(signal, item.sourceInstanceId);
102
- if (!identityKey || !personId) continue;
103
- const entry = grouped.get(identityKey) ?? {
104
- label,
105
- personId,
106
- events: /* @__PURE__ */ new Map()
107
- };
108
- const eventKey = logicalEventKey(item);
109
- if (!entry.events.has(eventKey)) entry.events.set(eventKey, item);
110
- grouped.set(identityKey, entry);
111
- }
112
- }
113
- return [...grouped.values()].sort((left, right) => right.events.size - left.events.size).slice(0, 8).map((entry) => ({
114
- class: "relationship",
115
- key: `person:${entry.personId}`,
116
- value: {
117
- label: entry.label,
118
- personId: entry.personId
119
- },
120
- items: [...entry.events.values()],
121
- windowDays: 90
122
- }));
123
- }
124
- function routineObservations(items) {
125
- const slots = /* @__PURE__ */ new Map();
126
- for (const item of recent(items, 120).filter((candidate) => candidate.itemType === "calendar_event")) {
127
- const date = new Date(item.occurredAt);
128
- const slot = `${date.getUTCDay()}:${date.getUTCHours()}`;
129
- const events = slots.get(slot) ?? /* @__PURE__ */ new Map();
130
- const eventKey = logicalEventKey(item);
131
- if (!events.has(eventKey)) events.set(eventKey, item);
132
- slots.set(slot, events);
133
- }
134
- return [...slots.entries()].sort((left, right) => right[1].size - left[1].size).slice(0, 4).map(([slot, events]) => {
135
- const [weekday, hour] = slot.split(":").map(Number);
136
- return {
137
- class: "routine",
138
- key: `calendar-slot:${slot}`,
139
- value: {
140
- weekday,
141
- hour,
142
- timezone: "UTC"
143
- },
144
- items: [...events.values()],
145
- windowDays: 120
146
- };
147
- });
148
- }
149
- function projectObservations(items) {
150
- const recentItems = recent(items, 60);
151
- const byId = new Map(recentItems.map((item) => [item.id, item]));
152
- return clusterUnderstandingSignals(recentItems.map(projectSignal).filter((signal) => Boolean(signal))).flatMap((cluster) => {
153
- const events = /* @__PURE__ */ new Map();
154
- for (const signal of cluster.signals) {
155
- const item = byId.get(signal.evidenceRef);
156
- const eventKey = item && logicalEventKey(item);
157
- if (item && eventKey && !events.has(eventKey)) events.set(eventKey, item);
158
- }
159
- if (![...events.values()].some((item) => item.itemType !== "calendar_event")) return [];
160
- return [{
161
- class: "project",
162
- key: `project:${cluster.key}`,
163
- value: { label: cluster.title },
164
- items: [...events.values()],
165
- windowDays: 60
166
- }];
167
- }).sort((left, right) => right.items.length - left.items.length).slice(0, 8);
168
- }
169
- function deriveConnectedClaimObservations(items) {
170
- const active = items.filter((item) => !item.deletedAt && item.synthesisPipeline === "connected_knowledge" && item.sensitivity !== "secret" && item.sensitivity !== "regulated" && item.metadata.observationKind !== "inventory");
171
- return [
172
- ...relationshipObservations(active),
173
- ...routineObservations(active),
174
- ...projectObservations(active)
175
- ];
176
- }
177
- function confidenceFor(observation) {
178
- const days = new Set(observation.items.map((item) => item.occurredAt?.slice(0, 10)).filter(Boolean)).size;
179
- return Math.min(.92, .48 + Math.min(observation.items.length, 8) * .035 + Math.min(days, 5) * .045);
180
- }
181
- function isDurableObservation(observation) {
182
- const days = new Set(observation.items.map((item) => item.occurredAt?.slice(0, 10)).filter(Boolean)).size;
183
- return observation.items.length >= 3 && days >= (observation.class === "routine" ? 3 : 2);
184
- }
185
- function renderConnectedObservation(observation) {
186
- const label = typeof observation.value.label === "string" ? observation.value.label : "";
187
- const confidence = confidenceFor(observation);
188
- if (observation.class === "relationship") return {
189
- kind: "relationship",
190
- content: `Frequently collaborates with ${label}.`,
191
- canonicalKey: `connected:${observation.key}`,
192
- payload: typeof observation.value.personId === "string" ? { personId: observation.value.personId } : void 0,
193
- confidence,
194
- importance: .65,
195
- explicitness: "inferred",
196
- durability: "recurring",
197
- sensitivity: "personal",
198
- disclosurePolicy: "ask_before_reference"
199
- };
200
- if (observation.class === "project") return {
201
- kind: "project_context",
202
- content: `Recently contributed repeatedly to ${label}.`,
203
- canonicalKey: `connected:${observation.key}`,
204
- confidence,
205
- importance: .72,
206
- explicitness: "inferred",
207
- durability: "recurring",
208
- sensitivity: "personal",
209
- disclosurePolicy: "referenceable"
210
- };
211
- const weekday = Number(observation.value.weekday);
212
- const hour = Number(observation.value.hour);
213
- return {
214
- kind: "routine",
215
- content: `Often has calendar activity on ${[
216
- "Sunday",
217
- "Monday",
218
- "Tuesday",
219
- "Wednesday",
220
- "Thursday",
221
- "Friday",
222
- "Saturday"
223
- ][weekday] ?? "Unknown"} around ${String(hour).padStart(2, "0")}:00 UTC.`,
224
- canonicalKey: `connected:${observation.key}`,
225
- confidence,
226
- importance: .58,
227
- explicitness: "inferred",
228
- durability: "recurring",
229
- sensitivity: "personal",
230
- disclosurePolicy: "referenceable"
231
- };
232
- }
233
- var ConnectedUnderstandingPipeline = class {
234
- constructor(memoryManager) {
235
- this.memoryManager = memoryManager;
236
- }
237
- async process(agentId, extractionRunId) {
238
- rebuildUserPeopleIndex();
239
- const observations = deriveConnectedClaimObservations(listKnowledgeSourceItems({
240
- agentId,
241
- includeDeleted: false,
242
- limit: 500
243
- }));
244
- const totals = {
245
- proposed: observations.length,
246
- created: 0,
247
- deduplicated: 0,
248
- rejected: 0,
249
- createdRecords: []
250
- };
251
- for (const observation of observations) {
252
- if (!isDurableObservation(observation)) continue;
253
- const sourceInstanceIds = [...new Set(observation.items.map((item) => item.sourceInstanceId))];
254
- const result = await this.memoryManager.applyUnderstandingCandidates([renderConnectedObservation(observation)], {
255
- sourceItemIds: observation.items.map((item) => item.id).slice(0, 20),
256
- sourceText: JSON.stringify({
257
- independentEvidenceCount: observation.items.length,
258
- activeDays: new Set(observation.items.map((item) => item.occurredAt?.slice(0, 10))).size,
259
- windowDays: observation.windowDays
260
- }),
261
- source: {
262
- provider: "connected-sources",
263
- ...sourceInstanceIds.length === 1 ? { sourceInstanceId: sourceInstanceIds[0] } : {}
264
- },
265
- reviewSource: "background",
266
- extractionRunId
267
- });
268
- totals.created += result.created;
269
- totals.deduplicated += result.deduplicated;
270
- totals.rejected += result.rejected;
271
- totals.createdRecords.push(...result.createdRecords);
272
- totals.writeOutputs = [...totals.writeOutputs ?? [], ...result.writeOutputs ?? []];
273
- }
274
- return totals;
275
- }
276
- };
277
- //#endregion
278
- export { ConnectedUnderstandingPipeline, deriveConnectedClaimObservations, renderConnectedObservation };
@@ -1,9 +0,0 @@
1
- import type { MobileActivityEvent } from './notification-types.js';
2
- /** Converts gateway domain events into a portable mobile activity and push payload. */
3
- export declare function mobileNotificationEventFromGatewayEvent(type: string, payload: unknown): Omit<MobileActivityEvent, 'id' | 'createdAt'> | null;
4
- export declare class MobileNotificationService {
5
- private readonly sent;
6
- handleGatewayEvent(type: string, payload: unknown): void;
7
- deliverGatewayEvent(type: string, payload: unknown): Promise<void>;
8
- private deliver;
9
- }
@@ -1,156 +0,0 @@
1
- import { createLogger } from "../utils/logger/index.js";
2
- import { init_logger } from "../utils/logger.js";
3
- import { createMobileActivityEvent, disableMobileDeviceForPushToken, listEnabledMobileDevices } from "./notification-store.js";
4
- //#region src/mobile/notification-service.ts
5
- init_logger();
6
- const log = createLogger("MobileNotifications");
7
- const EXPO_PUSH_URL = "https://exp.host/--/api/v2/push/send";
8
- function shouldDeliver(type, preferences) {
9
- if (type === "task.needs_input") return preferences.needsInput;
10
- if (type === "task.blocked") return preferences.failed;
11
- if (type === "automation.failed") return preferences.automationFailed;
12
- if (type === "proactive.insight") return preferences.needsInput;
13
- return preferences.completed;
14
- }
15
- function taskEvent(payload) {
16
- if (!payload || typeof payload !== "object") return null;
17
- const data = payload;
18
- const task = data.task;
19
- const taskId = typeof task?.id === "string" ? task.id : typeof data.taskId === "string" ? data.taskId : "";
20
- if (!taskId) return null;
21
- const type = data.reason === "blocked" ? "task.blocked" : typeof data.reason === "string" ? "task.needs_input" : data.to === "closed" && data.resolution === "done" ? "task.completed" : void 0;
22
- if (!type) return null;
23
- const route = `/tasks/${encodeURIComponent(taskId)}`;
24
- return {
25
- type,
26
- entity: {
27
- kind: "task",
28
- id: taskId
29
- },
30
- priority: type === "task.needs_input" || type === "task.blocked" ? "high" : "normal",
31
- title: type === "task.needs_input" ? "Action needed" : type === "task.blocked" ? "Task blocked" : "Task completed",
32
- body: typeof task?.title === "string" ? task.title.slice(0, 120) : void 0,
33
- deepLink: route,
34
- payload: {
35
- route,
36
- taskId,
37
- eventType: type
38
- }
39
- };
40
- }
41
- function automationEvent(payload) {
42
- if (!payload || typeof payload !== "object") return null;
43
- const event = payload;
44
- if (event.notificationPolicy === "none") return null;
45
- if (event.notificationPolicy === "attention" && event.requiresAttention !== true) return null;
46
- const run = event.run;
47
- if (!run || run.status !== "failed" && run.status !== "timeout" && run.status !== "succeeded") return null;
48
- const type = run.status === "succeeded" ? "automation.completed" : "automation.failed";
49
- const route = `/automations?automation=${encodeURIComponent(run.automationId)}&run=${encodeURIComponent(run.id)}`;
50
- return {
51
- type,
52
- entity: {
53
- kind: "automation",
54
- id: run.automationId
55
- },
56
- priority: type === "automation.failed" ? "high" : "normal",
57
- title: type === "automation.failed" ? "Automation failed" : "Automation completed",
58
- body: run.automationName.slice(0, 120),
59
- deepLink: route,
60
- payload: {
61
- route,
62
- automationId: run.automationId,
63
- runId: run.id,
64
- eventType: type
65
- }
66
- };
67
- }
68
- function proactiveInsightEvent(payload) {
69
- if (!payload || typeof payload !== "object") return null;
70
- const item = payload;
71
- if (typeof item.id !== "string" || typeof item.insight?.id !== "string" || typeof item.insight.title !== "string") return null;
72
- const route = `/inbox?item=${encodeURIComponent(item.id)}`;
73
- return {
74
- type: "proactive.insight",
75
- entity: {
76
- kind: "insight",
77
- id: item.insight.id
78
- },
79
- priority: item.insight.urgency === "high" || item.insight.urgency === "critical" ? "high" : "normal",
80
- title: item.insight.title.slice(0, 120),
81
- body: typeof item.insight.summary === "string" ? item.insight.summary.slice(0, 180) : void 0,
82
- deepLink: route,
83
- payload: {
84
- route,
85
- inboxItemId: item.id,
86
- eventType: "proactive.insight"
87
- }
88
- };
89
- }
90
- /** Converts gateway domain events into a portable mobile activity and push payload. */
91
- function mobileNotificationEventFromGatewayEvent(type, payload) {
92
- if (type === "task.attention_required.v2" || type === "task.phase_changed.v2") return taskEvent(payload);
93
- if (type === "automation.run.completed") return automationEvent(payload);
94
- if (type === "proactive.inbox.created") return proactiveInsightEvent(payload);
95
- return null;
96
- }
97
- async function sendExpoPush(token, event) {
98
- const response = await fetch(EXPO_PUSH_URL, {
99
- method: "POST",
100
- headers: {
101
- "content-type": "application/json",
102
- accept: "application/json"
103
- },
104
- body: JSON.stringify({
105
- to: token,
106
- title: event.title,
107
- body: event.body,
108
- sound: event.priority === "high" ? "default" : void 0,
109
- priority: event.priority,
110
- data: {
111
- eventId: event.id,
112
- ...event.payload
113
- }
114
- })
115
- });
116
- if (!response.ok) throw new Error(`Expo push request failed (${response.status})`);
117
- const result = await response.json().catch(() => null);
118
- const item = Array.isArray(result?.data) ? result?.data[0] : result?.data;
119
- if (item?.status === "error") {
120
- if (item.details?.error === "DeviceNotRegistered") {
121
- disableMobileDeviceForPushToken(token);
122
- return;
123
- }
124
- throw new Error(`Expo push rejected: ${item.details?.error ?? "unknown error"}`);
125
- }
126
- }
127
- var MobileNotificationService = class {
128
- sent = /* @__PURE__ */ new Set();
129
- handleGatewayEvent(type, payload) {
130
- this.deliverGatewayEvent(type, payload).catch((err) => {
131
- log.warn({
132
- err,
133
- eventType: type
134
- }, "Mobile notification delivery failed");
135
- });
136
- }
137
- async deliverGatewayEvent(type, payload) {
138
- const event = mobileNotificationEventFromGatewayEvent(type, payload);
139
- if (!event) return;
140
- const dedupeKey = `${event.type}:${event.entity.kind}:${event.entity.id}:${JSON.stringify(event.payload)}`;
141
- if (this.sent.has(dedupeKey)) return;
142
- this.sent.add(dedupeKey);
143
- try {
144
- await this.deliver(event);
145
- } finally {
146
- this.sent.delete(dedupeKey);
147
- }
148
- }
149
- async deliver(input) {
150
- const event = createMobileActivityEvent(input);
151
- const devices = listEnabledMobileDevices().filter((device) => shouldDeliver(event.type, device.preferences));
152
- await Promise.all(devices.map((device) => sendExpoPush(device.pushToken, event)));
153
- }
154
- };
155
- //#endregion
156
- export { MobileNotificationService, mobileNotificationEventFromGatewayEvent };
@@ -1,28 +0,0 @@
1
- import { type MobileActivityEvent, type MobileDevice, type MobileNotificationPermission, type MobileNotificationPreferences, type MobilePlatform } from './notification-types.js';
2
- export type RegisterMobileDeviceInput = {
3
- id: string;
4
- platform: MobilePlatform;
5
- pushToken: string;
6
- permissions: MobileNotificationPermission;
7
- preferences?: Partial<MobileNotificationPreferences>;
8
- appVersion?: string;
9
- };
10
- export declare function registerMobileDevice(input: RegisterMobileDeviceInput): MobileDevice;
11
- export declare function getMobileDevice(deviceId: string): MobileDevice | null;
12
- export declare function listEnabledMobileDevices(): MobileDevice[];
13
- export declare function updateMobileDevicePreferences(deviceId: string, patch: Partial<MobileNotificationPreferences>): MobileDevice | null;
14
- export declare function removeMobileDevice(deviceId: string): boolean;
15
- export declare function disableMobileDeviceForPushToken(pushToken: string): void;
16
- export type CreateMobileActivityEventInput = Omit<MobileActivityEvent, 'id' | 'createdAt'> & {
17
- id?: string;
18
- createdAt?: number;
19
- };
20
- export declare function createMobileActivityEvent(input: CreateMobileActivityEventInput): MobileActivityEvent;
21
- export declare function listMobileActivityEvents(options?: {
22
- cursor?: number;
23
- limit?: number;
24
- }): {
25
- items: MobileActivityEvent[];
26
- nextCursor: number | null;
27
- };
28
- export declare function acknowledgeMobileActivityEvent(eventId: string, deviceId: string): boolean;
@@ -1,132 +0,0 @@
1
- import { getSqliteDatabase, runSqliteWriteTransaction } from "../storage/sqlite/transaction.js";
2
- import { DEFAULT_MOBILE_NOTIFICATION_PREFERENCES } from "./notification-types.js";
3
- import { randomUUID } from "node:crypto";
4
- //#region src/mobile/notification-store.ts
5
- function parseJson(raw, fallback) {
6
- try {
7
- return JSON.parse(raw);
8
- } catch {
9
- return fallback;
10
- }
11
- }
12
- function normalizePreferences(input) {
13
- return {
14
- needsInput: input?.needsInput ?? DEFAULT_MOBILE_NOTIFICATION_PREFERENCES.needsInput,
15
- failed: input?.failed ?? DEFAULT_MOBILE_NOTIFICATION_PREFERENCES.failed,
16
- completed: input?.completed ?? DEFAULT_MOBILE_NOTIFICATION_PREFERENCES.completed,
17
- automationFailed: input?.automationFailed ?? DEFAULT_MOBILE_NOTIFICATION_PREFERENCES.automationFailed
18
- };
19
- }
20
- function deviceFromRow(row) {
21
- return {
22
- id: row.device_id,
23
- platform: row.platform === "android" ? "android" : "ios",
24
- pushToken: row.push_token,
25
- enabled: row.enabled !== 0,
26
- permissions: row.permissions === "granted" || row.permissions === "denied" ? row.permissions : "unknown",
27
- preferences: normalizePreferences(parseJson(row.preferences_json, {})),
28
- appVersion: row.app_version ?? void 0,
29
- lastSeenAt: row.last_seen_at,
30
- createdAt: row.created_at,
31
- updatedAt: row.updated_at
32
- };
33
- }
34
- function activityFromRow(row) {
35
- return {
36
- id: row.event_id,
37
- type: row.event_type,
38
- entity: {
39
- kind: row.entity_kind,
40
- id: row.entity_id
41
- },
42
- priority: row.priority,
43
- title: row.title,
44
- body: row.body ?? void 0,
45
- deepLink: row.deep_link,
46
- payload: parseJson(row.payload_json, {}),
47
- createdAt: row.created_at
48
- };
49
- }
50
- function registerMobileDevice(input) {
51
- const now = Date.now();
52
- const preferences = input.preferences ? normalizePreferences(input.preferences) : getMobileDevice(input.id)?.preferences ?? normalizePreferences();
53
- runSqliteWriteTransaction((db) => {
54
- db.prepare(`DELETE FROM mobile_devices
55
- WHERE push_provider = 'expo' AND push_token = ? AND device_id <> ?`).run(input.pushToken, input.id);
56
- db.prepare(`INSERT INTO mobile_devices (
57
- device_id, platform, push_token, permissions, preferences_json,
58
- app_version, last_seen_at, created_at, updated_at
59
- ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)
60
- ON CONFLICT(device_id) DO UPDATE SET
61
- platform = excluded.platform,
62
- push_token = excluded.push_token,
63
- enabled = 1,
64
- permissions = excluded.permissions,
65
- preferences_json = excluded.preferences_json,
66
- app_version = excluded.app_version,
67
- last_seen_at = excluded.last_seen_at,
68
- updated_at = excluded.updated_at`).run(input.id, input.platform, input.pushToken, input.permissions, JSON.stringify(preferences), input.appVersion?.trim() || null, now, now, now);
69
- });
70
- return getMobileDevice(input.id);
71
- }
72
- function getMobileDevice(deviceId) {
73
- const row = getSqliteDatabase().prepare(`SELECT * FROM mobile_devices WHERE device_id = ?`).get(deviceId);
74
- return row ? deviceFromRow(row) : null;
75
- }
76
- function listEnabledMobileDevices() {
77
- return getSqliteDatabase().prepare(`SELECT * FROM mobile_devices WHERE enabled = 1 AND permissions = 'granted' ORDER BY updated_at DESC`).all().map(deviceFromRow);
78
- }
79
- function updateMobileDevicePreferences(deviceId, patch) {
80
- const current = getMobileDevice(deviceId);
81
- if (!current) return null;
82
- const preferences = normalizePreferences({
83
- ...current.preferences,
84
- ...patch
85
- });
86
- runSqliteWriteTransaction((db) => {
87
- db.prepare(`UPDATE mobile_devices SET preferences_json = ?, updated_at = ? WHERE device_id = ?`).run(JSON.stringify(preferences), Date.now(), deviceId);
88
- });
89
- return getMobileDevice(deviceId);
90
- }
91
- function removeMobileDevice(deviceId) {
92
- return runSqliteWriteTransaction((db) => db.prepare(`DELETE FROM mobile_devices WHERE device_id = ?`).run(deviceId).changes > 0);
93
- }
94
- function disableMobileDeviceForPushToken(pushToken) {
95
- runSqliteWriteTransaction((db) => {
96
- db.prepare(`UPDATE mobile_devices SET enabled = 0, updated_at = ? WHERE push_token = ?`).run(Date.now(), pushToken);
97
- });
98
- }
99
- function createMobileActivityEvent(input) {
100
- const event = {
101
- ...input,
102
- id: input.id ?? randomUUID(),
103
- createdAt: input.createdAt ?? Date.now()
104
- };
105
- runSqliteWriteTransaction((db) => {
106
- db.prepare(`INSERT INTO mobile_activity_events (
107
- event_id, event_type, entity_kind, entity_id, priority, title, body,
108
- deep_link, payload_json, created_at
109
- ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`).run(event.id, event.type, event.entity.kind, event.entity.id, event.priority, event.title, event.body ?? null, event.deepLink, JSON.stringify(event.payload), event.createdAt);
110
- });
111
- return event;
112
- }
113
- function listMobileActivityEvents(options) {
114
- const limit = Math.max(1, Math.min(100, options?.limit ?? 50));
115
- const cursor = options?.cursor;
116
- const items = (cursor == null ? getSqliteDatabase().prepare(`SELECT * FROM mobile_activity_events ORDER BY created_at DESC LIMIT ?`).all(limit) : getSqliteDatabase().prepare(`SELECT * FROM mobile_activity_events WHERE created_at < ? ORDER BY created_at DESC LIMIT ?`).all(cursor, limit)).map(activityFromRow);
117
- return {
118
- items,
119
- nextCursor: items.length === limit ? items[items.length - 1].createdAt : null
120
- };
121
- }
122
- function acknowledgeMobileActivityEvent(eventId, deviceId) {
123
- if (!getMobileDevice(deviceId)) return false;
124
- if (!getSqliteDatabase().prepare(`SELECT 1 FROM mobile_activity_events WHERE event_id = ?`).get(eventId)) return false;
125
- runSqliteWriteTransaction((db) => {
126
- db.prepare(`INSERT OR REPLACE INTO mobile_activity_acknowledgements (event_id, device_id, acknowledged_at)
127
- VALUES (?, ?, ?)`).run(eventId, deviceId, Date.now());
128
- });
129
- return true;
130
- }
131
- //#endregion
132
- export { acknowledgeMobileActivityEvent, createMobileActivityEvent, disableMobileDeviceForPushToken, getMobileDevice, listEnabledMobileDevices, listMobileActivityEvents, registerMobileDevice, removeMobileDevice, updateMobileDevicePreferences };
@@ -1,37 +0,0 @@
1
- export type MobilePlatform = 'ios' | 'android';
2
- export type MobileNotificationPermission = 'granted' | 'denied' | 'unknown';
3
- export type MobileNotificationPriority = 'normal' | 'high';
4
- export type MobileNotificationEventType = 'task.needs_input' | 'task.blocked' | 'task.completed' | 'automation.failed' | 'automation.completed' | 'proactive.insight';
5
- export type MobileNotificationPreferences = {
6
- needsInput: boolean;
7
- failed: boolean;
8
- completed: boolean;
9
- automationFailed: boolean;
10
- };
11
- export type MobileDevice = {
12
- id: string;
13
- platform: MobilePlatform;
14
- pushToken: string;
15
- enabled: boolean;
16
- permissions: MobileNotificationPermission;
17
- preferences: MobileNotificationPreferences;
18
- appVersion?: string;
19
- lastSeenAt: number;
20
- createdAt: number;
21
- updatedAt: number;
22
- };
23
- export type MobileActivityEvent = {
24
- id: string;
25
- type: MobileNotificationEventType;
26
- entity: {
27
- kind: 'task' | 'automation' | 'insight';
28
- id: string;
29
- };
30
- priority: MobileNotificationPriority;
31
- title: string;
32
- body?: string;
33
- deepLink: string;
34
- payload: Record<string, unknown>;
35
- createdAt: number;
36
- };
37
- export declare const DEFAULT_MOBILE_NOTIFICATION_PREFERENCES: MobileNotificationPreferences;
@@ -1,9 +0,0 @@
1
- //#region src/mobile/notification-types.ts
2
- const DEFAULT_MOBILE_NOTIFICATION_PREFERENCES = {
3
- needsInput: true,
4
- failed: true,
5
- completed: false,
6
- automationFailed: true
7
- };
8
- //#endregion
9
- export { DEFAULT_MOBILE_NOTIFICATION_PREFERENCES };