@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
@@ -11,7 +11,7 @@
11
11
  <link rel="apple-touch-icon" sizes="180x180" href="/apple-touch-icon.png?v=20260713-1" />
12
12
  <link rel="manifest" href="/site.webmanifest?v=20260713-1" />
13
13
  <title>XOPC — Turn goals into loops. Keep what matters moving.</title>
14
- <script type="module" crossorigin src="/assets/index-CAZ9343h.js"></script>
14
+ <script type="module" crossorigin src="/assets/index-TnouSpay.js"></script>
15
15
  <link rel="modulepreload" crossorigin href="/assets/rolldown-runtime-aKtaBQYM.js">
16
16
  <link rel="modulepreload" crossorigin href="/assets/preload-helper-zJ_50EbN.js">
17
17
  <link rel="modulepreload" crossorigin href="/assets/vendor-react-BOUWij0V.js">
@@ -24,17 +24,17 @@
24
24
  <link rel="modulepreload" crossorigin href="/assets/check-DUBLcKHA.js">
25
25
  <link rel="modulepreload" crossorigin href="/assets/circle-alert-BEjgurr2.js">
26
26
  <link rel="modulepreload" crossorigin href="/assets/middleware-Pd0e8Igk.js">
27
- <link rel="modulepreload" crossorigin href="/assets/messages-DWrg3c4K.js">
28
- <link rel="modulepreload" crossorigin href="/assets/locale-store-Ccv7tH8B.js">
27
+ <link rel="modulepreload" crossorigin href="/assets/messages-BP8aQX-5.js">
28
+ <link rel="modulepreload" crossorigin href="/assets/locale-store-DO-u1yS7.js">
29
29
  <link rel="modulepreload" crossorigin href="/assets/cn-JdwAhgNB.js">
30
30
  <link rel="modulepreload" crossorigin href="/assets/schemas-DgQq6Z5S.js">
31
31
  <link rel="modulepreload" crossorigin href="/assets/product-delivery-BTRT9kCS.js">
32
32
  <link rel="modulepreload" crossorigin href="/assets/config-reload-event-Bjh2zoKp.js">
33
33
  <link rel="modulepreload" crossorigin href="/assets/copy-to-clipboard-HOJ79TWv.js">
34
- <link rel="modulepreload" crossorigin href="/assets/gateway-startup-retry-C2JXXtwg.js">
35
- <link rel="modulepreload" crossorigin href="/assets/activity-store-ByVA0N5n.js">
36
- <link rel="modulepreload" crossorigin href="/assets/theme-store-DCKDVPFF.js">
37
- <link rel="stylesheet" crossorigin href="/assets/index-BCkNJ5cR.css">
34
+ <link rel="modulepreload" crossorigin href="/assets/gateway-startup-retry-C8f5KwkT.js">
35
+ <link rel="modulepreload" crossorigin href="/assets/activity-store-CM6mQUS2.js">
36
+ <link rel="modulepreload" crossorigin href="/assets/theme-store-BZWNdSZC.js">
37
+ <link rel="stylesheet" crossorigin href="/assets/index-DJ5vdaHk.css">
38
38
  </head>
39
39
  <body>
40
40
  <div id="root"></div>
package/dist/package.js CHANGED
@@ -1,4 +1,4 @@
1
1
  //#region package.json
2
- var version = "0.0.173";
2
+ var version = "0.0.175";
3
3
  //#endregion
4
4
  export { version };
@@ -17,8 +17,8 @@ import { clearBootstrapSnapshot } from "./bootstrap/bootstrap-cache.js";
17
17
  import { resolveBootstrapContextSync } from "./bootstrap/bootstrap-files.js";
18
18
  import { loadProjectAgentsContextFile } from "./bootstrap/project-agents-context.js";
19
19
  import { createSkillConfigManager, isSkillEnabled, resolveSkillConfig } from "./skills/config.js";
20
- import { resolveWorkspaceSkillsDir, resolveWorkspaceSkillsLockPath } from "./skills/workspace-skills-dir.js";
21
20
  import { isValidSkillEnvVarName } from "./skills/required-env-vars.js";
21
+ import { resolveWorkspaceSkillsDir, resolveWorkspaceSkillsLockPath } from "./skills/workspace-skills-dir.js";
22
22
  import { loadSkillsLock } from "./skills/hub-lock.js";
23
23
  import { isUnderManagedSkillsDir } from "./skills/managed-store.js";
24
24
  import { isMemorySubsystemEnabled, shouldRegisterCuratedMemoryTool } from "./memory/memory-config.js";
@@ -3,9 +3,9 @@ import { init_logger } from "../../utils/logger.js";
3
3
  import { init_string_coerce, normalizeOptionalString } from "../../utils/string-coerce.js";
4
4
  import { XopcStdioClientTransport } from "./mcp-stdio-transport.js";
5
5
  import { resolveMcpTransportConfig } from "./mcp-transport-config.js";
6
+ import { fetch } from "undici";
6
7
  import { SSEClientTransport } from "@modelcontextprotocol/sdk/client/sse.js";
7
8
  import { StreamableHTTPClientTransport } from "@modelcontextprotocol/sdk/client/streamableHttp.js";
