@xopcai/xopc 0.0.158 → 0.0.160

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 (218) hide show
  1. package/dist/browser-ext/manifest.json +1 -1
  2. package/dist/extensions/dashscope/src/image-generation-provider.js +1 -1
  3. package/dist/extensions/fal/src/image-generation-provider.js +1 -1
  4. package/dist/extensions/google/src/image-generation-provider.js +1 -1
  5. package/dist/extensions/telegram/xopc.extension.json +1 -1
  6. package/dist/gateway/static/root/assets/{action-boundary-settings-panel-2p1f4-KA.js → action-boundary-settings-panel-CY3sizqC.js} +1 -1
  7. package/dist/gateway/static/root/assets/{activity-store-C-57rvkX.js → activity-store-3Cso_2qm.js} +1 -1
  8. package/dist/gateway/static/root/assets/{agent-avatar-dicebear-BIl6X2b_.js → agent-avatar-dicebear-B_27aaZQ.js} +1 -1
  9. package/dist/gateway/static/root/assets/agents-B1l3iii6.js +2 -0
  10. package/dist/gateway/static/root/assets/{api-BjcBIV2O.js → api-BbzB57CJ.js} +1 -1
  11. package/dist/gateway/static/root/assets/{app-management-settings-panel-CZxw161D.js → app-management-settings-panel-DfmyWcyh.js} +1 -1
  12. package/dist/gateway/static/root/assets/{appearance-settings-CRXNlDhH.js → appearance-settings-B2v0c-K-.js} +1 -1
  13. package/dist/gateway/static/root/assets/apps-page-DaNFLsp0.js +1 -0
  14. package/dist/gateway/static/root/assets/{archive-plugin-CpVshjXu.js → archive-plugin-DL5Lnx0C.js} +1 -1
  15. package/dist/gateway/static/root/assets/{attachment-load-M9WqqJnQ.js → attachment-load-InuP-ZjQ.js} +1 -1
  16. package/dist/gateway/static/root/assets/{automation-suggestion-card-CYMsAsYf.js → automation-suggestion-card-CahGuh7B.js} +1 -1
  17. package/dist/gateway/static/root/assets/automations-page-Cd0gMx6p.js +6 -0
  18. package/dist/gateway/static/root/assets/{binary-plugins-Cjn3zb4u.js → binary-plugins-CdOTGYVu.js} +1 -1
  19. package/dist/gateway/static/root/assets/{block-editor-BPKdquaV.js → block-editor-D6ShK1S-.js} +3 -3
  20. package/dist/gateway/static/root/assets/browser-settings-page-BmUYDL2Z.js +8 -0
  21. package/dist/gateway/static/root/assets/{capability-presets-api-Bzkcsyzn.js → capability-presets-api-BzoLm52Z.js} +1 -1
  22. package/dist/gateway/static/root/assets/{capability-presets-settings-panel-D4rH4Dax.js → capability-presets-settings-panel-CE7mrWtS.js} +2 -2
  23. package/dist/gateway/static/root/assets/{channel-recipient-api-CFqrSi5K.js → channel-recipient-api-DbgydMjl.js} +1 -1
  24. package/dist/gateway/static/root/assets/channels-settings-D1_gcAHK.js +1 -0
  25. package/dist/gateway/static/root/assets/channels-status-swr-Cqfqv59m.js +1 -0
  26. package/dist/gateway/static/root/assets/{connector-logo-ljPKdYKh.js → connector-logo-C3bJC9nt.js} +1 -1
  27. package/dist/gateway/static/root/assets/connectors-page-CaLBi6Na.js +2 -0
  28. package/dist/gateway/static/root/assets/desktop-pet-settings-BrHVvbBw.js +1 -0
  29. package/dist/gateway/static/root/assets/desktop-pet-sprite-CFd1jGLJ.js +1 -0
  30. package/dist/gateway/static/root/assets/desktop-pet-wacrnJJ1.js +1 -0
  31. package/dist/gateway/static/root/assets/{directory-picker-path-field-Dmy1035j.js → directory-picker-path-field-BPI969w-.js} +1 -1
  32. package/dist/gateway/static/root/assets/{dreaming-settings-tT4WkBkd.js → dreaming-settings-iw6QXD45.js} +3 -3
  33. package/dist/gateway/static/root/assets/{extension-debug-page-CL79q8AH.js → extension-debug-page-rCHyhEr6.js} +1 -1
  34. package/dist/gateway/static/root/assets/{extension-page-hq80wkFI.js → extension-page-C4gQsAPt.js} +1 -1
  35. package/dist/gateway/static/root/assets/{extension-settings-page-BV-9GDfT.js → extension-settings-page-DB_3eik7.js} +1 -1
  36. package/dist/gateway/static/root/assets/{gateway-config-api-CFqoN2NW.js → gateway-config-api-Cdt38iF2.js} +1 -1
  37. package/dist/gateway/static/root/assets/gateway-settings-DM4BgyGw.js +1 -0
  38. package/dist/gateway/static/root/assets/{gateway-startup-retry-cxQ94qMm.js → gateway-startup-retry-ChRFNjj_.js} +1 -1
  39. package/dist/gateway/static/root/assets/goal-create-dialog-BQamcEmF.js +1 -0
  40. package/dist/gateway/static/root/assets/goal-detail-page-DZUQ0Lf1.js +4 -0
  41. package/dist/gateway/static/root/assets/{goals-config-api--qJ4qlRq.js → goals-config-api-RvljeEm6.js} +1 -1
  42. package/dist/gateway/static/root/assets/goals-page-BtxVD27C.js +2 -0
  43. package/dist/gateway/static/root/assets/{goals-settings-h7x9h5lb.js → goals-settings-DMGV4S4L.js} +1 -1
  44. package/dist/gateway/static/root/assets/{heartbeat-settings-71IhhM3s.js → heartbeat-settings-B8r5EXc5.js} +1 -1
  45. package/dist/gateway/static/root/assets/index-CHKe7nwC.js +197 -0
  46. package/dist/gateway/static/root/assets/index-CXhfUIjh.css +1 -0
  47. package/dist/gateway/static/root/assets/{keyboard-shortcuts-settings-BZGmHvLu.js → keyboard-shortcuts-settings-1-LYibQ4.js} +1 -1
  48. package/dist/gateway/static/root/assets/local-app-workbench-page-CTTfyFe3.js +2 -0
  49. package/dist/gateway/static/root/assets/{local-apps-page-CiLqrMIh.js → local-apps-page-CC4vtUUI.js} +1 -1
  50. package/dist/gateway/static/root/assets/{locale-store-C_M71MK9.js → locale-store-CPbGB_6l.js} +1 -1
  51. package/dist/gateway/static/root/assets/logs-page-Bn_taxBV.js +7 -0
  52. package/dist/gateway/static/root/assets/{markdown-split-r1HPWfCU.js → markdown-split-CprEIf8A.js} +1 -1
  53. package/dist/gateway/static/root/assets/{media-plugins-D74kd3hn.js → media-plugins-BXt_Sj2O.js} +1 -1
  54. package/dist/gateway/static/root/assets/{messages-BuT0SR1R.js → messages-DDsiqdJS.js} +4 -4
  55. package/dist/gateway/static/root/assets/models-hub-panel-DJReXRP9.js +2 -0
  56. package/dist/gateway/static/root/assets/{notes-page-Dgu02514.js → notes-page-Wf5-eyyM.js} +1 -1
  57. package/dist/gateway/static/root/assets/notes-workbench-BbdjzYzs.js +4 -0
  58. package/dist/gateway/static/root/assets/{page-tabs-hinRdDy3.js → page-tabs-dtpK_4Fs.js} +1 -1
  59. package/dist/gateway/static/root/assets/{preview-open-alternatives-C7fw3oGy.js → preview-open-alternatives-DijtEVxG.js} +1 -1
  60. package/dist/gateway/static/root/assets/project-detail-page-BwG8SOzI.js +1 -0
  61. package/dist/gateway/static/root/assets/projects-page-nUlyUtxh.js +1 -0
  62. package/dist/gateway/static/root/assets/remote-access-hub-rf7bjije.js +1 -0
  63. package/dist/gateway/static/root/assets/{save-bar-controls-C3aU8-vO.js → save-bar-controls-qhDisdqY.js} +1 -1
  64. package/dist/gateway/static/root/assets/{schedule-field-DjegExFD.js → schedule-field-AhJ50NoT.js} +1 -1
  65. package/dist/gateway/static/root/assets/{schema-form-DLubnsql.js → schema-form-AuJg2CXU.js} +1 -1
  66. package/dist/gateway/static/root/assets/sessions-page-CSoHUe38.js +1 -0
  67. package/dist/gateway/static/root/assets/settings-advanced-gate-Db976IEa.js +1 -0
  68. package/dist/gateway/static/root/assets/{settings-collapsible-section-3syQHsNR.js → settings-collapsible-section-D5ganr_X.js} +1 -1
  69. package/dist/gateway/static/root/assets/{settings-form-section-D4DCZzKg.js → settings-form-section-Db3cKRsg.js} +1 -1
  70. package/dist/gateway/static/root/assets/{settings-loading-skeleton-c5K85ylS.js → settings-loading-skeleton-D05YKT2x.js} +1 -1
  71. package/dist/gateway/static/root/assets/{settings-page-DNiDlaRq.js → settings-page-DYfXmfTx.js} +1 -1
  72. package/dist/gateway/static/root/assets/{settings-page-layout-iTRY1Hy-.js → settings-page-layout-Cv_Cu4I5.js} +1 -1
  73. package/dist/gateway/static/root/assets/setup-status-panel-wBWOFpvw.js +1 -0
  74. package/dist/gateway/static/root/assets/{share-preview-page-B88Afrhe.js → share-preview-page-CYkZVuse.js} +1 -1
  75. package/dist/gateway/static/root/assets/shares-settings-BAMma1-P.js +1 -0
  76. package/dist/gateway/static/root/assets/skill-reload-api-TWxFFWxM.js +1 -0
  77. package/dist/gateway/static/root/assets/skills-page-Ca2RA29R.js +2 -0
  78. package/dist/gateway/static/root/assets/{system-settings-panel-DtpTq837.js → system-settings-panel-C1Ng5bXh.js} +1 -1
  79. package/dist/gateway/static/root/assets/{theme-store-C8ohIHhw.js → theme-store-LMHIDR9n.js} +1 -1
  80. package/dist/gateway/static/root/assets/{typed-models-lib-ndEnUP3b.js → typed-models-lib-Ch2Bdm_5.js} +1 -1
  81. package/dist/gateway/static/root/assets/{use-channel-catalog-BWzou5ar.js → use-channel-catalog-CZnaMOeL.js} +1 -1
  82. package/dist/gateway/static/root/assets/user-context-page-CTumZa0y.js +1 -0
  83. package/dist/gateway/static/root/assets/voice-api-key-field-DdlMxeqO.js +1 -0
  84. package/dist/gateway/static/root/assets/work-discovery-page-CcfZhdBi.js +1 -0
  85. package/dist/gateway/static/root/assets/work-item-detail-page--wxLw1p_.js +1 -0
  86. package/dist/gateway/static/root/assets/work-page-DyS0XBpV.js +1 -0
  87. package/dist/gateway/static/root/assets/{workflow-run-setup-panel-ukmpkj66.js → workflow-run-setup-panel-BFk8TvTw.js} +2 -2
  88. package/dist/gateway/static/root/assets/workflows-page-CVVJd4gy.js +11 -0
  89. package/dist/gateway/static/root/index.html +7 -7
  90. package/dist/package.js +1 -1
  91. package/dist/src/agent/embedded/session-tool-result-guard.js +14 -0
  92. package/dist/src/agent/image/generation/openai-compatible-image-provider.js +1 -1
  93. package/dist/src/agent/service/process-direct-streaming.js +1 -1
  94. package/dist/src/agent/tools/image-generate-tool.js +10 -3
  95. package/dist/src/agent/tools/send-media.js +20 -70
  96. package/dist/src/agent/tools/tool-media.d.ts +9 -0
  97. package/dist/src/agent/tools/tool-media.js +58 -0
  98. package/dist/src/automations/service/action-executor.js +1 -1
  99. package/dist/src/cli/commands/doctor/checks/database-schema.js +1 -1
  100. package/dist/src/config/agent-profile.js +1 -1
  101. package/dist/src/gateway/agent-run-relay.d.ts +2 -0
  102. package/dist/src/gateway/agent-run-relay.js +114 -14
  103. package/dist/src/gateway/agents-admin.js +1 -1
  104. package/dist/src/gateway/chat-stream/mapper.d.ts +1 -0
  105. package/dist/src/gateway/chat-stream/mapper.js +40 -19
  106. package/dist/src/gateway/chat-stream/thinking-delta-coalescer.d.ts +7 -0
  107. package/dist/src/gateway/chat-stream/thinking-delta-coalescer.js +103 -0
  108. package/dist/src/gateway/hono/routes/home.js +15 -2
  109. package/dist/src/gateway/hono/routes/work-discovery.js +451 -0
  110. package/dist/src/gateway/hono/sse.d.ts +1 -1
  111. package/dist/src/gateway/hono/sse.js +1 -1
  112. package/dist/src/gateway/service/run-gateway-agent.js +5 -1
  113. package/dist/src/gateway/service.d.ts +2 -0
  114. package/dist/src/gateway/service.js +27 -2
  115. package/dist/src/media/session-references.js +9 -6
  116. package/dist/src/mobile/notification-service.js +1 -0
  117. package/dist/src/pets/factory.js +23 -26
  118. package/dist/src/pets/manifest.d.ts +2 -1
  119. package/dist/src/pets/manifest.js +15 -8
  120. package/dist/src/pets/validator.js +8 -3
  121. package/dist/src/proactive/calendar-signals.d.ts +4 -0
  122. package/dist/src/proactive/calendar-signals.js +120 -0
  123. package/dist/src/proactive/focus-service.d.ts +62 -0
  124. package/dist/src/proactive/focus-service.js +173 -0
  125. package/dist/src/proactive/index.d.ts +7 -0
  126. package/dist/src/proactive/index.js +7 -0
  127. package/dist/src/proactive/insight-repository.d.ts +19 -0
  128. package/dist/src/proactive/insight-repository.js +106 -0
  129. package/dist/src/proactive/run-processor.d.ts +19 -0
  130. package/dist/src/proactive/run-processor.js +125 -0
  131. package/dist/src/proactive/trial-expiry-reconciler.d.ts +5 -0
  132. package/dist/src/proactive/trial-expiry-reconciler.js +30 -0
  133. package/dist/src/proactive/types.d.ts +64 -0
  134. package/dist/src/proactive/types.js +1 -0
  135. package/dist/src/proactive/watch-repository.d.ts +28 -0
  136. package/dist/src/proactive/watch-repository.js +129 -0
  137. package/dist/src/session/client-history.d.ts +1 -0
  138. package/dist/src/session/client-history.js +56 -12
  139. package/dist/src/session/types.d.ts +1 -0
  140. package/dist/src/storage/sqlite/knowledge-repository.d.ts +1 -0
  141. package/dist/src/storage/sqlite/knowledge-repository.js +4 -0
  142. package/dist/src/storage/sqlite/migrations/047_work_discovery_sources.sql +16 -0
  143. package/dist/src/storage/sqlite/migrations/048_work_understanding_investigations.sql +40 -0
  144. package/dist/src/storage/sqlite/migrations/049_work_understanding_threads.sql +52 -0
  145. package/dist/src/storage/sqlite/migrations/050_work_discovery_source_refreshes.sql +15 -0
  146. package/dist/src/storage/sqlite/migrations/051_focus_watches.sql +26 -0
  147. package/dist/src/storage/sqlite/migrations/052_proactive_insights.sql +25 -0
  148. package/dist/src/storage/sqlite/migrations/runner.d.ts +1 -1
  149. package/dist/src/storage/sqlite/migrations/runner.js +3 -3
  150. package/dist/src/storage/sqlite/migrations/runner.ts +1 -1
  151. package/dist/src/storage/sqlite/schema.js +1 -1
  152. package/dist/src/work-discovery/analyzer.d.ts +12 -1
  153. package/dist/src/work-discovery/analyzer.js +126 -7
  154. package/dist/src/work-discovery/candidate-discovery.d.ts +17 -0
  155. package/dist/src/work-discovery/candidate-discovery.js +279 -0
  156. package/dist/src/work-discovery/evaluation.d.ts +11 -0
  157. package/dist/src/work-discovery/evaluation.js +17 -0
  158. package/dist/src/work-discovery/governance.d.ts +25 -0
  159. package/dist/src/work-discovery/governance.js +96 -0
  160. package/dist/src/work-discovery/incremental-repository.d.ts +13 -0
  161. package/dist/src/work-discovery/incremental-repository.js +55 -0
  162. package/dist/src/work-discovery/incremental.d.ts +2 -0
  163. package/dist/src/work-discovery/incremental.js +7 -0
  164. package/dist/src/work-discovery/index.d.ts +10 -0
  165. package/dist/src/work-discovery/index.js +13 -3
  166. package/dist/src/work-discovery/investigation-repository.d.ts +16 -0
  167. package/dist/src/work-discovery/investigation-repository.js +122 -0
  168. package/dist/src/work-discovery/investigator.d.ts +55 -0
  169. package/dist/src/work-discovery/investigator.js +358 -0
  170. package/dist/src/work-discovery/probe.d.ts +22 -0
  171. package/dist/src/work-discovery/probe.js +88 -1
  172. package/dist/src/work-discovery/service.d.ts +110 -1
  173. package/dist/src/work-discovery/service.js +578 -8
  174. package/dist/src/work-discovery/source-repository.d.ts +13 -0
  175. package/dist/src/work-discovery/source-repository.js +72 -0
  176. package/dist/src/work-discovery/thread-repository.d.ts +34 -0
  177. package/dist/src/work-discovery/thread-repository.js +112 -0
  178. package/dist/src/work-discovery/thread-service.d.ts +8 -0
  179. package/dist/src/work-discovery/thread-service.js +104 -0
  180. package/dist/src/work-discovery/types.d.ts +145 -0
  181. package/package.json +1 -1
  182. package/skills/creative/hatch-pet/SKILL.md +2 -2
  183. package/dist/gateway/static/root/assets/agents-bnkKH9EI.js +0 -2
  184. package/dist/gateway/static/root/assets/apps-page-l4ripRNG.js +0 -1
  185. package/dist/gateway/static/root/assets/automations-page-Kny7tLiF.js +0 -6
  186. package/dist/gateway/static/root/assets/browser-settings-page-vr1tXAab.js +0 -8
  187. package/dist/gateway/static/root/assets/channels-settings-Tlhbi5eh.js +0 -1
  188. package/dist/gateway/static/root/assets/channels-status-swr-vooEF4lG.js +0 -1
  189. package/dist/gateway/static/root/assets/connectors-page-_XfvjXoY.js +0 -2
  190. package/dist/gateway/static/root/assets/desktop-pet-DKUlAgm7.js +0 -1
  191. package/dist/gateway/static/root/assets/desktop-pet-settings-aWWzjdza.js +0 -1
  192. package/dist/gateway/static/root/assets/desktop-pet-sprite-DqZ6fbIj.js +0 -1
  193. package/dist/gateway/static/root/assets/gateway-settings-DzR-kM91.js +0 -1
  194. package/dist/gateway/static/root/assets/goal-create-dialog-BLjHRtqe.js +0 -1
  195. package/dist/gateway/static/root/assets/goal-detail-page-BRxeujXh.js +0 -4
  196. package/dist/gateway/static/root/assets/goals-page-BaZ3aw4u.js +0 -2
  197. package/dist/gateway/static/root/assets/index-EXa_i6BT.js +0 -193
  198. package/dist/gateway/static/root/assets/index-gpwk8Nro.css +0 -1
  199. package/dist/gateway/static/root/assets/local-app-workbench-page-lUpd6lSo.js +0 -2
  200. package/dist/gateway/static/root/assets/logs-page-FPDTmcWe.js +0 -7
  201. package/dist/gateway/static/root/assets/models-hub-panel-BXrdePhv.js +0 -2
  202. package/dist/gateway/static/root/assets/notes-workbench-D-EAhXv1.js +0 -4
  203. package/dist/gateway/static/root/assets/project-detail-page-BjpB1wrp.js +0 -1
  204. package/dist/gateway/static/root/assets/projects-page-BxyjqOfC.js +0 -1
  205. package/dist/gateway/static/root/assets/remote-access-hub-BFv6Upke.js +0 -1
  206. package/dist/gateway/static/root/assets/sessions-page-BX4DH8J7.js +0 -1
  207. package/dist/gateway/static/root/assets/settings-advanced-gate-CJ9MbRP8.js +0 -1
  208. package/dist/gateway/static/root/assets/setup-status-panel-BH4xQKM9.js +0 -1
  209. package/dist/gateway/static/root/assets/shares-settings-B6kKkvOb.js +0 -1
  210. package/dist/gateway/static/root/assets/skill-reload-api-DtjS-nUK.js +0 -1
  211. package/dist/gateway/static/root/assets/skills-page-CQEoPv0u.js +0 -2
  212. package/dist/gateway/static/root/assets/sliding-segmented-uWmrxE3P.js +0 -1
  213. package/dist/gateway/static/root/assets/user-context-page-Dn2T3itn.js +0 -1
  214. package/dist/gateway/static/root/assets/voice-api-key-field-wtWc3SfN.js +0 -1
  215. package/dist/gateway/static/root/assets/work-discovery-page-Ckxhj66e.js +0 -1
  216. package/dist/gateway/static/root/assets/work-item-detail-page-_1QgGPNw.js +0 -1
  217. package/dist/gateway/static/root/assets/work-page-BPdf2iuv.js +0 -1
  218. package/dist/gateway/static/root/assets/workflows-page-DdKTx0Hs.js +0 -11
