@xopcai/xopc 0.0.173 → 0.0.175

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 (224) 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-ByVA0N5n.js → activity-store-CM6mQUS2.js} +1 -1
  4. package/dist/gateway/static/root/assets/{agent-avatar-dicebear-CJ5HvqE7.js → agent-avatar-dicebear-eckyE9AY.js} +1 -1
  5. package/dist/gateway/static/root/assets/agents-D-OIB_r0.js +2 -0
  6. package/dist/gateway/static/root/assets/api-2SLLStKp.js +1 -0
  7. package/dist/gateway/static/root/assets/{api-BZtCKzg4.js → api-BfMRS6FX.js} +1 -1
  8. package/dist/gateway/static/root/assets/{app-management-settings-panel-B0oNNcFn.js → app-management-settings-panel-DYkzZQzZ.js} +1 -1
  9. package/dist/gateway/static/root/assets/{appearance-settings-DbIj4NQ1.js → appearance-settings-CDXXN57j.js} +1 -1
  10. package/dist/gateway/static/root/assets/apps-page-CuvFyvuu.js +1 -0
  11. package/dist/gateway/static/root/assets/{archive-plugin-BICLQFWJ.js → archive-plugin-k909a76t.js} +1 -1
  12. package/dist/gateway/static/root/assets/{attachment-load-DV3PteSU.js → attachment-load-CqNzyhdJ.js} +1 -1
  13. package/dist/gateway/static/root/assets/{automation-suggestion-card-CZUImis0.js → automation-suggestion-card-snNG6u0v.js} +1 -1
  14. package/dist/gateway/static/root/assets/automations-page-DetGVTjI.js +6 -0
  15. package/dist/gateway/static/root/assets/{binary-plugins-D6zkab6N.js → binary-plugins-PfQ9ZHDF.js} +1 -1
  16. package/dist/gateway/static/root/assets/{block-editor-zCzoQI-g.js → block-editor-Xrw-DnE_.js} +6 -6
  17. package/dist/gateway/static/root/assets/browser-settings-page-G92AdEnX.js +8 -0
  18. package/dist/gateway/static/root/assets/{browser-workflow-inputs-CY3X83xQ.js → browser-workflow-inputs-DJPF2lUY.js} +1 -1
  19. package/dist/gateway/static/root/assets/{browser-workflows-page-DDRtZLuM.js → browser-workflows-page-BoXs4pgc.js} +2 -2
  20. package/dist/gateway/static/root/assets/capabilities-settings-panel-nS_AMN1K.js +7 -0
  21. package/dist/gateway/static/root/assets/{capability-presets-api-pYLW6P7g.js → capability-presets-api-BgY-Ysmi.js} +1 -1
  22. package/dist/gateway/static/root/assets/capability-presets-settings-panel-DIO8ZNHW.js +1 -0
  23. package/dist/gateway/static/root/assets/{channel-recipient-api-DxyOH3BO.js → channel-recipient-api-D32T1EJM.js} +1 -1
  24. package/dist/gateway/static/root/assets/channels-settings-4Im3vtnO.js +1 -0
  25. package/dist/gateway/static/root/assets/channels-status-swr-CMctpuqb.js +1 -0
  26. package/dist/gateway/static/root/assets/{connector-logo-BgANwjt-.js → connector-logo-C-l8haIK.js} +1 -1
  27. package/dist/gateway/static/root/assets/connectors-page-vL3SjHSc.js +2 -0
  28. package/dist/gateway/static/root/assets/copy-VueTIC2x.js +1 -0
  29. package/dist/gateway/static/root/assets/{desktop-pet-BPjQbPeA.js → desktop-pet-CwOI_Hei.js} +1 -1
  30. package/dist/gateway/static/root/assets/{desktop-pet-settings-8CaU1Mhm.js → desktop-pet-settings-Cldo_pA3.js} +1 -1
  31. package/dist/gateway/static/root/assets/{directory-picker-path-field-BtNRUvzM.js → directory-picker-path-field-CMASXbgJ.js} +1 -1
  32. package/dist/gateway/static/root/assets/dreaming-settings-BnMx02w0.js +3 -0
  33. package/dist/gateway/static/root/assets/{extension-debug-page-DFjTfx6f.js → extension-debug-page-mUFs3ign.js} +1 -1
  34. package/dist/gateway/static/root/assets/{extension-page-NyEYtWWg.js → extension-page-BsFBOZ5N.js} +1 -1
  35. package/dist/gateway/static/root/assets/{extension-settings-page-BynTCfgf.js → extension-settings-page-CTEoovnV.js} +1 -1
  36. package/dist/gateway/static/root/assets/focus-detail-page-CCaZthpU.js +1 -0
  37. package/dist/gateway/static/root/assets/{gateway-config-api-BzOWImvU.js → gateway-config-api-Bwx-EetD.js} +1 -1
  38. package/dist/gateway/static/root/assets/{gateway-settings-DXepE_Jw.js → gateway-settings-CvgyqhR_.js} +1 -1
  39. package/dist/gateway/static/root/assets/{gateway-startup-retry-C2JXXtwg.js → gateway-startup-retry-C8f5KwkT.js} +1 -1
  40. package/dist/gateway/static/root/assets/{goal-create-dialog-ClOZyG52.js → goal-create-dialog-Bhynl9LN.js} +1 -1
  41. package/dist/gateway/static/root/assets/goal-detail-page-ChS2rU0w.js +4 -0
  42. package/dist/gateway/static/root/assets/{goals-config-api-CU3JR9MI.js → goals-config-api-CUnfbgHa.js} +1 -1
  43. package/dist/gateway/static/root/assets/goals-page-BAS_liXl.js +2 -0
  44. package/dist/gateway/static/root/assets/{goals-settings-DSZguLEx.js → goals-settings-Bkk-tOcf.js} +1 -1
  45. package/dist/gateway/static/root/assets/{heartbeat-settings-KRkYziEF.js → heartbeat-settings-D9Pldf5E.js} +1 -1
  46. package/dist/gateway/static/root/assets/{image-generation-api-Y-n6TaZ_.js → image-generation-api-D7aCMgOv.js} +1 -1
  47. package/dist/gateway/static/root/assets/index-DJ5vdaHk.css +1 -0
  48. package/dist/gateway/static/root/assets/index-TnouSpay.js +212 -0
  49. package/dist/gateway/static/root/assets/{keyboard-shortcuts-settings-CwrQv952.js → keyboard-shortcuts-settings-CBhtXhHb.js} +1 -1
  50. package/dist/gateway/static/root/assets/local-app-workbench-page-HQeu_F1C.js +2 -0
  51. package/dist/gateway/static/root/assets/{local-apps-page-DtITcS4K.js → local-apps-page-BtJGF3M8.js} +1 -1
  52. package/dist/gateway/static/root/assets/{locale-store-Ccv7tH8B.js → locale-store-DO-u1yS7.js} +1 -1
  53. package/dist/gateway/static/root/assets/logs-page-0lvwfLAA.js +7 -0
  54. package/dist/gateway/static/root/assets/{markdown-split-D1oZlq1m.js → markdown-split-BGPaeTch.js} +1 -1
  55. package/dist/gateway/static/root/assets/{media-plugins-BKz5V32t.js → media-plugins-C_Cx8v6u.js} +1 -1
  56. package/dist/gateway/static/root/assets/messages-BP8aQX-5.js +3 -0
  57. package/dist/gateway/static/root/assets/{notes-page-DLekBQPa.js → notes-page-CIYy5BKF.js} +1 -1
  58. package/dist/gateway/static/root/assets/notes-workbench-_FgNPlOx.js +4 -0
  59. package/dist/gateway/static/root/assets/{page-tabs-pT4nLfqS.js → page-tabs-C2vsdfJO.js} +1 -1
  60. package/dist/gateway/static/root/assets/{preview-open-alternatives-OtAiaJm2.js → preview-open-alternatives-D_VT83bW.js} +1 -1
  61. package/dist/gateway/static/root/assets/{product-open-page-CfryBKD9.js → product-open-page-BNP9kZ3Q.js} +1 -1
  62. package/dist/gateway/static/root/assets/project-detail-page-MNi-3mZU.js +1 -0
  63. package/dist/gateway/static/root/assets/{projects-page-3ubcbqHr.js → projects-page-xx8nUKZO.js} +1 -1
  64. package/dist/gateway/static/root/assets/remote-access-hub-H5DSn2bR.js +1 -0
  65. package/dist/gateway/static/root/assets/{save-bar-controls-nP1SB3Lf.js → save-bar-controls-BJL6Xb-F.js} +1 -1
  66. package/dist/gateway/static/root/assets/{schedule-field-OEQTsUNz.js → schedule-field-CxCPSLbu.js} +1 -1
  67. package/dist/gateway/static/root/assets/{schema-form-DIcAa7CJ.js → schema-form-Cao1wGbk.js} +1 -1
  68. package/dist/gateway/static/root/assets/sessions-page-CMQsupwM.js +1 -0
  69. package/dist/gateway/static/root/assets/settings-advanced-gate-OBUdG6bV.js +1 -0
  70. package/dist/gateway/static/root/assets/{settings-form-section-BxNcTbYO.js → settings-form-section-9pgClEud.js} +1 -1
  71. package/dist/gateway/static/root/assets/{settings-loading-skeleton-Dpdxu4sf.js → settings-loading-skeleton-CQz0gEUK.js} +1 -1
  72. package/dist/gateway/static/root/assets/{settings-page-DwPeOm1c.js → settings-page-DgsMzZLm.js} +1 -1
  73. package/dist/gateway/static/root/assets/{settings-page-layout-CqirFmMn.js → settings-page-layout-BhqupMfG.js} +1 -1
  74. package/dist/gateway/static/root/assets/setup-status-panel-B7BsWxJt.js +1 -0
  75. package/dist/gateway/static/root/assets/{share-preview-page-D72gYeux.js → share-preview-page-CC4dQsQN.js} +1 -1
  76. package/dist/gateway/static/root/assets/shares-settings-Bhz21P05.js +1 -0
  77. package/dist/gateway/static/root/assets/skill-reload-api-CBP-UB88.js +1 -0
  78. package/dist/gateway/static/root/assets/skills-page-A0rNObNB.js +2 -0
  79. package/dist/gateway/static/root/assets/skills-page.utils-CF4AYPQg.js +1 -0
  80. package/dist/gateway/static/root/assets/{system-settings-panel-U0tBgW46.js → system-settings-panel-CzZHWI4u.js} +1 -1
  81. package/dist/gateway/static/root/assets/{theme-store-DCKDVPFF.js → theme-store-BZWNdSZC.js} +1 -1
  82. package/dist/gateway/static/root/assets/time-picker-BC922Mdg.js +1 -0
  83. package/dist/gateway/static/root/assets/{typed-models-lib-D0XCOCAM.js → typed-models-lib-C1S-B1pk.js} +1 -1
  84. package/dist/gateway/static/root/assets/{use-channel-catalog-mq_Inao2.js → use-channel-catalog-DTiLxcLF.js} +1 -1
  85. package/dist/gateway/static/root/assets/user-context-page-8XdpiAyP.js +1 -0
  86. package/dist/gateway/static/root/assets/{voice-api-key-field-CKaDitO6.js → voice-api-key-field-CtIYRNfI.js} +1 -1
  87. package/dist/gateway/static/root/assets/work-discovery-page-DBer86NF.js +1 -0
  88. package/dist/gateway/static/root/assets/work-item-detail-page-BUPyfYaq.js +1 -0
  89. package/dist/gateway/static/root/assets/work-page-G8phwwI1.js +1 -0
  90. package/dist/gateway/static/root/assets/{workflow-run-setup-panel-s_kS_FYA.js → workflow-run-setup-panel-IKxqDAXw.js} +2 -2
  91. package/dist/gateway/static/root/assets/workflows-page-CNls7g6v.js +11 -0
  92. package/dist/gateway/static/root/index.html +7 -7
  93. package/dist/package.js +1 -1
  94. package/dist/src/agent/agent-manager.js +1 -1
  95. package/dist/src/agent/mcp/mcp-transport.js +1 -1
  96. package/dist/src/agent/service.js +1 -1
  97. package/dist/src/agent/skills/hub-pull.js +1 -1
  98. package/dist/src/agent/skills/index.d.ts +2 -0
  99. package/dist/src/agent/skills/index.js +14 -5
  100. package/dist/src/agent/skills/marketplace/adapters/store/store-api-client.js +1 -1
  101. package/dist/src/agent/skills/skill-manage-ops.js +1 -1
  102. package/dist/src/agent/skills/test-framework.js +1 -1
  103. package/dist/src/automations/domain/defaults.d.ts +1 -0
  104. package/dist/src/automations/domain/defaults.js +4 -0
  105. package/dist/src/automations/domain/index.d.ts +1 -0
  106. package/dist/src/automations/domain/index.js +2 -1
  107. package/dist/src/automations/index.js +2 -1
  108. package/dist/src/automations/service/action-executor.js +2 -2
  109. package/dist/src/cli/commands/doctor/checks/database-schema.js +1 -1
  110. package/dist/src/cli/commands/gateway/lifecycle.js +1 -1
  111. package/dist/src/cli/commands/skills.js +1 -1
  112. package/dist/src/config/agent-profile.js +1 -1
  113. package/dist/src/focuses/candidate-repository.d.ts +15 -0
  114. package/dist/src/focuses/candidate-repository.js +91 -0
  115. package/dist/src/focuses/index.d.ts +7 -0
  116. package/dist/src/focuses/index.js +7 -0
  117. package/dist/src/focuses/insight-repository.d.ts +22 -0
  118. package/dist/src/focuses/insight-repository.js +77 -0
  119. package/dist/src/focuses/prompts.d.ts +2 -0
  120. package/dist/src/focuses/prompts.js +18 -0
  121. package/dist/src/focuses/reconciler.d.ts +5 -0
  122. package/dist/src/focuses/reconciler.js +26 -0
  123. package/dist/src/focuses/repository.d.ts +61 -0
  124. package/dist/src/focuses/repository.js +214 -0
  125. package/dist/src/focuses/run-processor.d.ts +18 -0
  126. package/dist/src/focuses/run-processor.js +162 -0
  127. package/dist/src/focuses/service.d.ts +42 -0
  128. package/dist/src/focuses/service.js +241 -0
  129. package/dist/src/focuses/types.d.ts +89 -0
  130. package/dist/src/gateway/agents-admin.js +1 -1
  131. package/dist/src/gateway/heartbeat/service.js +1 -1
  132. package/dist/src/gateway/hono/routes/focuses.d.ts +3 -0
  133. package/dist/src/gateway/hono/routes/focuses.js +319 -0
  134. package/dist/src/gateway/hono/routes/home.d.ts +16 -3
  135. package/dist/src/gateway/hono/routes/home.js +113 -42
  136. package/dist/src/gateway/hono/routes/index.js +4 -0
  137. package/dist/src/gateway/hono/routes/local-apps.js +1 -1
  138. package/dist/src/gateway/hono/routes/project-skills.d.ts +3 -0
  139. package/dist/src/gateway/hono/routes/project-skills.js +119 -0
  140. package/dist/src/gateway/hono/routes/projects.js +2 -103
  141. package/dist/src/gateway/hono/routes/work-discovery.js +0 -239
  142. package/dist/src/gateway/service.d.ts +1 -1
  143. package/dist/src/gateway/service.js +17 -13
  144. package/dist/src/heartbeat/index.js +1 -1
  145. package/dist/src/infra/update-restart.js +1 -1
  146. package/dist/src/mcp/channel-bridge.js +1 -1
  147. package/dist/src/projects/index.d.ts +1 -0
  148. package/dist/src/projects/index.js +2 -1
  149. package/dist/src/projects/project-skill-service.d.ts +67 -0
  150. package/dist/src/projects/project-skill-service.js +131 -0
  151. package/dist/src/storage/sqlite/home-attention-repository.d.ts +3 -0
  152. package/dist/src/storage/sqlite/home-attention-repository.js +21 -0
  153. package/dist/src/storage/sqlite/index.d.ts +1 -0
  154. package/dist/src/storage/sqlite/index.js +2 -1
  155. package/dist/src/storage/sqlite/migrations/066_first_class_focuses.sql +126 -0
  156. package/dist/src/storage/sqlite/migrations/067_home_attention_acknowledgements.sql +9 -0
  157. package/dist/src/storage/sqlite/migrations/runner.d.ts +1 -1
  158. package/dist/src/storage/sqlite/migrations/runner.js +3 -3
  159. package/dist/src/storage/sqlite/migrations/runner.ts +1 -1
  160. package/dist/src/storage/sqlite/schema.js +1 -1
  161. package/dist/src/storage/sqlite/schema.sql +10 -0
  162. package/dist/src/tui/tui-startup-resources.js +1 -1
  163. package/dist/src/work-discovery/index.d.ts +0 -2
  164. package/dist/src/work-discovery/index.js +1 -3
  165. package/dist/src/work-discovery/service.d.ts +0 -30
  166. package/dist/src/work-discovery/service.js +1 -35
  167. package/dist/src/work-discovery/thread-service.d.ts +5 -0
  168. package/dist/src/work-discovery/thread-service.js +36 -88
  169. package/dist/src/workflows/service/workflow-run-service.js +1 -1
  170. package/package.json +1 -1
  171. package/dist/gateway/static/root/assets/agents--TQ9jM_1.js +0 -2
  172. package/dist/gateway/static/root/assets/apps-page-BDsoZDEn.js +0 -1
  173. package/dist/gateway/static/root/assets/automations-page-CHrNcppN.js +0 -6
  174. package/dist/gateway/static/root/assets/browser-settings-page-BQoRuQzH.js +0 -8
  175. package/dist/gateway/static/root/assets/capabilities-settings-panel-BOcU0qeM.js +0 -7
  176. package/dist/gateway/static/root/assets/capability-presets-settings-panel-CJ1F_hlX.js +0 -1
  177. package/dist/gateway/static/root/assets/channels-settings-C4vDwRil.js +0 -1
  178. package/dist/gateway/static/root/assets/channels-status-swr-B0Pgq5x2.js +0 -1
  179. package/dist/gateway/static/root/assets/connectors-page-D6JEqDEj.js +0 -2
  180. package/dist/gateway/static/root/assets/dreaming-settings-Byv-h8XZ.js +0 -3
  181. package/dist/gateway/static/root/assets/goal-detail-page-UbZB77De.js +0 -4
  182. package/dist/gateway/static/root/assets/goals-page-GMqV8Fwv.js +0 -2
  183. package/dist/gateway/static/root/assets/index-BCkNJ5cR.css +0 -1
  184. package/dist/gateway/static/root/assets/index-CAZ9343h.js +0 -212
  185. package/dist/gateway/static/root/assets/local-app-workbench-page-m5HEyrHT.js +0 -2
  186. package/dist/gateway/static/root/assets/logs-page-Bf_nk75f.js +0 -7
  187. package/dist/gateway/static/root/assets/messages-DWrg3c4K.js +0 -3
  188. package/dist/gateway/static/root/assets/notes-workbench-BTDmprHM.js +0 -4
  189. package/dist/gateway/static/root/assets/project-detail-page-C7kntu4H.js +0 -1
  190. package/dist/gateway/static/root/assets/remote-access-hub-DoUkN3ik.js +0 -1
  191. package/dist/gateway/static/root/assets/sessions-page-ElAAlZ-R.js +0 -1
  192. package/dist/gateway/static/root/assets/settings-advanced-gate-CQn_KBqr.js +0 -1
  193. package/dist/gateway/static/root/assets/setup-status-panel-DX_LdcTN.js +0 -1
  194. package/dist/gateway/static/root/assets/shares-settings-nSfe-5xK.js +0 -1
  195. package/dist/gateway/static/root/assets/skill-reload-api-1tYpZrJf.js +0 -1
  196. package/dist/gateway/static/root/assets/skills-page-BUJl8LJG.js +0 -2
  197. package/dist/gateway/static/root/assets/time-picker-BpiBF5-d.js +0 -1
  198. package/dist/gateway/static/root/assets/user-context-page-BOC6Hn19.js +0 -1
  199. package/dist/gateway/static/root/assets/work-discovery-page-DWGYp5yV.js +0 -1
  200. package/dist/gateway/static/root/assets/work-item-detail-page-CpeWcpSp.js +0 -1
  201. package/dist/gateway/static/root/assets/work-page-MsEKzmSt.js +0 -1
  202. package/dist/gateway/static/root/assets/workflows-page-ByhHaUHB.js +0 -11
  203. package/dist/src/proactive/calendar-signals.d.ts +0 -4
  204. package/dist/src/proactive/calendar-signals.js +0 -120
  205. package/dist/src/proactive/focus-service.d.ts +0 -62
  206. package/dist/src/proactive/focus-service.js +0 -173
  207. package/dist/src/proactive/index.d.ts +0 -7
  208. package/dist/src/proactive/index.js +0 -7
  209. package/dist/src/proactive/insight-repository.d.ts +0 -21
  210. package/dist/src/proactive/insight-repository.js +0 -109
  211. package/dist/src/proactive/run-processor.d.ts +0 -19
  212. package/dist/src/proactive/run-processor.js +0 -146
  213. package/dist/src/proactive/trial-expiry-reconciler.d.ts +0 -5
  214. package/dist/src/proactive/trial-expiry-reconciler.js +0 -30
  215. package/dist/src/proactive/types.d.ts +0 -66
  216. package/dist/src/proactive/value-score.d.ts +0 -13
  217. package/dist/src/proactive/value-score.js +0 -30
  218. package/dist/src/proactive/watch-repository.d.ts +0 -28
  219. package/dist/src/proactive/watch-repository.js +0 -129
  220. package/dist/src/work-discovery/governance.d.ts +0 -25
  221. package/dist/src/work-discovery/governance.js +0 -96
  222. package/dist/src/work-discovery/thread-repository.d.ts +0 -34
  223. package/dist/src/work-discovery/thread-repository.js +0 -112
  224. /package/dist/src/{proactive → focuses}/types.js +0 -0
