@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
@@ -1,10 +1,6 @@
1
1
  import { getAgentDefaultModelRef, init_schema } from "../../../config/schema.js";
2
2
  import { init_providers, resolveModel } from "../../../providers/index.js";
3
3
  import { isLocalModelBaseUrl } from "../../../providers/model-call.js";
4
- import { listFocusCalendarSignals } from "../../../proactive/calendar-signals.js";
5
- import { FocusService } from "../../../proactive/focus-service.js";
6
- import { claimProactiveInsightApproval, getProactiveInsight, setProactiveInsightStatus } from "../../../proactive/insight-repository.js";
7
- import "../../../proactive/index.js";
8
4
  import { previewWorkDiscoveryRoot } from "../../../work-discovery/probe.js";
9
5
  import { WorkDiscoveryService } from "../../../work-discovery/service.js";
10
6
  //#region src/gateway/hono/routes/work-discovery.ts
@@ -30,7 +26,6 @@ function stringField(body, field) {
30
26
  }
31
27
  function registerWorkDiscoveryRoutes(authenticated, deps) {
32
28
  const service = workDiscoveryService(deps);
33
- const focuses = new FocusService(deps.service.automationServiceInstance);
34
29
  const limited = deps.strictRateLimitMiddleware;
35
30
  authenticated.get("/api/onboarding/work-discovery", (c) => c.json({
36
31
  enabled: service.isEnabled(),
@@ -304,240 +299,6 @@ function registerWorkDiscoveryRoutes(authenticated, deps) {
304
299
  error: "Investigation not found"
305
300
  }, 404);
306
301
  });
307
- authenticated.get("/api/work-understanding/threads", (c) => {
308
- const projectId = c.req.query("projectId")?.trim();
309
- const limit = Number(c.req.query("limit"));
310
- return c.json({
311
- ok: true,
312
- threads: service.listWorkThreads({
313
- ...projectId ? { projectId } : {},
314
- ...Number.isFinite(limit) ? { limit } : {}
315
- })
316
- });
317
- });
318
- authenticated.get("/api/work-understanding/metrics", (c) => c.json({
319
- ok: true,
320
- metrics: service.getUnderstandingMetrics()
321
- }));
322
- authenticated.get("/api/work-understanding/sources/:sourceId/lineage", (c) => {
323
- const lineage = service.getSourceLineage(c.req.param("sourceId"));
324
- return lineage ? c.json({
325
- ok: true,
326
- lineage
327
- }) : c.json({
328
- ok: false,
329
- error: "Source not found"
330
- }, 404);
331
- });
332
- authenticated.delete("/api/work-understanding/sources/:sourceId/derived-data", limited, (c) => {
333
- const deleted = service.deleteSourceDerivedData(c.req.param("sourceId"));
334
- return deleted ? c.json({
335
- ok: true,
336
- deleted
337
- }) : c.json({
338
- ok: false,
339
- error: "Source not found"
340
- }, 404);
341
- });
342
- authenticated.get("/api/work-understanding/threads/:threadId", (c) => {
343
- const thread = service.getWorkThread(c.req.param("threadId"));
344
- return thread ? c.json({
345
- ok: true,
346
- thread
347
- }) : c.json({
348
- ok: false,
349
- error: "Work thread not found"
350
- }, 404);
351
- });
352
- authenticated.patch("/api/work-understanding/threads/:threadId", limited, async (c) => {
353
- const body = await c.req.json().catch(() => null);
354
- const decision = stringField(body, "decision");
355
- if (![
356
- "confirmed",
357
- "corrected",
358
- "rejected",
359
- "paused",
360
- "completed"
361
- ].includes(decision)) return c.json({
362
- ok: false,
363
- error: "Invalid work thread decision"
364
- }, 400);
365
- const thread = service.updateWorkThread({
366
- id: c.req.param("threadId"),
367
- decision,
368
- ...stringField(body, "correctedTitle") ? { correctedTitle: stringField(body, "correctedTitle") } : {},
369
- ...stringField(body, "correctedSummary") ? { correctedSummary: stringField(body, "correctedSummary") } : {}
370
- });
371
- return thread ? c.json({
372
- ok: true,
373
- thread
374
- }) : c.json({
375
- ok: false,
376
- error: "Work thread not found"
377
- }, 404);
378
- });
379
- authenticated.get("/api/focuses", (c) => {
380
- return c.json({
381
- ok: true,
382
- focuses: focuses.list({ includeUnreviewed: c.req.query("includeUnreviewed") === "true" })
383
- });
384
- });
385
- authenticated.post("/api/focuses/:focusId/confirm", limited, (c) => {
386
- const focus = focuses.confirm(c.req.param("focusId"));
387
- return focus ? c.json({
388
- ok: true,
389
- focus
390
- }) : c.json({
391
- ok: false,
392
- error: "Focus not found"
393
- }, 404);
394
- });
395
- authenticated.post("/api/focuses/:focusId/watches/trial", limited, async (c) => {
396
- const requestedKind = stringField(await c.req.json().catch(() => null), "kind");
397
- const kind = [
398
- "progress",
399
- "staleness",
400
- "deadline",
401
- "intelligence"
402
- ].includes(requestedKind) ? requestedKind : void 0;
403
- try {
404
- const result = await focuses.activateTrial({
405
- threadId: c.req.param("focusId"),
406
- ...kind ? { kind } : {}
407
- });
408
- return c.json({
409
- ok: true,
410
- ...result
411
- }, 201);
412
- } catch (error) {
413
- return c.json({
414
- ok: false,
415
- error: error instanceof Error ? error.message : String(error)
416
- }, 400);
417
- }
418
- });
419
- authenticated.post("/api/focuses/:focusId/watches/:watchId/pause", limited, async (c) => {
420
- const watch = focuses.list({ includeUnreviewed: true }).find((item) => item.id === c.req.param("focusId"))?.watches.find((item) => item.id === c.req.param("watchId"));
421
- if (!watch) return c.json({
422
- ok: false,
423
- error: "Watch not found"
424
- }, 404);
425
- const paused = await focuses.pauseWatch(watch.id);
426
- return c.json({
427
- ok: true,
428
- watch: paused
429
- });
430
- });
431
- authenticated.patch("/api/proactive/insights/:insightId", limited, async (c) => {
432
- const requested = stringField(await c.req.json().catch(() => null), "status");
433
- const status = requested === "read" || requested === "dismissed" ? requested : void 0;
434
- if (!status) return c.json({
435
- ok: false,
436
- error: "Status must be read or dismissed"
437
- }, 400);
438
- const insight = setProactiveInsightStatus(c.req.param("insightId"), status, Date.now(), "unread");
439
- if (!insight) return c.json({
440
- ok: false,
441
- error: "Insight was already handled or not found"
442
- }, 409);
443
- if (status === "dismissed") await focuses.recordInsightFeedback(insight.watchId, false);
444
- return c.json({
445
- ok: true,
446
- insight
447
- });
448
- });
449
- authenticated.post("/api/proactive/insights/:insightId/approve", limited, async (c) => {
450
- const insight = getProactiveInsight(c.req.param("insightId"));
451
- if (!insight) return c.json({
452
- ok: false,
453
- error: "Insight not found"
454
- }, 404);
455
- if (insight.status !== "unread") return c.json({
456
- ok: false,
457
- error: `Insight is ${insight.status}`
458
- }, 409);
459
- const focus = focuses.list({ includeUnreviewed: true }).find((item) => item.watches.some((watch) => watch.id === insight.watchId));
460
- if (!focus) return c.json({
461
- ok: false,
462
- error: "Focus not found"
463
- }, 404);
464
- if (!claimProactiveInsightApproval(insight.id)) return c.json({
465
- ok: false,
466
- error: "Insight was already handled"
467
- }, 409);
468
- let automationId;
469
- try {
470
- const automation = await deps.service.automationServiceInstance.create({
471
- name: `Investigate: ${insight.title}`.slice(0, 200),
472
- description: `User-approved read-only proposal from proactive insight ${insight.id}.`,
473
- ...focus.projectIds[0] ? { projectId: focus.projectIds[0] } : {},
474
- trigger: { kind: "manual" },
475
- action: {
476
- kind: "agent",
477
- instruction: [
478
- "The user approved this evidence-backed proposal for read-only investigation and preparation.",
479
- `Focus: ${focus.title}`,
480
- `Observed change: ${insight.summary}`,
481
- `Why it matters: ${insight.whyItMatters}`,
482
- `Approved next step: ${insight.nextAction}`,
483
- `Evidence: ${JSON.stringify(insight.evidence)}`,
484
- "Investigate or prepare the requested material. Return a concise result with evidence. Do not modify files or external systems."
485
- ].join("\n"),
486
- timeoutSeconds: 300
487
- },
488
- safety: { mode: "suggest_only" },
489
- afterRun: { kind: "none" },
490
- reliability: {
491
- timeoutSeconds: 300,
492
- disableAfterConsecutiveFailures: 1
493
- }
494
- });
495
- automationId = automation.id;
496
- const run = await deps.service.automationServiceInstance.runNow(automation.id);
497
- await focuses.recordInsightFeedback(insight.watchId, true);
498
- return c.json({
499
- ok: true,
500
- automationId: automation.id,
501
- runId: run.id
502
- }, 202);
503
- } catch (error) {
504
- if (automationId) await deps.service.automationServiceInstance.remove(automationId);
505
- setProactiveInsightStatus(insight.id, "unread", Date.now(), "approved");
506
- return c.json({
507
- ok: false,
508
- error: error instanceof Error ? error.message : String(error)
509
- }, 500);
510
- }
511
- });
512
- authenticated.post("/api/focuses/:focusId/calendar/:signalId/prepare", limited, async (c) => {
513
- const focus = focuses.list().find((item) => item.id === c.req.param("focusId"));
514
- if (!focus) return c.json({
515
- ok: false,
516
- error: "Focus not found"
517
- }, 404);
518
- const signal = listFocusCalendarSignals([focus]).find((item) => item.id === c.req.param("signalId"));
519
- if (!signal) return c.json({
520
- ok: false,
521
- error: "Calendar event not found"
522
- }, 404);
523
- const eventContext = `${signal.title} at ${new Date(signal.startsAt).toISOString()}`;
524
- try {
525
- const result = await focuses.activateTrial({
526
- threadId: focus.id,
527
- kind: "deadline",
528
- eventContext
529
- });
530
- return c.json({
531
- ok: true,
532
- ...result
533
- });
534
- } catch (error) {
535
- return c.json({
536
- ok: false,
537
- error: error instanceof Error ? error.message : String(error)
538
- }, 500);
539
- }
540
- });
541
302
  authenticated.post("/api/work-discovery/runs/:runId/cancel", (c) => {
542
303
  const run = service.cancelRun(c.req.param("runId"));
543
304
  return run ? c.json({
@@ -68,7 +68,7 @@ export declare class GatewayService {
68
68
  private connectedKnowledgeCoordinator;
69
69
  private stopAutomationProductEventBridge;
70
70
  private stopSessionTranscriptAutomationEvents;
71
- private stopFocusTrialExpiryReconciler;
71
+ private stopFocusReconciler;
72
72
  /**
73
73
  * Webchat agent invocation surface (`runAgent`, `abortAgentRun`, `steer*`,
74
74
  * `submitClarifyResponse`, clarify-bridge dispatch). Owns the
@@ -46,14 +46,12 @@ import { startConnectedKnowledgeCoordinator } from "../knowledge/coordinator.js"
46
46
  import "../knowledge/index.js";
47
47
  import { startConnectorLearningCoordinator } from "../connectors/learning-coordinator.js";
48
48
  import { startConnectorSupervisor } from "../connectors/supervisor.js";
49
- import { LocalAppService } from "../local-apps/service.js";
50
- import "../local-apps/index.js";
49
+ import { FocusService } from "../focuses/service.js";
50
+ import { processFocusMonitorRun } from "../focuses/run-processor.js";
51
+ import { startFocusReconciler } from "../focuses/reconciler.js";
52
+ import "../focuses/index.js";
51
53
  import { assertGatewayAuthConfigured, extractToken, resolveGatewayAuth, validateToken } from "./auth.js";
52
54
  import { reconcileDreamingAutomations } from "./dreaming-automation-reconciler.js";
53
- import { FocusService } from "../proactive/focus-service.js";
54
- import { processFocusAutomationRun } from "../proactive/run-processor.js";
55
- import { startTrialExpiryReconciler } from "../proactive/trial-expiry-reconciler.js";
56
- import "../proactive/index.js";
57
55
  import { NotesStore } from "../notes/store.js";
58
56
  import { buildNoteAgentContext } from "../notes/agent-context.js";
59
57
  import { NotesService } from "../notes/service.js";
@@ -79,6 +77,8 @@ import { auditGatewayConfig } from "./security/audit.js";
79
77
  import { ModelCatalogSyncService } from "../providers/model-catalog-sync-service.js";
80
78
  import { runBootstrapMigrationsSync } from "../migrations/runner.js";
81
79
  import { MobileNotificationService } from "../mobile/notification-service.js";
80
+ import { LocalAppService } from "../local-apps/service.js";
81
+ import "../local-apps/index.js";
82
82
  import { createRuntimeBrowserRecipeService } from "../browser/recipes/runtime-service.js";
83
83
  import "../browser/recipes/index.js";
84
84
  import { scheduleGatewayUpdateCheck } from "../infra/update-startup.js";
@@ -163,7 +163,7 @@ var GatewayService = class {
163
163
  connectedKnowledgeCoordinator = null;
164
164
  stopAutomationProductEventBridge = null;
165
165
  stopSessionTranscriptAutomationEvents = null;
166
- stopFocusTrialExpiryReconciler = null;
166
+ stopFocusReconciler = null;
167
167
  /**
168
168
  * Webchat agent invocation surface (`runAgent`, `abortAgentRun`, `steer*`,
169
169
  * `submitClarifyResponse`, clarify-bridge dispatch). Owns the
@@ -706,7 +706,7 @@ var GatewayService = class {
706
706
  });
707
707
  await trace.measure("automations.initialize", () => this.automationService.initialize());
708
708
  await trace.measure("dreaming.reconcile", () => this.reconcileDreamingAutomations());
709
- this.stopFocusTrialExpiryReconciler = startTrialExpiryReconciler(new FocusService(this.automationService));
709
+ this.stopFocusReconciler = startFocusReconciler(new FocusService(this.automationService));
710
710
  await this.notesService.initialize();
711
711
  this.ensureHeartbeatService().start(heartbeatRunnerConfigFromConfig(this.config));
712
712
  this.connectorSupervisor = startConnectorSupervisor({
@@ -866,8 +866,8 @@ var GatewayService = class {
866
866
  this.lastChannelConnectDeferMode = "auto";
867
867
  this.lastChannelConnectDeferSource = "off";
868
868
  await this.channelManager.stop();
869
- await this.stopFocusTrialExpiryReconciler?.();
870
- this.stopFocusTrialExpiryReconciler = null;
869
+ await this.stopFocusReconciler?.();
870
+ this.stopFocusReconciler = null;
871
871
  await this.automationService.stop();
872
872
  this.stopAutomationProductEventBridge?.();
873
873
  this.stopAutomationProductEventBridge = null;
@@ -1273,12 +1273,16 @@ var GatewayService = class {
1273
1273
  }
1274
1274
  handleAutomationRunCompleted(run) {
1275
1275
  try {
1276
- const proactive = processFocusAutomationRun(run);
1276
+ const focusResult = processFocusMonitorRun(run);
1277
1277
  this.emit("automation.run.completed", {
1278
1278
  run,
1279
- silent: proactive.handled
1279
+ silent: focusResult.handled
1280
+ });
1281
+ if (focusResult.handled) this.emit("focus.run.updated", {
1282
+ automationId: run.automationId,
1283
+ run
1280
1284
  });
1281
- if (proactive.insight) this.emit("proactive.insight.created", { insight: proactive.insight });
1285
+ if (focusResult.insight) this.emit("focus.insight.created", { insight: focusResult.insight });
1282
1286
  } catch (err) {
1283
1287
  log.warn({
1284
1288
  err,
@@ -1,6 +1,6 @@
1
1
  import { DEFAULT_ACK_MAX_CHARS, HEARTBEAT_OK, NO_REPLY, shouldSilence, stripHeartbeatToken } from "./tokens.js";
2
+ import { appendCronEventLines } from "./event-prompt.js";
2
3
  import { isWithinActiveHours } from "./active-hours.js";
3
4
  import { isHeartbeatContentEmpty } from "./content-check.js";
4
- import { appendCronEventLines } from "./event-prompt.js";
5
5
  import { createHeartbeatWake } from "./wake.js";
6
6
  export { DEFAULT_ACK_MAX_CHARS, HEARTBEAT_OK, NO_REPLY, appendCronEventLines, createHeartbeatWake, isHeartbeatContentEmpty, isWithinActiveHours, shouldSilence, stripHeartbeatToken };
@@ -2,8 +2,8 @@ import { createLogger } from "../utils/logger/index.js";
2
2
  import { init_logger } from "../utils/logger.js";
3
3
  import { init_paths, resolveConfigPath } from "../config/paths.js";
4
4
  import { init_loader, loadConfig } from "../config/loader.js";
5
- import { isRestartEnabled } from "../config/commands.flags.js";
6
5
  import { resolveGatewayService } from "../daemon/service.js";
6
+ import { isRestartEnabled } from "../config/commands.flags.js";
7
7
  import { authorizeGatewaySigusr1Restart, writeGatewayRestartIntentSync } from "./restart.js";
8
8
  import { findVerifiedGatewayListenerPidsOnPortSync, signalVerifiedGatewayPidSync } from "./gateway-processes.js";
9
9
  import { refreshGatewayServiceAfterUpdate } from "./update-service-refresh.js";
@@ -2,9 +2,9 @@ import { createLogger } from "../utils/logger/index.js";
2
2
  import { init_logger } from "../utils/logger.js";
3
3
  import { init_loader, loadConfig } from "../config/loader.js";
4
4
  import { gatewayCredentialAuthorization } from "../gateway/credential.js";
5
+ import { loadUndiciRuntimeDeps } from "../infra/undici-fetch.js";
5
6
  import { toConversation } from "./channel-shared.js";
6
7
  import { createGatewayHttpClientFromConfig, resolveGatewayHttpBaseUrl } from "./gateway-http-client.js";
7
- import { loadUndiciRuntimeDeps } from "../infra/undici-fetch.js";
8
8
  //#region src/mcp/channel-bridge.ts
9
9
  init_loader();
10
10
  init_logger();
@@ -1,6 +1,7 @@
1
1
  export * from './types.js';
2
2
  export * from './project-store.js';
3
3
  export * from './project-service.js';
4
+ export * from './project-skill-service.js';
4
5
  export * from './project-agent.js';
5
6
  export * from './project-agent-suggestion.js';
6
7
  export * from './project-kind.js';
@@ -4,6 +4,7 @@ import { bindGoalToProject, bindGoalsToProject, listProjectGoalIds, unbindGoalFr
4
4
  import { bindSessionToProject, bindSessionsToProject, listProjectSessionKeys, moveSessionToProject, unbindSessionFromProject } from "./session-bind.js";
5
5
  import { ProjectWorkspaceConflictError, ProjectWorkspaceMissingError, canonicalWorkspacePath, ensureWorkspaceDirectory, inferProjectNameFromWorkspaceRoot, isPathSameOrInsideWorkspace, isSafeAutoCreateWorkspaceRoot, resolveWorkspaceProjectRoot, workspaceDirectoryExists } from "./workspace-project.js";
6
6
  import { ProjectService } from "./project-service.js";
7
+ import { ProjectSkillError, ProjectSkillService } from "./project-skill-service.js";
7
8
  import { isValidProjectAgentId, normalizeProjectAgentId, resolveProjectAgentId } from "./project-agent.js";
8
9
  import { inferProjectKind } from "./project-kind.js";
9
10
  import { CODING_PROJECT_AGENT_ID, inferSuggestedProjectDefaultAgentId, suggestProjectDefaultAgentId } from "./project-agent-suggestion.js";
@@ -11,4 +12,4 @@ import { buildProjectLoopOverview } from "./project-loop.js";
11
12
  import { bindWorkflowRunToProject } from "./workflow-bind.js";
12
13
  import { bindAutomationToProject } from "./automation-bind.js";
13
14
  import { bindMemoryRecordToProject } from "./memory-bind.js";
14
- export { CODING_PROJECT_AGENT_ID, ProjectService, ProjectStore, ProjectWorkspaceConflictError, ProjectWorkspaceMissingError, bindAutomationToProject, bindGoalToProject, bindGoalsToProject, bindMemoryRecordToProject, bindSessionToProject, bindSessionsToProject, bindWorkflowRunToProject, buildProjectLoopOverview, canonicalWorkspacePath, ensureWorkspaceDirectory, getProjectForSession, getProjectWorkspacePathForSession, inferProjectKind, inferProjectNameFromWorkspaceRoot, inferSuggestedProjectDefaultAgentId, isPathSameOrInsideWorkspace, isSafeAutoCreateWorkspaceRoot, isValidProjectAgentId, listProjectGoalIds, listProjectSessionKeys, moveSessionToProject, normalizeProjectAgentId, resolveProjectAgentId, resolveProjectWorkspacePath, resolveWorkspaceProjectRoot, slugifyProjectName, suggestProjectDefaultAgentId, unbindGoalFromProject, unbindSessionFromProject, workspaceDirectoryExists };
15
+ export { CODING_PROJECT_AGENT_ID, ProjectService, ProjectSkillError, ProjectSkillService, ProjectStore, ProjectWorkspaceConflictError, ProjectWorkspaceMissingError, bindAutomationToProject, bindGoalToProject, bindGoalsToProject, bindMemoryRecordToProject, bindSessionToProject, bindSessionsToProject, bindWorkflowRunToProject, buildProjectLoopOverview, canonicalWorkspacePath, ensureWorkspaceDirectory, getProjectForSession, getProjectWorkspacePathForSession, inferProjectKind, inferProjectNameFromWorkspaceRoot, inferSuggestedProjectDefaultAgentId, isPathSameOrInsideWorkspace, isSafeAutoCreateWorkspaceRoot, isValidProjectAgentId, listProjectGoalIds, listProjectSessionKeys, moveSessionToProject, normalizeProjectAgentId, resolveProjectAgentId, resolveProjectWorkspacePath, resolveWorkspaceProjectRoot, slugifyProjectName, suggestProjectDefaultAgentId, unbindGoalFromProject, unbindSessionFromProject, workspaceDirectoryExists };
@@ -0,0 +1,67 @@
1
+ import type { Config } from '../config/schema.js';
2
+ import type { SkillDiagnostic, SkillMetadata, SkillToolConditions } from '../agent/skills/types.js';
3
+ import type { ProjectService } from './project-service.js';
4
+ export type ProjectSkillErrorCode = 'project_not_found' | 'project_workspace_required' | 'project_workspace_missing' | 'project_workspace_not_writable' | 'skill_not_found' | 'invalid_skill_id';
5
+ export declare class ProjectSkillError extends Error {
6
+ readonly code: ProjectSkillErrorCode;
7
+ readonly status: 400 | 403 | 404 | 409;
8
+ constructor(code: ProjectSkillErrorCode, status: 400 | 403 | 404 | 409, message: string);
9
+ }
10
+ export interface ProjectSkillSummary {
11
+ id: string;
12
+ name: string;
13
+ description: string;
14
+ category?: string;
15
+ disableModelInvocation: boolean;
16
+ metadata: SkillMetadata;
17
+ toolConditions?: SkillToolConditions;
18
+ requiredEnvVarNames?: string[];
19
+ }
20
+ export interface ProjectSkillListResult {
21
+ workspaceRoot: string;
22
+ skillsRoot: string;
23
+ items: ProjectSkillSummary[];
24
+ diagnostics: SkillDiagnostic[];
25
+ }
26
+ interface ProjectSkillServiceOptions {
27
+ projects: ProjectService;
28
+ getConfig: () => Config;
29
+ refreshSkills: () => void | Promise<void>;
30
+ }
31
+ export declare class ProjectSkillService {
32
+ private readonly options;
33
+ constructor(options: ProjectSkillServiceOptions);
34
+ list(projectId: string): ProjectSkillListResult;
35
+ getContent(projectId: string, skillId: string): ProjectSkillSummary & {
36
+ bodyMarkdown: string;
37
+ };
38
+ installZip(projectId: string, buffer: Buffer, input?: {
39
+ skillId?: string;
40
+ overwrite?: boolean;
41
+ }): Promise<ProjectSkillSummary & {
42
+ bodyMarkdown: string;
43
+ }>;
44
+ installMarketplace(projectId: string, input: {
45
+ name: string;
46
+ version?: string;
47
+ provider?: string;
48
+ overwrite?: boolean;
49
+ }): Promise<ProjectSkillSummary & {
50
+ bodyMarkdown: string;
51
+ }>;
52
+ installSource(projectId: string, input: {
53
+ source: string;
54
+ skillId?: string;
55
+ ref?: string;
56
+ subpath?: string;
57
+ force?: boolean;
58
+ }): Promise<ProjectSkillSummary & {
59
+ bodyMarkdown: string;
60
+ }>;
61
+ remove(projectId: string, skillId: string): Promise<void>;
62
+ private findSkill;
63
+ private resolveLocation;
64
+ private isDirectSkill;
65
+ private toSummary;
66
+ }
67
+ export {};
@@ -0,0 +1,131 @@
1
+ import { resolveWorkspaceSkillsDir, resolveWorkspaceSkillsLockPath } from "../agent/skills/workspace-skills-dir.js";
2
+ import { loadWorkspaceSkills } from "../agent/skills/index.js";
3
+ import { removeSkillsLockEntry } from "../agent/skills/hub-lock.js";
4
+ import { deleteManagedSkill, installSkillFromZip, isValidSkillId } from "../agent/skills/managed-store.js";
5
+ import { pullSkillFromSource } from "../agent/skills/hub-pull.js";
6
+ import { downloadFromMarketplace } from "../agent/skills/skills-marketplace.js";
7
+ import { basename, dirname, join, relative, resolve, sep } from "node:path";
8
+ import { accessSync, constants, existsSync, statSync } from "node:fs";
9
+ //#region src/projects/project-skill-service.ts
10
+ var ProjectSkillError = class extends Error {
11
+ constructor(code, status, message) {
12
+ super(message);
13
+ this.code = code;
14
+ this.status = status;
15
+ this.name = "ProjectSkillError";
16
+ }
17
+ };
18
+ var ProjectSkillService = class {
19
+ constructor(options) {
20
+ this.options = options;
21
+ }
22
+ list(projectId) {
23
+ const location = this.resolveLocation(projectId, false);
24
+ const loaded = loadWorkspaceSkills(location.workspaceRoot);
25
+ return {
26
+ ...location,
27
+ items: loaded.skills.filter((skill) => this.isDirectSkill(skill, location.skillsRoot)).map((skill) => this.toSummary(skill)),
28
+ diagnostics: loaded.diagnostics
29
+ };
30
+ }
31
+ getContent(projectId, skillId) {
32
+ const { skill } = this.findSkill(projectId, skillId);
33
+ return {
34
+ ...this.toSummary(skill),
35
+ bodyMarkdown: skill.content
36
+ };
37
+ }
38
+ async installZip(projectId, buffer, input = {}) {
39
+ const location = this.resolveLocation(projectId, true);
40
+ const installed = installSkillFromZip(buffer, {
41
+ skillId: input.skillId,
42
+ overwrite: input.overwrite,
43
+ rootDir: location.skillsRoot
44
+ });
45
+ removeSkillsLockEntry(installed.skillId, resolveWorkspaceSkillsLockPath(location.workspaceRoot));
46
+ await this.options.refreshSkills();
47
+ return this.getContent(projectId, installed.skillId);
48
+ }
49
+ async installMarketplace(projectId, input) {
50
+ const downloaded = await downloadFromMarketplace(this.options.getConfig(), input.name, input.version, input.provider);
51
+ return this.installZip(projectId, downloaded.buffer, {
52
+ skillId: downloaded.skillId,
53
+ overwrite: input.overwrite
54
+ });
55
+ }
56
+ async installSource(projectId, input) {
57
+ const location = this.resolveLocation(projectId, true);
58
+ const installed = await pullSkillFromSource(input.source, {
59
+ skillId: input.skillId,
60
+ ref: input.ref,
61
+ subpath: input.subpath,
62
+ force: input.force,
63
+ installRoot: location.skillsRoot,
64
+ lockPath: resolveWorkspaceSkillsLockPath(location.workspaceRoot)
65
+ });
66
+ await this.options.refreshSkills();
67
+ return this.getContent(projectId, installed.skillId);
68
+ }
69
+ async remove(projectId, skillId) {
70
+ const location = this.resolveLocation(projectId, true);
71
+ if (!isValidSkillId(skillId)) throw new ProjectSkillError("invalid_skill_id", 400, "Invalid skill id");
72
+ if (!existsSync(join(location.skillsRoot, skillId, "SKILL.md"))) throw new ProjectSkillError("skill_not_found", 404, "Project skill not found");
73
+ deleteManagedSkill(skillId, location.skillsRoot);
74
+ removeSkillsLockEntry(skillId, resolveWorkspaceSkillsLockPath(location.workspaceRoot));
75
+ await this.options.refreshSkills();
76
+ }
77
+ findSkill(projectId, skillId) {
78
+ if (!isValidSkillId(skillId)) throw new ProjectSkillError("invalid_skill_id", 400, "Invalid skill id");
79
+ const location = this.resolveLocation(projectId, false);
80
+ const skill = loadWorkspaceSkills(location.workspaceRoot).skills.find((item) => {
81
+ return !relative(location.skillsRoot, item.baseDir).includes(sep) && basename(item.baseDir) === skillId;
82
+ });
83
+ if (!skill) throw new ProjectSkillError("skill_not_found", 404, "Project skill not found");
84
+ return {
85
+ skill,
86
+ skillsRoot: location.skillsRoot
87
+ };
88
+ }
89
+ resolveLocation(projectId, requireWritable) {
90
+ const project = this.options.projects.get(projectId);
91
+ if (!project) throw new ProjectSkillError("project_not_found", 404, "Project not found");
92
+ const configuredRoot = project.workspaceRoot?.trim();
93
+ if (!configuredRoot) throw new ProjectSkillError("project_workspace_required", 409, "Project workspace is required");
94
+ const workspaceRoot = resolve(configuredRoot);
95
+ try {
96
+ if (!existsSync(workspaceRoot) || !statSync(workspaceRoot).isDirectory()) throw new ProjectSkillError("project_workspace_missing", 409, "Project workspace does not exist");
97
+ } catch (error) {
98
+ if (error instanceof ProjectSkillError) throw error;
99
+ throw new ProjectSkillError("project_workspace_missing", 409, "Project workspace does not exist");
100
+ }
101
+ const skillsRoot = resolveWorkspaceSkillsDir(workspaceRoot);
102
+ if (requireWritable) try {
103
+ const xopcRoot = dirname(skillsRoot);
104
+ accessSync(existsSync(skillsRoot) ? skillsRoot : existsSync(xopcRoot) ? xopcRoot : workspaceRoot, constants.W_OK);
105
+ } catch {
106
+ throw new ProjectSkillError("project_workspace_not_writable", 403, "Project workspace is not writable");
107
+ }
108
+ return {
109
+ workspaceRoot,
110
+ skillsRoot
111
+ };
112
+ }
113
+ isDirectSkill(skill, skillsRoot) {
114
+ const rel = relative(skillsRoot, skill.baseDir);
115
+ return Boolean(rel) && !rel.includes(sep) && isValidSkillId(basename(skill.baseDir));
116
+ }
117
+ toSummary(skill) {
118
+ return {
119
+ id: basename(skill.baseDir),
120
+ name: skill.name,
121
+ description: skill.description,
122
+ category: skill.category,
123
+ disableModelInvocation: skill.disableModelInvocation,
124
+ metadata: skill.metadata,
125
+ toolConditions: skill.toolConditions,
126
+ requiredEnvVarNames: skill.requiredEnvVarNames
127
+ };
128
+ }
129
+ };
130
+ //#endregion
131
+ export { ProjectSkillError, ProjectSkillService };
@@ -0,0 +1,3 @@
1
+ export type HomeAttentionSubjectKind = 'automation_run' | 'workflow_run';
2
+ export declare function acknowledgeHomeAttention(subjectKind: HomeAttentionSubjectKind, subjectId: string, acknowledgedAt?: number): void;
3
+ export declare function isHomeAttentionAcknowledged(subjectKind: HomeAttentionSubjectKind, subjectId: string): boolean;
@@ -0,0 +1,21 @@
1
+ import { getSqliteDatabase, runSqliteWriteTransaction } from "./transaction.js";
2
+ //#region src/storage/sqlite/home-attention-repository.ts
3
+ function acknowledgeHomeAttention(subjectKind, subjectId, acknowledgedAt = Date.now()) {
4
+ runSqliteWriteTransaction((db) => {
5
+ db.prepare(`
6
+ INSERT INTO home_attention_acknowledgements (subject_kind, subject_id, acknowledged_at)
7
+ VALUES (?, ?, ?)
8
+ ON CONFLICT(subject_kind, subject_id) DO UPDATE SET
9
+ acknowledged_at = excluded.acknowledged_at
10
+ `).run(subjectKind, subjectId, acknowledgedAt);
11
+ });
12
+ }
13
+ function isHomeAttentionAcknowledged(subjectKind, subjectId) {
14
+ return getSqliteDatabase().prepare(`
15
+ SELECT 1
16
+ FROM home_attention_acknowledgements
17
+ WHERE subject_kind = ? AND subject_id = ?
18
+ `).get(subjectKind, subjectId) !== void 0;
19
+ }
20
+ //#endregion
21
+ export { acknowledgeHomeAttention, isHomeAttentionAcknowledged };
@@ -5,6 +5,7 @@ export { DatabaseSchemaMigrationGapError, DatabaseSchemaTooNewError, } from './m
5
5
  export { discoverSqlMigrations, listRegisteredMigrationTargets } from './migrations/discover.js';
6
6
  export { closeXopcDatabase, getXopcDatabase, isXopcDatabaseOpen, openXopcDatabase, requireXopcDatabase, resetXopcDatabaseSingletonForTest, type OpenXopcDatabaseOptions, type XopcDatabase, } from './connection.js';
7
7
  export { getSqliteDatabase, runSqliteWriteTransaction } from './transaction.js';
8
+ export { acknowledgeHomeAttention, isHomeAttentionAcknowledged, type HomeAttentionSubjectKind, } from './home-attention-repository.js';
8
9
  export { getUserClaim, linkUserClaimMemoryRecord, listUserClaimEvidence, listUserClaimStatsBySource, listUserClaims, listUserPeopleGraphRows, removeUserClaimEvidenceForSource, reinforceUserClaim, resolveUserEntity, setUserClaimDecision, type UserClaim, type UserClaimClass, type UserClaimState, type UserEntity, } from './user-claims-repository.js';
9
10
  export { claimNextConnectorLearningJob, enqueueConnectorLearningJob, listConnectorLearningJobs, recoverStaleConnectorLearningJobs, setConnectorLearningPaused, updateConnectorLearningJob, type ConnectorLearningJob, type ConnectorLearningMode, type ConnectorLearningPhase, type ConnectorLearningStatus, } from './connector-learning-repository.js';
10
11
  export { appendComposerInputHistory, clearComposerInputHistory, listComposerInputHistory, COMPOSER_INPUT_HISTORY_LIMIT, type ComposerInputHistoryItem, } from './composer-input-history-repository.js';