@@ -48,6 +48,10 @@ import { startConnectorMemorySyncCoordinator } from "../connectors/memory-sync-c
48
48
  import { startConnectorSupervisor } from "../connectors/supervisor.js";
49
49
  import { assertGatewayAuthConfigured, extractToken, resolveGatewayAuth, validateToken } from "./auth.js";
50
50
  import { reconcileDreamingAutomations } from "./dreaming-automation-reconciler.js";
51
+ import { FocusService } from "../proactive/focus-service.js";
52
+ import { processFocusAutomationRun } from "../proactive/run-processor.js";
53
+ import { startTrialExpiryReconciler } from "../proactive/trial-expiry-reconciler.js";
54
+ import "../proactive/index.js";
51
55
  import { NotesStore } from "../notes/store.js";
52
56
  import { buildNoteAgentContext } from "../notes/agent-context.js";
53
57
  import { NotesService } from "../notes/service.js";
@@ -141,6 +145,7 @@ var GatewayService = class {
141
145
  connectedKnowledgeCoordinator = null;
142
146
  stopAutomationProductEventBridge = null;
143
147
  stopSessionTranscriptAutomationEvents = null;
148
+ stopFocusTrialExpiryReconciler = null;
144
149
  /**
145
150
  * Webchat agent invocation surface (`runAgent`, `abortAgentRun`, `steer*`,
146
151
  * `submitClarifyResponse`, clarify-bridge dispatch). Owns the
@@ -356,7 +361,7 @@ var GatewayService = class {
356
361
  getDefaultAgentId: () => getDefaultAgentId(this.config),
357
362
  getProjectWorkspaceRoot: (projectId) => this.projects.get(projectId)?.workspaceRoot,
358
363
  workflowRunService: this.createWorkflowRunService(),
359
- onRunCompleted: (run) => this.emit("automation.run.completed", { run })
364
+ onRunCompleted: (run) => this.handleAutomationRunCompleted(run)
360
365
  });
361
366
  this._agentService.persistentGoals.setWebchatContinuationScheduler((sessionKey, message) => {
362
367
  const scheduleWhenIdle = () => {
@@ -666,7 +671,7 @@ var GatewayService = class {
666
671
  agentService: this.agentService,
667
672
  getDefaultAgentId: () => getDefaultAgentId(this.config),
668
673
  workflowRunService: this.createWorkflowRunService(),
669
- onRunCompleted: (run) => this.emit("automation.run.completed", { run })
674
+ onRunCompleted: (run) => this.handleAutomationRunCompleted(run)
670
675
  });
671
676
  this.startAutomationProductEventBridge();
672
677
  await trace.measure("workflows.reconcile", () => this.reconcileInterruptedWorkflowRuns());
@@ -679,6 +684,7 @@ var GatewayService = class {
679
684
  });
680
685
  await trace.measure("automations.initialize", () => this.automationService.initialize());
681
686
  await trace.measure("dreaming.reconcile", () => this.reconcileDreamingAutomations());
687
+ this.stopFocusTrialExpiryReconciler = startTrialExpiryReconciler(new FocusService(this.automationService));
682
688
  await this.notesService.initialize();
683
689
  this.ensureHeartbeatService().start(heartbeatRunnerConfigFromConfig(this.config));
684
690
  this.connectorSupervisor = startConnectorSupervisor({
@@ -834,6 +840,8 @@ var GatewayService = class {
834
840
  this.lastChannelConnectDeferMode = "auto";
835
841
  this.lastChannelConnectDeferSource = "off";
836
842
  await this.channelManager.stop();
843
+ await this.stopFocusTrialExpiryReconciler?.();
844
+ this.stopFocusTrialExpiryReconciler = null;
837
845
  await this.automationService.stop();
838
846
  this.stopAutomationProductEventBridge?.();
839
847
  this.stopAutomationProductEventBridge = null;
@@ -1234,6 +1242,23 @@ var GatewayService = class {
1234
1242
  this.createGoalNotificationService().handleGatewayEvent(type, payload);
1235
1243
  this.createMobileNotificationService().handleGatewayEvent(type, payload);
1236
1244
  }
1245
+ handleAutomationRunCompleted(run) {
1246
+ try {
1247
+ const proactive = processFocusAutomationRun(run);
1248
+ this.emit("automation.run.completed", {
1249
+ run,
1250
+ silent: proactive.handled
1251
+ });
1252
+ if (proactive.insight) this.emit("proactive.insight.created", { insight: proactive.insight });
1253
+ } catch (err) {
1254
+ log.warn({
1255
+ err,
1256
+ automationId: run.automationId,
1257
+ runId: run.id
1258
+ }, "Proactive result processing failed");
1259
+ this.emit("automation.run.completed", { run });
1260
+ }
1261
+ }
1237
1262
  startAutomationProductEventBridge() {
1238
1263
  this.stopAutomationProductEventBridge?.();
1239
1264
  this.stopSessionTranscriptAutomationEvents?.();
@@ -1,25 +1,28 @@
1
1
  import { tryParseMediaUri } from "./uri.js";
2
2
  import { deleteMediaBuffer } from "./store.js";
3
3
  //#region src/media/session-references.ts
4
- function collectFromValue(value, out) {
4
+ function collectFromValue(value, out, seen) {
5
5
  if (!value) return;
6
6
  if (typeof value === "string") {
7
7
  if (value.startsWith("media://")) out.add(value.trim());
8
8
  return;
9
9
  }
10
10
  if (Array.isArray(value)) {
11
- for (const item of value) collectFromValue(item, out);
11
+ if (seen.has(value)) return;
12
+ seen.add(value);
13
+ for (const item of value) collectFromValue(item, out, seen);
12
14
  return;
13
15
  }
14
16
  if (typeof value !== "object") return;
17
+ if (seen.has(value)) return;
18
+ seen.add(value);
15
19
  const record = value;
16
- if (typeof record.uri === "string" && record.uri.startsWith("media://")) out.add(record.uri.trim());
17
- if (Array.isArray(record.media)) collectFromValue(record.media, out);
18
- if (Array.isArray(record.attachments)) collectFromValue(record.attachments, out);
20
+ for (const nested of Object.values(record)) collectFromValue(nested, out, seen);
19
21
  }
20
22
  function collectMediaUrisFromMessages(messages) {
21
23
  const out = /* @__PURE__ */ new Set();
22
- for (const message of messages) collectFromValue(message, out);
24
+ const seen = /* @__PURE__ */ new WeakSet();
25
+ for (const message of messages) collectFromValue(message, out, seen);
23
26
  return out;
24
27
  }
