@xopcai/xopc 0.0.225 → 0.0.228

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 (239) 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-CtTYnku4.js → activity-store-M0nAY5XB.js} +1 -1
  4. package/dist/gateway/static/root/assets/{agent-avatar-dicebear-dizuqu_4.js → agent-avatar-dicebear-CjGZBs4C.js} +1 -1
  5. package/dist/gateway/static/root/assets/agents-B0NI4_NI.js +68 -0
  6. package/dist/gateway/static/root/assets/{api-CLRMz2BT.js → api-BywYxpaS.js} +1 -1
  7. package/dist/gateway/static/root/assets/{app-management-settings-panel-Cnk-DtQh.js → app-management-settings-panel--SjycrXk.js} +1 -1
  8. package/dist/gateway/static/root/assets/{appearance-settings-wP0rogVI.js → appearance-settings-8G-TVUtg.js} +1 -1
  9. package/dist/gateway/static/root/assets/apps-page-2NiqD-YP.js +1 -0
  10. package/dist/gateway/static/root/assets/{archive-plugin-Cpzsm-DM.js → archive-plugin-7_DXaMTP.js} +1 -1
  11. package/dist/gateway/static/root/assets/{attachment-load-Bd2OOoEK.js → attachment-load-Bx44zSpz.js} +1 -1
  12. package/dist/gateway/static/root/assets/{automations-page-DNqhguyk.js → automations-page-CrKAHqc0.js} +1 -1
  13. package/dist/gateway/static/root/assets/automations-workspace-Q3g9cf0h.js +6 -0
  14. package/dist/gateway/static/root/assets/{binary-plugins-Dcma5HdI.js → binary-plugins-DjDwnHAQ.js} +1 -1
  15. package/dist/gateway/static/root/assets/{block-editor-D-B8ThwK.js → block-editor-7aMOKoZM.js} +3 -3
  16. package/dist/gateway/static/root/assets/browser-settings-page-DTwPkmAC.js +8 -0
  17. package/dist/gateway/static/root/assets/{browser-workflow-inputs-BAPZIXrs.js → browser-workflow-inputs-8NC2qDRF.js} +1 -1
  18. package/dist/gateway/static/root/assets/{browser-workflows-page-DHtaSKEh.js → browser-workflows-page-DVLrWKz_.js} +2 -2
  19. package/dist/gateway/static/root/assets/capabilities-settings-panel-YcP4FbN7.js +7 -0
  20. package/dist/gateway/static/root/assets/{capability-presets-api-zsZQ7im3.js → capability-presets-api-o0y9WgAI.js} +1 -1
  21. package/dist/gateway/static/root/assets/capability-presets-settings-panel-AcPjHHia.js +3 -0
  22. package/dist/gateway/static/root/assets/{channel-recipient-api-Cp8iaaXp.js → channel-recipient-api-C5ABr73b.js} +1 -1
  23. package/dist/gateway/static/root/assets/channels-settings-Ca94Q1D-.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-Dr6Rq2ln.js → chat-terminal-dock-BR-_7KC0.js} +2 -2
  26. package/dist/gateway/static/root/assets/connectors-page-SGxfLTd6.js +2 -0
  27. package/dist/gateway/static/root/assets/{cron-expression-BiXrpzmo.js → cron-expression-D8-c-Tkw.js} +1 -1
  28. package/dist/gateway/static/root/assets/{date-picker-BPuRtwKt.js → date-picker-kV-Jyl9J.js} +1 -1
  29. package/dist/gateway/static/root/assets/{dependency-picker-BNC_W7wI.js → dependency-picker-CwKcrfGj.js} +1 -1
  30. package/dist/gateway/static/root/assets/{desktop-pet-DzOpt5nI.js → desktop-pet-D9rnchu3.js} +1 -1
  31. package/dist/gateway/static/root/assets/{desktop-pet-settings-BW0brCvH.js → desktop-pet-settings-CTs5WGzk.js} +1 -1
  32. package/dist/gateway/static/root/assets/{directory-picker-path-field-Baml0uTS.js → directory-picker-path-field-CCl0aaDm.js} +1 -1
  33. package/dist/gateway/static/root/assets/{extension-debug-page-CBXyKmfS.js → extension-debug-page-Cau40SvC.js} +1 -1
  34. package/dist/gateway/static/root/assets/{extension-page-BBhcr_SZ.js → extension-page-BsJXdvIL.js} +1 -1
  35. package/dist/gateway/static/root/assets/{extension-settings-page-4rwWpN9_.js → extension-settings-page-qWqJyF7-.js} +1 -1
  36. package/dist/gateway/static/root/assets/{gateway-config-api-Dg-BlBe4.js → gateway-config-api-BI0SELXm.js} +1 -1
  37. package/dist/gateway/static/root/assets/{gateway-config-swr-Du0MvK9s.js → gateway-config-swr-BWGjnmDl.js} +1 -1
  38. package/dist/gateway/static/root/assets/{gateway-settings-BOuYZOYe.js → gateway-settings-6ZdOIC7F.js} +1 -1
  39. package/dist/gateway/static/root/assets/{gateway-startup-retry-JbjcHCaN.js → gateway-startup-retry-B_zrtccP.js} +1 -1
  40. package/dist/gateway/static/root/assets/heartbeat-settings-KBwhXeFD.js +1 -0
  41. package/dist/gateway/static/root/assets/home-page-BA2M4CLi.js +1 -0
  42. package/dist/gateway/static/root/assets/{image-generation-api-G2tfPvKP.js → image-generation-api-YKP2me5Z.js} +1 -1
  43. package/dist/gateway/static/root/assets/index-BX0dz1JK.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-L1Vtxgp9.js → keyboard-shortcuts-settings-kHtpnyEm.js} +1 -1
  46. package/dist/gateway/static/root/assets/local-app-workbench-page-D2nkn09R.js +2 -0
  47. package/dist/gateway/static/root/assets/{local-apps-page--thlkBLS.js → local-apps-page-BCXa0oUa.js} +1 -1
  48. package/dist/gateway/static/root/assets/{locale-store-DqJz-cOR.js → locale-store-CXhjfe4q.js} +1 -1
  49. package/dist/gateway/static/root/assets/logs-page-D3sNst0K.js +2 -0
  50. package/dist/gateway/static/root/assets/{management-settings-p55fR4XO.js → management-settings-tHnlfOAQ.js} +1 -1
  51. package/dist/gateway/static/root/assets/{markdown-split-DwMcRlBR.js → markdown-split-BMLqHHr5.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-O6H3GZn7.js → media-plugins-DybwqTgv.js} +1 -1
  55. package/dist/gateway/static/root/assets/messages-BMdD0LWk.js +3 -0
  56. package/dist/gateway/static/root/assets/{notes-api-CrjQbmk1.js → notes-api-BFsOGYkd.js} +1 -1
  57. package/dist/gateway/static/root/assets/{notes-page-miO9ig9C.js → notes-page-C24SfF6r.js} +1 -1
  58. package/dist/gateway/static/root/assets/notes-workbench-CTdZc3ov.js +4 -0
  59. package/dist/gateway/static/root/assets/{product-open-page-BOu07nXf.js → product-open-page-DBfCVlJq.js} +1 -1
  60. package/dist/gateway/static/root/assets/project-detail-page-COHaEpbA.js +1 -0
  61. package/dist/gateway/static/root/assets/projects-page-lMnST7D_.js +1 -0
  62. package/dist/gateway/static/root/assets/{registry-api-Bf_HDLUJ.js → registry-api-BFZrVYfy.js} +1 -1
  63. package/dist/gateway/static/root/assets/remote-access-hub-BIRKBvO_.js +1 -0
  64. package/dist/gateway/static/root/assets/{runtime-tools-settings-panel-DthuRqUH.js → runtime-tools-settings-panel-BPEGTip5.js} +2 -2
  65. package/dist/gateway/static/root/assets/{schema-form-8W8PhXxa.js → schema-form-Dxlu60Td.js} +1 -1
  66. package/dist/gateway/static/root/assets/sessions-page-CATO9G3y.js +1 -0
  67. package/dist/gateway/static/root/assets/settings-advanced-gate-Cco_W41x.js +1 -0
  68. package/dist/gateway/static/root/assets/{settings-form-section-CrsKGYiG.js → settings-form-section-ChXh3Bwk.js} +1 -1
  69. package/dist/gateway/static/root/assets/{settings-loading-skeleton-WJtI0AAq.js → settings-loading-skeleton-BCAUqIe2.js} +1 -1
  70. package/dist/gateway/static/root/assets/{settings-page-PCjwRF47.js → settings-page-D25W9Okr.js} +1 -1
  71. package/dist/gateway/static/root/assets/{setup-status-panel-D65CwlNC.js → setup-status-panel-DsN7Z4Fl.js} +1 -1
  72. package/dist/gateway/static/root/assets/{share-preview-page-BGtvLLeZ.js → share-preview-page-CRFnUaNb.js} +1 -1
  73. package/dist/gateway/static/root/assets/shares-settings-CAX0eNaP.js +1 -0
  74. package/dist/gateway/static/root/assets/skill-reload-api-Doy1gghe.js +1 -0
  75. package/dist/gateway/static/root/assets/{skills-page-C_npyryI.js → skills-page-Cl7jjTK7.js} +1 -1
  76. package/dist/gateway/static/root/assets/{skills-page.utils-C46Sd78k.js → skills-page.utils-BiCl4nb5.js} +1 -1
  77. package/dist/gateway/static/root/assets/{system-settings-panel-DomTLwki.js → system-settings-panel-BuESR7ZT.js} +1 -1
  78. package/dist/gateway/static/root/assets/task-detail-page-BRiy8NL3.js +1 -0
  79. package/dist/gateway/static/root/assets/{theme-store-Ce7wq__X.js → theme-store-DOdCjyuw.js} +1 -1
  80. package/dist/gateway/static/root/assets/{use-autosave-Do9mCRcY.js → use-autosave-Dg1mgJ_l.js} +1 -1
  81. package/dist/gateway/static/root/assets/user-context-page-CqoADNKu.js +1 -0
  82. package/dist/gateway/static/root/assets/{voice-api-key-field-Bc5p-0tX.js → voice-api-key-field-BDNexlVR.js} +1 -1
  83. package/dist/gateway/static/root/assets/{work-discovery-overlay-BieqsmT1.js → work-discovery-overlay-BHTfeaWL.js} +1 -1
  84. package/dist/gateway/static/root/assets/{workflow-run-setup-panel-DVj8iYvm.js → workflow-run-setup-panel-Cf_w-NZy.js} +2 -2
  85. package/dist/gateway/static/root/assets/workflows-page-j0P-uECz.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-manager.d.ts +3 -1
  92. package/dist/src/agent/agent-manager.js +22 -5
  93. package/dist/src/agent/lifecycle/timeout-wrapper.d.ts +1 -0
  94. package/dist/src/agent/lifecycle/timeout-wrapper.js +7 -6
  95. package/dist/src/agent/mcp/mcp-transport-config.d.ts +1 -1
  96. package/dist/src/agent/mcp/mcp-transport-config.js +1 -1
  97. package/dist/src/agent/memory/understanding/service.js +1 -0
  98. package/dist/src/agent/memory/understanding/types.d.ts +1 -0
  99. package/dist/src/agent/orchestration/run-agent-turn-with-timeout.d.ts +2 -2
  100. package/dist/src/agent/orchestration/run-agent-turn-with-timeout.js +4 -4
  101. package/dist/src/agent/service.d.ts +2 -0
  102. package/dist/src/agent/service.js +6 -0
  103. package/dist/src/agent/skills/index.d.ts +22 -2
  104. package/dist/src/agent/skills/index.js +74 -32
  105. package/dist/src/agent/skills/skill-sources.d.ts +0 -1
  106. package/dist/src/agent/skills/skill-sources.js +1 -11
  107. package/dist/src/agent/tools/create-share-tool.js +14 -1
  108. package/dist/src/agent/tools/exec-command.js +3 -3
  109. package/dist/src/agent/tools/execute-code-tool.js +1 -1
  110. package/dist/src/agent/tools/executor.js +2 -2
  111. package/dist/src/agent/tools/image-generate-tool.js +12 -0
  112. package/dist/src/agent/tools/send-media.js +11 -0
  113. package/dist/src/agent/tools/xopc-use-tool.js +1 -1
  114. package/dist/src/cli/command-loaders.js +1 -0
  115. package/dist/src/cli/command-manifest.js +4 -0
  116. package/dist/src/cli/commands/doctor/checks/database-schema.js +1 -1
  117. package/dist/src/cli/commands/gateway/lifecycle.js +1 -1
  118. package/dist/src/cli/commands/history.d.ts +1 -0
  119. package/dist/src/cli/commands/history.js +50 -0
  120. package/dist/src/config/agent-profile.js +1 -1
  121. package/dist/src/connectors/connected-source-understanding.js +1 -1
  122. package/dist/src/gateway/agents-admin.js +1 -1
  123. package/dist/src/gateway/chat-stream/protocol.d.ts +3 -2
  124. package/dist/src/gateway/chat-stream/turn-outcome-collector.d.ts +16 -0
  125. package/dist/src/gateway/chat-stream/turn-outcome-collector.js +111 -0
  126. package/dist/src/gateway/heartbeat/service.js +1 -1
  127. package/dist/src/gateway/hono/lib/static-ui.js +7 -5
  128. package/dist/src/gateway/hono/routes/connectors.js +18 -16
  129. package/dist/src/gateway/hono/routes/index.js +2 -0
  130. package/dist/src/gateway/hono/routes/mobile.js +18 -40
  131. package/dist/src/gateway/hono/routes/notifications.d.ts +3 -0
  132. package/dist/src/gateway/hono/routes/notifications.js +45 -0
  133. package/dist/src/gateway/hono/routes/project-skills.js +30 -2
  134. package/dist/src/gateway/hono/routes/sessions.js +31 -0
  135. package/dist/src/gateway/hono/routes/tasks.js +1 -1
  136. package/dist/src/gateway/hono/routes/voice.js +1 -1
  137. package/dist/src/gateway/hono/routes/you.js +52 -0
  138. package/dist/src/gateway/service/agent-runner.js +6 -2
  139. package/dist/src/gateway/service/run-gateway-agent.js +53 -1
  140. package/dist/src/gateway/service/sessions-api.d.ts +6 -0
  141. package/dist/src/gateway/service/sessions-api.js +60 -3
  142. package/dist/src/gateway/service.d.ts +2 -2
  143. package/dist/src/gateway/service.js +8 -7
  144. package/dist/src/heartbeat/index.js +1 -1
  145. package/dist/src/history/ctx/exporter.d.ts +14 -0
  146. package/dist/src/history/ctx/exporter.js +99 -0
  147. package/dist/src/history/ctx/format.d.ts +25 -0
  148. package/dist/src/history/ctx/format.js +282 -0
  149. package/dist/src/infra/update-restart.js +1 -1
  150. package/dist/src/knowledge/connected-understanding-pipeline.js +12 -3
  151. package/dist/src/knowledge/index.d.ts +0 -1
  152. package/dist/src/knowledge/index.js +1 -2
  153. package/dist/src/media/session-references.d.ts +6 -0
  154. package/dist/src/media/session-references.js +24 -3
  155. package/dist/src/notifications/device-store.d.ts +16 -0
  156. package/dist/src/notifications/device-store.js +96 -0
  157. package/dist/src/notifications/planner.d.ts +6 -0
  158. package/dist/src/notifications/planner.js +156 -0
  159. package/dist/src/notifications/service.d.ts +18 -0
  160. package/dist/src/notifications/service.js +184 -0
  161. package/dist/src/notifications/store.d.ts +53 -0
  162. package/dist/src/notifications/store.js +184 -0
  163. package/dist/src/notifications/types.d.ts +29 -0
  164. package/dist/src/notifications/types.js +14 -0
  165. package/dist/src/projects/project-skill-service.d.ts +28 -6
  166. package/dist/src/projects/project-skill-service.js +76 -29
  167. package/dist/src/session/client-history.d.ts +3 -1
  168. package/dist/src/session/client-history.js +13 -0
  169. package/dist/src/session/index.d.ts +1 -1
  170. package/dist/src/session/manager.d.ts +1 -0
  171. package/dist/src/session/manager.js +6 -0
  172. package/dist/src/session/store.d.ts +15 -0
  173. package/dist/src/session/store.js +58 -0
  174. package/dist/src/storage/sqlite/index.d.ts +2 -1
  175. package/dist/src/storage/sqlite/index.js +3 -2
  176. package/dist/src/storage/sqlite/migrations/135_user_people.sql +59 -0
  177. package/dist/src/storage/sqlite/migrations/136_product_notifications.sql +79 -0
  178. package/dist/src/storage/sqlite/migrations/runner.d.ts +1 -1
  179. package/dist/src/storage/sqlite/migrations/runner.js +3 -3
  180. package/dist/src/storage/sqlite/migrations/runner.ts +1 -1
  181. package/dist/src/storage/sqlite/schema.js +1 -1
  182. package/dist/src/storage/sqlite/session-input-repository.d.ts +5 -0
  183. package/dist/src/storage/sqlite/session-input-repository.js +9 -1
  184. package/dist/src/storage/sqlite/user-people-repository.d.ts +32 -0
  185. package/dist/src/storage/sqlite/user-people-repository.js +246 -0
  186. package/dist/src/tasks/index.js +2 -2
  187. package/dist/src/tasks/task-application-service.js +42 -6
  188. package/dist/src/tasks/task-change-events.d.ts +9 -0
  189. package/dist/src/tasks/task-change-events.js +17 -1
  190. package/dist/src/tasks/task-outbox-dispatcher.js +5 -1
  191. package/dist/src/tasks/task-run-dispatcher.js +4 -2
  192. package/dist/src/tasks/task-run-repository.js +13 -0
  193. package/dist/src/user-context/relationships/indexer.d.ts +13 -0
  194. package/dist/src/user-context/relationships/indexer.js +185 -0
  195. package/dist/src/user-context/relationships/service.d.ts +22 -0
  196. package/dist/src/user-context/relationships/service.js +50 -0
  197. package/dist/src/user-context/relationships/types.d.ts +55 -0
  198. package/dist/src/user-context/relationships/types.js +10 -0
  199. package/dist/src/user-context/sources/repository.d.ts +1 -1
  200. package/dist/src/user-context/sources/repository.js +8 -2
  201. package/dist/src/work-discovery/service.js +1 -1
  202. package/package.json +2 -2
  203. package/dist/gateway/static/root/assets/agents-DeEEFZJ4.js +0 -68
  204. package/dist/gateway/static/root/assets/apps-page-Db5YNHVM.js +0 -1
  205. package/dist/gateway/static/root/assets/automations-workspace-CNT05YTb.js +0 -6
  206. package/dist/gateway/static/root/assets/browser-settings-page-UbDj3LIq.js +0 -8
  207. package/dist/gateway/static/root/assets/capabilities-settings-panel-CiO152QS.js +0 -7
  208. package/dist/gateway/static/root/assets/capability-presets-settings-panel-Bc_hRwfL.js +0 -3
  209. package/dist/gateway/static/root/assets/channels-settings-CFW7zBoT.js +0 -1
  210. package/dist/gateway/static/root/assets/channels-status-swr-5rNVq7iI.js +0 -1
  211. package/dist/gateway/static/root/assets/connectors-page-DLBr5nre.js +0 -2
  212. package/dist/gateway/static/root/assets/heartbeat-settings-Dq4YAlSx.js +0 -1
  213. package/dist/gateway/static/root/assets/home-page-BIXkO0Ck.js +0 -1
  214. package/dist/gateway/static/root/assets/index-Csccu8sa.js +0 -74
  215. package/dist/gateway/static/root/assets/index-D3_xSYKd.css +0 -2
  216. package/dist/gateway/static/root/assets/local-app-workbench-page-D-eacBcO.js +0 -2
  217. package/dist/gateway/static/root/assets/logs-page-BRCglHvd.js +0 -2
  218. package/dist/gateway/static/root/assets/markdown-view-CTB9u15e.js +0 -69
  219. package/dist/gateway/static/root/assets/mermaid-render-BbqDc_LQ.js +0 -134
  220. package/dist/gateway/static/root/assets/messages-CeydamsI.js +0 -3
  221. package/dist/gateway/static/root/assets/notes-workbench-_13lmvmF.js +0 -4
  222. package/dist/gateway/static/root/assets/project-detail-page-BStRkOQr.js +0 -1
  223. package/dist/gateway/static/root/assets/projects-page-CY03RxVr.js +0 -1
  224. package/dist/gateway/static/root/assets/remote-access-hub-B19llkld.js +0 -1
  225. package/dist/gateway/static/root/assets/sessions-page-BDA2qbTd.js +0 -1
  226. package/dist/gateway/static/root/assets/settings-advanced-gate-BONIDX4v.js +0 -1
  227. package/dist/gateway/static/root/assets/shares-settings-CdzVKrBl.js +0 -1
  228. package/dist/gateway/static/root/assets/skill-reload-api-CsRWid5h.js +0 -1
  229. package/dist/gateway/static/root/assets/task-detail-page-B6YFX7kK.js +0 -1
  230. package/dist/gateway/static/root/assets/user-context-page-CiCQA40E.js +0 -1
  231. package/dist/gateway/static/root/assets/workflows-page-AG04TTuH.js +0 -5
  232. package/dist/src/knowledge/people-graph.d.ts +0 -25
  233. package/dist/src/knowledge/people-graph.js +0 -92
  234. package/dist/src/mobile/notification-service.d.ts +0 -9
  235. package/dist/src/mobile/notification-service.js +0 -156
  236. package/dist/src/mobile/notification-store.d.ts +0 -28
  237. package/dist/src/mobile/notification-store.js +0 -132
  238. package/dist/src/mobile/notification-types.d.ts +0 -37
  239. package/dist/src/mobile/notification-types.js +0 -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 };