@@ -0,0 +1,61 @@
1
+ import type { Focus, FocusActivity, FocusActivityType, FocusCadence, FocusMonitor, FocusMonitorKind, FocusMonitorRunState, FocusSource, FocusStatus } from './types.js';
2
+ export declare function getFocus(id: string): Focus | null;
3
+ export declare function listFocuses(options?: {
4
+ statuses?: FocusStatus[];
5
+ limit?: number;
6
+ }): Focus[];
7
+ export declare function createFocus(input: {
8
+ title: string;
9
+ summary: string;
10
+ source?: FocusSource;
11
+ sourceCandidateId?: string;
12
+ projectIds?: string[];
13
+ goalId?: string;
14
+ nowMs?: number;
15
+ }): Focus;
16
+ export declare function updateFocus(input: {
17
+ id: string;
18
+ title?: string;
19
+ summary?: string;
20
+ status?: FocusStatus;
21
+ projectIds?: string[];
22
+ nowMs?: number;
23
+ }): Focus | null;
24
+ export declare function deleteFocus(id: string): boolean;
25
+ export declare function getFocusMonitor(focusId: string, kind: FocusMonitorKind): FocusMonitor | null;
26
+ export declare function getFocusMonitorByAutomationId(automationId: string): FocusMonitor | null;
27
+ export declare function listFocusMonitors(focusId: string): FocusMonitor[];
28
+ export declare function listAllFocusMonitors(): FocusMonitor[];
29
+ export declare function upsertFocusMonitor(input: {
30
+ focusId: string;
31
+ kind: FocusMonitorKind;
32
+ enabled: boolean;
33
+ runState?: FocusMonitorRunState;
34
+ cadence: FocusCadence;
35
+ automationId?: string | null;
36
+ nowMs?: number;
37
+ }): FocusMonitor;
38
+ export declare function updateFocusMonitorRuntime(input: {
39
+ id: string;
40
+ runState: FocusMonitorRunState;
41
+ automationId?: string | null;
42
+ lastRunId?: string;
43
+ lastRunAt?: number;
44
+ nextRunAt?: number | null;
45
+ meaningful?: boolean;
46
+ error?: string | null;
47
+ nowMs?: number;
48
+ }): FocusMonitor | null;
49
+ export declare function createFocusActivity(input: {
50
+ focusId: string;
51
+ monitorId?: string;
52
+ type: FocusActivityType;
53
+ summary: string;
54
+ details?: Record<string, unknown>;
55
+ nowMs?: number;
56
+ }): FocusActivity;
57
+ export declare function listFocusActivities(input: {
58
+ focusId: string;
59
+ before?: number;
60
+ limit?: number;
61
+ }): FocusActivity[];
@@ -0,0 +1,214 @@
1
+ import { requireXopcDatabase } from "../storage/sqlite/connection.js";
2
+ import { runSqliteWriteTransaction } from "../storage/sqlite/transaction.js";
3
+ import { randomUUID } from "node:crypto";
4
+ //#region src/focuses/repository.ts
5
+ function parseObject(value) {
6
+ try {
7
+ const parsed = JSON.parse(value);
8
+ return parsed && typeof parsed === "object" && !Array.isArray(parsed) ? parsed : {};
9
+ } catch {
10
+ return {};
11
+ }
12
+ }
13
+ function parseCadence(value) {
14
+ const parsed = parseObject(value);
15
+ return {
16
+ kind: "interval",
17
+ everyMs: typeof parsed.everyMs === "number" && parsed.everyMs > 0 ? parsed.everyMs : 864e5
18
+ };
19
+ }
20
+ function projectIdsForFocus(db, focusId) {
21
+ return db.prepare("SELECT project_id FROM focus_projects WHERE focus_id = ? ORDER BY created_at, project_id").all(focusId).map((row) => row.project_id);
22
+ }
23
+ function focusFromRow(db, row) {
24
+ return {
25
+ id: row.focus_id,
26
+ title: row.title,
27
+ summary: row.summary,
28
+ status: row.status,
29
+ source: row.source,
30
+ ...row.source_candidate_id ? { sourceCandidateId: row.source_candidate_id } : {},
31
+ projectIds: projectIdsForFocus(db, row.focus_id),
32
+ ...row.goal_id ? { goalId: row.goal_id } : {},
33
+ createdAt: row.created_at,
34
+ updatedAt: row.updated_at,
35
+ ...row.completed_at != null ? { completedAt: row.completed_at } : {},
36
+ ...row.last_activity_at != null ? { lastActivityAt: row.last_activity_at } : {}
37
+ };
38
+ }
39
+ function monitorFromRow(row) {
40
+ return {
41
+ id: row.monitor_id,
42
+ focusId: row.focus_id,
43
+ kind: row.kind,
44
+ enabled: row.enabled === 1,
45
+ runState: row.run_state,
46
+ cadence: parseCadence(row.cadence_json),
47
+ ...row.automation_id ? { automationId: row.automation_id } : {},
48
+ ...row.last_run_id ? { lastRunId: row.last_run_id } : {},
49
+ ...row.last_run_at != null ? { lastRunAt: row.last_run_at } : {},
50
+ ...row.next_run_at != null ? { nextRunAt: row.next_run_at } : {},
51
+ ...row.last_meaningful_result_at != null ? { lastMeaningfulResultAt: row.last_meaningful_result_at } : {},
52
+ ...row.last_error ? { lastError: row.last_error } : {},
53
+ consecutiveFailures: row.consecutive_failures,
54
+ createdAt: row.created_at,
55
+ updatedAt: row.updated_at
56
+ };
57
+ }
58
+ function activityFromRow(row) {
59
+ return {
60
+ id: row.activity_id,
61
+ focusId: row.focus_id,
62
+ ...row.monitor_id ? { monitorId: row.monitor_id } : {},
63
+ type: row.type,
64
+ summary: row.summary,
65
+ details: parseObject(row.details_json),
66
+ createdAt: row.created_at
67
+ };
68
+ }
69
+ function getFocus(id) {
70
+ const { db } = requireXopcDatabase();
71
+ const row = db.prepare("SELECT * FROM focuses WHERE focus_id = ?").get(id);
72
+ return row ? focusFromRow(db, row) : null;
73
+ }
74
+ function listFocuses(options = {}) {
75
+ const statuses = options.statuses ?? ["active", "paused"];
76
+ if (statuses.length === 0) return [];
77
+ const limit = Math.max(1, Math.min(200, options.limit ?? 50));
78
+ const { db } = requireXopcDatabase();
79
+ return db.prepare(`SELECT * FROM focuses WHERE status IN (${statuses.map(() => "?").join(", ")})
80
+ ORDER BY COALESCE(last_activity_at, updated_at) DESC LIMIT ?`).all(...statuses, limit).map((row) => focusFromRow(db, row));
81
+ }
82
+ function createFocus(input) {
83
+ const id = randomUUID();
84
+ const now = input.nowMs ?? Date.now();
85
+ runSqliteWriteTransaction((db) => {
86
+ db.prepare(`INSERT INTO focuses (
87
+ focus_id, title, summary, status, source, source_candidate_id, goal_id,
88
+ created_at, updated_at, last_activity_at
89
+ ) VALUES (?, ?, ?, 'active', ?, ?, ?, ?, ?, ?)`).run(id, input.title.trim().slice(0, 200), input.summary.trim().slice(0, 2e3), input.source ?? "user", input.sourceCandidateId ?? null, input.goalId ?? null, now, now, now);
90
+ const insertProject = db.prepare("INSERT INTO focus_projects (focus_id, project_id, created_at) VALUES (?, ?, ?)");
91
+ for (const projectId of [...new Set(input.projectIds ?? [])].slice(0, 20)) insertProject.run(id, projectId, now);
92
+ insertFocusActivity(db, {
93
+ focusId: id,
94
+ type: "created",
95
+ summary: "Focus created",
96
+ nowMs: now
97
+ });
98
+ });
99
+ return getFocus(id);
100
+ }
101
+ function updateFocus(input) {
102
+ const current = getFocus(input.id);
103
+ if (!current) return null;
104
+ const now = input.nowMs ?? Date.now();
105
+ const status = input.status ?? current.status;
106
+ runSqliteWriteTransaction((db) => {
107
+ db.prepare(`UPDATE focuses SET title = ?, summary = ?, status = ?, completed_at = ?, updated_at = ?
108
+ WHERE focus_id = ?`).run(input.title?.trim().slice(0, 200) || current.title, input.summary?.trim().slice(0, 2e3) || current.summary, status, status === "completed" ? current.completedAt ?? now : null, now, input.id);
109
+ if (input.projectIds) {
110
+ db.prepare("DELETE FROM focus_projects WHERE focus_id = ?").run(input.id);
111
+ const insertProject = db.prepare("INSERT INTO focus_projects (focus_id, project_id, created_at) VALUES (?, ?, ?)");
112
+ for (const projectId of [...new Set(input.projectIds)].slice(0, 20)) insertProject.run(input.id, projectId, now);
113
+ }
114
+ });
115
+ return getFocus(input.id);
116
+ }
117
+ function deleteFocus(id) {
118
+ let deleted = false;
119
+ runSqliteWriteTransaction((db) => {
120
+ deleted = db.prepare("DELETE FROM focuses WHERE focus_id = ?").run(id).changes > 0;
121
+ });
122
+ return deleted;
123
+ }
124
+ function getFocusMonitor(focusId, kind) {
125
+ const { db } = requireXopcDatabase();
126
+ const row = db.prepare("SELECT * FROM focus_monitors WHERE focus_id = ? AND kind = ?").get(focusId, kind);
127
+ return row ? monitorFromRow(row) : null;
128
+ }
129
+ function getFocusMonitorByAutomationId(automationId) {
130
+ const { db } = requireXopcDatabase();
131
+ const row = db.prepare("SELECT * FROM focus_monitors WHERE automation_id = ?").get(automationId);
132
+ return row ? monitorFromRow(row) : null;
133
+ }
134
+ function listFocusMonitors(focusId) {
135
+ const { db } = requireXopcDatabase();
136
+ return db.prepare("SELECT * FROM focus_monitors WHERE focus_id = ? ORDER BY kind").all(focusId).map(monitorFromRow);
137
+ }
138
+ function listAllFocusMonitors() {
139
+ const { db } = requireXopcDatabase();
140
+ return db.prepare("SELECT * FROM focus_monitors ORDER BY updated_at DESC").all().map(monitorFromRow);
141
+ }
142
+ function upsertFocusMonitor(input) {
143
+ const existing = getFocusMonitor(input.focusId, input.kind);
144
+ const id = existing?.id ?? randomUUID();
145
+ const now = input.nowMs ?? Date.now();
146
+ runSqliteWriteTransaction((db) => {
147
+ db.prepare(`INSERT INTO focus_monitors (
148
+ monitor_id, focus_id, kind, enabled, run_state, cadence_json, automation_id,
149
+ consecutive_failures, created_at, updated_at
150
+ ) VALUES (?, ?, ?, ?, ?, ?, ?, 0, ?, ?)
151
+ ON CONFLICT(focus_id, kind) DO UPDATE SET
152
+ enabled = excluded.enabled,
153
+ run_state = excluded.run_state,
154
+ cadence_json = excluded.cadence_json,
155
+ automation_id = excluded.automation_id,
156
+ last_error = CASE WHEN excluded.enabled = 1 THEN NULL ELSE focus_monitors.last_error END,
157
+ updated_at = excluded.updated_at`).run(id, input.focusId, input.kind, input.enabled ? 1 : 0, input.runState ?? "idle", JSON.stringify(input.cadence), input.automationId === void 0 ? existing?.automationId ?? null : input.automationId, existing?.createdAt ?? now, now);
158
+ });
159
+ return getFocusMonitor(input.focusId, input.kind);
160
+ }
161
+ function updateFocusMonitorRuntime(input) {
162
+ const now = input.nowMs ?? Date.now();
163
+ let changed = false;
164
+ runSqliteWriteTransaction((db) => {
165
+ changed = db.prepare(`UPDATE focus_monitors SET
166
+ run_state = ?,
167
+ automation_id = COALESCE(?, automation_id),
168
+ last_run_id = COALESCE(?, last_run_id),
169
+ last_run_at = COALESCE(?, last_run_at),
170
+ next_run_at = CASE WHEN ? = 1 THEN ? ELSE next_run_at END,
171
+ last_meaningful_result_at = CASE WHEN ? = 1 THEN ? ELSE last_meaningful_result_at END,
172
+ last_error = ?,
173
+ consecutive_failures = CASE WHEN ? IS NOT NULL THEN consecutive_failures + 1 ELSE 0 END,
174
+ updated_at = ?
175
+ WHERE monitor_id = ?`).run(input.runState, input.automationId ?? null, input.lastRunId ?? null, input.lastRunAt ?? null, input.nextRunAt === void 0 ? 0 : 1, input.nextRunAt ?? null, input.meaningful ? 1 : 0, now, input.error ?? null, input.error ?? null, now, input.id).changes > 0;
176
+ });
177
+ if (!changed) return null;
178
+ const { db } = requireXopcDatabase();
179
+ return monitorFromRow(db.prepare("SELECT * FROM focus_monitors WHERE monitor_id = ?").get(input.id));
180
+ }
181
+ function insertFocusActivity(db, input) {
182
+ const id = randomUUID();
183
+ db.prepare(`INSERT INTO focus_activities (
184
+ activity_id, focus_id, monitor_id, type, summary, details_json, created_at
185
+ ) VALUES (?, ?, ?, ?, ?, ?, ?)`).run(id, input.focusId, input.monitorId ?? null, input.type, input.summary.slice(0, 500), JSON.stringify(input.details ?? {}), input.nowMs);
186
+ db.prepare("UPDATE focuses SET last_activity_at = ?, updated_at = MAX(updated_at, ?) WHERE focus_id = ?").run(input.nowMs, input.nowMs, input.focusId);
187
+ return {
188
+ id,
189
+ focusId: input.focusId,
190
+ ...input.monitorId ? { monitorId: input.monitorId } : {},
191
+ type: input.type,
192
+ summary: input.summary.slice(0, 500),
193
+ details: input.details ?? {},
194
+ createdAt: input.nowMs
195
+ };
196
+ }
197
+ function createFocusActivity(input) {
198
+ let activity;
199
+ runSqliteWriteTransaction((db) => {
200
+ activity = insertFocusActivity(db, {
201
+ ...input,
202
+ nowMs: input.nowMs ?? Date.now()
203
+ });
204
+ });
205
+ return activity;
206
+ }
207
+ function listFocusActivities(input) {
208
+ const limit = Math.max(1, Math.min(100, input.limit ?? 30));
209
+ const { db } = requireXopcDatabase();
210
+ return db.prepare(`SELECT * FROM focus_activities WHERE focus_id = ? AND created_at < ?
211
+ ORDER BY created_at DESC, activity_id DESC LIMIT ?`).all(input.focusId, input.before ?? Number.MAX_SAFE_INTEGER, limit).map(activityFromRow);
212
+ }
213
+ //#endregion
214
+ export { createFocus, createFocusActivity, deleteFocus, getFocus, getFocusMonitor, getFocusMonitorByAutomationId, listAllFocusMonitors, listFocusActivities, listFocusMonitors, listFocuses, updateFocus, updateFocusMonitorRuntime, upsertFocusMonitor };
@@ -0,0 +1,18 @@
1
+ import type { AutomationRun } from '../automations/index.js';
2
+ import type { FocusEvidence, FocusInsight } from './types.js';
3
+ interface MeaningfulResult {
4
+ meaningful: true;
5
+ title: string;
6
+ summary: string;
7
+ whyItMatters: string;
8
+ nextAction: string;
9
+ evidence: FocusEvidence[];
10
+ }
11
+ export declare function parseFocusMonitorResult(summary: string): MeaningfulResult | {
12
+ meaningful: false;
13
+ } | null;
14
+ export declare function processFocusMonitorRun(run: AutomationRun): {
15
+ handled: boolean;
16
+ insight?: FocusInsight;
17
+ };
18
+ export {};
@@ -0,0 +1,162 @@
1
+ import { createLogger } from "../utils/logger/index.js";
2
+ import { init_logger } from "../utils/logger.js";
3
+ import { createFocusActivity, getFocusMonitorByAutomationId, updateFocusMonitorRuntime } from "./repository.js";
4
+ import { createFocusInsight } from "./insight-repository.js";
5
+ //#region src/focuses/run-processor.ts
6
+ init_logger();
7
+ const log = createLogger("FocusRunProcessor");
8
+ function nonEmptyString(value) {
9
+ return typeof value === "string" && value.trim() ? value.trim() : null;
10
+ }
11
+ function parseFocusMonitorResult(summary) {
12
+ const start = summary.indexOf("{");
13
+ const end = summary.lastIndexOf("}");
14
+ if (start < 0 || end <= start) return null;
15
+ let value;
16
+ try {
17
+ value = JSON.parse(summary.slice(start, end + 1));
18
+ } catch {
19
+ return null;
20
+ }
21
+ if (!value || typeof value !== "object" || Array.isArray(value)) return null;
22
+ const result = value;
23
+ if (result.meaningful === false) return { meaningful: false };
24
+ if (result.meaningful !== true) return null;
25
+ const title = nonEmptyString(result.title);
26
+ const resultSummary = nonEmptyString(result.summary);
27
+ const whyItMatters = nonEmptyString(result.whyItMatters);
28
+ const nextAction = nonEmptyString(result.nextAction);
29
+ const evidence = Array.isArray(result.evidence) ? result.evidence.flatMap((item) => {
30
+ if (!item || typeof item !== "object" || Array.isArray(item)) return [];
31
+ const record = item;
32
+ const label = nonEmptyString(record.label);
33
+ const source = nonEmptyString(record.source);
34
+ const publishedAtValue = nonEmptyString(record.publishedAt);
35
+ const publishedAt = publishedAtValue && Number.isFinite(Date.parse(publishedAtValue)) ? new Date(publishedAtValue).toISOString() : null;
36
+ return label ? [{
37
+ label,
38
+ ...source ? { source } : {},
39
+ ...publishedAt ? { publishedAt } : {}
40
+ }] : [];
41
+ }).slice(0, 8) : [];
42
+ if (!title || !resultSummary || !whyItMatters || !nextAction || evidence.length === 0) return null;
43
+ return {
44
+ meaningful: true,
45
+ title,
46
+ summary: resultSummary,
47
+ whyItMatters,
48
+ nextAction,
49
+ evidence
50
+ };
51
+ }
52
+ function hasDatedExternalEvidence(evidence) {
53
+ return evidence.some((item) => {
54
+ if (!item.source || !item.publishedAt) return false;
55
+ try {
56
+ const url = new URL(item.source);
57
+ return (url.protocol === "https:" || url.protocol === "http:") && Number.isFinite(Date.parse(item.publishedAt));
58
+ } catch {
59
+ return false;
60
+ }
61
+ });
62
+ }
63
+ function processFocusMonitorRun(run) {
64
+ const monitor = getFocusMonitorByAutomationId(run.automationId);
65
+ if (!monitor) return { handled: false };
66
+ if (monitor.lastRunId === run.id && monitor.lastRunAt != null) return { handled: true };
67
+ const endedAt = run.endedAtMs ?? Date.now();
68
+ if (run.status !== "succeeded" || !run.summary) {
69
+ const errorMessage = run.error || `Monitor run ${run.status}`;
70
+ updateFocusMonitorRuntime({
71
+ id: monitor.id,
72
+ runState: "failed",
73
+ lastRunId: run.id,
74
+ lastRunAt: endedAt,
75
+ error: errorMessage
76
+ });
77
+ createFocusActivity({
78
+ focusId: monitor.focusId,
79
+ monitorId: monitor.id,
80
+ type: "run_failed",
81
+ summary: errorMessage,
82
+ details: { runId: run.id },
83
+ nowMs: endedAt
84
+ });
85
+ return { handled: true };
86
+ }
87
+ const result = parseFocusMonitorResult(run.summary);
88
+ if (!result || result.meaningful && monitor.kind === "external_changes" && !hasDatedExternalEvidence(result.evidence)) {
89
+ updateFocusMonitorRuntime({
90
+ id: monitor.id,
91
+ runState: "failed",
92
+ lastRunId: run.id,
93
+ lastRunAt: endedAt,
94
+ error: "Monitor returned an invalid result"
95
+ });
96
+ createFocusActivity({
97
+ focusId: monitor.focusId,
98
+ monitorId: monitor.id,
99
+ type: "run_failed",
100
+ summary: "Monitor returned an invalid result",
101
+ details: { runId: run.id },
102
+ nowMs: endedAt
103
+ });
104
+ log.warn({
105
+ automationId: run.automationId,
106
+ runId: run.id,
107
+ monitorKind: monitor.kind
108
+ }, "Focus monitor returned an invalid result");
109
+ return { handled: true };
110
+ }
111
+ updateFocusMonitorRuntime({
112
+ id: monitor.id,
113
+ runState: "idle",
114
+ lastRunId: run.id,
115
+ lastRunAt: endedAt,
116
+ meaningful: result.meaningful,
117
+ error: null
118
+ });
119
+ if (!result.meaningful) {
120
+ createFocusActivity({
121
+ focusId: monitor.focusId,
122
+ monitorId: monitor.id,
123
+ type: "run_no_change",
124
+ summary: "No meaningful change found",
125
+ details: { runId: run.id },
126
+ nowMs: endedAt
127
+ });
128
+ return { handled: true };
129
+ }
130
+ const insight = createFocusInsight({
131
+ focusId: monitor.focusId,
132
+ monitorId: monitor.id,
133
+ runId: run.id,
134
+ kind: monitor.kind,
135
+ title: result.title,
136
+ summary: result.summary,
137
+ whyItMatters: result.whyItMatters,
138
+ nextAction: result.nextAction,
139
+ evidence: result.evidence,
140
+ nowMs: endedAt
141
+ });
142
+ if (insight) {
143
+ createFocusActivity({
144
+ focusId: monitor.focusId,
145
+ monitorId: monitor.id,
146
+ type: "insight_created",
147
+ summary: insight.title,
148
+ details: {
149
+ runId: run.id,
150
+ insightId: insight.id
151
+ },
152
+ nowMs: endedAt
153
+ });
154
+ return {
155
+ handled: true,
156
+ insight
157
+ };
158
+ }
159
+ return { handled: true };
160
+ }
161
+ //#endregion
162
+ export { parseFocusMonitorResult, processFocusMonitorRun };
@@ -0,0 +1,42 @@
1
+ import type { Automation, AutomationRun } from '../automations/index.js';
2
+ import type { FocusCadence, FocusDetail, FocusMonitor, FocusMonitorKind, FocusStatus } from './types.js';
3
+ export interface FocusAutomationPort {
4
+ create(input: Parameters<import('../automations/index.js').AutomationService['create']>[0]): Promise<Automation>;
5
+ get(id: string): Promise<Automation | null>;
6
+ update(id: string, input: Parameters<import('../automations/index.js').AutomationService['update']>[1]): Promise<Automation>;
7
+ pause(id: string): Promise<Automation>;
8
+ resume(id: string): Promise<Automation>;
9
+ remove(id: string): Promise<boolean>;
10
+ runNow(id: string): Promise<AutomationRun>;
11
+ }
12
+ export declare class FocusService {
13
+ private readonly automations;
14
+ constructor(automations: FocusAutomationPort);
15
+ list(statuses?: FocusStatus[]): FocusDetail[];
16
+ get(id: string): FocusDetail | null;
17
+ create(input: {
18
+ title: string;
19
+ summary: string;
20
+ projectIds?: string[];
21
+ goalId?: string;
22
+ }): FocusDetail;
23
+ update(id: string, input: {
24
+ title?: string;
25
+ summary?: string;
26
+ projectIds?: string[];
27
+ }): FocusDetail | null;
28
+ setStatus(id: string, status: FocusStatus): Promise<FocusDetail | null>;
29
+ remove(id: string): Promise<boolean>;
30
+ configureMonitor(input: {
31
+ focusId: string;
32
+ kind: FocusMonitorKind;
33
+ enabled: boolean;
34
+ cadence?: FocusCadence;
35
+ }): Promise<{
36
+ monitor: FocusMonitor;
37
+ initialRunId?: string;
38
+ }>;
39
+ runMonitorNow(focusId: string, kind: FocusMonitorKind): Promise<AutomationRun>;
40
+ reconcile(): Promise<void>;
41
+ private detail;
42
+ }