25
28
  function messagesReferenceMediaUri(messages, uri) {
@@ -44,6 +44,7 @@ function goalEvent(payload) {
44
44
  }
45
45
  function automationEvent(payload) {
46
46
  if (!payload || typeof payload !== "object") return null;
47
+ if (payload.silent === true) return null;
47
48
  const run = payload.run;
48
49
  if (!run || run.status !== "failed" && run.status !== "timeout" && run.status !== "succeeded") return null;
49
50
  const type = run.status === "succeeded" ? "automation.completed" : "automation.failed";
@@ -75,23 +75,26 @@ function esc(value) {
75
75
  return value.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;");
76
76
  }
77
77
  function desktopPetActionFrameCount(action) {
78
- if (action === "idle") return 6;
79
- if (action === "success" || action === "error") return 8;
78
+ if (action === "idle" || action === "sleep") return 6;
79
+ if (action === "success" || action === "concern") return 8;
80
80
  return 10;
81
81
  }
82
82
  function desktopPetActionFps(action) {
83
- if (action === "idle") return 6;
84
- if (action === "success" || action === "error") return 12;
83
+ if (action === "idle" || action === "sleep") return 6;
84
+ if (action === "success" || action === "concern") return 12;
85
85
  return 10;
86
86
  }
87
87
  function desktopPetActionLoops(action) {
88
- return action !== "success" && action !== "error";
88
+ return action === "idle" || action === "sleep" || action === "research" || action === "read" || action === "create" || action === "execute" || action === "wait";
89
89
  }
90
90
  function renderAccessory(action, frame, style) {
91
91
  const t = frame / Math.max(1, desktopPetActionFrameCount(action) - 1);
92
92
  const bob = Math.sin(t * Math.PI * 2) * 2;
93
93
  const { palette } = style;
94
- if (action === "typing") {
94
+ if (action === "sleep") return `<g fill="${palette.screen}" font-family="Arial, sans-serif" font-weight="800"><text x="70" y="28" font-size="13" opacity="${frame % 2 ? .45 : .9}">z</text><text x="80" y="17" font-size="10" opacity="${frame % 2 ? .9 : .45}">z</text></g>`;
95
+ if (action === "greet" || action === "wake" || action === "pet") return `<path d="M76 23c-7-9-19 1-7 13l7 7 7-7c12-12 0-22-7-13z" fill="${palette.cheek}" stroke="#101827" stroke-width="2"/>`;
96
+ if (action === "wait") return `<g fill="${palette.screen}" transform="translate(62 18)"><circle cx="0" cy="0" r="3" opacity="${frame % 3 === 0 ? 1 : .35}"/><circle cx="10" cy="0" r="3" opacity="${frame % 3 === 1 ? 1 : .35}"/><circle cx="20" cy="0" r="3" opacity="${frame % 3 === 2 ? 1 : .35}"/></g>`;
97
+ if (action === "create") {
95
98
  const glow = frame % 2 === 0 ? 1 : .45;
96
99
  return `
97
100
  <g transform="translate(55 ${59 + bob})">
@@ -103,7 +106,7 @@ function renderAccessory(action, frame, style) {
103
106
  <rect x="29" y="28" width="5" height="2" rx="1" fill="#e0f2fe" opacity="${glow}"/>
104
107
  </g>`;
105
108
  }
106
- if (action === "toolbox") {
109
+ if (action === "prepare") {
107
110
  const open = frame % 2 === 0 ? -11 : -3;
108
111
  return `
109
112
  <g transform="translate(6 ${61 + bob})">
@@ -114,38 +117,30 @@ function renderAccessory(action, frame, style) {
114
117
  <rect x="29" y="${8 + open / 2}" width="5" height="17" rx="2" fill="#e5e7eb" stroke="#101827" stroke-width="2" transform="rotate(25 31 24)"/>
115
118
  </g>`;
116
119
  }
117
- if (action === "search") return `
120
+ if (action === "research") return `
118
121
  <g transform="translate(58 ${58 + bob}) rotate(${frame % 2 === 0 ? -7 : 4} 18 18)">
119
122
  <circle cx="15" cy="14" r="11" fill="#e0f2fe" stroke="${palette.accent}" stroke-width="5"/>
120
123
  <rect x="24" y="24" width="17" height="7" rx="3" fill="${palette.accent}" stroke="#101827" stroke-width="3" transform="rotate(43 24 24)"/>
121
124
  </g>`;
122
- if (action === "file") return `
125
+ if (action === "read") return `
123
126
  <g transform="translate(59 ${55 + bob}) rotate(${frame % 2 === 0 ? -5 : 5} 16 20)">
124
127
  <path d="M5 1h22l9 9v31H5z" fill="#eff6ff" stroke="#101827" stroke-width="3" stroke-linejoin="round"/>
125
128
  <path d="M27 1v10h9" fill="${palette.accent}" stroke="#101827" stroke-width="3" stroke-linejoin="round"/>
126
129
  <rect x="12" y="20" width="16" height="3" rx="1.5" fill="${palette.body}"/>
127
130
  <rect x="12" y="28" width="12" height="3" rx="1.5" fill="${palette.body}"/>
128
131
  </g>`;
129
- if (action === "terminal") return `
132
+ if (action === "execute") return `
130
133
  <g transform="translate(55 ${61 + bob})">
131
134
  <rect x="0" y="0" width="39" height="29" rx="7" fill="#111827" stroke="#101827" stroke-width="3"/>
132
135
  <path d="M10 10l6 5-6 5" fill="none" stroke="#86efac" stroke-width="3" stroke-linecap="round" stroke-linejoin="round" opacity="${frame % 2 === 0 ? 1 : .4}"/>
133
136
  <path d="M20 20h9" stroke="#86efac" stroke-width="3" stroke-linecap="round"/>
134
- </g>`;
135
- if (action === "browser") return `
136
- <g transform="translate(55 ${58 + bob})">
137
- <rect x="0" y="0" width="40" height="31" rx="7" fill="#e0f2fe" stroke="#101827" stroke-width="3"/>
138
- <path d="M1 11h38" stroke="${palette.accent}" stroke-width="8"/>
139
- <circle cx="10" cy="10" r="2" fill="#101827"/>
140
- <circle cx="17" cy="10" r="2" fill="#101827"/>
141
- <rect x="11" y="21" width="20" height="4" rx="2" fill="${palette.body}"/>
142
137
  </g>`;
143
138
  if (action === "success") return `
144
139
  <g fill="#facc15" transform="translate(61 ${12 + bob})">
145
140
  <path d="M12 0l3 8 8 3-8 3-3 8-3-8-8-3 8-3z"/>
146
141
  <path d="M-12 18l2 5 5 2-5 2-2 5-2-5-5-2 5-2z" opacity="0.78"/>
147
142
  </g>`;
148
- if (action === "error") return `
143
+ if (action === "concern") return `
149
144
  <g transform="translate(61 ${56 + bob})">
150
145
  <path d="M18 0l18 32H0z" fill="#facc15" stroke="#101827" stroke-width="3" stroke-linejoin="round"/>
151
146
  <text x="18" y="26" text-anchor="middle" font-family="Arial, sans-serif" font-size="22" font-weight="900" fill="#101827">!</text>
@@ -170,14 +165,14 @@ function renderHead(style) {
170
165
  }
171
166
  function renderFrame(style, action, frame) {
172
167
  const t = frame / Math.max(1, desktopPetActionFrameCount(action) - 1);
173
- const bob = Math.sin(t * Math.PI * 2) * (action === "idle" ? 2.5 : 1.5);
174
- const tilt = action === "toolbox" ? Math.sin(t * Math.PI * 2) * 2.5 : 0;
168
+ const bob = action === "sleep" ? 7 : action === "pickedUp" ? -6 : action === "released" ? 4 : Math.sin(t * Math.PI * 2) * (action === "idle" ? 2.5 : 1.5);
169
+ const tilt = action === "prepare" ? Math.sin(t * Math.PI * 2) * 2.5 : action === "pet" ? Math.sin(t * Math.PI) * 5 : 0;
175
170
  const { palette } = style;
176
- const face = action === "error" ? "#3f0f18" : palette.face;
177
- const eye = action === "error" ? "#fca5a5" : palette.screen;
178
- const mouth = action === "success" ? "M39 45q5 5 10 0" : "M42 46h9";
179
- const leftArm = action === "typing" ? 23 + frame % 2 * 13 : action === "toolbox" ? 39 + frame % 2 * 10 : 9;
180
- const rightArm = action === "typing" ? -23 - frame % 2 * 13 : action === "toolbox" ? -39 - frame % 2 * 10 : -9;
171
+ const face = action === "concern" ? "#3f0f18" : palette.face;
172
+ const eye = action === "concern" ? "#fca5a5" : palette.screen;
173
+ const mouth = action === "success" || action === "greet" || action === "pet" ? "M39 45q5 5 10 0" : "M42 46h9";
174
+ const leftArm = action === "create" || action === "execute" ? 23 + frame % 2 * 13 : action === "prepare" || action === "read" ? 39 + frame % 2 * 10 : action === "pickedUp" ? 58 : 9;
175
+ const rightArm = action === "create" || action === "execute" ? -23 - frame % 2 * 13 : action === "prepare" || action === "read" ? -39 - frame % 2 * 10 : action === "greet" || action === "wake" ? -48 - frame % 2 * 12 : action === "pickedUp" ? -58 : -9;
181
176
  return `
182
177
  <g transform="translate(0 ${bob}) rotate(${tilt} 48 76)">
183
178
  ${renderHead(style)}
@@ -287,6 +282,7 @@ async function createDesktopPetPackage(input) {
287
282
  await mkdir(targetRoot, { recursive: true });
288
283
  const { id, dir } = await resolvePackageDir(targetRoot, (input.id?.trim() ? normalizePackageId(input.id) : null) || slugify(input.name?.trim() || titleFromPrompt(prompt), `pet-${hashString(prompt).toString(36)}`), input.overwrite === true);
289
284
  const existingManifest = input.overwrite === true ? await readExistingManifest(dir) : null;
285
+ if (existingManifest && existingManifest.schemaVersion !== 2) throw new Error(`Existing pet package must use schemaVersion 2`);
290
286
  const existingName = typeof existingManifest?.name === "string" ? existingManifest.name.trim() : "";
291
287
  const persona = normalizePersona(input.persona ?? existingManifest?.persona);
292
288
  const baseName = clampText(input.name?.trim() || existingName || titleFromPrompt(prompt), 36);
@@ -296,6 +292,7 @@ async function createDesktopPetPackage(input) {
296
292
  const thumbnailPath = join(tempDir, "thumbnail.svg");
297
293
  const manifestPath = join(tempDir, "manifest.json");
298
294
  const manifest = {
295
+ schemaVersion: 2,
299
296
  id,
300
297
  name: baseName,
301
298
  description,
@@ -1,2 +1,3 @@
1
- export declare const DESKTOP_PET_ACTIONS: readonly ["idle", "typing", "toolbox", "search", "file", "terminal", "browser", "success", "error"];
1
+ export declare const DESKTOP_PET_SCHEMA_VERSION: 2;
2
+ export declare const DESKTOP_PET_ACTIONS: readonly ["idle", "sleep", "wake", "greet", "prepare", "research", "read", "create", "execute", "wait", "success", "concern", "pet", "pickedUp", "released"];
2
3
  export type DesktopPetPackageAction = (typeof DESKTOP_PET_ACTIONS)[number];
@@ -1,14 +1,21 @@
1
1
  //#region src/pets/manifest.ts
2
+ const DESKTOP_PET_SCHEMA_VERSION = 2;
2
3
  const DESKTOP_PET_ACTIONS = [
3
4
  "idle",
4
- "typing",
5
- "toolbox",
6
- "search",
7
- "file",
8
- "terminal",
9
- "browser",
5
+ "sleep",
6
+ "wake",
7
+ "greet",
8
+ "prepare",
9
+ "research",
10
+ "read",
11
+ "create",
12
+ "execute",
13
+ "wait",
10
14
  "success",
11
- "error"
15
+ "concern",
16
+ "pet",
17
+ "pickedUp",
18
+ "released"
12
19
  ];
13
20
  //#endregion
14
- export { DESKTOP_PET_ACTIONS };
21
+ export { DESKTOP_PET_ACTIONS, DESKTOP_PET_SCHEMA_VERSION };
@@ -135,6 +135,7 @@ async function validateDesktopPetPackage(dir) {
135
135
  };
136
136
  }
137
137
  if (typeof manifest.id !== "string" || !manifest.id.trim()) details.push("id is required");
138
+ if (manifest.schemaVersion !== 2) details.push(`schemaVersion must be 2`);
138
139
  if (typeof manifest.name !== "string" || !manifest.name.trim()) details.push("name is required");
139
140
  if (typeof manifest.description !== "string" || !manifest.description.trim()) details.push("description is required");
140
141
  if (positiveNumber(manifest.canvasWidth) === null || positiveNumber(manifest.canvasHeight) === null) details.push("canvasWidth and canvasHeight must be positive numbers");
@@ -143,9 +144,13 @@ async function validateDesktopPetPackage(dir) {
143
144
  const rawAnimations = manifest.animations && typeof manifest.animations === "object" ? manifest.animations : null;
144
145
  if (!rawAnimations) details.push("animations is required");
145
146
  const animations = [];
146
- if (rawAnimations) for (const action of DESKTOP_PET_ACTIONS) {
147
- const animation = parseAnimation(action, rawAnimations[action], details);
148
- if (animation) animations.push(animation);
147
+ if (rawAnimations) {
148
+ const supportedActions = new Set(DESKTOP_PET_ACTIONS);
149
+ for (const action of Object.keys(rawAnimations)) if (!supportedActions.has(action)) details.push(`${action}: unsupported animation action`);
150
+ for (const action of DESKTOP_PET_ACTIONS) {
151
+ const animation = parseAnimation(action, rawAnimations[action], details);
152
+ if (animation) animations.push(animation);
153
+ }
149
154
  }
150
155
  for (const animation of animations) {
151
156
  const sourcePath = safeResolve(dir, animation.src);
@@ -0,0 +1,4 @@
1
+ import type { KnowledgeSourceItem } from '../knowledge/types.js';
2
+ import type { FocusCalendarSignal, FocusView } from './types.js';
3
+ export declare function buildFocusCalendarSignals(items: KnowledgeSourceItem[], focuses: FocusView[], nowMs?: number): FocusCalendarSignal[];
4
+ export declare function listFocusCalendarSignals(focuses: FocusView[], nowMs?: number): FocusCalendarSignal[];
@@ -0,0 +1,120 @@
1
+ import { listKnowledgeSourceItems } from "../storage/sqlite/knowledge-repository.js";
2
+ //#region src/proactive/calendar-signals.ts
3
+ const LOOKAHEAD_MS = 7 * 864e5;
4
+ const FIELD_LIMIT = 8;
5
+ const TITLE_KEYS = new Set([
6
+ "summary",
7
+ "title",
8
+ "name",
9
+ "subject"
10
+ ]);
11
+ const DESCRIPTION_KEYS = new Set([
12
+ "description",
13
+ "notes",
14
+ "body",
15
+ "agenda"
16
+ ]);
17
+ const START_KEYS = new Set([
18
+ "start",
19
+ "starttime",
20
+ "start_time",
21
+ "startat",
22
+ "start_at",
23
+ "datetime"
24
+ ]);
25
+ const END_KEYS = new Set([
26
+ "end",
27
+ "endtime",
28
+ "end_time",
29
+ "endat",
30
+ "end_at"
31
+ ]);
32
+ const STOP_WORDS = new Set([
33
+ "about",
34
+ "after",
35
+ "before",
36
+ "from",
37
+ "have",
38
+ "meeting",
39
+ "project",
40
+ "review",
41
+ "the",
42
+ "this",
43
+ "with"
44
+ ]);
45
+ function parsePayload(item) {
46
+ if (!item.normalizedText) return null;
47
+ try {
48
+ return JSON.parse(item.normalizedText);
49
+ } catch {
50
+ return null;
51
+ }
52
+ }
53
+ function findStrings(value, keys, depth = 0) {
54
+ if (depth > 6 || value == null) return [];
55
+ if (Array.isArray(value)) return value.flatMap((item) => findStrings(item, keys, depth + 1)).slice(0, FIELD_LIMIT);
56
+ if (typeof value !== "object") return [];
57
+ const record = value;
58
+ const direct = Object.entries(record).flatMap(([key, nested]) => {
59
+ if (!keys.has(key.toLowerCase().replaceAll("-", "_"))) return [];
60
+ if (typeof nested === "string") return [nested];
61
+ return findStrings(nested, new Set([
62
+ "datetime",
63
+ "date",
64
+ "value"
65
+ ]), depth + 1);
66
+ });
67
+ if (direct.length > 0) return direct.slice(0, FIELD_LIMIT);
68
+ return Object.values(record).flatMap((nested) => findStrings(nested, keys, depth + 1)).slice(0, FIELD_LIMIT);
69
+ }
70
+ function firstDate(payload, keys) {
71
+ for (const value of findStrings(payload, keys)) {
72
+ const parsed = Date.parse(value);
73
+ if (Number.isFinite(parsed)) return parsed;
74
+ }
75
+ }
76
+ function terms(value) {
77
+ const normalized = value.toLocaleLowerCase();
78
+ const result = new Set(normalized.match(/[a-z0-9][a-z0-9_-]{2,}/g)?.filter((word) => !STOP_WORDS.has(word)) ?? []);
79
+ for (const sequence of normalized.match(/[\p{Script=Han}]{2,}/gu) ?? []) for (let index = 0; index < sequence.length - 1; index += 1) result.add(sequence.slice(index, index + 2));
80
+ return result;
81
+ }
82
+ function relatedFocus(focuses, text) {
83
+ const eventTerms = terms(text);
84
+ if (eventTerms.size === 0) return void 0;
85
+ return focuses.map((focus) => ({
86
+ focus,
87
+ score: [...terms(`${focus.title} ${focus.summary}`)].filter((term) => eventTerms.has(term)).length
88
+ })).filter((candidate) => candidate.score >= 2).toSorted((left, right) => right.score - left.score || right.focus.focusScore - left.focus.focusScore)[0]?.focus;
89
+ }
90
+ function buildFocusCalendarSignals(items, focuses, nowMs = Date.now()) {
91
+ const end = nowMs + LOOKAHEAD_MS;
92
+ const signals = items.flatMap((item) => {
93
+ if (item.itemType !== "calendar_event") return [];
94
+ const payload = parsePayload(item);
95
+ const title = findStrings(payload, TITLE_KEYS)[0]?.trim();
96
+ const startsAt = firstDate(payload, START_KEYS);
97
+ if (!title || startsAt == null || startsAt < nowMs || startsAt > end) return [];
98
+ const focus = relatedFocus(focuses, `${title} ${findStrings(payload, DESCRIPTION_KEYS).join(" ")}`);
99
+ if (!focus) return [];
100
+ const endsAt = firstDate(payload, END_KEYS);
101
+ return [{
102
+ id: item.id,
103
+ focusId: focus.id,
104
+ focusTitle: focus.title,
105
+ title,
106
+ startsAt,
107
+ ...endsAt != null ? { endsAt } : {},
108
+ sourceInstanceId: item.sourceInstanceId
109
+ }];
110
+ }).toSorted((left, right) => left.startsAt - right.startsAt);
111
+ return signals.filter((signal, index) => signals.findIndex((candidate) => candidate.focusId === signal.focusId && candidate.startsAt === signal.startsAt && candidate.title.toLocaleLowerCase() === signal.title.toLocaleLowerCase()) === index).slice(0, 20);
112
+ }
113
+ function listFocusCalendarSignals(focuses, nowMs = Date.now()) {
114
+ return buildFocusCalendarSignals(listKnowledgeSourceItems({
115
+ itemType: "calendar_event",
116
+ limit: 500
117
+ }), focuses, nowMs);
118
+ }
119
+ //#endregion
120
+ export { buildFocusCalendarSignals, listFocusCalendarSignals };
@@ -0,0 +1,62 @@
1
+ import type { Automation, AutomationRun } from '../automations/index.js';
2
+ import type { FocusView, FocusWatch, FocusWatchKind } from './types.js';
3
+ interface AutomationPort {
4
+ create(input: {
5
+ name: string;
6
+ description: string;
7
+ projectId?: string;
8
+ trigger: {
9
+ kind: 'schedule';
10
+ schedule: {
11
+ kind: 'interval';
12
+ everyMs: number;
13
+ };
14
+ };
15
+ action: {
16
+ kind: 'agent';
17
+ instruction: string;
18
+ timeoutSeconds: number;
19
+ };
20
+ safety: {
21
+ mode: 'suggest_only';
22
+ };
23
+ afterRun: {
24
+ kind: 'none';
25
+ };
26
+ reliability: {
27
+ timeoutSeconds: number;
28
+ disableAfterConsecutiveFailures: number;
29
+ };
30
+ }): Promise<Automation>;
31
+ pause(id: string): Promise<Automation | null>;
32
+ resume(id: string): Promise<Automation | null>;
33
+ update(id: string, patch: {
34
+ action: {
35
+ kind: 'agent';
36
+ instruction: string;
37
+ timeoutSeconds: number;
38
+ };
39
+ }): Promise<Automation | null>;
40
+ runNow(id: string): Promise<AutomationRun>;
41
+ }
42
+ export declare class FocusService {
43
+ private readonly automations;
44
+ private readonly goals;
45
+ constructor(automations: AutomationPort);
46
+ list(options?: {
47
+ includeUnreviewed?: boolean;
48
+ }): FocusView[];
49
+ confirm(id: string): FocusView | null;
50
+ activateTrial(input: {
51
+ threadId: string;
52
+ kind?: FocusWatchKind;
53
+ eventContext?: string;
54
+ }): Promise<{
55
+ focus: FocusView;
56
+ watch: FocusWatch;
57
+ }>;
58
+ pauseWatch(id: string): Promise<FocusWatch | null>;
59
+ reconcileExpiredTrials(nowMs?: number): Promise<number>;
60
+ recordInsightFeedback(watchId: string, useful: boolean): Promise<FocusWatch | null>;
61
+ }
62
+ export {};