8
- import { fetch } from "undici";
9
9
  //#region src/agent/mcp/mcp-transport.ts
10
10
  init_logger();
11
11
  init_string_coerce();
@@ -12,6 +12,7 @@ import { getProjectForSession } from "../projects/workspace.js";
12
12
  import { resolveWorkspaceSkillsDir, resolveWorkspaceSkillsLockPath } from "./skills/workspace-skills-dir.js";
13
13
  import { removeSkillsLockEntry } from "./skills/hub-lock.js";
14
14
  import { installSkillFromZip } from "./skills/managed-store.js";
15
+ import { pullSkillFromSource } from "./skills/hub-pull.js";
15
16
  import { normalizeSkillInstallTarget } from "./skills/install-target.js";
16
17
  import { onSessionTranscriptUpdate } from "../session/transcript-events.js";
17
18
  import { persistInboundAttachments } from "../channels/attachments/inbound-persist.js";
@@ -63,7 +64,6 @@ import "./workflow/index.js";
63
64
  import { FeedbackCoordinator } from "./feedback/feedback-coordinator.js";
64
65
  import "./feedback/index.js";
65
66
  import { PersistentGoalService } from "./goals/persistent-goal-service.js";
66
- import { pullSkillFromSource } from "./skills/hub-pull.js";
67
67
  import { existsSync, readFileSync } from "node:fs";
68
68
  import { readFile } from "node:fs/promises";
69
69
  //#region src/agent/service.ts
@@ -1,8 +1,8 @@
1
1
  import { parseFrontmatter } from "../../markdown/frontmatter.js";
2
2
  import { formatScanSummary, scanSkillDirectory } from "./scanner.js";
3
+ import { computeSkillTreeHashSync } from "./hub-hash.js";
3
4
  import { getSkillsLockEntry, recordSkillsHubInstall } from "./hub-lock.js";
4
5
  import { installSkillFromZip, isIgnorableZipEntry, isValidSkillId, prepareManagedSkillTempDir, promoteManagedSkillTempDir } from "./managed-store.js";
5
- import { computeSkillTreeHashSync } from "./hub-hash.js";
6
6
  import { tmpdir } from "node:os";
7
7
  import { basename, dirname, join, normalize, resolve, sep } from "node:path";
8
8
  import { cpSync, existsSync, mkdirSync, mkdtempSync, readFileSync, readdirSync, rmSync, statSync, writeFileSync } from "node:fs";
@@ -5,6 +5,8 @@ export declare function loadSkills(options: {
5
5
  builtinDir?: string;
6
6
  extraDirs?: string[];
7
7
  }): LoadSkillsResult;
