@xopcai/xopc 0.0.118 → 0.0.120

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 (503) hide show
  1. package/README.md +2 -1
  2. package/README.zh-CN.md +2 -1
  3. package/dist/browser-ext/manifest.json +1 -1
  4. package/dist/extensions/telegram/xopc.extension.json +1 -1
  5. package/dist/gateway/static/root/assets/{agent-avatar-dicebear-dzUrQoeZ.js → agent-avatar-dicebear-APTlX9Sq.js} +1 -1
  6. package/dist/gateway/static/root/assets/agents-CFW_FS_V.js +2 -0
  7. package/dist/gateway/static/root/assets/app-management-settings-panel-DTKc5HHT.js +1 -0
  8. package/dist/gateway/static/root/assets/appearance-settings-BTciFrE9.js +1 -0
  9. package/dist/gateway/static/root/assets/{apps-page--wMEL00f.js → apps-page-DT52OrbM.js} +1 -1
  10. package/dist/gateway/static/root/assets/{archive-plugin-Cki4SfU2.js → archive-plugin-CiHaUMII.js} +1 -1
  11. package/dist/gateway/static/root/assets/{attachment-load-D-KnS2Do.js → attachment-load-t4gSrNjL.js} +1 -1
  12. package/dist/gateway/static/root/assets/automation-suggestion-card-CtysjSoQ.js +1 -0
  13. package/dist/gateway/static/root/assets/automations-page-B2YvT3ES.js +1 -0
  14. package/dist/gateway/static/root/assets/{binary-plugins-D2sgvJja.js → binary-plugins-BAbSldW5.js} +1 -1
  15. package/dist/gateway/static/root/assets/{block-editor-DIq-4Gvb.js → block-editor-BNr_82xl.js} +28 -28
  16. package/dist/gateway/static/root/assets/browser-settings-page-BQEXPhDU.js +8 -0
  17. package/dist/gateway/static/root/assets/capability-presets-api-tzD702Gg.js +1 -0
  18. package/dist/gateway/static/root/assets/capability-presets-settings-panel-AGhTueAc.js +1 -0
  19. package/dist/gateway/static/root/assets/channel-recipient-api-DL_KzwGE.js +1 -0
  20. package/dist/gateway/static/root/assets/channels-settings-DRTutLlN.js +1 -0
  21. package/dist/gateway/static/root/assets/cn-BQ_8x0bT.js +1 -0
  22. package/dist/gateway/static/root/assets/connectors-page-DneJVuge.js +2 -0
  23. package/dist/gateway/static/root/assets/cron-expression-B3B1eqnr.js +2 -0
  24. package/dist/gateway/static/root/assets/dreaming-settings-BEwWA1yf.js +1 -0
  25. package/dist/gateway/static/root/assets/{extension-debug-page-DYu1KaFQ.js → extension-debug-page-Dl2kO0Sf.js} +1 -1
  26. package/dist/gateway/static/root/assets/{extension-page-B3W6QwlZ.js → extension-page-DmbLPsx_.js} +1 -1
  27. package/dist/gateway/static/root/assets/{extension-settings-page-D7VQ-cxE.js → extension-settings-page-BS2rx40e.js} +1 -1
  28. package/dist/gateway/static/root/assets/{fetch-B7xDPu-R.js → fetch-B3ME5Eri.js} +1 -1
  29. package/dist/gateway/static/root/assets/format-cron-label-arqgGlVV.js +1 -0
  30. package/dist/gateway/static/root/assets/{gateway-config-api-BTBLSeUu.js → gateway-config-api-DI9_BBTo.js} +1 -1
  31. package/dist/gateway/static/root/assets/gateway-settings-DAFI_T0W.js +1 -0
  32. package/dist/gateway/static/root/assets/{gateway-startup-retry-CYj9FWCp.js → gateway-startup-retry-CSZQTz6K.js} +1 -1
  33. package/dist/gateway/static/root/assets/goal-detail-page-DLuz4jC9.js +1 -0
  34. package/dist/gateway/static/root/assets/{goals-config-api-CQQgzPr3.js → goals-config-api-Bhzqrp2w.js} +1 -1
  35. package/dist/gateway/static/root/assets/{goals-page-BHitvJAv.js → goals-page-DTAfv9Ft.js} +2 -2
  36. package/dist/gateway/static/root/assets/goals-settings-CWN2iirQ.js +1 -0
  37. package/dist/gateway/static/root/assets/heartbeat-settings-CkkkHvOi.js +1 -0
  38. package/dist/gateway/static/root/assets/index-CnjzMw5i.js +191 -0
  39. package/dist/gateway/static/root/assets/index-E1QinYKp.css +1 -0
  40. package/dist/gateway/static/root/assets/keyboard-shortcuts-settings-kMp08SlX.js +1 -0
  41. package/dist/gateway/static/root/assets/{locale-store-DjbfSsfA.js → locale-store-Ba72bFmP.js} +1 -1
  42. package/dist/gateway/static/root/assets/{logs-page-C2Uqvae9.js → logs-page-CDXDlS_W.js} +2 -2
  43. package/dist/gateway/static/root/assets/{markdown-split-BwOFrJ2E.js → markdown-split-Bc0w40vz.js} +1 -1
  44. package/dist/gateway/static/root/assets/{media-plugins-Cnz6Q5G6.js → media-plugins-DJ_HvgIy.js} +1 -1
  45. package/dist/gateway/static/root/assets/messages-CISb1HLv.js +3 -0
  46. package/dist/gateway/static/root/assets/models-hub-panel-BTwxMIgZ.js +2 -0
  47. package/dist/gateway/static/root/assets/note-detail-page-BBfOeB0m.js +2 -0
  48. package/dist/gateway/static/root/assets/{note-image-lightbox-B-Svpmza.js → note-image-lightbox-4zntqpZq.js} +1 -1
  49. package/dist/gateway/static/root/assets/notes-page-VocWOjoK.js +1 -0
  50. package/dist/gateway/static/root/assets/{preview-open-alternatives-Bss4TiwP.js → preview-open-alternatives-BbA7sRd_.js} +1 -1
  51. package/dist/gateway/static/root/assets/remote-access-hub-CXwjuD_Q.js +1 -0
  52. package/dist/gateway/static/root/assets/{save-bar-controls-BRNjdgKq.js → save-bar-controls-Dividh61.js} +1 -1
  53. package/dist/gateway/static/root/assets/schedule-field-pRheF2CO.js +1 -0
  54. package/dist/gateway/static/root/assets/{schema-form-Dub9sy8r.js → schema-form-D6PiPxfr.js} +1 -1
  55. package/dist/gateway/static/root/assets/sessions-page-CpcVySQK.js +1 -0
  56. package/dist/gateway/static/root/assets/settings-advanced-gate-BVy_TawT.js +1 -0
  57. package/dist/gateway/static/root/assets/{settings-collapsible-section-BeFLavGi.js → settings-collapsible-section-BMCOfuE_.js} +1 -1
  58. package/dist/gateway/static/root/assets/settings-form-section-DBkGwpIN.js +1 -0
  59. package/dist/gateway/static/root/assets/settings-page-CZpNyCWn.js +1 -0
  60. package/dist/gateway/static/root/assets/settings-page-layout-NxoW5Y57.js +1 -0
  61. package/dist/gateway/static/root/assets/setup-status-panel-MVHLLu_a.js +1 -0
  62. package/dist/gateway/static/root/assets/{share-preview-page-C8glrdqe.js → share-preview-page-B0suFCfj.js} +1 -1
  63. package/dist/gateway/static/root/assets/shares-settings-C6DBbQGo.js +1 -0
  64. package/dist/gateway/static/root/assets/skill-reload-api-6hJmhwSn.js +1 -0
  65. package/dist/gateway/static/root/assets/skills-page-Im1MA0Iw.js +2 -0
  66. package/dist/gateway/static/root/assets/system-settings-panel-CrmEnyX4.js +1 -0
  67. package/dist/gateway/static/root/assets/{theme-store-CD2wtgZV.js → theme-store-Bt6vAkSB.js} +1 -1
  68. package/dist/gateway/static/root/assets/typed-models-lib-BAsGn25g.js +1 -0
  69. package/dist/gateway/static/root/assets/{use-channel-catalog-DqlWTsDb.js → use-channel-catalog-C7vcAoGb.js} +1 -1
  70. package/dist/gateway/static/root/assets/user-profile-settings-panel-QAQWGelF.js +1 -0
  71. package/dist/gateway/static/root/assets/utils-Dl9efgnV.js +1 -0
  72. package/dist/gateway/static/root/assets/{voice-api-key-field-C73IVZeC.js → voice-api-key-field-D-6XueTv.js} +1 -1
  73. package/dist/gateway/static/root/assets/{voice-player-store-C_ArLJPM.js → voice-player-store-CMC5NOJp.js} +1 -1
  74. package/dist/gateway/static/root/assets/workflow-run-setup-panel-DVPllR4k.js +3 -0
  75. package/dist/gateway/static/root/assets/workflows-page-B94WISTW.js +18 -0
  76. package/dist/gateway/static/root/index.html +8 -9
  77. package/dist/package.js +1 -1
  78. package/dist/src/agent/agent-manager.d.ts +4 -5
  79. package/dist/src/agent/agent-manager.js +4 -8
  80. package/dist/src/agent/agent-manager.js.map +1 -1
  81. package/dist/src/agent/context/workspace-templates/AGENTS.md +3 -2
  82. package/dist/src/agent/embedded/run-for-session.js +102 -14
  83. package/dist/src/agent/embedded/run-for-session.js.map +1 -1
  84. package/dist/src/agent/fallback/candidates.d.ts +0 -8
  85. package/dist/src/agent/fallback/candidates.js.map +1 -1
  86. package/dist/src/agent/index.js +1 -1
  87. package/dist/src/agent/lifecycle/handlers/compaction.d.ts +1 -3
  88. package/dist/src/agent/lifecycle/handlers/compaction.js +1 -16
  89. package/dist/src/agent/lifecycle/handlers/compaction.js.map +1 -1
  90. package/dist/src/agent/lifecycle/progress.d.ts +0 -1
  91. package/dist/src/agent/lifecycle/progress.js +1 -6
  92. package/dist/src/agent/lifecycle/progress.js.map +1 -1
  93. package/dist/src/agent/lifecycle/timeout-wrapper.d.ts +1 -2
  94. package/dist/src/agent/lifecycle/timeout-wrapper.js +1 -7
  95. package/dist/src/agent/lifecycle/timeout-wrapper.js.map +1 -1
  96. package/dist/src/agent/memory/builtin-memory-store.d.ts +1 -1
  97. package/dist/src/agent/memory/builtin-memory-store.js +1 -1
  98. package/dist/src/agent/memory/builtin-memory-store.js.map +1 -1
  99. package/dist/src/agent/memory/builtin-provider.d.ts +2 -2
  100. package/dist/src/agent/memory/builtin-provider.js +2 -2
  101. package/dist/src/agent/memory/builtin-provider.js.map +1 -1
  102. package/dist/src/agent/memory/dreaming/light-sweep.d.ts +0 -7
  103. package/dist/src/agent/memory/dreaming/light-sweep.js +16 -277
  104. package/dist/src/agent/memory/dreaming/light-sweep.js.map +1 -1
  105. package/dist/src/agent/memory/dreaming/rem-patterns.d.ts +1 -1
  106. package/dist/src/agent/memory/dreaming/rem-patterns.js +1 -1
  107. package/dist/src/agent/memory/dreaming/rem-patterns.js.map +1 -1
  108. package/dist/src/agent/memory/dreaming/short-term-store.d.ts +3 -3
  109. package/dist/src/agent/memory/dreaming/short-term-store.js +5 -5
  110. package/dist/src/agent/memory/dreaming/short-term-store.js.map +1 -1
  111. package/dist/src/agent/memory/dreaming/utils.d.ts +2 -2
  112. package/dist/src/agent/memory/dreaming/utils.js +2 -2
  113. package/dist/src/agent/memory/dreaming/utils.js.map +1 -1
  114. package/dist/src/agent/memory/index.d.ts +0 -2
  115. package/dist/src/agent/memory/index.js +1 -2
  116. package/dist/src/agent/middleware/self-verify.d.ts +0 -1
  117. package/dist/src/agent/middleware/self-verify.js +0 -2
  118. package/dist/src/agent/middleware/self-verify.js.map +1 -1
  119. package/dist/src/agent/models/index.d.ts +1 -1
  120. package/dist/src/agent/models/manager.d.ts +4 -20
  121. package/dist/src/agent/models/manager.js +9 -126
  122. package/dist/src/agent/models/manager.js.map +1 -1
  123. package/dist/src/agent/orchestration/agent-orchestrator.d.ts +0 -4
  124. package/dist/src/agent/orchestration/agent-orchestrator.js +1 -9
  125. package/dist/src/agent/orchestration/agent-orchestrator.js.map +1 -1
  126. package/dist/src/agent/prompt/sections/memory-skills.js +11 -10
  127. package/dist/src/agent/prompt/sections/memory-skills.js.map +1 -1
  128. package/dist/src/agent/prompt/sections/tooling.js +4 -4
  129. package/dist/src/agent/prompt/sections/tooling.js.map +1 -1
  130. package/dist/src/agent/prompt/service-prompt-builder.d.ts +0 -1
  131. package/dist/src/agent/prompt/service-prompt-builder.js +0 -12
  132. package/dist/src/agent/prompt/service-prompt-builder.js.map +1 -1
  133. package/dist/src/agent/prompt/subagent-context.js +1 -1
  134. package/dist/src/agent/prompt/subagent-context.js.map +1 -1
  135. package/dist/src/agent/prompt/types.d.ts +1 -1
  136. package/dist/src/agent/reply/startup-context.js +6 -105
  137. package/dist/src/agent/reply/startup-context.js.map +1 -1
  138. package/dist/src/agent/service.d.ts +1 -12
  139. package/dist/src/agent/service.js +3 -81
  140. package/dist/src/agent/service.js.map +1 -1
  141. package/dist/src/agent/service.types.d.ts +2 -2
  142. package/dist/src/agent/session/session-config-service.d.ts +11 -11
  143. package/dist/src/agent/session/session-config-service.js +14 -14
  144. package/dist/src/agent/session/session-config-service.js.map +1 -1
  145. package/dist/src/agent/session/session-inspector.js +3 -2
  146. package/dist/src/agent/session/session-inspector.js.map +1 -1
  147. package/dist/src/agent/starter-agents.js +12 -12
  148. package/dist/src/agent/starter-agents.js.map +1 -1
  149. package/dist/src/agent/tools/automation-tool.d.ts +14 -0
  150. package/dist/src/agent/tools/automation-tool.js +102 -0
  151. package/dist/src/agent/tools/automation-tool.js.map +1 -0
  152. package/dist/src/agent/tools/delegate-tool.js +1 -1
  153. package/dist/src/agent/tools/delegate-tool.js.map +1 -1
  154. package/dist/src/agent/tools/factory.d.ts +3 -3
  155. package/dist/src/agent/tools/factory.js +2 -2
  156. package/dist/src/agent/tools/factory.js.map +1 -1
  157. package/dist/src/agent/tools/index.d.ts +1 -1
  158. package/dist/src/agent/tools/index.js +2 -2
  159. package/dist/src/agent/tools/memory-tool.js +2 -2
  160. package/dist/src/agent/tools/memory-tool.js.map +1 -1
  161. package/dist/src/agent-manifest/resolver.d.ts +1 -0
  162. package/dist/src/agent-manifest/resolver.js +1 -0
  163. package/dist/src/agent-manifest/resolver.js.map +1 -1
  164. package/dist/src/agent-manifest/schema.d.ts +6 -0
  165. package/dist/src/agent-manifest/schema.js +12 -3
  166. package/dist/src/agent-manifest/schema.js.map +1 -1
  167. package/dist/src/ai-assist/text-assist.d.ts +1 -1
  168. package/dist/src/ai-assist/text-assist.js +56 -0
  169. package/dist/src/ai-assist/text-assist.js.map +1 -1
  170. package/dist/src/auth/profiles/store.js.map +1 -1
  171. package/dist/src/automations/api/routes.d.ts +3 -0
  172. package/dist/src/automations/api/routes.js +193 -0
  173. package/dist/src/automations/api/routes.js.map +1 -0
  174. package/dist/src/automations/domain/index.d.ts +3 -0
  175. package/dist/src/automations/domain/index.js +3 -0
  176. package/dist/src/automations/domain/schedule.d.ts +4 -0
  177. package/dist/src/automations/domain/schedule.js +37 -0
  178. package/dist/src/automations/domain/schedule.js.map +1 -0
  179. package/dist/src/automations/domain/types.d.ts +160 -0
  180. package/dist/src/automations/domain/validation.d.ts +370 -0
  181. package/dist/src/automations/domain/validation.js +149 -0
  182. package/dist/src/automations/domain/validation.js.map +1 -0
  183. package/dist/src/automations/draft/automation-draft-prompt.d.ts +26 -0
  184. package/dist/src/automations/draft/automation-draft-prompt.js +127 -0
  185. package/dist/src/automations/draft/automation-draft-prompt.js.map +1 -0
  186. package/dist/src/automations/draft/automation-draft-service.d.ts +12 -0
  187. package/dist/src/automations/draft/automation-draft-service.js +135 -0
  188. package/dist/src/automations/draft/automation-draft-service.js.map +1 -0
  189. package/dist/src/automations/draft/automation-draft-validator.d.ts +99 -0
  190. package/dist/src/automations/draft/automation-draft-validator.js +105 -0
  191. package/dist/src/automations/draft/automation-draft-validator.js.map +1 -0
  192. package/dist/src/automations/draft/automation-draft.types.d.ts +40 -0
  193. package/dist/src/automations/draft/index.d.ts +3 -0
  194. package/dist/src/automations/draft/index.js +3 -0
  195. package/dist/src/automations/index.d.ts +3 -0
  196. package/dist/src/automations/index.js +8 -0
  197. package/dist/src/automations/product-events.d.ts +5 -0
  198. package/dist/src/automations/product-events.js +21 -0
  199. package/dist/src/automations/product-events.js.map +1 -0
  200. package/dist/src/automations/service/action-executor.d.ts +9 -0
  201. package/dist/src/automations/service/action-executor.js +157 -0
  202. package/dist/src/automations/service/action-executor.js.map +1 -0
  203. package/dist/src/automations/service/automation-service.d.ts +54 -0
  204. package/dist/src/automations/service/automation-service.js +404 -0
  205. package/dist/src/automations/service/automation-service.js.map +1 -0
  206. package/dist/src/automations/service/index.d.ts +2 -0
  207. package/dist/src/automations/service/index.js +3 -0
  208. package/dist/src/automations/storage/automation-repository.d.ts +6 -0
  209. package/dist/src/automations/storage/automation-repository.js +61 -0
  210. package/dist/src/automations/storage/automation-repository.js.map +1 -0
  211. package/dist/src/automations/storage/automation-run-repository.d.ts +17 -0
  212. package/dist/src/automations/storage/automation-run-repository.js +130 -0
  213. package/dist/src/automations/storage/automation-run-repository.js.map +1 -0
  214. package/dist/src/automations/storage/index.d.ts +2 -0
  215. package/dist/src/automations/storage/index.js +3 -0
  216. package/dist/src/channels/plugin-types.d.ts +3 -0
  217. package/dist/src/chat-commands/builtins/thinking.js.map +1 -1
  218. package/dist/src/cli/command-catalog.js +0 -39
  219. package/dist/src/cli/command-catalog.js.map +1 -1
  220. package/dist/src/cli/command-loaders.js +0 -1
  221. package/dist/src/cli/command-loaders.js.map +1 -1
  222. package/dist/src/cli/command-manifest.js +0 -4
  223. package/dist/src/cli/command-manifest.js.map +1 -1
  224. package/dist/src/cli/commands/agents.js +7 -6
  225. package/dist/src/cli/commands/agents.js.map +1 -1
  226. package/dist/src/cli/commands/doctor/checks/database-schema.js +1 -1
  227. package/dist/src/cli/commands/doctor/checks/{cron-health.d.ts → migrations.d.ts} +1 -1
  228. package/dist/src/cli/commands/doctor/checks/migrations.js +40 -0
  229. package/dist/src/cli/commands/doctor/checks/migrations.js.map +1 -0
  230. package/dist/src/cli/commands/doctor/flow.js +2 -2
  231. package/dist/src/cli/commands/doctor/flow.js.map +1 -1
  232. package/dist/src/cli/commands/gateway/call.js +2 -2
  233. package/dist/src/cli/commands/gateway/call.js.map +1 -1
  234. package/dist/src/cli/commands/gateway/run-foreground.js +4 -2
  235. package/dist/src/cli/commands/gateway/run-foreground.js.map +1 -1
  236. package/dist/src/cli/commands/init.js +27 -9
  237. package/dist/src/cli/commands/init.js.map +1 -1
  238. package/dist/src/cli/commands/tui.js +24 -2
  239. package/dist/src/cli/commands/tui.js.map +1 -1
  240. package/dist/src/cli/templates.js +3 -2
  241. package/dist/src/cli/templates.js.map +1 -1
  242. package/dist/src/cli/utils/init-workspace-core.js +2 -0
  243. package/dist/src/cli/utils/init-workspace-core.js.map +1 -1
  244. package/dist/src/commands/agents.config.d.ts +9 -0
  245. package/dist/src/commands/agents.config.js +40 -2
  246. package/dist/src/commands/agents.config.js.map +1 -1
  247. package/dist/src/config/agent-profile.js +4 -3
  248. package/dist/src/config/agent-profile.js.map +1 -1
  249. package/dist/src/config/agent-typed-models.js.map +1 -1
  250. package/dist/src/config/config-surface.d.ts +3 -0
  251. package/dist/src/config/index.d.ts +0 -1
  252. package/dist/src/config/index.js +3 -3
  253. package/dist/src/config/index.js.map +1 -1
  254. package/dist/src/config/paths.d.ts +0 -9
  255. package/dist/src/config/paths.js +1 -14
  256. package/dist/src/config/paths.js.map +1 -1
  257. package/dist/src/config/profile.js +0 -1
  258. package/dist/src/config/profile.js.map +1 -1
  259. package/dist/src/config/rules.js +0 -5
  260. package/dist/src/config/rules.js.map +1 -1
  261. package/dist/src/config/schema.d.ts +13 -12
  262. package/dist/src/config/schema.js +22 -26
  263. package/dist/src/config/schema.js.map +1 -1
  264. package/dist/src/config/web-patch.d.ts +0 -12
  265. package/dist/src/config/web-patch.js +2 -29
  266. package/dist/src/config/web-patch.js.map +1 -1
  267. package/dist/src/extensions/api.d.ts +2 -0
  268. package/dist/src/extensions/api.js +10 -0
  269. package/dist/src/extensions/api.js.map +1 -1
  270. package/dist/src/extensions/extension-registry-impl.d.ts +4 -1
  271. package/dist/src/extensions/extension-registry-impl.js +8 -0
  272. package/dist/src/extensions/extension-registry-impl.js.map +1 -1
  273. package/dist/src/extensions/loader.d.ts +3 -3
  274. package/dist/src/extensions/loader.js +3 -3
  275. package/dist/src/extensions/loader.js.map +1 -1
  276. package/dist/src/extensions/sdk/testing.d.ts +2 -0
  277. package/dist/src/extensions/sdk/testing.js +7 -0
  278. package/dist/src/extensions/sdk/testing.js.map +1 -1
  279. package/dist/src/extensions/types/core.d.ts +10 -1
  280. package/dist/src/extensions/types/index.d.ts +1 -1
  281. package/dist/src/extensions/types/{phase4.d.ts → registration.d.ts} +2 -2
  282. package/dist/src/gateway/agent-builtin-tools.d.ts +1 -1
  283. package/dist/src/gateway/agent-builtin-tools.js +1 -1
  284. package/dist/src/gateway/agent-builtin-tools.js.map +1 -1
  285. package/dist/src/gateway/agents-admin.d.ts +1 -0
  286. package/dist/src/gateway/agents-admin.js +13 -15
  287. package/dist/src/gateway/agents-admin.js.map +1 -1
  288. package/dist/src/gateway/capability-presets-admin.d.ts +1 -0
  289. package/dist/src/gateway/capability-presets-admin.js +19 -10
  290. package/dist/src/gateway/capability-presets-admin.js.map +1 -1
  291. package/dist/src/gateway/dreaming-automation-reconciler.d.ts +11 -0
  292. package/dist/src/gateway/dreaming-automation-reconciler.js +105 -0
  293. package/dist/src/gateway/dreaming-automation-reconciler.js.map +1 -0
  294. package/dist/src/gateway/heartbeat/service.d.ts +0 -2
  295. package/dist/src/gateway/heartbeat/service.js +0 -7
  296. package/dist/src/gateway/heartbeat/service.js.map +1 -1
  297. package/dist/src/gateway/hono/lib/config-payload.d.ts +5 -6
  298. package/dist/src/gateway/hono/lib/config-payload.js +2 -2
  299. package/dist/src/gateway/hono/lib/config-payload.js.map +1 -1
  300. package/dist/src/gateway/hono/routes/agents.js.map +1 -1
  301. package/dist/src/gateway/hono/routes/config-patch/misc.d.ts +1 -1
  302. package/dist/src/gateway/hono/routes/config-patch/misc.js +15 -6
  303. package/dist/src/gateway/hono/routes/config-patch/misc.js.map +1 -1
  304. package/dist/src/gateway/hono/routes/dreaming.js +27 -37
  305. package/dist/src/gateway/hono/routes/dreaming.js.map +1 -1
  306. package/dist/src/gateway/hono/routes/home.d.ts +2 -2
  307. package/dist/src/gateway/hono/routes/home.js +34 -25
  308. package/dist/src/gateway/hono/routes/home.js.map +1 -1
  309. package/dist/src/gateway/hono/routes/lazy-bundles.js +10 -6
  310. package/dist/src/gateway/hono/routes/lazy-bundles.js.map +1 -1
  311. package/dist/src/gateway/hono/routes/migrations.d.ts +3 -0
  312. package/dist/src/gateway/hono/routes/migrations.js +35 -0
  313. package/dist/src/gateway/hono/routes/migrations.js.map +1 -0
  314. package/dist/src/gateway/hono/routes/public-gateway.js +2 -1
  315. package/dist/src/gateway/hono/routes/public-gateway.js.map +1 -1
  316. package/dist/src/gateway/hono/routes/sessions.js +14 -0
  317. package/dist/src/gateway/hono/routes/sessions.js.map +1 -1
  318. package/dist/src/gateway/run-loop.js +2 -0
  319. package/dist/src/gateway/run-loop.js.map +1 -1
  320. package/dist/src/gateway/security/operator-scopes.js +5 -1
  321. package/dist/src/gateway/security/operator-scopes.js.map +1 -1
  322. package/dist/src/gateway/service/config-coordinator.d.ts +4 -4
  323. package/dist/src/gateway/service/config-coordinator.js +14 -8
  324. package/dist/src/gateway/service/config-coordinator.js.map +1 -1
  325. package/dist/src/gateway/service/sessions-api.d.ts +2 -1
  326. package/dist/src/gateway/service/sessions-api.js +6 -1
  327. package/dist/src/gateway/service/sessions-api.js.map +1 -1
  328. package/dist/src/gateway/service.d.ts +7 -3
  329. package/dist/src/gateway/service.js +61 -27
  330. package/dist/src/gateway/service.js.map +1 -1
  331. package/dist/src/goals/goal-service.js +45 -4
  332. package/dist/src/goals/goal-service.js.map +1 -1
  333. package/dist/src/migrations/config/default-capability-preset.d.ts +10 -0
  334. package/dist/src/migrations/config/default-capability-preset.js +135 -0
  335. package/dist/src/migrations/config/default-capability-preset.js.map +1 -0
  336. package/dist/src/migrations/index.d.ts +4 -0
  337. package/dist/src/migrations/index.js +4 -0
  338. package/dist/src/migrations/registry.d.ts +8 -0
  339. package/dist/src/migrations/registry.js +18 -0
  340. package/dist/src/migrations/registry.js.map +1 -0
  341. package/dist/src/migrations/runner.d.ts +17 -0
  342. package/dist/src/migrations/runner.js +191 -0
  343. package/dist/src/migrations/runner.js.map +1 -0
  344. package/dist/src/migrations/types.d.ts +34 -0
  345. package/dist/src/notes/service.js +24 -1
  346. package/dist/src/notes/service.js.map +1 -1
  347. package/dist/src/providers/model-registry.d.ts +0 -1
  348. package/dist/src/providers/model-registry.js +0 -3
  349. package/dist/src/providers/model-registry.js.map +1 -1
  350. package/dist/src/routing/resolve-tui-session-key.d.ts +3 -0
  351. package/dist/src/routing/resolve-tui-session-key.js +14 -3
  352. package/dist/src/routing/resolve-tui-session-key.js.map +1 -1
  353. package/dist/src/session/transcript-outline.d.ts +47 -0
  354. package/dist/src/session/transcript-outline.js +481 -0
  355. package/dist/src/session/transcript-outline.js.map +1 -0
  356. package/dist/src/storage/sqlite/index.d.ts +0 -2
  357. package/dist/src/storage/sqlite/index.js +1 -3
  358. package/dist/src/storage/sqlite/migrations/016_automations.sql +47 -0
  359. package/dist/src/storage/sqlite/migrations/017_automation_run_events.sql +14 -0
  360. package/dist/src/storage/sqlite/migrations/018_automation_safety.sql +1 -0
  361. package/dist/src/storage/sqlite/migrations/runner.d.ts +1 -1
  362. package/dist/src/storage/sqlite/migrations/runner.js +3 -3
  363. package/dist/src/storage/sqlite/migrations/runner.js.map +1 -1
  364. package/dist/src/storage/sqlite/migrations/runner.ts +1 -1
  365. package/dist/src/storage/sqlite/row-mappers.js +3 -1
  366. package/dist/src/storage/sqlite/row-mappers.js.map +1 -1
  367. package/dist/src/storage/sqlite/schema.js +1 -1
  368. package/dist/src/storage/sqlite/schema.sql +56 -46
  369. package/dist/src/tui/backends/embedded-backend.d.ts +6 -0
  370. package/dist/src/tui/backends/embedded-backend.js +19 -9
  371. package/dist/src/tui/backends/embedded-backend.js.map +1 -1
  372. package/dist/src/tui/backends/gateway-sse-backend.d.ts +3 -0
  373. package/dist/src/tui/backends/gateway-sse-backend.js +14 -0
  374. package/dist/src/tui/backends/gateway-sse-backend.js.map +1 -1
  375. package/dist/src/tui/tui-backend.d.ts +4 -0
  376. package/dist/src/tui/tui-commands.d.ts +5 -0
  377. package/dist/src/tui/tui-commands.js +43 -0
  378. package/dist/src/tui/tui-commands.js.map +1 -1
  379. package/dist/src/tui/tui-transcript-tree.d.ts +1 -1
  380. package/dist/src/tui/tui-transcript-tree.js +17 -257
  381. package/dist/src/tui/tui-transcript-tree.js.map +1 -1
  382. package/dist/src/tui/tui-types.d.ts +2 -0
  383. package/dist/src/tui/tui-types.js.map +1 -1
  384. package/dist/src/tui/tui.js +7 -2
  385. package/dist/src/tui/tui.js.map +1 -1
  386. package/dist/src/workflows/domain/index.js +1 -1
  387. package/dist/src/workflows/domain/run.d.ts +7 -7
  388. package/dist/src/workflows/domain/run.js.map +1 -1
  389. package/dist/src/workflows/index.js +2 -2
  390. package/dist/src/workflows/service/workflow-run-service.d.ts +2 -0
  391. package/dist/src/workflows/service/workflow-run-service.js +31 -9
  392. package/dist/src/workflows/service/workflow-run-service.js.map +1 -1
  393. package/dist/src/workflows/service/workflow-run-service.types.d.ts +1 -1
  394. package/package.json +4 -2
  395. package/dist/gateway/static/root/assets/agents-BCxZbkOw.js +0 -2
  396. package/dist/gateway/static/root/assets/app-management-settings-panel-bxYJVJpx.js +0 -1
  397. package/dist/gateway/static/root/assets/appearance-settings-BCIykXlI.js +0 -1
  398. package/dist/gateway/static/root/assets/browser-settings-page-DRhKdn81.js +0 -8
  399. package/dist/gateway/static/root/assets/capability-presets-api-CorhiHlg.js +0 -1
  400. package/dist/gateway/static/root/assets/capability-presets-settings-panel-qFx9Jtce.js +0 -1
  401. package/dist/gateway/static/root/assets/channels-settings-BAwAkqIA.js +0 -1
  402. package/dist/gateway/static/root/assets/cn-JdwAhgNB.js +0 -1
  403. package/dist/gateway/static/root/assets/connectors-page-BQLcfitM.js +0 -2
  404. package/dist/gateway/static/root/assets/createLucideIcon-DPHK1VkS.js +0 -1
  405. package/dist/gateway/static/root/assets/cron-api-qGwmL-24.js +0 -1
  406. package/dist/gateway/static/root/assets/cron-dreaming-jobs-nCMWCf0p.js +0 -1
  407. package/dist/gateway/static/root/assets/cron-page-BBWMAj8-.js +0 -3
  408. package/dist/gateway/static/root/assets/dreaming-settings-Dw89Obml.js +0 -1
  409. package/dist/gateway/static/root/assets/format-cron-label-BsotZDO5.js +0 -2
  410. package/dist/gateway/static/root/assets/format-interval-label-BzxafKxR.js +0 -1
  411. package/dist/gateway/static/root/assets/gateway-settings-Cmwy58rS.js +0 -1
  412. package/dist/gateway/static/root/assets/goal-detail-page-l7mu5GWX.js +0 -1
  413. package/dist/gateway/static/root/assets/goals-settings-CYVY4NGp.js +0 -1
  414. package/dist/gateway/static/root/assets/heartbeat-config-api-DriO_CN9.js +0 -1
  415. package/dist/gateway/static/root/assets/heartbeat-settings-CUQTKxg7.js +0 -1
  416. package/dist/gateway/static/root/assets/index-C17Tsd_b.css +0 -1
  417. package/dist/gateway/static/root/assets/index-Cc41r16l.js +0 -191
  418. package/dist/gateway/static/root/assets/interval-presets-DFPCKW_W.js +0 -1
  419. package/dist/gateway/static/root/assets/keyboard-shortcuts-settings-CcVcqstx.js +0 -1
  420. package/dist/gateway/static/root/assets/messages-B1iSKjiw.js +0 -3
  421. package/dist/gateway/static/root/assets/models-hub-panel-BfLfcta8.js +0 -2
  422. package/dist/gateway/static/root/assets/note-detail-page-BjwOQBfT.js +0 -2
  423. package/dist/gateway/static/root/assets/notes-page-DktdBiwB.js +0 -1
  424. package/dist/gateway/static/root/assets/remote-access-hub-rfVx96fq.js +0 -1
  425. package/dist/gateway/static/root/assets/schedule-field-CUCKODde.js +0 -1
  426. package/dist/gateway/static/root/assets/sessions-page-DbtMFuuH.js +0 -1
  427. package/dist/gateway/static/root/assets/settings-advanced-gate-5re5gAnP.js +0 -1
  428. package/dist/gateway/static/root/assets/settings-form-section-dmyaPOTG.js +0 -1
  429. package/dist/gateway/static/root/assets/settings-page-D-WMyLlj.js +0 -1
  430. package/dist/gateway/static/root/assets/setup-status-panel-Cl-DEJAU.js +0 -1
  431. package/dist/gateway/static/root/assets/shares-settings-CyPVvbLt.js +0 -1
  432. package/dist/gateway/static/root/assets/skill-reload-api-CleTH1oz.js +0 -1
  433. package/dist/gateway/static/root/assets/skills-page-Ck8hdXqR.js +0 -2
  434. package/dist/gateway/static/root/assets/system-settings-panel-DI-LN_8G.js +0 -1
  435. package/dist/gateway/static/root/assets/typed-models-lib-kX9duch4.js +0 -1
  436. package/dist/gateway/static/root/assets/user-profile-settings-panel-B-UFPMXy.js +0 -1
  437. package/dist/gateway/static/root/assets/utils-Dm0hKalR.js +0 -1
  438. package/dist/gateway/static/root/assets/workflows-page-BtFGp2y_.js +0 -18
  439. package/dist/src/agent/fallback/error.d.ts +0 -22
  440. package/dist/src/agent/fallback/error.js +0 -32
  441. package/dist/src/agent/fallback/error.js.map +0 -1
  442. package/dist/src/agent/fallback/index.d.ts +0 -5
  443. package/dist/src/agent/fallback/index.js +0 -9
  444. package/dist/src/agent/fallback/index.js.map +0 -1
  445. package/dist/src/agent/memory/memory-flush.d.ts +0 -27
  446. package/dist/src/agent/memory/memory-flush.js +0 -124
  447. package/dist/src/agent/memory/memory-flush.js.map +0 -1
  448. package/dist/src/agent/orchestration/run-agent-turn-with-fallbacks.d.ts +0 -29
  449. package/dist/src/agent/orchestration/run-agent-turn-with-fallbacks.js +0 -76
  450. package/dist/src/agent/orchestration/run-agent-turn-with-fallbacks.js.map +0 -1
  451. package/dist/src/agent/service/reconcile-dreaming-cron.d.ts +0 -6
  452. package/dist/src/agent/service/reconcile-dreaming-cron.js +0 -84
  453. package/dist/src/agent/service/reconcile-dreaming-cron.js.map +0 -1
  454. package/dist/src/agent/tools/cronjob-tool.d.ts +0 -29
  455. package/dist/src/agent/tools/cronjob-tool.js +0 -274
  456. package/dist/src/agent/tools/cronjob-tool.js.map +0 -1
  457. package/dist/src/cli/commands/cron-cli.d.ts +0 -2
  458. package/dist/src/cli/commands/cron-cli.js +0 -15
  459. package/dist/src/cli/commands/cron-cli.js.map +0 -1
  460. package/dist/src/cli/commands/cron.d.ts +0 -4
  461. package/dist/src/cli/commands/cron.js +0 -188
  462. package/dist/src/cli/commands/cron.js.map +0 -1
  463. package/dist/src/cli/commands/doctor/checks/cron-health.js +0 -35
  464. package/dist/src/cli/commands/doctor/checks/cron-health.js.map +0 -1
  465. package/dist/src/cron/execution-types.d.ts +0 -42
  466. package/dist/src/cron/executor.d.ts +0 -67
  467. package/dist/src/cron/executor.js +0 -669
  468. package/dist/src/cron/executor.js.map +0 -1
  469. package/dist/src/cron/index.d.ts +0 -7
  470. package/dist/src/cron/index.js +0 -7
  471. package/dist/src/cron/job-content.d.ts +0 -5
  472. package/dist/src/cron/job-content.js +0 -15
  473. package/dist/src/cron/job-content.js.map +0 -1
  474. package/dist/src/cron/run-log-store.d.ts +0 -12
  475. package/dist/src/cron/run-log-store.js +0 -58
  476. package/dist/src/cron/run-log-store.js.map +0 -1
  477. package/dist/src/cron/schedule.d.ts +0 -10
  478. package/dist/src/cron/schedule.js +0 -85
  479. package/dist/src/cron/schedule.js.map +0 -1
  480. package/dist/src/cron/service.d.ts +0 -58
  481. package/dist/src/cron/service.js +0 -419
  482. package/dist/src/cron/service.js.map +0 -1
  483. package/dist/src/cron/types.d.ts +0 -183
  484. package/dist/src/cron/validation.d.ts +0 -500
  485. package/dist/src/cron/validation.js +0 -192
  486. package/dist/src/cron/validation.js.map +0 -1
  487. package/dist/src/cron/workflow-run-completion.d.ts +0 -23
  488. package/dist/src/cron/workflow-run-completion.js +0 -72
  489. package/dist/src/cron/workflow-run-completion.js.map +0 -1
  490. package/dist/src/extensions/types/phase4.js +0 -1
  491. package/dist/src/gateway/hono/routes/cron.d.ts +0 -3
  492. package/dist/src/gateway/hono/routes/cron.js +0 -109
  493. package/dist/src/gateway/hono/routes/cron.js.map +0 -1
  494. package/dist/src/storage/sqlite/cron-job-repository.d.ts +0 -6
  495. package/dist/src/storage/sqlite/cron-job-repository.js +0 -70
  496. package/dist/src/storage/sqlite/cron-job-repository.js.map +0 -1
  497. package/dist/src/storage/sqlite/cron-run-repository.d.ts +0 -5
  498. package/dist/src/storage/sqlite/cron-run-repository.js +0 -96
  499. package/dist/src/storage/sqlite/cron-run-repository.js.map +0 -1
  500. /package/dist/src/{cron → automations/domain}/types.js +0 -0
  501. /package/dist/src/{config/defaults.d.ts → automations/draft/automation-draft.types.js} +0 -0
  502. /package/dist/src/{config/defaults.js → extensions/types/registration.js} +0 -0
  503. /package/dist/src/{cron/execution-types.js → migrations/types.js} +0 -0