8
+ /** Discover only skills owned by a workspace, without global or bundled skills. */
9
+ export declare function loadWorkspaceSkills(workspaceDir: string): LoadSkillsResult;
8
10
  export interface SkillLoader {
9
11
  init: (workspace: string, builtin: string | null) => LoadSkillsResult;
10
12
  load: () => LoadSkillsResult;
@@ -5,12 +5,12 @@ import { init_paths } from "../../config/paths.js";
5
5
  import { parseFrontmatter } from "../../markdown/frontmatter.js";
6
6
  import { findInstallSpec, getDefaultInstallerPreferences, hasBinary, installSkill } from "./installer.js";
7
7
  import { applySkillEnvOverrides, createSkillConfigManager, getSkillEnvironment, isSkillEnabled, resolveSkillConfig, validateSkillConfig } from "./config.js";
8
- import { collectSkillInstallWarnings, formatScanSummary, scanSkillDirectory } from "./scanner.js";
9
- import { resolveWorkspaceSkillsDir } from "./workspace-skills-dir.js";
10
8
  import { parseSkillToolConditions } from "./skill-tool-gating.js";
9
+ import { formatSkillsForPrompt } from "./format-skills-prompt.js";
11
10
  import { parseRequiredEnvVarNames } from "./required-env-vars.js";
12
11
  import { parseSkillMetadata } from "./parse-skill-metadata.js";
13
- import { formatSkillsForPrompt } from "./format-skills-prompt.js";
12
+ import { resolveWorkspaceSkillsDir } from "./workspace-skills-dir.js";
13
+ import { collectSkillInstallWarnings, formatScanSummary, scanSkillDirectory } from "./scanner.js";
14
14
  import { SkillTestFramework, SkillTestRunner, formatTestResults, formatTestResultsJson, formatTestResultsTap } from "./test-framework.js";
15
15
  import { basename, dirname, join, relative, sep } from "path";
16
16
  import { existsSync, readFileSync, readdirSync } from "fs";
@@ -193,7 +193,7 @@ function loadSkills(options) {
193
193
  for (const skill of discovered.skills) skillMap.set(skill.name, skill);
194
194
  }
195
195
  if (workspaceDir) {
196
- const discovered = discoverSkills(resolveWorkspaceSkillsDir(workspaceDir), "workspace");
196
+ const discovered = loadWorkspaceSkills(workspaceDir);
197
197
  diagnostics.push(...discovered.diagnostics);
198
198
  const workspaceSkills = discovered.skills;
199
199
  for (const skill of workspaceSkills) skillMap.set(skill.name, skill);
@@ -211,6 +211,15 @@ function loadSkills(options) {
211
211
  diagnostics
212
212
  };
213
213
  }
214
+ /** Discover only skills owned by a workspace, without global or bundled skills. */
215
+ function loadWorkspaceSkills(workspaceDir) {
216
+ const discovered = discoverSkills(resolveWorkspaceSkillsDir(workspaceDir), "workspace");
217
+ return {
218
+ skills: discovered.skills,
219
+ prompt: formatSkillsForPrompt(discovered.skills),
220
+ diagnostics: discovered.diagnostics
221
+ };
222
+ }
214
223
  function createSkillLoader() {
215
224
  let cachedSkills = [];
216
225
  let cachedPrompt = "";
@@ -270,4 +279,4 @@ function createSkillLoader() {
270
279
  };
271
280
  }
272
281
  //#endregion
273
- export { SkillTestFramework, SkillTestRunner, applySkillEnvOverrides, collectSkillInstallWarnings, createSkillConfigManager, createSkillLoader, findInstallSpec, formatScanSummary, formatTestResults, formatTestResultsJson, formatTestResultsTap, getDefaultInstallerPreferences, getSkillEnvironment, hasBinary, installSkill, isSkillEnabled, loadSkills, resolveSkillConfig, scanSkillDirectory, validateSkillConfig };
282
+ export { SkillTestFramework, SkillTestRunner, applySkillEnvOverrides, collectSkillInstallWarnings, createSkillConfigManager, createSkillLoader, findInstallSpec, formatScanSummary, formatTestResults, formatTestResultsJson, formatTestResultsTap, getDefaultInstallerPreferences, getSkillEnvironment, hasBinary, installSkill, isSkillEnabled, loadSkills, loadWorkspaceSkills, resolveSkillConfig, scanSkillDirectory, validateSkillConfig };
@@ -1,5 +1,5 @@
1
- import { MAX_EXTENSION_STORE_ZIP_BYTES } from "../../../../../extensions/store-zip-limits.js";
2
1
  import { MAX_SKILL_ZIP_BYTES, isValidSkillId } from "../../../managed-store.js";
2
+ import { MAX_EXTENSION_STORE_ZIP_BYTES } from "../../../../../extensions/store-zip-limits.js";
3
3
  import { createHash } from "node:crypto";
4
4
  //#region src/agent/skills/marketplace/adapters/store/store-api-client.ts
5
5
  /**
@@ -1,8 +1,8 @@
1
1
  import { init_paths, resolveSkillsDir } from "../../config/paths.js";
2
2
  import { parseFrontmatter } from "../../markdown/frontmatter.js";
3
3
  import { fuzzyFindText, normalizeForFuzzyMatch, normalizeToLF, restoreLineEndings } from "../tools/edit-diff.js";
4
- import { formatScanSummary, scanSkillDirectory } from "./scanner.js";
5
4
  import { resolveWorkspaceSkillsDir } from "./workspace-skills-dir.js";
5
+ import { formatScanSummary, scanSkillDirectory } from "./scanner.js";
6
6
  import { join, resolve, sep } from "path";
7
7
  import { existsSync, realpathSync } from "fs";
8
8
  import { mkdir, writeFile } from "fs/promises";
@@ -2,8 +2,8 @@ import { createLogger } from "../../utils/logger/index.js";
2
2
  import { init_logger } from "../../utils/logger.js";
3
3
  import { parseFrontmatter } from "../../markdown/frontmatter.js";
4
4
  import { hasBinary } from "./installer.js";
5
- import { scanSkillDirectory } from "./scanner.js";
6
5
  import { parseSkillMetadata } from "./parse-skill-metadata.js";
6
+ import { scanSkillDirectory } from "./scanner.js";
7
7
  import { basename, join, relative } from "path";
8
8
  import { existsSync, readFileSync, readdirSync } from "fs";
9
9
  //#region src/agent/skills/test-framework.ts
@@ -0,0 +1 @@
1
+ export declare const DEFAULT_AUTOMATION_TIMEOUT_SECONDS = 300;
@@ -0,0 +1,4 @@
1
+ //#region src/automations/domain/defaults.ts
2
+ const DEFAULT_AUTOMATION_TIMEOUT_SECONDS = 300;
3
+ //#endregion
4
+ export { DEFAULT_AUTOMATION_TIMEOUT_SECONDS };
@@ -1,3 +1,4 @@
1
+ export * from './defaults.js';
1
2
  export * from './schedule.js';
2
3
  export * from './types.js';
3
4
  export * from './validation.js';
@@ -1,3 +1,4 @@
1
+ import { DEFAULT_AUTOMATION_TIMEOUT_SECONDS } from "./defaults.js";
1
2
  import { computeNextAutomationRunAtMs, computeNextScheduleRunAtMs, timerDelayUntil } from "./schedule.js";
2
3
  import { AutomationActionSchema, AutomationAfterRunSchema, AutomationReliabilitySchema, AutomationSafetyPolicySchema, AutomationScheduleSchema, AutomationSchema, AutomationStateSchema, AutomationTriggerSchema, CreateAutomationSchema, UpdateAutomationSchema } from "./validation.js";
3
- export { AutomationActionSchema, AutomationAfterRunSchema, AutomationReliabilitySchema, AutomationSafetyPolicySchema, AutomationScheduleSchema, AutomationSchema, AutomationStateSchema, AutomationTriggerSchema, CreateAutomationSchema, UpdateAutomationSchema, computeNextAutomationRunAtMs, computeNextScheduleRunAtMs, timerDelayUntil };
4
+ export { AutomationActionSchema, AutomationAfterRunSchema, AutomationReliabilitySchema, AutomationSafetyPolicySchema, AutomationScheduleSchema, AutomationSchema, AutomationStateSchema, AutomationTriggerSchema, CreateAutomationSchema, DEFAULT_AUTOMATION_TIMEOUT_SECONDS, UpdateAutomationSchema, computeNextAutomationRunAtMs, computeNextScheduleRunAtMs, timerDelayUntil };
@@ -1,8 +1,9 @@
1
1
  import { onAutomationProductEvent, publishAutomationProductEvent } from "./product-events.js";
2
+ import { DEFAULT_AUTOMATION_TIMEOUT_SECONDS } from "./domain/defaults.js";
2
3
  import { computeNextAutomationRunAtMs, computeNextScheduleRunAtMs, timerDelayUntil } from "./domain/schedule.js";
3
4
  import { AutomationActionSchema, AutomationAfterRunSchema, AutomationReliabilitySchema, AutomationSafetyPolicySchema, AutomationScheduleSchema, AutomationSchema, AutomationStateSchema, AutomationTriggerSchema, CreateAutomationSchema, UpdateAutomationSchema } from "./domain/validation.js";
4
5
  import "./domain/index.js";
5
6
  import { AutomationActionExecutor } from "./service/action-executor.js";
6
7
  import { AutomationAlreadyRunningError, AutomationService } from "./service/automation-service.js";
7
8
  import "./service/index.js";
8
- export { AutomationActionExecutor, AutomationActionSchema, AutomationAfterRunSchema, AutomationAlreadyRunningError, AutomationReliabilitySchema, AutomationSafetyPolicySchema, AutomationScheduleSchema, AutomationSchema, AutomationService, AutomationStateSchema, AutomationTriggerSchema, CreateAutomationSchema, UpdateAutomationSchema, computeNextAutomationRunAtMs, computeNextScheduleRunAtMs, onAutomationProductEvent, publishAutomationProductEvent, timerDelayUntil };
9
+ export { AutomationActionExecutor, AutomationActionSchema, AutomationAfterRunSchema, AutomationAlreadyRunningError, AutomationReliabilitySchema, AutomationSafetyPolicySchema, AutomationScheduleSchema, AutomationSchema, AutomationService, AutomationStateSchema, AutomationTriggerSchema, CreateAutomationSchema, DEFAULT_AUTOMATION_TIMEOUT_SECONDS, UpdateAutomationSchema, computeNextAutomationRunAtMs, computeNextScheduleRunAtMs, onAutomationProductEvent, publishAutomationProductEvent, timerDelayUntil };
@@ -2,13 +2,13 @@ import { createLogger } from "../../utils/logger/index.js";
2
2
  import { init_logger } from "../../utils/logger.js";
3
3
  import { init_agent_scope, normalizeAgentId } from "../../agent/agent-scope.js";
4
4
  import { buildSessionKey, init_session_key } from "../../routing/session-key.js";
5
+ import "../domain/defaults.js";
5
6
  import crypto from "node:crypto";
6
7
  //#region src/automations/service/action-executor.ts
7
8
  init_agent_scope();
8
9
  init_session_key();
9
10
  init_logger();
10
11
  const log = createLogger("Automation:ActionExecutor");
11
- const DEFAULT_TIMEOUT_MS = 18e4;
12
12
  function withTimeout(promise, timeoutMs, signal) {
13
13
  return new Promise((resolve, reject) => {
14
14
  if (signal.aborted) {
@@ -41,7 +41,7 @@ var AutomationActionExecutor = class {
41
41
  };
42
42
  }
43
43
  async execute(automation, run, signal) {
44
- const timeoutMs = (automation.action.timeoutSeconds ?? automation.reliability?.timeoutSeconds ?? 0) > 0 ? (automation.action.timeoutSeconds ?? automation.reliability?.timeoutSeconds) * 1e3 : DEFAULT_TIMEOUT_MS;
44
+ const timeoutMs = (automation.action.timeoutSeconds ?? automation.reliability?.timeoutSeconds ?? 0) > 0 ? (automation.action.timeoutSeconds ?? automation.reliability?.timeoutSeconds) * 1e3 : 300 * 1e3;
45
45
  return withTimeout(this.executeWithoutTimeout(automation, run, signal), timeoutMs, signal).catch((err) => {
46
46
  const message = err instanceof Error ? err.message : String(err);
47
47
  return {
@@ -52,7 +52,7 @@ async function checkDatabaseSchema(ctx) {
52
52
  id: "database-schema",
53
53
  label: "Database schema",
54
54
  status: "pass",
55
- message: `SQLite schema v${status.dbVersion} (current release v65).`,
55
+ message: `SQLite schema v${status.dbVersion} (current release v67).`,
56
56
  hints: []
57
57
  };
58
58
  }
@@ -1,8 +1,8 @@
1
1
  import { init_paths, resolveConfigPath } from "../../../config/paths.js";
2
2
  import { loadConfig } from "../../../config/loader.js";
3
3
  import "../../../config/index.js";
4
- import { isRestartEnabled } from "../../../config/commands.flags.js";
5
4
  import { resolveGatewayService } from "../../../daemon/service.js";
5
+ import { isRestartEnabled } from "../../../config/commands.flags.js";
6
6
  import { authorizeGatewaySigusr1Restart, writeGatewayRestartIntentSync } from "../../../infra/restart.js";
7
7
  import { findVerifiedGatewayListenerPidsOnPortSync, formatGatewayPidList, signalVerifiedGatewayPidSync } from "../../../infra/gateway-processes.js";
8
8
  import { runServiceRestart, runServiceStop } from "./lifecycle-core.js";
@@ -3,8 +3,8 @@ import { init_paths, resolveBundledSkillsDir, resolveSkillsLockPath } from "../.
3
3
  import { findInstallSpec, getDefaultInstallerPreferences, hasBinary, installSkill } from "../../agent/skills/installer.js";
4
4
  import { createSkillConfigManager, isSkillEnabled } from "../../agent/skills/config.js";
5
5
  import { formatScanSummary, scanSkillDirectory } from "../../agent/skills/scanner.js";
6
- import { loadSkillsLock } from "../../agent/skills/hub-lock.js";
7
6
  import { createSkillLoader } from "../../agent/skills/index.js";
7
+ import { loadSkillsLock } from "../../agent/skills/hub-lock.js";
8
8
  import { pullSkillFromSource, updateSkillFromLock } from "../../agent/skills/hub-pull.js";
9
9
  import { register } from "../registry.js";
10
10
  import { createSkillsTestCommand } from "./skills-test.js";
@@ -1,6 +1,6 @@
1
+ import { init_agent_scope, normalizeAgentId, resolveAgentWorkspaceDir } from "../agent/agent-scope.js";
1
2
  import { resolveEffectiveAgentManifest } from "../agent-manifest/resolver.js";
2
3
  import "../agent-manifest/index.js";
3
- import { init_agent_scope, normalizeAgentId, resolveAgentWorkspaceDir } from "../agent/agent-scope.js";
4
4
  import { init_session_key, parseSessionKey } from "../routing/session-key.js";
5
5
  import { agentExists, getDefaultAgentId, init_resolve_route } from "../routing/resolve-route.js";
6
6
  //#region src/config/agent-profile.ts
@@ -0,0 +1,15 @@
1
+ import type { FocusCandidate, FocusCandidateStatus, FocusEvidence } from './types.js';
2
+ import type { Focus } from './types.js';
3
+ export declare function getFocusCandidate(id: string): FocusCandidate | null;
4
+ export declare function listFocusCandidates(status?: FocusCandidateStatus, limit?: number): FocusCandidate[];
5
+ export declare function upsertFocusCandidate(input: {
6
+ canonicalKey: string;
7
+ title: string;
8
+ summary: string;
9
+ confidence: number;
10
+ evidence?: FocusEvidence[];
11
+ projectIds?: string[];
12
+ nowMs?: number;
13
+ }): FocusCandidate;
14
+ export declare function setFocusCandidateStatus(id: string, status: FocusCandidateStatus, nowMs?: number): FocusCandidate | null;
15
+ export declare function acceptFocusCandidate(id: string, nowMs?: number): Focus | null;
@@ -0,0 +1,91 @@
1
+ import { requireXopcDatabase } from "../storage/sqlite/connection.js";
2
+ import { runSqliteWriteTransaction } from "../storage/sqlite/transaction.js";
3
+ import { getFocus } from "./repository.js";
4
+ import { randomUUID } from "node:crypto";
5
+ //#region src/focuses/candidate-repository.ts
6
+ function projectIdsForCandidate(db, id) {
7
+ return db.prepare("SELECT project_id FROM focus_candidate_projects WHERE candidate_id = ? ORDER BY created_at, project_id").all(id).map((row) => row.project_id);
8
+ }
9
+ function candidateFromRow(db, row) {
10
+ let evidence = [];
11
+ try {
12
+ const parsed = JSON.parse(row.evidence_json);
13
+ if (Array.isArray(parsed)) evidence = parsed;
14
+ } catch {
15
+ evidence = [];
16
+ }
17
+ return {
18
+ id: row.candidate_id,
19
+ canonicalKey: row.canonical_key,
20
+ title: row.title,
21
+ summary: row.summary,
22
+ confidence: row.confidence,
23
+ evidence,
24
+ projectIds: projectIdsForCandidate(db, row.candidate_id),
25
+ status: row.status,
26
+ discoveredAt: row.discovered_at,
27
+ updatedAt: row.updated_at
28
+ };
29
+ }
30
+ function getFocusCandidate(id) {
31
+ const { db } = requireXopcDatabase();
32
+ const row = db.prepare("SELECT * FROM focus_candidates WHERE candidate_id = ?").get(id);
33
+ return row ? candidateFromRow(db, row) : null;
34
+ }
35
+ function listFocusCandidates(status = "pending", limit = 20) {
36
+ const { db } = requireXopcDatabase();
37
+ return db.prepare("SELECT * FROM focus_candidates WHERE status = ? ORDER BY updated_at DESC LIMIT ?").all(status, Math.max(1, Math.min(100, limit))).map((row) => candidateFromRow(db, row));
38
+ }
39
+ function upsertFocusCandidate(input) {
40
+ const now = input.nowMs ?? Date.now();
41
+ const id = randomUUID();
42
+ runSqliteWriteTransaction((db) => {
43
+ db.prepare(`INSERT INTO focus_candidates (
44
+ candidate_id, canonical_key, title, summary, confidence, evidence_json,
45
+ status, discovered_at, updated_at
46
+ ) VALUES (?, ?, ?, ?, ?, ?, 'pending', ?, ?)
47
+ ON CONFLICT(canonical_key) DO UPDATE SET
48
+ title = CASE WHEN focus_candidates.status = 'pending' THEN excluded.title ELSE focus_candidates.title END,
49
+ summary = CASE WHEN focus_candidates.status = 'pending' THEN excluded.summary ELSE focus_candidates.summary END,
50
+ confidence = CASE WHEN focus_candidates.status = 'pending' THEN excluded.confidence ELSE focus_candidates.confidence END,
51
+ evidence_json = CASE WHEN focus_candidates.status = 'pending' THEN excluded.evidence_json ELSE focus_candidates.evidence_json END,
52
+ updated_at = excluded.updated_at`).run(id, input.canonicalKey.trim().slice(0, 300), input.title.trim().slice(0, 200), input.summary.trim().slice(0, 2e3), Math.max(0, Math.min(1, input.confidence)), JSON.stringify(input.evidence ?? []), now, now);
53
+ const row = db.prepare("SELECT candidate_id, status FROM focus_candidates WHERE canonical_key = ?").get(input.canonicalKey.trim().slice(0, 300));
54
+ if (row.status === "pending") {
55
+ db.prepare("DELETE FROM focus_candidate_projects WHERE candidate_id = ?").run(row.candidate_id);
56
+ const insertProject = db.prepare("INSERT INTO focus_candidate_projects (candidate_id, project_id, created_at) VALUES (?, ?, ?)");
57
+ for (const projectId of [...new Set(input.projectIds ?? [])].slice(0, 20)) insertProject.run(row.candidate_id, projectId, now);
58
+ }
59
+ });
60
+ const { db } = requireXopcDatabase();
61
+ return candidateFromRow(db, db.prepare("SELECT * FROM focus_candidates WHERE canonical_key = ?").get(input.canonicalKey.trim().slice(0, 300)));
62
+ }
63
+ function setFocusCandidateStatus(id, status, nowMs = Date.now()) {
64
+ let changed = false;
65
+ runSqliteWriteTransaction((db) => {
66
+ changed = db.prepare("UPDATE focus_candidates SET status = ?, updated_at = ? WHERE candidate_id = ?").run(status, nowMs, id).changes > 0;
67
+ });
68
+ return changed ? getFocusCandidate(id) : null;
69
+ }
70
+ function acceptFocusCandidate(id, nowMs = Date.now()) {
71
+ const candidate = getFocusCandidate(id);
72
+ if (!candidate) return null;
73
+ const existing = requireXopcDatabase().db.prepare("SELECT focus_id FROM focuses WHERE source_candidate_id = ?").get(id);
74
+ if (existing) return getFocus(existing.focus_id);
75
+ const focusId = randomUUID();
76
+ runSqliteWriteTransaction((db) => {
77
+ db.prepare(`INSERT INTO focuses (
78
+ focus_id, title, summary, status, source, source_candidate_id,
79
+ created_at, updated_at, last_activity_at
80
+ ) VALUES (?, ?, ?, 'active', 'discovery', ?, ?, ?, ?)`).run(focusId, candidate.title, candidate.summary, candidate.id, nowMs, nowMs, nowMs);
81
+ const insertProject = db.prepare("INSERT INTO focus_projects (focus_id, project_id, created_at) VALUES (?, ?, ?)");
82
+ for (const projectId of candidate.projectIds) insertProject.run(focusId, projectId, nowMs);
83
+ db.prepare(`INSERT INTO focus_activities (
84
+ activity_id, focus_id, type, summary, details_json, created_at
85
+ ) VALUES (?, ?, 'created', 'Focus created from discovery', '{}', ?)`).run(randomUUID(), focusId, nowMs);
86
+ db.prepare("UPDATE focus_candidates SET status = 'accepted', updated_at = ? WHERE candidate_id = ?").run(nowMs, candidate.id);
87
+ });
88
+ return getFocus(focusId);
89
+ }
90
+ //#endregion
91
+ export { acceptFocusCandidate, getFocusCandidate, listFocusCandidates, setFocusCandidateStatus, upsertFocusCandidate };
@@ -0,0 +1,7 @@
1
+ export * from './types.js';
2
+ export * from './repository.js';
3
+ export * from './candidate-repository.js';
4
+ export * from './insight-repository.js';
5
+ export * from './service.js';
6
+ export * from './run-processor.js';
7
+ export * from './reconciler.js';
@@ -0,0 +1,7 @@
1
+ import { createFocus, createFocusActivity, deleteFocus, getFocus, getFocusMonitor, getFocusMonitorByAutomationId, listAllFocusMonitors, listFocusActivities, listFocusMonitors, listFocuses, updateFocus, updateFocusMonitorRuntime, upsertFocusMonitor } from "./repository.js";
2
+ import { acceptFocusCandidate, getFocusCandidate, listFocusCandidates, setFocusCandidateStatus, upsertFocusCandidate } from "./candidate-repository.js";
3
+ import { createFocusInsight, getFocusInsight, listFocusInsights, setFocusInsightStatus } from "./insight-repository.js";
4
+ import { FocusService } from "./service.js";
5
+ import { parseFocusMonitorResult, processFocusMonitorRun } from "./run-processor.js";
6
+ import { startFocusReconciler } from "./reconciler.js";
7
+ export { FocusService, acceptFocusCandidate, createFocus, createFocusActivity, createFocusInsight, deleteFocus, getFocus, getFocusCandidate, getFocusInsight, getFocusMonitor, getFocusMonitorByAutomationId, listAllFocusMonitors, listFocusActivities, listFocusCandidates, listFocusInsights, listFocusMonitors, listFocuses, parseFocusMonitorResult, processFocusMonitorRun, setFocusCandidateStatus, setFocusInsightStatus, startFocusReconciler, updateFocus, updateFocusMonitorRuntime, upsertFocusCandidate, upsertFocusMonitor };
@@ -0,0 +1,22 @@
1
+ import type { FocusEvidence, FocusInsight, FocusInsightStatus, FocusMonitorKind } from './types.js';
2
+ export declare function getFocusInsight(id: string): FocusInsight | null;
3
+ export declare function listFocusInsights(input: {
4
+ focusId: string;
5
+ statuses?: FocusInsightStatus[];
6
+ limit?: number;
7
+ }): FocusInsight[];
8
+ export declare function createFocusInsight(input: {
9
+ focusId: string;
10
+ monitorId: string;
11
+ runId: string;
12
+ kind: FocusMonitorKind;
13
+ title: string;
14
+ summary: string;
15
+ whyItMatters: string;
16
+ nextAction: string;
17
+ evidence: FocusEvidence[];
18
+ valueScore?: number;
19
+ valueReasons?: string[];
20
+ nowMs?: number;
21
+ }): FocusInsight | null;
22
+ export declare function setFocusInsightStatus(id: string, status: FocusInsightStatus, expectedStatus?: FocusInsightStatus, nowMs?: number): FocusInsight | null;
@@ -0,0 +1,77 @@
1
+ import { requireXopcDatabase } from "../storage/sqlite/connection.js";
2
+ import { runSqliteWriteTransaction } from "../storage/sqlite/transaction.js";
3
+ import { createHash, randomUUID } from "node:crypto";
4
+ //#region src/focuses/insight-repository.ts
5
+ function parseArray(value) {
6
+ try {
7
+ const parsed = JSON.parse(value);
8
+ return Array.isArray(parsed) ? parsed : [];
9
+ } catch {
10
+ return [];
11
+ }
12
+ }
13
+ function insightFromRow(row) {
14
+ return {
15
+ id: row.insight_id,
16
+ focusId: row.focus_id,
17
+ monitorId: row.monitor_id,
18
+ runId: row.run_id,
19
+ kind: row.kind,
20
+ title: row.title,
21
+ summary: row.summary,
22
+ whyItMatters: row.why_it_matters,
23
+ nextAction: row.next_action,
24
+ evidence: parseArray(row.evidence_json),
25
+ status: row.status,
26
+ valueScore: row.value_score,
27
+ valueReasons: parseArray(row.value_reasons_json),
28
+ createdAt: row.created_at,
29
+ updatedAt: row.updated_at
30
+ };
31
+ }
32
+ function getFocusInsight(id) {
33
+ const { db } = requireXopcDatabase();
34
+ const row = db.prepare("SELECT * FROM focus_insights WHERE insight_id = ?").get(id);
35
+ return row ? insightFromRow(row) : null;
36
+ }
37
+ function listFocusInsights(input) {
38
+ const statuses = input.statuses ?? ["unread", "approved"];
39
+ if (statuses.length === 0) return [];
40
+ const { db } = requireXopcDatabase();
41
+ return db.prepare(`SELECT * FROM focus_insights WHERE focus_id = ?
42
+ AND status IN (${statuses.map(() => "?").join(", ")})
43
+ ORDER BY created_at DESC LIMIT ?`).all(input.focusId, ...statuses, Math.max(1, Math.min(100, input.limit ?? 20))).map(insightFromRow);
44
+ }
45
+ function createFocusInsight(input) {
46
+ const now = input.nowMs ?? Date.now();
47
+ const id = randomUUID();
48
+ const normalized = JSON.stringify({
49
+ kind: input.kind,
50
+ title: input.title.trim().toLocaleLowerCase(),
51
+ evidence: input.evidence.map((item) => [
52
+ item.label.trim().toLocaleLowerCase(),
53
+ item.source?.trim().toLocaleLowerCase() ?? "",
54
+ item.publishedAt ?? ""
55
+ ])
56
+ });
57
+ const contentHash = createHash("sha256").update(normalized).digest("hex");
58
+ let created = false;
59
+ runSqliteWriteTransaction((db) => {
60
+ created = db.prepare(`INSERT OR IGNORE INTO focus_insights (
61
+ insight_id, focus_id, monitor_id, run_id, kind, title, summary,
62
+ why_it_matters, next_action, evidence_json, content_hash, status,
63
+ value_score, value_reasons_json, created_at, updated_at
64
+ ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, 'unread', ?, ?, ?, ?)`).run(id, input.focusId, input.monitorId, input.runId, input.kind, input.title.trim().slice(0, 200), input.summary.trim().slice(0, 2e3), input.whyItMatters.trim().slice(0, 2e3), input.nextAction.trim().slice(0, 2e3), JSON.stringify(input.evidence), contentHash, input.valueScore ?? 0, JSON.stringify(input.valueReasons ?? []), now, now).changes > 0;
65
+ });
66
+ return created ? getFocusInsight(id) : null;
67
+ }
68
+ function setFocusInsightStatus(id, status, expectedStatus, nowMs = Date.now()) {
69
+ let changed = false;
70
+ runSqliteWriteTransaction((db) => {
71
+ changed = db.prepare(`UPDATE focus_insights SET status = ?, updated_at = ? WHERE insight_id = ?
72
+ ${expectedStatus ? "AND status = ?" : ""}`).run(status, nowMs, id, ...expectedStatus ? [expectedStatus] : []).changes > 0;
73
+ });
74
+ return changed ? getFocusInsight(id) : null;
75
+ }
76
+ //#endregion
77
+ export { createFocusInsight, getFocusInsight, listFocusInsights, setFocusInsightStatus };
@@ -0,0 +1,2 @@
1
+ import type { Focus, FocusMonitorKind } from './types.js';
2
+ export declare function buildFocusMonitorInstruction(focus: Focus, kind: FocusMonitorKind): string;
@@ -0,0 +1,18 @@
1
+ //#region src/focuses/prompts.ts
2
+ function buildFocusMonitorInstruction(focus, kind) {
3
+ const intent = kind === "progress" ? "Look for meaningful progress, blockers, and the most useful next step." : "Search for external changes published since the previous check. Prefer primary sources and include publication dates and canonical URLs.";
4
+ return [
5
+ "Monitor this user-confirmed focus in suggest-only mode.",
6
+ `Focus: ${focus.title}`,
7
+ `Context: ${focus.summary}`,
8
+ intent,
9
+ "Inspect only evidence that changed since the previous check.",
10
+ "Do not modify files, send messages, publish content, or claim progress without evidence.",
11
+ "Return JSON only, with no markdown.",
12
+ "If nothing materially changed: {\"meaningful\":false}.",
13
+ "Otherwise return {\"meaningful\":true,\"title\":\"short title\",\"summary\":\"what changed\",\"whyItMatters\":\"concrete impact\",\"nextAction\":\"one next action\",\"evidence\":[{\"label\":\"specific evidence\",\"source\":\"file, event, or canonical URL\",\"publishedAt\":\"ISO date for external changes\"}]}.",
14
+ "A meaningful result requires specific evidence. Never invent evidence."
15
+ ].join("\n");
16
+ }
17
+ //#endregion
18
+ export { buildFocusMonitorInstruction };
@@ -0,0 +1,5 @@
1
+ interface ReconcileService {
2
+ reconcile(): Promise<void>;
3
+ }
4
+ export declare function startFocusReconciler(service: ReconcileService, intervalMs?: number): () => Promise<void>;
5
+ export {};
@@ -0,0 +1,26 @@
1
+ import { createLogger } from "../utils/logger/index.js";
2
+ import { init_logger } from "../utils/logger.js";
3
+ //#region src/focuses/reconciler.ts
4
+ init_logger();
5
+ const log = createLogger("FocusReconciler");
6
+ const DEFAULT_INTERVAL_MS = 6e4;
7
+ function startFocusReconciler(service, intervalMs = DEFAULT_INTERVAL_MS) {
8
+ let stopped = false;
9
+ let pending = null;
10
+ const reconcile = () => {
11
+ if (stopped || pending) return;
12
+ pending = service.reconcile().catch((err) => log.warn({ err }, "Focus state reconciliation failed")).finally(() => {
13
+ pending = null;
14
+ });
15
+ };
16
+ reconcile();
17
+ const timer = setInterval(reconcile, intervalMs);
18
+ timer.unref();
19
+ return async () => {
20
+ stopped = true;
21
+ clearInterval(timer);
22
+ await pending;
23
+ };
24
+ }
25
+ //#endregion
26
+ export { startFocusReconciler };