@@ -0,0 +1,157 @@
1
+ import { init_agent_scope, normalizeAgentId } from "../../agent/agent-scope.js";
2
+ import { buildSessionKey, init_session_key } from "../../routing/session-key.js";
3
+ import { createLogger } from "../../utils/logger/index.js";
4
+ import { init_logger } from "../../utils/logger.js";
5
+ import crypto from "node:crypto";
6
+ //#region src/automations/service/action-executor.ts
7
+ init_agent_scope();
8
+ init_session_key();
9
+ init_logger();
10
+ const log = createLogger("Automation:ActionExecutor");
11
+ const DEFAULT_TIMEOUT_MS = 18e4;
12
+ function withTimeout(promise, timeoutMs, signal) {
13
+ return new Promise((resolve, reject) => {
14
+ if (signal.aborted) {
15
+ reject(/* @__PURE__ */ new Error("Automation run was cancelled"));
16
+ return;
17
+ }
18
+ const timer = setTimeout(() => reject(/* @__PURE__ */ new Error(`Automation timed out after ${timeoutMs}ms`)), timeoutMs);
19
+ const onAbort = () => {
20
+ clearTimeout(timer);
21
+ reject(/* @__PURE__ */ new Error("Automation run was cancelled"));
22
+ };
23
+ signal.addEventListener("abort", onAbort, { once: true });
24
+ promise.then((value) => {
25
+ clearTimeout(timer);
26
+ signal.removeEventListener("abort", onAbort);
27
+ resolve(value);
28
+ }, (err) => {
29
+ clearTimeout(timer);
30
+ signal.removeEventListener("abort", onAbort);
31
+ reject(err);
32
+ });
33
+ });
34
+ }
35
+ var AutomationActionExecutor = class {
36
+ deps = {};
37
+ setDeps(deps) {
38
+ this.deps = {
39
+ ...this.deps,
40
+ ...deps
41
+ };
42
+ }
43
+ async execute(automation, run, signal) {
44
+ const timeoutMs = (automation.action.timeoutSeconds ?? automation.reliability?.timeoutSeconds ?? 0) > 0 ? (automation.action.timeoutSeconds ?? automation.reliability?.timeoutSeconds) * 1e3 : DEFAULT_TIMEOUT_MS;
45
+ return withTimeout(this.executeWithoutTimeout(automation, run, signal), timeoutMs, signal).catch((err) => {
46
+ const message = err instanceof Error ? err.message : String(err);
47
+ return {
48
+ status: message.toLowerCase().includes("cancelled") ? "cancelled" : message.toLowerCase().includes("timed out") ? "timeout" : "failed",
49
+ error: message
50
+ };
51
+ });
52
+ }
53
+ async executeWithoutTimeout(automation, run, signal) {
54
+ if (signal.aborted) return {
55
+ status: "cancelled",
56
+ error: "Automation run was cancelled"
57
+ };
58
+ if (automation.action.kind === "workflow") return this.executeWorkflow(automation, automation.action, run);
59
+ return this.executeAgent(automation, automation.action);
60
+ }
61
+ async executeAgent(automation, action) {
62
+ const agentService = this.deps.agentService;
63
+ if (!agentService?.turnDispatcher?.processDirect) return {
64
+ status: "failed",
65
+ error: "Agent service is not available"
66
+ };
67
+ const sessionKey = buildSessionKey({
68
+ agentId: normalizeAgentId(action.agentId || this.deps.getDefaultAgentId?.() || "main"),
69
+ source: "automation",
70
+ accountId: "default",
71
+ peerKind: "dm",
72
+ peerId: `${automation.id}-${crypto.randomUUID().slice(0, 8)}`
73
+ });
74
+ await agentService.sessionConfig?.applyAutomationWorkingDirectory?.(sessionKey, action.workingDirectory);
75
+ if (agentService.sessionConfig?.applyAutomationModelOverride) {
76
+ if (!await agentService.sessionConfig.applyAutomationModelOverride(sessionKey, action.model) && action.model) log.warn({
77
+ automationId: automation.id,
78
+ sessionKey,
79
+ model: action.model
80
+ }, "Automation model override invalid; using agent default");
81
+ }
82
+ const response = await agentService.turnDispatcher.processDirect(buildSafetyInstruction(automation, action.instruction), sessionKey);
83
+ const model = agentService.getModelForSession?.(sessionKey);
84
+ return {
85
+ status: "succeeded",
86
+ summary: response.slice(0, 500),
87
+ sessionKey,
88
+ model
89
+ };
90
+ }
91
+ async executeWorkflow(automation, action, run) {
92
+ const safetyMode = automation.safety?.mode ?? "auto_apply";
93
+ if (safetyMode === "suggest_only") return {
94
+ status: "succeeded",
95
+ summary: `Suggest only: workflow ${action.workflowId} was not started. Review the automation and upgrade safety mode to run it automatically.`
96
+ };
97
+ if (safetyMode === "ask_before_apply") return {
98
+ status: "succeeded",
99
+ summary: `Ask before applying: workflow ${action.workflowId} is ready, but was not started automatically. Upgrade to Auto apply when you trust this automation.`
100
+ };
101
+ const workflowRunService = this.deps.workflowRunService;
102
+ if (!workflowRunService) return {
103
+ status: "failed",
104
+ error: "Workflow service is not available"
105
+ };
106
+ const agentId = normalizeAgentId(action.agentId || this.deps.getDefaultAgentId?.() || "main");
107
+ const idempotencyKey = `automation:${automation.id}:${run.id}`;
108
+ const result = await workflowRunService.startWorkflowRun({
109
+ agentId,
110
+ definitionId: action.workflowId,
111
+ input: action.input,
112
+ inputEnvelope: action.inputEnvelope,
113
+ goal: action.goal,
114
+ concurrency: action.concurrency,
115
+ maxSubagents: action.maxSubagents,
116
+ source: {
117
+ kind: "automation",
118
+ automationId: automation.id,
119
+ runId: run.id
120
+ },
121
+ idempotencyKey
122
+ });
123
+ if (result.ok === false) return {
124
+ status: "failed",
125
+ error: result.message
126
+ };
127
+ return {
128
+ status: "succeeded",
129
+ summary: `Started workflow run ${result.runId}`,
130
+ sessionKey: result.sessionKey,
131
+ workflowRunId: result.runId
132
+ };
133
+ }
134
+ };
135
+ function buildSafetyInstruction(automation, instruction) {
136
+ const mode = automation.safety?.mode ?? "auto_apply";
137
+ if (mode === "suggest_only") return [
138
+ "Automation safety mode: Suggest only.",
139
+ "Only analyze the situation and produce a concise recommendation.",
140
+ "Do not modify files, notes, goals, workflows, external systems, or persistent state.",
141
+ "If a change seems useful, describe the exact change for the user to review.",
142
+ "",
143
+ instruction
144
+ ].join("\n");
145
+ if (mode === "ask_before_apply") return [
146
+ "Automation safety mode: Ask before applying.",
147
+ "Draft the proposed change or action and clearly ask for user confirmation before applying anything.",
148
+ "Do not perform irreversible or external side effects unless the user has explicitly approved them in this run.",
149
+ "",
150
+ instruction
151
+ ].join("\n");
152
+ return instruction;
153
+ }
154
+ //#endregion
155
+ export { AutomationActionExecutor };
156
+
157
+ //# sourceMappingURL=action-executor.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"action-executor.js","names":[],"sources":["../../../../src/automations/service/action-executor.ts"],"sourcesContent":["import crypto from 'node:crypto';\n\nimport { DEFAULT_AGENT_ID, normalizeAgentId } from '../../agent/agent-scope.js';\nimport { buildSessionKey } from '../../routing/session-key.js';\nimport { createLogger } from '../../utils/logger.js';\nimport type {\n Automation,\n AutomationAction,\n AutomationActionOutcome,\n AutomationDeps,\n AutomationRun,\n} from '../domain/types.js';\n\nconst log = createLogger('Automation:ActionExecutor');\n\nconst DEFAULT_TIMEOUT_MS = 180_000;\n\nfunction withTimeout<T>(promise: Promise<T>, timeoutMs: number, signal: AbortSignal): Promise<T> {\n return new Promise<T>((resolve, reject) => {\n if (signal.aborted) {\n reject(new Error('Automation run was cancelled'));\n return;\n }\n const timer = setTimeout(() => reject(new Error(`Automation timed out after ${timeoutMs}ms`)), timeoutMs);\n const onAbort = () => {\n clearTimeout(timer);\n reject(new Error('Automation run was cancelled'));\n };\n signal.addEventListener('abort', onAbort, { once: true });\n promise.then(\n (value) => {\n clearTimeout(timer);\n signal.removeEventListener('abort', onAbort);\n resolve(value);\n },\n (err) => {\n clearTimeout(timer);\n signal.removeEventListener('abort', onAbort);\n reject(err);\n },\n );\n });\n}\n\nexport class AutomationActionExecutor {\n private deps: AutomationDeps = {};\n\n setDeps(deps: AutomationDeps): void {\n this.deps = { ...this.deps, ...deps };\n }\n\n async execute(\n automation: Automation,\n run: AutomationRun,\n signal: AbortSignal,\n ): Promise<AutomationActionOutcome> {\n const timeoutMs =\n (automation.action.timeoutSeconds ?? automation.reliability?.timeoutSeconds ?? 0) > 0\n ? (automation.action.timeoutSeconds ?? automation.reliability?.timeoutSeconds)! * 1000\n : DEFAULT_TIMEOUT_MS;\n\n return withTimeout(this.executeWithoutTimeout(automation, run, signal), timeoutMs, signal).catch((err) => {\n const message = err instanceof Error ? err.message : String(err);\n return {\n status: message.toLowerCase().includes('cancelled')\n ? 'cancelled'\n : message.toLowerCase().includes('timed out')\n ? 'timeout'\n : 'failed',\n error: message,\n };\n });\n }\n\n private async executeWithoutTimeout(\n automation: Automation,\n run: AutomationRun,\n signal: AbortSignal,\n ): Promise<AutomationActionOutcome> {\n if (signal.aborted) {\n return { status: 'cancelled', error: 'Automation run was cancelled' };\n }\n if (automation.action.kind === 'workflow') {\n return this.executeWorkflow(automation, automation.action, run);\n }\n return this.executeAgent(automation, automation.action);\n }\n\n private async executeAgent(\n automation: Automation,\n action: Extract<AutomationAction, { kind: 'agent' }>,\n ): Promise<AutomationActionOutcome> {\n const agentService = this.deps.agentService;\n if (!agentService?.turnDispatcher?.processDirect) {\n return { status: 'failed', error: 'Agent service is not available' };\n }\n const agentId = normalizeAgentId(\n action.agentId || this.deps.getDefaultAgentId?.() || DEFAULT_AGENT_ID,\n );\n const sessionKey = buildSessionKey({\n agentId,\n source: 'automation',\n accountId: 'default',\n peerKind: 'dm',\n peerId: `${automation.id}-${crypto.randomUUID().slice(0, 8)}`,\n });\n\n await agentService.sessionConfig?.applyAutomationWorkingDirectory?.(\n sessionKey,\n action.workingDirectory,\n );\n if (agentService.sessionConfig?.applyAutomationModelOverride) {\n const ok = await agentService.sessionConfig.applyAutomationModelOverride(sessionKey, action.model);\n if (!ok && action.model) {\n log.warn(\n { automationId: automation.id, sessionKey, model: action.model },\n 'Automation model override invalid; using agent default',\n );\n }\n }\n\n const response = await agentService.turnDispatcher.processDirect(\n buildSafetyInstruction(automation, action.instruction),\n sessionKey,\n );\n const model = agentService.getModelForSession?.(sessionKey);\n return {\n status: 'succeeded',\n summary: response.slice(0, 500),\n sessionKey,\n model,\n };\n }\n\n private async executeWorkflow(\n automation: Automation,\n action: Extract<AutomationAction, { kind: 'workflow' }>,\n run: AutomationRun,\n ): Promise<AutomationActionOutcome> {\n const safetyMode = automation.safety?.mode ?? 'auto_apply';\n if (safetyMode === 'suggest_only') {\n return {\n status: 'succeeded',\n summary: `Suggest only: workflow ${action.workflowId} was not started. Review the automation and upgrade safety mode to run it automatically.`,\n };\n }\n if (safetyMode === 'ask_before_apply') {\n return {\n status: 'succeeded',\n summary: `Ask before applying: workflow ${action.workflowId} is ready, but was not started automatically. Upgrade to Auto apply when you trust this automation.`,\n };\n }\n const workflowRunService = this.deps.workflowRunService;\n if (!workflowRunService) {\n return { status: 'failed', error: 'Workflow service is not available' };\n }\n const agentId = normalizeAgentId(\n action.agentId || this.deps.getDefaultAgentId?.() || DEFAULT_AGENT_ID,\n );\n const idempotencyKey = `automation:${automation.id}:${run.id}`;\n const result = await workflowRunService.startWorkflowRun({\n agentId,\n definitionId: action.workflowId,\n input: action.input,\n inputEnvelope: action.inputEnvelope,\n goal: action.goal,\n concurrency: action.concurrency,\n maxSubagents: action.maxSubagents,\n source: { kind: 'automation', automationId: automation.id, runId: run.id },\n idempotencyKey,\n });\n if (result.ok === false) {\n return { status: 'failed', error: result.message };\n }\n return {\n status: 'succeeded',\n summary: `Started workflow run ${result.runId}`,\n sessionKey: result.sessionKey,\n workflowRunId: result.runId,\n };\n }\n}\n\nfunction buildSafetyInstruction(automation: Automation, instruction: string): string {\n const mode = automation.safety?.mode ?? 'auto_apply';\n if (mode === 'suggest_only') {\n return [\n 'Automation safety mode: Suggest only.',\n 'Only analyze the situation and produce a concise recommendation.',\n 'Do not modify files, notes, goals, workflows, external systems, or persistent state.',\n 'If a change seems useful, describe the exact change for the user to review.',\n '',\n instruction,\n ].join('\\n');\n }\n if (mode === 'ask_before_apply') {\n return [\n 'Automation safety mode: Ask before applying.',\n 'Draft the proposed change or action and clearly ask for user confirmation before applying anything.',\n 'Do not perform irreversible or external side effects unless the user has explicitly approved them in this run.',\n '',\n instruction,\n ].join('\\n');\n }\n return instruction;\n}\n"],"mappings":"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"}
@@ -0,0 +1,54 @@
1
+ import type { Automation, AutomationDeps, AutomationEvent, AutomationMetrics, AutomationProductEventRun, AutomationRun, AutomationRunEvent } from '../domain/types.js';
2
+ import { type CreateAutomationInput, type UpdateAutomationInput } from '../domain/validation.js';
3
+ export declare class AutomationAlreadyRunningError extends Error {
4
+ readonly automationId: string;
5
+ readonly runningRunId?: string;
6
+ constructor(automationId: string, runningRunId?: string);
7
+ }
8
+ export declare class AutomationService {
9
+ private readonly executor;
10
+ private timer;
11
+ private stopped;
12
+ private runningScheduler;
13
+ private deps;
14
+ private maxConcurrentRuns;
15
+ private readonly activeRuns;
16
+ setDeps(deps: AutomationDeps): void;
17
+ initialize(options?: {
18
+ maxConcurrentRuns?: number;
19
+ }): Promise<void>;
20
+ stop(): Promise<void>;
21
+ create(input: CreateAutomationInput): Promise<Automation>;
22
+ list(): Promise<Automation[]>;
23
+ get(id: string): Promise<Automation | null>;
24
+ update(id: string, patch: UpdateAutomationInput): Promise<Automation | null>;
25
+ remove(id: string): Promise<boolean>;
26
+ pause(id: string): Promise<Automation | null>;
27
+ resume(id: string): Promise<Automation | null>;
28
+ runNow(id: string): Promise<AutomationRun>;
29
+ rerunFromRun(runId: string): Promise<AutomationRun>;
30
+ triggerEvent(event: AutomationEvent): Promise<AutomationRun[]>;
31
+ listRuns(options?: {
32
+ automationId?: string;
33
+ limit?: number;
34
+ }): Promise<AutomationRun[]>;
35
+ listRunsForProductEvent(options: {
36
+ eventType: string;
37
+ source?: string;
38
+ payloadKey?: string;
39
+ payloadValue?: string;
40
+ limit?: number;
41
+ }): Promise<AutomationProductEventRun[]>;
42
+ getRun(runId: string): Promise<AutomationRun | null>;
43
+ listRunEvents(runId: string): Promise<AutomationRunEvent[]>;
44
+ cancelRun(runId: string): Promise<boolean>;
45
+ getMetrics(): Promise<AutomationMetrics>;
46
+ private recomputeNextRuns;
47
+ private armTimer;
48
+ private onTimer;
49
+ private startRun;
50
+ private executeRun;
51
+ private appendRunEvent;
52
+ private finishAutomationRun;
53
+ private postAfterRunWebhook;
54
+ }
@@ -0,0 +1,404 @@
1
+ import { createLogger } from "../../utils/logger/index.js";
2
+ import { init_logger } from "../../utils/logger.js";
3
+ import { computeNextAutomationRunAtMs, timerDelayUntil } from "../domain/schedule.js";
4
+ import { AutomationSchema, CreateAutomationSchema, UpdateAutomationSchema } from "../domain/validation.js";
5
+ import { AutomationActionExecutor } from "./action-executor.js";
6
+ import { deleteAutomation, getAutomation, listAutomations, saveAutomation, saveAutomations } from "../storage/automation-repository.js";
7
+ import { appendAutomationRunEvent, getAutomationRun, listAutomationRunEvents, listAutomationRuns, listAutomationRunsForProductEvent, saveAutomationRun } from "../storage/automation-run-repository.js";
8
+ import "../storage/index.js";
9
+ import { randomUUID } from "node:crypto";
10
+ //#region src/automations/service/automation-service.ts
11
+ init_logger();
12
+ const log = createLogger("AutomationService");
13
+ const DEFAULT_MAX_CONCURRENT_RUNS = 5;
14
+ const MISSED_RUN_STAGGER_MS = 5e3;
15
+ var AutomationAlreadyRunningError = class extends Error {
16
+ constructor(automationId, runningRunId) {
17
+ super(`Automation is already running: ${automationId}`);
18
+ this.automationId = automationId;
19
+ this.runningRunId = runningRunId;
20
+ this.name = "AutomationAlreadyRunningError";
21
+ }
22
+ };
23
+ var AutomationService = class {
24
+ executor = new AutomationActionExecutor();
25
+ timer = null;
26
+ stopped = true;
27
+ runningScheduler = false;
28
+ deps = {};
29
+ maxConcurrentRuns = DEFAULT_MAX_CONCURRENT_RUNS;
30
+ activeRuns = /* @__PURE__ */ new Map();
31
+ setDeps(deps) {
32
+ this.deps = {
33
+ ...this.deps,
34
+ ...deps
35
+ };
36
+ this.executor.setDeps(this.deps);
37
+ }
38
+ async initialize(options) {
39
+ this.maxConcurrentRuns = Math.max(1, Math.floor(options?.maxConcurrentRuns ?? DEFAULT_MAX_CONCURRENT_RUNS));
40
+ this.stopped = false;
41
+ await this.recomputeNextRuns({ catchUp: true });
42
+ this.armTimer();
43
+ log.info("Automation service initialized");
44
+ }
45
+ async stop() {
46
+ this.stopped = true;
47
+ if (this.timer) {
48
+ clearTimeout(this.timer);
49
+ this.timer = null;
50
+ }
51
+ for (const controller of this.activeRuns.values()) controller.abort();
52
+ log.info("Automation service stopped");
53
+ }
54
+ async create(input) {
55
+ const parsed = CreateAutomationSchema.parse(input);
56
+ const now = Date.now();
57
+ const automation = AutomationSchema.parse({
58
+ ...parsed,
59
+ id: parsed.id?.trim() || randomUUID().slice(0, 12),
60
+ enabled: parsed.enabled ?? true,
61
+ safety: parsed.safety ?? { mode: "auto_apply" },
62
+ afterRun: parsed.afterRun ?? { kind: "none" },
63
+ state: parsed.state ?? {},
64
+ createdAtMs: now,
65
+ updatedAtMs: now
66
+ });
67
+ automation.state.nextRunAtMs = computeNextAutomationRunAtMs(automation, now);
68
+ saveAutomation(automation);
69
+ this.armTimer();
70
+ return automation;
71
+ }
72
+ async list() {
73
+ return listAutomations();
74
+ }
75
+ async get(id) {
76
+ return getAutomation(id);
77
+ }
78
+ async update(id, patch) {
79
+ const parsed = UpdateAutomationSchema.parse(patch);
80
+ const current = getAutomation(id);
81
+ if (!current) return null;
82
+ const now = Date.now();
83
+ const next = AutomationSchema.parse({
84
+ ...current,
85
+ ...parsed,
86
+ id: current.id,
87
+ createdAtMs: current.createdAtMs,
88
+ updatedAtMs: now,
89
+ state: {
90
+ ...current.state,
91
+ ...parsed.state ?? {}
92
+ }
93
+ });
94
+ if ("enabled" in parsed || "trigger" in parsed) next.state.nextRunAtMs = computeNextAutomationRunAtMs(next, now);
95
+ saveAutomation(next);
96
+ this.armTimer();
97
+ return next;
98
+ }
99
+ async remove(id) {
100
+ const automation = getAutomation(id);
101
+ if (automation?.state.runningRunId) this.activeRuns.get(automation.state.runningRunId)?.abort();
102
+ const removed = deleteAutomation(id);
103
+ if (removed) this.armTimer();
104
+ return removed;
105
+ }
106
+ async pause(id) {
107
+ return this.update(id, { enabled: false });
108
+ }
109
+ async resume(id) {
110
+ return this.update(id, { enabled: true });
111
+ }
112
+ async runNow(id) {
113
+ const automation = getAutomation(id);
114
+ if (!automation) throw new Error(`Automation not found: ${id}`);
115
+ if (automation.state.runningRunId) throw new AutomationAlreadyRunningError(id, automation.state.runningRunId);
116
+ return this.startRun(automation, { manual: true });
117
+ }
118
+ async rerunFromRun(runId) {
119
+ const previous = getAutomationRun(runId);
120
+ if (!previous) throw new Error(`Automation run not found: ${runId}`);
121
+ const automation = getAutomation(previous.automationId);
122
+ if (!automation) throw new Error(`Automation not found: ${previous.automationId}`);
123
+ if (automation.state.runningRunId) throw new AutomationAlreadyRunningError(automation.id, automation.state.runningRunId);
124
+ const triggerEvent = listAutomationRunEvents(runId).map((event) => readAutomationEventFromRunEvent(event)).find((event) => event !== null);
125
+ return this.startRun(automation, triggerEvent ? {
126
+ manual: false,
127
+ event: triggerEvent
128
+ } : { manual: true });
129
+ }
130
+ async triggerEvent(event) {
131
+ const normalized = {
132
+ ...event,
133
+ occurredAtMs: event.occurredAtMs ?? Date.now()
134
+ };
135
+ const automations = listAutomations().filter((automation) => automation.enabled && automation.trigger.kind === "event" && !automation.state.runningRunId && matchesAutomationEvent(automation.trigger, normalized));
136
+ const availableSlots = Math.max(0, this.maxConcurrentRuns - this.activeRuns.size);
137
+ const started = [];
138
+ for (const automation of automations.slice(0, availableSlots)) started.push(await this.startRun(automation, {
139
+ manual: false,
140
+ event: normalized
141
+ }));
142
+ return started;
143
+ }
144
+ async listRuns(options) {
145
+ return listAutomationRuns(options);
146
+ }
147
+ async listRunsForProductEvent(options) {
148
+ return listAutomationRunsForProductEvent(options);
149
+ }
150
+ async getRun(runId) {
151
+ return getAutomationRun(runId);
152
+ }
153
+ async listRunEvents(runId) {
154
+ return listAutomationRunEvents(runId);
155
+ }
156
+ async cancelRun(runId) {
157
+ const controller = this.activeRuns.get(runId);
158
+ if (!controller) return false;
159
+ controller.abort();
160
+ return true;
161
+ }
162
+ async getMetrics() {
163
+ const automations = listAutomations();
164
+ const enabled = automations.filter((automation) => automation.enabled);
165
+ const next = enabled.filter((automation) => automation.state.nextRunAtMs != null).toSorted((a, b) => (a.state.nextRunAtMs ?? 0) - (b.state.nextRunAtMs ?? 0))[0];
166
+ const oneHourAgo = Date.now() - 60 * 6e4;
167
+ return {
168
+ totalAutomations: automations.length,
169
+ enabledAutomations: enabled.length,
170
+ runningRuns: this.activeRuns.size,
171
+ failedLastHour: automations.filter((automation) => (automation.state.lastRunStatus === "failed" || automation.state.lastRunStatus === "timeout") && (automation.state.lastRunAtMs ?? 0) >= oneHourAgo).length,
172
+ nextRun: next?.state.nextRunAtMs ? {
173
+ automationId: next.id,
174
+ name: next.name,
175
+ runAtMs: next.state.nextRunAtMs
176
+ } : void 0
177
+ };
178
+ }
179
+ async recomputeNextRuns(options) {
180
+ const now = Date.now();
181
+ saveAutomations(listAutomations().map((automation, index) => {
182
+ const next = {
183
+ ...automation,
184
+ state: { ...automation.state }
185
+ };
186
+ if (next.state.runningRunId) {
187
+ next.state.lastRunStatus = "failed";
188
+ next.state.lastError = "Interrupted by gateway restart";
189
+ next.state.consecutiveFailures = (next.state.consecutiveFailures ?? 0) + 1;
190
+ delete next.state.runningRunId;
191
+ }
192
+ const computed = computeNextAutomationRunAtMs(next, now);
193
+ next.state.nextRunAtMs = options?.catchUp && computed != null && computed <= now ? now + index * MISSED_RUN_STAGGER_MS : computed;
194
+ return next;
195
+ }));
196
+ }
197
+ armTimer() {
198
+ if (this.stopped) return;
199
+ if (this.timer) {
200
+ clearTimeout(this.timer);
201
+ this.timer = null;
202
+ }
203
+ const next = listAutomations().filter((automation) => automation.enabled && automation.state.nextRunAtMs != null).toSorted((a, b) => (a.state.nextRunAtMs ?? 0) - (b.state.nextRunAtMs ?? 0))[0];
204
+ if (!next?.state.nextRunAtMs) return;
205
+ this.timer = setTimeout(() => {
206
+ this.onTimer();
207
+ }, timerDelayUntil(next.state.nextRunAtMs));
208
+ this.timer.unref?.();
209
+ }
210
+ async onTimer() {
211
+ if (this.stopped) return;
212
+ if (this.runningScheduler) {
213
+ this.armTimer();
214
+ return;
215
+ }
216
+ this.runningScheduler = true;
217
+ try {
218
+ const now = Date.now();
219
+ const due = listAutomations().filter((automation) => automation.enabled && automation.trigger.kind === "schedule" && automation.state.nextRunAtMs != null && automation.state.nextRunAtMs <= now && !automation.state.runningRunId).slice(0, this.maxConcurrentRuns);
220
+ await Promise.all(due.map((automation) => this.startRun(automation, { manual: false })));
221
+ } finally {
222
+ this.runningScheduler = false;
223
+ this.armTimer();
224
+ }
225
+ }
226
+ async startRun(automation, opts) {
227
+ const now = Date.now();
228
+ const run = {
229
+ id: randomUUID(),
230
+ automationId: automation.id,
231
+ automationName: automation.name,
232
+ status: "queued",
233
+ triggerSnapshot: automation.trigger,
234
+ actionSnapshot: automation.action,
235
+ manual: opts.manual,
236
+ createdAtMs: now
237
+ };
238
+ saveAutomationRun(run);
239
+ this.appendRunEvent(run, "run.queued", opts.event ? `Event ${opts.event.type} queued automation` : opts.manual ? "Manual run queued" : "Scheduled run queued", {
240
+ trigger: automation.trigger,
241
+ actionKind: automation.action.kind,
242
+ safety: automation.safety ?? { mode: "auto_apply" },
243
+ event: opts.event
244
+ });
245
+ const nextAutomation = {
246
+ ...automation,
247
+ state: {
248
+ ...automation.state,
249
+ runningRunId: run.id
250
+ }
251
+ };
252
+ saveAutomation(nextAutomation);
253
+ this.executeRun(nextAutomation, run).catch((err) => {
254
+ log.error({
255
+ err,
256
+ automationId: automation.id,
257
+ runId: run.id
258
+ }, `Automation run failed: ${err instanceof Error ? err.message : String(err)}`);
259
+ });
260
+ return run;
261
+ }
262
+ async executeRun(automation, initialRun) {
263
+ const controller = new AbortController();
264
+ this.activeRuns.set(initialRun.id, controller);
265
+ const startedAtMs = Date.now();
266
+ let run = {
267
+ ...initialRun,
268
+ status: "running",
269
+ startedAtMs
270
+ };
271
+ saveAutomationRun(run);
272
+ this.appendRunEvent(run, "run.started", "Automation run started");
273
+ let status = "failed";
274
+ let error;
275
+ let activePhase = "action";
276
+ try {
277
+ this.appendRunEvent(run, "action.started", `Running ${automation.action.kind} action`, {
278
+ actionKind: automation.action.kind,
279
+ safety: automation.safety ?? { mode: "auto_apply" }
280
+ });
281
+ const outcome = await this.executor.execute(automation, run, controller.signal);
282
+ status = outcome.status;
283
+ error = outcome.error;
284
+ this.appendRunEvent(run, status === "succeeded" ? "action.completed" : "action.failed", status === "succeeded" ? `${automation.action.kind} action completed` : `${automation.action.kind} action ${status}`, {
285
+ summary: outcome.summary,
286
+ error: outcome.error,
287
+ sessionKey: outcome.sessionKey,
288
+ workflowRunId: outcome.workflowRunId,
289
+ model: outcome.model
290
+ });
291
+ run = {
292
+ ...run,
293
+ status,
294
+ summary: outcome.summary,
295
+ error,
296
+ sessionKey: outcome.sessionKey,
297
+ workflowRunId: outcome.workflowRunId,
298
+ model: outcome.model
299
+ };
300
+ if ((automation.safety?.mode ?? "auto_apply") !== "auto_apply" && automation.afterRun?.kind === "webhook") this.appendRunEvent(run, "after_run.completed", "After-run webhook skipped by safety mode", { safety: automation.safety ?? { mode: "auto_apply" } });
301
+ else if (automation.afterRun?.kind === "webhook") {
302
+ activePhase = "after_run";
303
+ this.appendRunEvent(run, "after_run.started", "Calling after-run webhook", { url: automation.afterRun.url });
304
+ await this.postAfterRunWebhook(automation.afterRun.url, run);
305
+ this.appendRunEvent(run, "after_run.completed", "After-run webhook completed");
306
+ }
307
+ } catch (err) {
308
+ error = err instanceof Error ? err.message : String(err);
309
+ status = controller.signal.aborted ? "cancelled" : "failed";
310
+ this.appendRunEvent(run, activePhase === "after_run" ? "after_run.failed" : "action.failed", `Automation run ${status}`, { error });
311
+ run = {
312
+ ...run,
313
+ status,
314
+ error
315
+ };
316
+ } finally {
317
+ const endedAtMs = Date.now();
318
+ run = {
319
+ ...run,
320
+ status,
321
+ endedAtMs,
322
+ durationMs: endedAtMs - startedAtMs
323
+ };
324
+ saveAutomationRun(run);
325
+ this.appendRunEvent(run, "run.completed", `Automation run ${status}`, {
326
+ status,
327
+ durationMs: run.durationMs,
328
+ error
329
+ });
330
+ this.activeRuns.delete(initialRun.id);
331
+ this.finishAutomationRun(automation.id, status, error, endedAtMs);
332
+ }
333
+ }
334
+ appendRunEvent(run, type, message, data) {
335
+ appendAutomationRunEvent({
336
+ id: randomUUID(),
337
+ runId: run.id,
338
+ automationId: run.automationId,
339
+ type,
340
+ message,
341
+ data,
342
+ createdAtMs: Date.now()
343
+ });
344
+ }
345
+ finishAutomationRun(automationId, status, error, finishedAtMs) {
346
+ const current = getAutomation(automationId);
347
+ if (!current) return;
348
+ const consecutiveFailures = status === "failed" || status === "timeout" ? (current.state.consecutiveFailures ?? 0) + 1 : 0;
349
+ const disableAfter = current.reliability?.disableAfterConsecutiveFailures;
350
+ const shouldDisable = disableAfter != null && consecutiveFailures >= disableAfter;
351
+ const next = {
352
+ ...current,
353
+ enabled: shouldDisable ? false : current.enabled,
354
+ state: {
355
+ ...current.state,
356
+ lastRunAtMs: finishedAtMs,
357
+ lastRunStatus: status,
358
+ lastError: error,
359
+ consecutiveFailures
360
+ },
361
+ updatedAtMs: shouldDisable ? finishedAtMs : current.updatedAtMs
362
+ };
363
+ delete next.state.runningRunId;
364
+ next.state.nextRunAtMs = computeNextAutomationRunAtMs(next, finishedAtMs);
365
+ saveAutomation(next);
366
+ this.armTimer();
367
+ }
368
+ async postAfterRunWebhook(url, run) {
369
+ const response = await fetch(url, {
370
+ method: "POST",
371
+ headers: { "content-type": "application/json" },
372
+ body: JSON.stringify({ run })
373
+ });
374
+ if (!response.ok) {
375
+ const text = await response.text().catch(() => "");
376
+ throw new Error(`Automation webhook failed: HTTP ${response.status}${text ? ` ${text.slice(0, 200)}` : ""}`);
377
+ }
378
+ }
379
+ };
380
+ function matchesAutomationEvent(trigger, event) {
381
+ if (trigger.eventType !== event.type) return false;
382
+ if (trigger.source && trigger.source !== event.source) return false;
383
+ const payloadMatch = trigger.payloadMatch;
384
+ if (!payloadMatch) return true;
385
+ const payload = event.payload ?? {};
386
+ return Object.entries(payloadMatch).every(([key, expected]) => Object.is(payload[key], expected));
387
+ }
388
+ function readAutomationEventFromRunEvent(event) {
389
+ if (!event.data || typeof event.data !== "object" || Array.isArray(event.data)) return null;
390
+ const raw = event.data.event;
391
+ if (!raw || typeof raw !== "object" || Array.isArray(raw)) return null;
392
+ const candidate = raw;
393
+ if (typeof candidate.type !== "string" || !candidate.type.trim()) return null;
394
+ return {
395
+ type: candidate.type,
396
+ source: typeof candidate.source === "string" ? candidate.source : void 0,
397
+ payload: candidate.payload && typeof candidate.payload === "object" && !Array.isArray(candidate.payload) ? candidate.payload : void 0,
398
+ occurredAtMs: typeof candidate.occurredAtMs === "number" ? candidate.occurredAtMs : void 0
399
+ };
400
+ }
401
+ //#endregion
402
+ export { AutomationAlreadyRunningError, AutomationService };
403
+
404
+ //# sourceMappingURL=automation-service.js.map