@xopcai/xopc 0.0.111 → 0.0.113

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 (443) hide show
  1. package/dist/browser-ext/icons/icon-128.png +0 -0
  2. package/dist/browser-ext/icons/icon-16.png +0 -0
  3. package/dist/browser-ext/icons/icon-32.png +0 -0
  4. package/dist/browser-ext/icons/icon-48.png +0 -0
  5. package/dist/browser-ext/manifest.json +1 -1
  6. package/dist/extensions/feishu/src/outbound/media-load.js +1 -1
  7. package/dist/extensions/feishu/src/workflow-progress.js +1 -1
  8. package/dist/extensions/telegram/src/adapters/streaming-adapter.js +1 -1
  9. package/dist/extensions/telegram/src/inbound-processor.js +1 -1
  10. package/dist/extensions/telegram/src/plugin.js +1 -1
  11. package/dist/extensions/telegram/src/routing-integration.js +2 -2
  12. package/dist/extensions/telegram/src/update-offset-store.js +1 -1
  13. package/dist/extensions/telegram/src/workflow-progress.js +1 -1
  14. package/dist/extensions/telegram/xopc.extension.json +1 -1
  15. package/dist/extensions/weixin/src/api/api.js +2 -2
  16. package/dist/extensions/weixin/src/auth/accounts.js +1 -1
  17. package/dist/extensions/weixin/src/cdn/upload.js +1 -1
  18. package/dist/extensions/weixin/src/delivery-to.d.ts +3 -3
  19. package/dist/extensions/weixin/src/delivery-to.js.map +1 -1
  20. package/dist/extensions/weixin/src/media/data-url.js +1 -1
  21. package/dist/extensions/weixin/src/messaging/debug-mode.js +1 -1
  22. package/dist/extensions/weixin/src/messaging/inbound.js +1 -1
  23. package/dist/extensions/weixin/src/messaging/process-message.js +1 -1
  24. package/dist/extensions/weixin/src/plugin.js +1 -1
  25. package/dist/extensions/weixin/src/storage/sync-buf.js +1 -1
  26. package/dist/extensions/weixin/src/workflow-progress.js +1 -1
  27. package/dist/gateway/static/root/apple-touch-icon.png +0 -0
  28. package/dist/gateway/static/root/assets/{agent-avatar-dicebear-zlx9l5Yp.js → agent-avatar-dicebear-CBlklyNr.js} +1 -1
  29. package/dist/gateway/static/root/assets/agent-browser-settings-page-rGbKc2Hh.js +6 -0
  30. package/dist/gateway/static/root/assets/{agent-defaults-tabbed-page-Bz7JWjRM.js → agent-defaults-tabbed-page-CtwVbjOA.js} +1 -1
  31. package/dist/gateway/static/root/assets/agents-CCBmGcwc.js +71 -0
  32. package/dist/gateway/static/root/assets/{app-management-settings-panel-DaQwdeCq.js → app-management-settings-panel-28E_WfMe.js} +1 -1
  33. package/dist/gateway/static/root/assets/{appearance-settings-D2zv6r3P.js → appearance-settings-Do1z0XgJ.js} +1 -1
  34. package/dist/gateway/static/root/assets/{apps-page-BIppe_jj.js → apps-page-xwCsJS15.js} +1 -1
  35. package/dist/gateway/static/root/assets/{archive-plugin-DEmu8eH7.js → archive-plugin-BAFlsov_.js} +1 -1
  36. package/dist/gateway/static/root/assets/{attachment-load-B98lJoN5.js → attachment-load-V3qGPC3x.js} +1 -1
  37. package/dist/gateway/static/root/assets/{binary-plugins-CL9QKmyo.js → binary-plugins-DT8NvA6W.js} +1 -1
  38. package/dist/gateway/static/root/assets/{block-editor-BOAhMAhT.js → block-editor-CdLMEcHd.js} +1 -1
  39. package/dist/gateway/static/root/assets/{channels-settings-Br8iRnXp.js → channels-settings-C044DcYk.js} +1 -1
  40. package/dist/gateway/static/root/assets/{config-api-0o1WYdz2.js → config-api-Bf5mjpu7.js} +1 -1
  41. package/dist/gateway/static/root/assets/config-reload-event-Bjh2zoKp.js +1 -0
  42. package/dist/gateway/static/root/assets/connectors-settings-8VEWUOTj.js +2 -0
  43. package/dist/gateway/static/root/assets/cron-api--pAB_rps.js +1 -0
  44. package/dist/gateway/static/root/assets/cron-page-DqmNGNOy.js +3 -0
  45. package/dist/gateway/static/root/assets/dreaming-settings-6UZE1FSK.js +1 -0
  46. package/dist/gateway/static/root/assets/{extension-debug-page-Cjx6pZVz.js → extension-debug-page-BGhE7msg.js} +1 -1
  47. package/dist/gateway/static/root/assets/{extension-page-BSPNL90V.js → extension-page-CvpI45WG.js} +1 -1
  48. package/dist/gateway/static/root/assets/extension-settings-page-DAmR5FUe.js +1 -0
  49. package/dist/gateway/static/root/assets/{fetch-Bs7in_4F.js → fetch-NZmjSXLl.js} +1 -1
  50. package/dist/gateway/static/root/assets/format-cron-label-BsotZDO5.js +2 -0
  51. package/dist/gateway/static/root/assets/{format-interval-label-CftJ5uXu.js → format-interval-label-qhth3BMV.js} +1 -1
  52. package/dist/gateway/static/root/assets/{gateway-config-api-Clfck-hW.js → gateway-config-api-CaXBt-9R.js} +1 -1
  53. package/dist/gateway/static/root/assets/gateway-settings-DphpbLBc.js +1 -0
  54. package/dist/gateway/static/root/assets/{gateway-startup-retry-BkjVJc38.js → gateway-startup-retry-Be1omjh3.js} +1 -1
  55. package/dist/gateway/static/root/assets/{goal-detail-page-kqJue0sE.js → goal-detail-page-bv0VRDaf.js} +1 -1
  56. package/dist/gateway/static/root/assets/goals-page-1Ywnt4Cb.js +2 -0
  57. package/dist/gateway/static/root/assets/{goals-settings-CJnzNSDo.js → goals-settings-ceEBjnfc.js} +1 -1
  58. package/dist/gateway/static/root/assets/{heartbeat-config-api-Cp7CPuIn.js → heartbeat-config-api-BzO6G4fD.js} +1 -1
  59. package/dist/gateway/static/root/assets/{heartbeat-settings-ifSI1Wbh.js → heartbeat-settings-DCST9-du.js} +1 -1
  60. package/dist/gateway/static/root/assets/index-Cxm6xsps.js +122 -0
  61. package/dist/gateway/static/root/assets/index-b_R4tKqt.css +1 -0
  62. package/dist/gateway/static/root/assets/interval-presets-DJmshV8n.js +1 -0
  63. package/dist/gateway/static/root/assets/{keyboard-shortcuts-settings--MI1rYl7.js → keyboard-shortcuts-settings-9AUUlQ5Q.js} +1 -1
  64. package/dist/gateway/static/root/assets/{logs-page-BwrVNlyW.js → logs-page-B_wrxhee.js} +1 -1
  65. package/dist/gateway/static/root/assets/{markdown-split-B_oc9lJe.js → markdown-split-CYYELqAr.js} +1 -1
  66. package/dist/gateway/static/root/assets/{media-plugins-DLPvB5H3.js → media-plugins-BEcMR2M8.js} +1 -1
  67. package/dist/gateway/static/root/assets/messages-CkT-lcgP.js +3 -0
  68. package/dist/gateway/static/root/assets/models-hub-panel-D0JDSbNu.js +2 -0
  69. package/dist/gateway/static/root/assets/note-detail-page-DpFV-EO6.js +2 -0
  70. package/dist/gateway/static/root/assets/{note-image-lightbox-rSqAgOi9.js → note-image-lightbox-DNAoPcmm.js} +1 -1
  71. package/dist/gateway/static/root/assets/{notes-page-C9ACGEty.js → notes-page-CdkjTch8.js} +1 -1
  72. package/dist/gateway/static/root/assets/{preview-open-alternatives-Bw_N2oZi.js → preview-open-alternatives-BPLz0AIv.js} +1 -1
  73. package/dist/gateway/static/root/assets/{remote-access-hub-BhcWIKuM.js → remote-access-hub-DSYVAi96.js} +1 -1
  74. package/dist/gateway/static/root/assets/{save-bar-controls-CNP2jmw0.js → save-bar-controls-CrWwWRVK.js} +1 -1
  75. package/dist/gateway/static/root/assets/schedule-field-CF2sadvN.js +1 -0
  76. package/dist/gateway/static/root/assets/{schema-form-CDPzua9q.js → schema-form-Di5cKjYE.js} +1 -1
  77. package/dist/gateway/static/root/assets/{sessions-page-DzkpSDZr.js → sessions-page-CenkcVjF.js} +1 -1
  78. package/dist/gateway/static/root/assets/settings-advanced-gate-D9sva86V.js +1 -0
  79. package/dist/gateway/static/root/assets/{settings-collapsible-section-C9bff85B.js → settings-collapsible-section-Chh282jW.js} +1 -1
  80. package/dist/gateway/static/root/assets/settings-form-section-Dq-83cQd.js +1 -0
  81. package/dist/gateway/static/root/assets/{settings-page-DWK4Zo7s.js → settings-page-DL35U0x0.js} +1 -1
  82. package/dist/gateway/static/root/assets/setup-status-panel-Ctwbp9Er.js +1 -0
  83. package/dist/gateway/static/root/assets/{share-preview-page-DnutoY_S.js → share-preview-page-0FXYnSUA.js} +1 -1
  84. package/dist/gateway/static/root/assets/{shares-settings-6oRgJMpn.js → shares-settings-DIM3JNsr.js} +1 -1
  85. package/dist/gateway/static/root/assets/skill-reload-api-DAlNaNzL.js +1 -0
  86. package/dist/gateway/static/root/assets/skills-page-CLrHVzAt.js +2 -0
  87. package/dist/gateway/static/root/assets/{system-settings-panel-qP1JDtDd.js → system-settings-panel-W1pTcojB.js} +1 -1
  88. package/dist/gateway/static/root/assets/use-agent-defaults-form-BVRvkK7m.js +1 -0
  89. package/dist/gateway/static/root/assets/{use-channel-catalog-C4mg1hjD.js → use-channel-catalog-CgJibfMM.js} +1 -1
  90. package/dist/gateway/static/root/assets/{use-settings-tab-guard-F6C0mpJt.js → use-settings-tab-guard-Bw_qkRQE.js} +1 -1
  91. package/dist/gateway/static/root/assets/{voice-api-key-field-BnDDb6qO.js → voice-api-key-field-vYAO71Gn.js} +1 -1
  92. package/dist/gateway/static/root/assets/{voice-player-store-B2EwIhtY.js → voice-player-store-C7lziaAx.js} +1 -1
  93. package/dist/gateway/static/root/assets/{workflow-page.utils-CRB7WX9l.js → workflow-page.utils-sgHjOXOm.js} +1 -1
  94. package/dist/gateway/static/root/assets/{workflows-page-2Fptr0je.js → workflows-page-DYyOTmFx.js} +1 -1
  95. package/dist/gateway/static/root/favicon-16x16.png +0 -0
  96. package/dist/gateway/static/root/favicon-32x32.png +0 -0
  97. package/dist/gateway/static/root/favicon-icon.svg +1 -0
  98. package/dist/gateway/static/root/favicon.ico +0 -0
  99. package/dist/gateway/static/root/favicon.png +0 -0
  100. package/dist/gateway/static/root/favicon.svg +24 -15
  101. package/dist/gateway/static/root/index.html +11 -10
  102. package/dist/gateway/static/root/logo-dark.svg +23 -15
  103. package/dist/gateway/static/root/logo.svg +23 -16
  104. package/dist/package.js +1 -1
  105. package/dist/src/agent/agent-manager.d.ts +28 -2
  106. package/dist/src/agent/agent-manager.js +82 -11
  107. package/dist/src/agent/agent-manager.js.map +1 -1
  108. package/dist/src/agent/agent-scope.js +1 -1
  109. package/dist/src/agent/bootstrap/load-bootstrap-files.js +1 -1
  110. package/dist/src/agent/context/workspace-seed.js +2 -2
  111. package/dist/src/agent/context/workspace-state.js +1 -1
  112. package/dist/src/agent/context/workspace.js +1 -1
  113. package/dist/src/agent/goals/goal-locale.js +2 -2
  114. package/dist/src/agent/goals/persistent-goal-service.js +1 -1
  115. package/dist/src/agent/goals/post-turn.js +3 -3
  116. package/dist/src/agent/image/load-image-media.js +2 -2
  117. package/dist/src/agent/ipc/inbox.js +3 -3
  118. package/dist/src/agent/ipc/socket.js +1 -1
  119. package/dist/src/agent/mcp/bundle-mcp-materialize.js +1 -1
  120. package/dist/src/agent/mcp/bundle-mcp-runtime.js +1 -1
  121. package/dist/src/agent/mcp/mcp-transport-config.js +1 -1
  122. package/dist/src/agent/mcp/mcp-transport.js +1 -1
  123. package/dist/src/agent/memory/builtin-memory-store.js +1 -1
  124. package/dist/src/agent/memory/dreaming/deep-promotion.js +1 -1
  125. package/dist/src/agent/memory/dreaming/events.js +1 -1
  126. package/dist/src/agent/memory/dreaming/last-run.js +1 -1
  127. package/dist/src/agent/memory/dreaming/light-sweep.js +1 -1
  128. package/dist/src/agent/memory/dreaming/preview.js +1 -1
  129. package/dist/src/agent/memory/dreaming/rem-patterns.js +1 -1
  130. package/dist/src/agent/memory/dreaming/short-term-store.js +1 -1
  131. package/dist/src/agent/memory/dreaming/utils.js +1 -1
  132. package/dist/src/agent/memory/memory-flush.js +1 -1
  133. package/dist/src/agent/memory/plugin-discovery.js +1 -1
  134. package/dist/src/agent/messaging/command-handler.d.ts +3 -0
  135. package/dist/src/agent/messaging/command-handler.js +5 -0
  136. package/dist/src/agent/messaging/command-handler.js.map +1 -1
  137. package/dist/src/agent/models/manager.js +1 -1
  138. package/dist/src/agent/prompt/memory/index.js +1 -1
  139. package/dist/src/agent/prompt/service-prompt-builder.js +2 -2
  140. package/dist/src/agent/reply/post-compaction-context.js +1 -1
  141. package/dist/src/agent/reply/workspace-boundary-read.js +1 -1
  142. package/dist/src/agent/sandbox/path-policy.js +2 -2
  143. package/dist/src/agent/service/process-direct-streaming.js +9 -4
  144. package/dist/src/agent/service/process-direct-streaming.js.map +1 -1
  145. package/dist/src/agent/service/reconcile-dreaming-cron.js +8 -5
  146. package/dist/src/agent/service/reconcile-dreaming-cron.js.map +1 -1
  147. package/dist/src/agent/service.d.ts +2 -1
  148. package/dist/src/agent/service.js +10 -5
  149. package/dist/src/agent/service.js.map +1 -1
  150. package/dist/src/agent/service.types.d.ts +4 -0
  151. package/dist/src/agent/session/session-config-service.d.ts +8 -0
  152. package/dist/src/agent/session/session-config-service.js +20 -0
  153. package/dist/src/agent/session/session-config-service.js.map +1 -1
  154. package/dist/src/agent/session/session-inspector.js +1 -1
  155. package/dist/src/agent/skills/config.js +2 -2
  156. package/dist/src/agent/skills/filesystem-watcher.d.ts +19 -0
  157. package/dist/src/agent/skills/filesystem-watcher.js +182 -0
  158. package/dist/src/agent/skills/filesystem-watcher.js.map +1 -0
  159. package/dist/src/agent/skills/hub-hash.js +2 -2
  160. package/dist/src/agent/skills/hub-lock.js +1 -1
  161. package/dist/src/agent/skills/hub-pull.js +30 -36
  162. package/dist/src/agent/skills/hub-pull.js.map +1 -1
  163. package/dist/src/agent/skills/index.js +82 -38
  164. package/dist/src/agent/skills/index.js.map +1 -1
  165. package/dist/src/agent/skills/installer.js +2 -2
  166. package/dist/src/agent/skills/managed-store.d.ts +19 -0
  167. package/dist/src/agent/skills/managed-store.js +97 -38
  168. package/dist/src/agent/skills/managed-store.js.map +1 -1
  169. package/dist/src/agent/skills/skill-manage-ops.js +1 -1
  170. package/dist/src/agent/skills/skill-manager.d.ts +16 -6
  171. package/dist/src/agent/skills/skill-manager.js +79 -24
  172. package/dist/src/agent/skills/skill-manager.js.map +1 -1
  173. package/dist/src/agent/skills/skill-view-path.js +1 -1
  174. package/dist/src/agent/skills/test-framework.js +1 -1
  175. package/dist/src/agent/skills/types.d.ts +11 -0
  176. package/dist/src/agent/skills/watcher.js +1 -1
  177. package/dist/src/agent/starter-agents.js +1 -1
  178. package/dist/src/agent/tools/cronjob-tool.d.ts +6 -3
  179. package/dist/src/agent/tools/cronjob-tool.js +58 -23
  180. package/dist/src/agent/tools/cronjob-tool.js.map +1 -1
  181. package/dist/src/agent/tools/dreaming-tool.js +1 -1
  182. package/dist/src/agent/tools/factory.js +1 -1
  183. package/dist/src/agent/tools/find.js +1 -1
  184. package/dist/src/agent/tools/grep.js +1 -1
  185. package/dist/src/agent/tools/image-generate-tool.js +1 -1
  186. package/dist/src/agent/tools/skill-manage-tool.js +1 -1
  187. package/dist/src/agent/tools/workflow-tool.js +1 -1
  188. package/dist/src/agent/workflow/catalog.js +1 -1
  189. package/dist/src/agent/workspace-runtime/registry.d.ts +5 -0
  190. package/dist/src/agent/workspace-runtime/registry.js +7 -0
  191. package/dist/src/agent/workspace-runtime/registry.js.map +1 -1
  192. package/dist/src/ai-assist/text-assist.d.ts +42 -0
  193. package/dist/src/ai-assist/text-assist.js +252 -0
  194. package/dist/src/ai-assist/text-assist.js.map +1 -0
  195. package/dist/src/auth/credentials.js +2 -2
  196. package/dist/src/auth/profiles/store.js +2 -2
  197. package/dist/src/auth/sync-provider-auth.js +1 -1
  198. package/dist/src/browser/cache-dir-policy.js +1 -1
  199. package/dist/src/browser/cdp-local-launcher.js +2 -2
  200. package/dist/src/browser/providers/browser-ext-install.js +4 -4
  201. package/dist/src/browser/providers/cloakbrowser.js +5 -5
  202. package/dist/src/browser/providers/playwright-doctor.js +1 -1
  203. package/dist/src/browser/stealth.js +1 -1
  204. package/dist/src/channels/outbound/persist-store.js +1 -1
  205. package/dist/src/channels/pairing/allow-from-file.js +1 -1
  206. package/dist/src/channels/pairing/pairing-store.js +2 -2
  207. package/dist/src/channels/plugins/types.adapters.d.ts +2 -2
  208. package/dist/src/chat-commands/agent-edit.js +2 -2
  209. package/dist/src/chat-commands/builtins/config.js +3 -3
  210. package/dist/src/chat-commands/builtins/system.js +11 -4
  211. package/dist/src/chat-commands/builtins/system.js.map +1 -1
  212. package/dist/src/chat-commands/context.d.ts +3 -0
  213. package/dist/src/chat-commands/context.js +7 -0
  214. package/dist/src/chat-commands/context.js.map +1 -1
  215. package/dist/src/chat-commands/types.d.ts +2 -0
  216. package/dist/src/cli/commands/config.js +1 -1
  217. package/dist/src/cli/commands/cron.js +55 -16
  218. package/dist/src/cli/commands/cron.js.map +1 -1
  219. package/dist/src/cli/commands/doctor/checks/config-health.js +1 -1
  220. package/dist/src/cli/commands/doctor/checks/cron-health.js +2 -83
  221. package/dist/src/cli/commands/doctor/checks/cron-health.js.map +1 -1
  222. package/dist/src/cli/commands/doctor/checks/database-schema.js +1 -1
  223. package/dist/src/cli/commands/doctor/checks/provider-auth.js +1 -1
  224. package/dist/src/cli/commands/doctor/checks/state-integrity.js +1 -1
  225. package/dist/src/cli/commands/doctor/checks/workspace-status.js +1 -1
  226. package/dist/src/cli/commands/extension-create.js +1 -1
  227. package/dist/src/cli/commands/extension-dev.js +2 -2
  228. package/dist/src/cli/commands/extension-marketplace.js +2 -2
  229. package/dist/src/cli/commands/extension-pack.js +2 -2
  230. package/dist/src/cli/commands/extension.js +3 -3
  231. package/dist/src/cli/commands/gateway/logs.js +1 -1
  232. package/dist/src/cli/commands/image.js +1 -1
  233. package/dist/src/cli/commands/init.js +2 -2
  234. package/dist/src/cli/commands/models.js +1 -1
  235. package/dist/src/cli/commands/skills-test.js +1 -1
  236. package/dist/src/cli/templates.js +1 -1
  237. package/dist/src/cli/utils/gateway-client.js +1 -1
  238. package/dist/src/cli/utils/init-workspace-core.js +2 -2
  239. package/dist/src/config/agent-profile.js +1 -1
  240. package/dist/src/config/agent-typed-models.js +1 -1
  241. package/dist/src/config/gateway-bind.js +1 -1
  242. package/dist/src/config/index.js +7 -7
  243. package/dist/src/config/loader.js +4 -4
  244. package/dist/src/config/models-json.js +2 -2
  245. package/dist/src/config/paths-state.js +1 -1
  246. package/dist/src/config/paths.js +1 -1
  247. package/dist/src/config/profile.js +1 -1
  248. package/dist/src/config/reload.js +1 -1
  249. package/dist/src/config/schema.d.ts +0 -2
  250. package/dist/src/config/schema.js +0 -3
  251. package/dist/src/config/schema.js.map +1 -1
  252. package/dist/src/config/web-patch.d.ts +0 -1
  253. package/dist/src/config/web-patch.js +0 -2
  254. package/dist/src/config/web-patch.js.map +1 -1
  255. package/dist/src/config/workspace-path.js +1 -1
  256. package/dist/src/cron/executor.js +102 -71
  257. package/dist/src/cron/executor.js.map +1 -1
  258. package/dist/src/cron/index.d.ts +1 -1
  259. package/dist/src/cron/index.js +3 -3
  260. package/dist/src/cron/run-log-store.d.ts +1 -0
  261. package/dist/src/cron/run-log-store.js +4 -2
  262. package/dist/src/cron/run-log-store.js.map +1 -1
  263. package/dist/src/cron/schedule.d.ts +10 -0
  264. package/dist/src/cron/schedule.js +85 -0
  265. package/dist/src/cron/schedule.js.map +1 -0
  266. package/dist/src/cron/service.d.ts +34 -77
  267. package/dist/src/cron/service.js +327 -264
  268. package/dist/src/cron/service.js.map +1 -1
  269. package/dist/src/cron/types.d.ts +80 -50
  270. package/dist/src/cron/validation.d.ts +358 -90
  271. package/dist/src/cron/validation.js +152 -132
  272. package/dist/src/cron/validation.js.map +1 -1
  273. package/dist/src/cron/workflow-run-completion.js +1 -1
  274. package/dist/src/daemon/constants.js +1 -1
  275. package/dist/src/daemon/install-plan.js +2 -2
  276. package/dist/src/daemon/launchd.js +2 -2
  277. package/dist/src/daemon/schtasks.js +2 -2
  278. package/dist/src/daemon/systemd.js +2 -2
  279. package/dist/src/extensions/bundle-mcp.js +1 -1
  280. package/dist/src/extensions/discover-extensions.js +2 -2
  281. package/dist/src/extensions/health.js +1 -1
  282. package/dist/src/extensions/install.js +2 -2
  283. package/dist/src/extensions/loader.js +2 -2
  284. package/dist/src/extensions/lockfile.js +3 -3
  285. package/dist/src/extensions/security.js +1 -1
  286. package/dist/src/extensions/update.js +2 -2
  287. package/dist/src/gateway/agents-admin.js +2 -2
  288. package/dist/src/gateway/chat-stream/mapper.d.ts +1 -0
  289. package/dist/src/gateway/chat-stream/mapper.js +6 -2
  290. package/dist/src/gateway/chat-stream/mapper.js.map +1 -1
  291. package/dist/src/gateway/chat-stream/protocol.d.ts +2 -0
  292. package/dist/src/gateway/file-path-classifier.js +2 -2
  293. package/dist/src/gateway/hono/lib/config-payload.d.ts +0 -1
  294. package/dist/src/gateway/hono/lib/config-payload.js +1 -1
  295. package/dist/src/gateway/hono/lib/extension-store.js +2 -2
  296. package/dist/src/gateway/hono/lib/static-ui.js +2 -2
  297. package/dist/src/gateway/hono/oauth-async.js +1 -1
  298. package/dist/src/gateway/hono/routes/agents.js +1 -1
  299. package/dist/src/gateway/hono/routes/ai-assist.d.ts +3 -0
  300. package/dist/src/gateway/hono/routes/ai-assist.js +66 -0
  301. package/dist/src/gateway/hono/routes/ai-assist.js.map +1 -0
  302. package/dist/src/gateway/hono/routes/auth-registry-extensions.js +1 -1
  303. package/dist/src/gateway/hono/routes/commands-skills.js +7 -0
  304. package/dist/src/gateway/hono/routes/commands-skills.js.map +1 -1
  305. package/dist/src/gateway/hono/routes/config-patch/misc.js +1 -1
  306. package/dist/src/gateway/hono/routes/cron.js +24 -5
  307. package/dist/src/gateway/hono/routes/cron.js.map +1 -1
  308. package/dist/src/gateway/hono/routes/dreaming.js +1 -1
  309. package/dist/src/gateway/hono/routes/home.js +5 -3
  310. package/dist/src/gateway/hono/routes/home.js.map +1 -1
  311. package/dist/src/gateway/hono/routes/host-fs.js +2 -2
  312. package/dist/src/gateway/hono/routes/lazy-bundles.js +8 -0
  313. package/dist/src/gateway/hono/routes/lazy-bundles.js.map +1 -1
  314. package/dist/src/gateway/hono/routes/models.js +1 -1
  315. package/dist/src/gateway/hono/routes/shares.js +1 -1
  316. package/dist/src/gateway/hono/routes/workflows.js +2 -2
  317. package/dist/src/gateway/hono/routes/workspace.js +2 -2
  318. package/dist/src/gateway/lock.js +3 -3
  319. package/dist/src/gateway/ports.js +1 -1
  320. package/dist/src/gateway/service/agent-runner.js +2 -2
  321. package/dist/src/gateway/service/config-coordinator.js +1 -1
  322. package/dist/src/gateway/service/marketplace-service.d.ts +22 -10
  323. package/dist/src/gateway/service/marketplace-service.js +46 -5
  324. package/dist/src/gateway/service/marketplace-service.js.map +1 -1
  325. package/dist/src/gateway/service.js +11 -5
  326. package/dist/src/gateway/service.js.map +1 -1
  327. package/dist/src/gateway/workspace-fs-file-list.js +1 -1
  328. package/dist/src/goals/goal-notifications.js +1 -1
  329. package/dist/src/goals/goal-workflow-judge.js +3 -3
  330. package/dist/src/i18n/goals-bundle.js +1 -1
  331. package/dist/src/i18n/index.js +1 -1
  332. package/dist/src/i18n/share-tool-bundle.js +2 -2
  333. package/dist/src/infra/brew.js +1 -1
  334. package/dist/src/infra/package-json.js +1 -1
  335. package/dist/src/infra/package-update-steps.js +1 -1
  336. package/dist/src/infra/path-env.js +2 -2
  337. package/dist/src/infra/restart.js +1 -1
  338. package/dist/src/infra/stable-node-path.js +1 -1
  339. package/dist/src/infra/update-check.js +1 -1
  340. package/dist/src/infra/update-global.js +1 -1
  341. package/dist/src/infra/update-lock.js +2 -2
  342. package/dist/src/infra/update-restart.js +1 -1
  343. package/dist/src/infra/update-runner.js +1 -1
  344. package/dist/src/infra/update-startup.js +1 -1
  345. package/dist/src/infra/write-file-atomic.js +2 -2
  346. package/dist/src/media/store.js +1 -1
  347. package/dist/src/notes/agent-context.js +1 -1
  348. package/dist/src/notes/service.js +1 -1
  349. package/dist/src/notes/store.js +2 -2
  350. package/dist/src/project-trust/trust-store.js +2 -2
  351. package/dist/src/providers/auth-runtime/auth-profile-store.js +1 -1
  352. package/dist/src/providers/index.js +1 -1
  353. package/dist/src/providers/model-registry.js +4 -4
  354. package/dist/src/session/init-session-turn.js +2 -2
  355. package/dist/src/session/resolve-session.js +3 -3
  356. package/dist/src/session/session-title.js +2 -2
  357. package/dist/src/session/store-reader.d.ts +5 -0
  358. package/dist/src/session/store-reader.js +1 -0
  359. package/dist/src/session/store.js +1 -1
  360. package/dist/src/share/share-auto.js +2 -2
  361. package/dist/src/share/share-store.js +3 -3
  362. package/dist/src/share/share-thumbnail.js +2 -2
  363. package/dist/src/share/share-zip.js +1 -1
  364. package/dist/src/share/site-share-store.js +3 -3
  365. package/dist/src/share/site-static-serve.js +1 -1
  366. package/dist/src/storage/sqlite/connection.js +1 -1
  367. package/dist/src/storage/sqlite/cron-job-repository.d.ts +6 -0
  368. package/dist/src/storage/sqlite/cron-job-repository.js +70 -0
  369. package/dist/src/storage/sqlite/cron-job-repository.js.map +1 -0
  370. package/dist/src/storage/sqlite/cron-run-repository.js +0 -1
  371. package/dist/src/storage/sqlite/cron-run-repository.js.map +1 -1
  372. package/dist/src/storage/sqlite/index.d.ts +1 -0
  373. package/dist/src/storage/sqlite/index.js +2 -1
  374. package/dist/src/storage/sqlite/memory-index-repository.js +2 -2
  375. package/dist/src/storage/sqlite/migrations/009_cron_jobs.sql +24 -0
  376. package/dist/src/storage/sqlite/migrations/discover.js +1 -1
  377. package/dist/src/storage/sqlite/migrations/runner.d.ts +1 -1
  378. package/dist/src/storage/sqlite/migrations/runner.js +4 -4
  379. package/dist/src/storage/sqlite/migrations/runner.js.map +1 -1
  380. package/dist/src/storage/sqlite/migrations/runner.ts +1 -1
  381. package/dist/src/storage/sqlite/schema.js +2 -2
  382. package/dist/src/storage/sqlite/schema.sql +25 -0
  383. package/dist/src/tui/clipboard-image.js +3 -3
  384. package/dist/src/tui/extension-host/load-extensions.js +1 -1
  385. package/dist/src/tui/theme-manager.js +1 -1
  386. package/dist/src/tui/tui-command-formatters.js +4 -4
  387. package/dist/src/tui/tui-commands.js +2 -2
  388. package/dist/src/tui/tui-keybindings-file.js +1 -1
  389. package/dist/src/tui/tui-scoped-models.js +2 -2
  390. package/dist/src/tui/tui-settings.js +1 -1
  391. package/dist/src/tui/tui-startup-resources.js +1 -1
  392. package/dist/src/tui/tui.js +6 -6
  393. package/dist/src/tunnel/frpc-binary.js +4 -4
  394. package/dist/src/tunnel/frpc-config.js +1 -1
  395. package/dist/src/tunnel/frpc-extract.js +1 -1
  396. package/dist/src/tunnel/tunnel-state.js +1 -1
  397. package/dist/src/utils/logger/audit.js +1 -1
  398. package/dist/src/utils/logger/log-store.js +1 -1
  399. package/dist/src/utils/logger/rotation.js +1 -1
  400. package/dist/src/utils/logger/streams.js +1 -1
  401. package/dist/src/voice/tts/audio.js +1 -1
  402. package/dist/src/voice/tts/providers/edge-speech.js +2 -2
  403. package/dist/src/workflows/draft/workflow-draft-service.js +1 -1
  404. package/dist/src/workflows/engine/projector.js +23 -14
  405. package/dist/src/workflows/engine/projector.js.map +1 -1
  406. package/dist/src/workflows/engine/workflow-engine.d.ts +1 -0
  407. package/dist/src/workflows/engine/workflow-engine.js +36 -0
  408. package/dist/src/workflows/engine/workflow-engine.js.map +1 -1
  409. package/dist/src/workflows/index.js +1 -1
  410. package/dist/src/workflows/service/workflow-run-service.js +2 -2
  411. package/dist/src/workflows/service/workflow-session-bridge.js +2 -2
  412. package/dist/src/workflows/store/event-store.js +1 -1
  413. package/dist/src/workflows/store/run-store.js +1 -1
  414. package/package.json +2 -3
  415. package/dist/gateway/static/root/assets/agent-browser-settings-page-B-0zGjt8.js +0 -6
  416. package/dist/gateway/static/root/assets/agents-DwDnJlXT.js +0 -71
  417. package/dist/gateway/static/root/assets/connectors-settings-DDvHo9in.js +0 -2
  418. package/dist/gateway/static/root/assets/cron-api-Dj_UZKST.js +0 -1
  419. package/dist/gateway/static/root/assets/cron-page-Dv7GII9G.js +0 -1
  420. package/dist/gateway/static/root/assets/cron-schedule-picker-DH10KgD6.js +0 -1
  421. package/dist/gateway/static/root/assets/dreaming-settings-L2rgZDQl.js +0 -1
  422. package/dist/gateway/static/root/assets/extension-settings-page-m_UQYkVc.js +0 -1
  423. package/dist/gateway/static/root/assets/gateway-settings-CS177xni.js +0 -1
  424. package/dist/gateway/static/root/assets/goals-page-C0FujUB5.js +0 -2
  425. package/dist/gateway/static/root/assets/index-COkF54xv.js +0 -121
  426. package/dist/gateway/static/root/assets/index-DIaSNGEO.css +0 -1
  427. package/dist/gateway/static/root/assets/interval-presets-B29Ss_2y.js +0 -2
  428. package/dist/gateway/static/root/assets/messages-Csef1aW7.js +0 -3
  429. package/dist/gateway/static/root/assets/models-hub-panel-DHGiTIvf.js +0 -2
  430. package/dist/gateway/static/root/assets/note-detail-page-BM7zlDiT.js +0 -2
  431. package/dist/gateway/static/root/assets/schedule-field-BPAWui3P.js +0 -1
  432. package/dist/gateway/static/root/assets/schedule-summary-B-hdSRdR.js +0 -1
  433. package/dist/gateway/static/root/assets/settings-advanced-gate-BYS-rpzn.js +0 -1
  434. package/dist/gateway/static/root/assets/settings-form-section-BsrK7TBF.js +0 -1
  435. package/dist/gateway/static/root/assets/setup-status-panel-DJiksNu4.js +0 -1
  436. package/dist/gateway/static/root/assets/skill-reload-api-CU9i0nJV.js +0 -1
  437. package/dist/gateway/static/root/assets/skills-page-ERbdWENm.js +0 -2
  438. package/dist/gateway/static/root/assets/use-agent-defaults-form-D3FGVLZb.js +0 -1
  439. package/dist/gateway/static/root/favicon-16.png +0 -0
  440. package/dist/gateway/static/root/favicon-32.png +0 -0
  441. package/dist/src/cron/persistence.d.ts +0 -62
  442. package/dist/src/cron/persistence.js +0 -188
  443. package/dist/src/cron/persistence.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"service.js","names":["uuidv4"],"sources":["../../../src/cron/service.ts"],"sourcesContent":["// CronService - Optimized with async I/O, caching, and execution tracking\nimport nodeCron from 'node-cron';\nimport { CronExpressionParser } from 'cron-parser';\nimport { v4 as uuidv4 } from 'uuid';\nimport { Config } from '../config/index.js';\nimport { resolveCronJobsPath } from '../config/paths.js';\nimport { createLogger } from '../utils/logger.js';\nimport { CronPersistence } from './persistence.js';\nimport { DefaultJobExecutor } from './executor.js';\nimport { CronRunLogStore } from './run-log-store.js';\nimport { z } from 'zod';\nimport { AddJobRequestSchema, UpdateJobRequestSchema } from './validation.js';\nimport type {\n JobData,\n JobExecution,\n JobExecutorDeps,\n CronMetrics,\n CronHealth,\n AddJobOptions,\n JobWithNextRun,\n CronRunHistoryRow,\n} from './types.js';\n\nconst log = createLogger('CronService');\n\ninterface ScheduledTask {\n stop: () => void;\n}\n\nexport interface CronServiceConfig {\n filePath?: string;\n agentService?: any;\n messageBus?: any;\n /** Override SQLite database path (tests). */\n dbPath?: string;\n}\n\nexport class CronService {\n private persistence: CronPersistence;\n private executor: DefaultJobExecutor;\n private runLogStore: CronRunLogStore;\n private tasks: Map<string, ScheduledTask> = new Map();\n private initialized = false;\n private agentService: any = null;\n private messageBus: any = null;\n\n constructor(config?: CronServiceConfig) {\n const filePath = config?.filePath || resolveCronJobsPath();\n this.persistence = new CronPersistence(filePath);\n this.executor = new DefaultJobExecutor();\n this.runLogStore = new CronRunLogStore(config?.dbPath);\n this.executor.setRunLogStore(this.runLogStore);\n\n // Set dependencies if provided\n if (config?.agentService || config?.messageBus) {\n this.setDeps({\n agentService: config.agentService,\n messageBus: config.messageBus,\n });\n }\n }\n\n /**\n * Set dependencies for the executor\n */\n setDeps(deps: JobExecutorDeps): void {\n this.agentService = deps.agentService;\n this.messageBus = deps.messageBus;\n this.executor.setDeps(deps);\n log.debug('CronService dependencies set');\n }\n\n /**\n * Initialize the service and load all jobs\n */\n async initialize(): Promise<void> {\n if (this.initialized) return;\n\n await this.persistence.initialize();\n await this.loadAllJobs();\n\n this.initialized = true;\n log.debug('CronService initialized');\n }\n\n /**\n * Add a new job\n */\n async addJob(schedule: string, options: AddJobOptions): Promise<{ id: string; schedule: string }> {\n const validationResult = AddJobRequestSchema.safeParse({\n schedule,\n ...options,\n });\n\n if (!validationResult.success) {\n const errorMsg = (validationResult as { error?: { errors: z.ZodIssue[] } }).error?.errors.map((e) => e.message).join(', ') || 'Unknown validation error';\n throw new Error(`Validation failed: ${errorMsg}`);\n }\n\n const data = validationResult.data;\n const id = uuidv4().slice(0, 8);\n const now = new Date().toISOString();\n const sessionTarget = data.sessionTarget ?? 'main';\n\n const job: JobData = {\n id,\n name: data.name,\n schedule: data.schedule,\n enabled: true,\n timezone: data.timezone,\n maxRetries: data.maxRetries ?? 3,\n timeout: data.timeout ?? 60000,\n created_at: now,\n updated_at: now,\n sessionTarget,\n ...(data.agentId ? { agentId: data.agentId } : {}),\n ...(data.workingDirectory ? { workingDirectory: data.workingDirectory } : {}),\n payload: data.payload,\n delivery: data.delivery,\n model: data.model,\n };\n\n // Save to persistence\n await this.persistence.addJob(job);\n\n // Schedule the job\n this.scheduleJob(job);\n\n log.info({ jobId: id, name: data.name, sessionTarget }, 'Job added');\n return { id, schedule: data.schedule };\n }\n\n /**\n * List all jobs with next run time\n */\n async listJobs(): Promise<JobWithNextRun[]> {\n const jobs = await this.persistence.getJobs();\n\n return jobs.map((job) => {\n let nextRun: string | undefined;\n\n if (job.enabled) {\n try {\n const options = job.timezone ? { tz: job.timezone } : undefined;\n const interval = CronExpressionParser.parse(job.schedule, options);\n nextRun = interval.next().toISOString();\n } catch (err) {\n log.debug({ jobId: job.id, err: err as Error }, 'Failed to parse cron for next run');\n }\n }\n\n return {\n id: job.id,\n name: job.name,\n schedule: job.schedule,\n enabled: job.enabled,\n timezone: job.timezone,\n maxRetries: job.maxRetries,\n timeout: job.timeout,\n sessionTarget: job.sessionTarget,\n ...(job.agentId ? { agentId: job.agentId } : {}),\n ...(job.workingDirectory ? { workingDirectory: job.workingDirectory } : {}),\n payload: job.payload,\n delivery: job.delivery,\n model: job.model,\n next_run: nextRun,\n };\n });\n }\n\n /**\n * Get a single job\n */\n async getJob(id: string): Promise<JobData | null> {\n return this.persistence.getJob(id);\n }\n\n /**\n * Update a job\n */\n async updateJob(id: string, updates: Partial<Omit<JobData, 'id' | 'created_at' | 'updated_at'>>): Promise<boolean> {\n // Validate updates\n const validationResult = UpdateJobRequestSchema.safeParse(updates);\n if (!validationResult.success) {\n const errorMsg = (validationResult as { error?: { errors: z.ZodIssue[] } }).error?.errors.map((e) => e.message).join(', ') || 'Unknown validation error';\n throw new Error(`Validation failed: ${errorMsg}`);\n }\n\n const job = await this.persistence.getJob(id);\n if (!job) return false;\n\n const validated = validationResult.data;\n const { agentId: agentIdPatch, workingDirectory: workingDirectoryPatch, ...rest } = validated;\n const patch: Partial<JobData> = { ...rest };\n let clearAgentId = false;\n if (agentIdPatch === null) {\n clearAgentId = true;\n } else if (agentIdPatch !== undefined) {\n patch.agentId = agentIdPatch;\n }\n\n let clearWorkingDirectory = false;\n if (workingDirectoryPatch === null) {\n clearWorkingDirectory = true;\n } else if (workingDirectoryPatch !== undefined) {\n patch.workingDirectory = workingDirectoryPatch;\n }\n\n // Cancel existing task if schedule changes\n if (patch.schedule && patch.schedule !== job.schedule) {\n this.cancelTask(id);\n }\n\n // Update persistence\n await this.persistence.updateJob(id, patch, { clearAgentId, clearWorkingDirectory });\n\n // Re-schedule if needed\n const updated = await this.persistence.getJob(id);\n if (updated && updated.enabled) {\n this.scheduleJob(updated);\n }\n\n log.info({ jobId: id }, 'Job updated');\n return true;\n }\n\n /**\n * Remove a job\n */\n async removeJob(id: string): Promise<boolean> {\n // Cancel task\n this.cancelTask(id);\n\n // Remove from persistence\n const removed = await this.persistence.removeJob(id);\n\n if (removed) {\n await this.runLogStore.deleteJobRuns(id);\n log.info({ jobId: id }, 'Job removed');\n }\n\n return removed;\n }\n\n /**\n * Toggle job enabled state\n */\n async toggleJob(id: string, enabled: boolean): Promise<boolean> {\n const job = await this.persistence.getJob(id);\n if (!job) return false;\n\n await this.persistence.updateJob(id, { enabled });\n\n if (enabled) {\n const updated = await this.persistence.getJob(id);\n if (updated) this.scheduleJob(updated);\n } else {\n this.cancelTask(id);\n }\n\n log.info({ jobId: id, enabled }, 'Job toggled');\n return true;\n }\n\n /**\n * Execution history for one job: merged in-memory (incl. running) + persisted SQLite rows.\n */\n async getJobHistory(jobId: string, limit?: number): Promise<JobExecution[]> {\n const cap = Math.min(Math.max(limit ?? 10, 1), 500);\n const [disk, memory] = await Promise.all([\n this.runLogStore.readJobHistory(jobId, cap * 2),\n Promise.resolve(this.executor.getHistory(jobId, cap * 2)),\n ]);\n const byId = new Map<string, JobExecution>();\n for (const e of memory) {\n byId.set(e.id, e);\n }\n for (const e of disk) {\n if (!byId.has(e.id)) {\n byId.set(e.id, e);\n }\n }\n const merged = [...byId.values()].sort(\n (a, b) => new Date(b.startedAt).getTime() - new Date(a.startedAt).getTime()\n );\n return merged.slice(0, cap);\n }\n\n /**\n * Latest runs across all jobs (persisted rows + optional job name).\n */\n async getAllRunsHistory(limit?: number): Promise<CronRunHistoryRow[]> {\n const cap = Math.min(Math.max(limit ?? 50, 1), 500);\n const jobs = await this.persistence.getJobs();\n const jobNames = new Map<string, string | undefined>(jobs.map((j) => [j.id, j.name] as const));\n return this.runLogStore.readAllRuns(cap, jobNames);\n }\n\n /**\n * Get service metrics\n */\n async getMetrics(): Promise<CronMetrics> {\n const jobs = await this.persistence.getJobs();\n const enabled = jobs.filter((j) => j.enabled);\n\n let nextScheduledJob: CronMetrics['nextScheduledJob'] | undefined;\n\n for (const job of enabled) {\n try {\n const options = job.timezone ? { tz: job.timezone } : undefined;\n const interval = CronExpressionParser.parse(job.schedule, options);\n const next = interval.next();\n\n if (!nextScheduledJob || next.getTime() < nextScheduledJob.runAt.getTime()) {\n nextScheduledJob = {\n id: job.id,\n name: job.name,\n runAt: next.toDate(),\n };\n }\n } catch {\n // Skip invalid schedules\n }\n }\n\n return {\n totalJobs: jobs.length,\n runningJobs: this.tasks.size,\n enabledJobs: enabled.length,\n failedLastHour: 0, // TODO: track from executor\n avgExecutionTime: 0, // TODO: track from executor\n nextScheduledJob,\n };\n }\n\n /**\n * Update config (hot reload)\n */\n updateConfig(_config: Config): void {\n log.debug('Cron config updated (jobs managed separately via addJob/removeJob)');\n }\n\n /**\n * Health check\n */\n async healthCheck(): Promise<CronHealth> {\n const issues: string[] = [];\n\n // Check if initialized\n if (!this.initialized) {\n issues.push('Service not initialized');\n }\n\n // Check for jobs with invalid schedules\n const jobs = await this.persistence.getJobs();\n for (const job of jobs) {\n if (!nodeCron.validate(job.schedule)) {\n issues.push(`Job ${job.id} has invalid schedule`);\n }\n }\n\n // Check if agent service is configured for isolated jobs\n for (const job of jobs) {\n if (job.enabled && job.sessionTarget === 'isolated' && !this.agentService) {\n issues.push(`Job ${job.id} requires agent service but none configured`);\n break;\n }\n }\n\n // Determine status\n let status: CronHealth['status'] = 'healthy';\n if (issues.length > 0) {\n status = issues.length > 5 ? 'unhealthy' : 'degraded';\n }\n\n return { status, issues };\n }\n\n /**\n * Run a job immediately (manual trigger)\n */\n async runJobNow(id: string): Promise<void> {\n const job = await this.persistence.getJob(id);\n if (!job) throw new Error(`Job not found: ${id}`);\n if (!job.enabled) throw new Error(`Job is disabled: ${id}`);\n\n await this.executeJob(job);\n }\n\n /**\n * Stop all jobs and cleanup\n */\n async stop(options?: { waitForRunning?: boolean; timeout?: number }): Promise<void> {\n const timeout = options?.timeout ?? 30000;\n\n // Cancel all scheduled tasks\n for (const [id, task] of this.tasks) {\n task.stop();\n\n // Cancel running executions\n this.executor.cancelJob(id);\n }\n this.tasks.clear();\n\n // Wait for running jobs if requested\n if (options?.waitForRunning) {\n const start = Date.now();\n while (Date.now() - start < timeout) {\n const running = this.executor.getRunningExecutions();\n if (running.length === 0) break;\n await new Promise((r) => setTimeout(r, 100));\n }\n }\n\n // Flush any pending writes\n await this.persistence.flush();\n\n log.info('CronService stopped');\n }\n\n /**\n * Load and schedule all enabled jobs\n */\n private async loadAllJobs(): Promise<void> {\n const jobs = await this.persistence.getJobs();\n\n for (const job of jobs) {\n if (job.enabled) {\n this.scheduleJob(job);\n }\n }\n\n log.debug({ count: this.tasks.size }, 'Jobs loaded');\n }\n\n /**\n * Schedule a job with node-cron\n */\n private scheduleJob(job: JobData): void {\n // Cancel existing if any\n this.cancelTask(job.id);\n\n // Validate schedule\n if (!nodeCron.validate(job.schedule)) {\n log.error({ jobId: job.id, schedule: job.schedule }, 'Invalid cron expression');\n return;\n }\n\n const options = job.timezone ? { timezone: job.timezone } : undefined;\n\n const task = nodeCron.schedule(\n job.schedule,\n async () => {\n await this.executeJob(job);\n },\n options\n );\n\n this.tasks.set(job.id, task);\n log.debug({ jobId: job.id, schedule: job.schedule }, 'Job scheduled');\n }\n\n /**\n * Execute a job with retry logic\n */\n private async executeJob(job: JobData): Promise<void> {\n // Prevent overlapping executions\n if (this.executor.isRunning(job.id)) {\n log.warn({ jobId: job.id }, 'Job already running, skipping');\n return;\n }\n\n const controller = new AbortController();\n\n try {\n await this.executor.execute(job, controller.signal);\n } catch (error) {\n log.error({ jobId: job.id, err: error as Error }, 'Job execution failed');\n // Retry logic can be added here based on error type\n }\n }\n\n /**\n * Cancel a scheduled task\n */\n private cancelTask(id: string): void {\n const task = this.tasks.get(id);\n if (task) {\n task.stop();\n this.tasks.delete(id);\n log.debug({ jobId: id }, 'Task cancelled');\n }\n }\n}\n"],"mappings":";;;;;;;;;;;YAKyD;aACP;AAiBlD,MAAM,MAAM,aAAa,cAAc;AAcvC,IAAa,cAAb,MAAyB;CACvB;CACA;CACA;CACA,wBAA4C,IAAI,KAAK;CACrD,cAAsB;CACtB,eAA4B;CAC5B,aAA0B;CAE1B,YAAY,QAA4B;EACtC,MAAM,WAAW,QAAQ,YAAY,qBAAqB;AAC1D,OAAK,cAAc,IAAI,gBAAgB,SAAS;AAChD,OAAK,WAAW,IAAI,oBAAoB;AACxC,OAAK,cAAc,IAAI,gBAAgB,QAAQ,OAAO;AACtD,OAAK,SAAS,eAAe,KAAK,YAAY;AAG9C,MAAI,QAAQ,gBAAgB,QAAQ,WAClC,MAAK,QAAQ;GACX,cAAc,OAAO;GACrB,YAAY,OAAO;GACpB,CAAC;;;;;CAON,QAAQ,MAA6B;AACnC,OAAK,eAAe,KAAK;AACzB,OAAK,aAAa,KAAK;AACvB,OAAK,SAAS,QAAQ,KAAK;AAC3B,MAAI,MAAM,+BAA+B;;;;;CAM3C,MAAM,aAA4B;AAChC,MAAI,KAAK,YAAa;AAEtB,QAAM,KAAK,YAAY,YAAY;AACnC,QAAM,KAAK,aAAa;AAExB,OAAK,cAAc;AACnB,MAAI,MAAM,0BAA0B;;;;;CAMtC,MAAM,OAAO,UAAkB,SAAmE;EAChG,MAAM,mBAAmB,oBAAoB,UAAU;GACrD;GACA,GAAG;GACJ,CAAC;AAEF,MAAI,CAAC,iBAAiB,SAAS;GAC7B,MAAM,WAAY,iBAA0D,OAAO,OAAO,KAAK,MAAM,EAAE,QAAQ,CAAC,KAAK,KAAK,IAAI;AAC9H,SAAM,IAAI,MAAM,sBAAsB,WAAW;;EAGnD,MAAM,OAAO,iBAAiB;EAC9B,MAAM,KAAKA,IAAQ,CAAC,MAAM,GAAG,EAAE;EAC/B,MAAM,uBAAM,IAAI,MAAM,EAAC,aAAa;EACpC,MAAM,gBAAgB,KAAK,iBAAiB;EAE5C,MAAM,MAAe;GACnB;GACA,MAAM,KAAK;GACX,UAAU,KAAK;GACf,SAAS;GACT,UAAU,KAAK;GACf,YAAY,KAAK,cAAc;GAC/B,SAAS,KAAK,WAAW;GACzB,YAAY;GACZ,YAAY;GACZ;GACA,GAAI,KAAK,UAAU,EAAE,SAAS,KAAK,SAAS,GAAG,EAAE;GACjD,GAAI,KAAK,mBAAmB,EAAE,kBAAkB,KAAK,kBAAkB,GAAG,EAAE;GAC5E,SAAS,KAAK;GACd,UAAU,KAAK;GACf,OAAO,KAAK;GACb;AAGD,QAAM,KAAK,YAAY,OAAO,IAAI;AAGlC,OAAK,YAAY,IAAI;AAErB,MAAI,KAAK;GAAE,OAAO;GAAI,MAAM,KAAK;GAAM;GAAe,EAAE,YAAY;AACpE,SAAO;GAAE;GAAI,UAAU,KAAK;GAAU;;;;;CAMxC,MAAM,WAAsC;AAG1C,UAAO,MAFY,KAAK,YAAY,SAAS,EAEjC,KAAK,QAAQ;GACvB,IAAI;AAEJ,OAAI,IAAI,QACN,KAAI;IACF,MAAM,UAAU,IAAI,WAAW,EAAE,IAAI,IAAI,UAAU,GAAG,KAAA;AAEtD,cADiB,qBAAqB,MAAM,IAAI,UAAU,QACxC,CAAC,MAAM,CAAC,aAAa;YAChC,KAAK;AACZ,QAAI,MAAM;KAAE,OAAO,IAAI;KAAS;KAAc,EAAE,oCAAoC;;AAIxF,UAAO;IACL,IAAI,IAAI;IACR,MAAM,IAAI;IACV,UAAU,IAAI;IACd,SAAS,IAAI;IACb,UAAU,IAAI;IACd,YAAY,IAAI;IAChB,SAAS,IAAI;IACb,eAAe,IAAI;IACnB,GAAI,IAAI,UAAU,EAAE,SAAS,IAAI,SAAS,GAAG,EAAE;IAC/C,GAAI,IAAI,mBAAmB,EAAE,kBAAkB,IAAI,kBAAkB,GAAG,EAAE;IAC1E,SAAS,IAAI;IACb,UAAU,IAAI;IACd,OAAO,IAAI;IACX,UAAU;IACX;IACD;;;;;CAMJ,MAAM,OAAO,IAAqC;AAChD,SAAO,KAAK,YAAY,OAAO,GAAG;;;;;CAMpC,MAAM,UAAU,IAAY,SAAuF;EAEjH,MAAM,mBAAmB,uBAAuB,UAAU,QAAQ;AAClE,MAAI,CAAC,iBAAiB,SAAS;GAC7B,MAAM,WAAY,iBAA0D,OAAO,OAAO,KAAK,MAAM,EAAE,QAAQ,CAAC,KAAK,KAAK,IAAI;AAC9H,SAAM,IAAI,MAAM,sBAAsB,WAAW;;EAGnD,MAAM,MAAM,MAAM,KAAK,YAAY,OAAO,GAAG;AAC7C,MAAI,CAAC,IAAK,QAAO;EAGjB,MAAM,EAAE,SAAS,cAAc,kBAAkB,uBAAuB,GAAG,SADzD,iBAAiB;EAEnC,MAAM,QAA0B,EAAE,GAAG,MAAM;EAC3C,IAAI,eAAe;AACnB,MAAI,iBAAiB,KACnB,gBAAe;WACN,iBAAiB,KAAA,EAC1B,OAAM,UAAU;EAGlB,IAAI,wBAAwB;AAC5B,MAAI,0BAA0B,KAC5B,yBAAwB;WACf,0BAA0B,KAAA,EACnC,OAAM,mBAAmB;AAI3B,MAAI,MAAM,YAAY,MAAM,aAAa,IAAI,SAC3C,MAAK,WAAW,GAAG;AAIrB,QAAM,KAAK,YAAY,UAAU,IAAI,OAAO;GAAE;GAAc;GAAuB,CAAC;EAGpF,MAAM,UAAU,MAAM,KAAK,YAAY,OAAO,GAAG;AACjD,MAAI,WAAW,QAAQ,QACrB,MAAK,YAAY,QAAQ;AAG3B,MAAI,KAAK,EAAE,OAAO,IAAI,EAAE,cAAc;AACtC,SAAO;;;;;CAMT,MAAM,UAAU,IAA8B;AAE5C,OAAK,WAAW,GAAG;EAGnB,MAAM,UAAU,MAAM,KAAK,YAAY,UAAU,GAAG;AAEpD,MAAI,SAAS;AACX,SAAM,KAAK,YAAY,cAAc,GAAG;AACxC,OAAI,KAAK,EAAE,OAAO,IAAI,EAAE,cAAc;;AAGxC,SAAO;;;;;CAMT,MAAM,UAAU,IAAY,SAAoC;AAE9D,MAAI,CAAC,MADa,KAAK,YAAY,OAAO,GAAG,CACnC,QAAO;AAEjB,QAAM,KAAK,YAAY,UAAU,IAAI,EAAE,SAAS,CAAC;AAEjD,MAAI,SAAS;GACX,MAAM,UAAU,MAAM,KAAK,YAAY,OAAO,GAAG;AACjD,OAAI,QAAS,MAAK,YAAY,QAAQ;QAEtC,MAAK,WAAW,GAAG;AAGrB,MAAI,KAAK;GAAE,OAAO;GAAI;GAAS,EAAE,cAAc;AAC/C,SAAO;;;;;CAMT,MAAM,cAAc,OAAe,OAAyC;EAC1E,MAAM,MAAM,KAAK,IAAI,KAAK,IAAI,SAAS,IAAI,EAAE,EAAE,IAAI;EACnD,MAAM,CAAC,MAAM,UAAU,MAAM,QAAQ,IAAI,CACvC,KAAK,YAAY,eAAe,OAAO,MAAM,EAAE,EAC/C,QAAQ,QAAQ,KAAK,SAAS,WAAW,OAAO,MAAM,EAAE,CAAC,CAC1D,CAAC;EACF,MAAM,uBAAO,IAAI,KAA2B;AAC5C,OAAK,MAAM,KAAK,OACd,MAAK,IAAI,EAAE,IAAI,EAAE;AAEnB,OAAK,MAAM,KAAK,KACd,KAAI,CAAC,KAAK,IAAI,EAAE,GAAG,CACjB,MAAK,IAAI,EAAE,IAAI,EAAE;AAMrB,SAHe,CAAC,GAAG,KAAK,QAAQ,CAAC,CAAC,MAC/B,GAAG,MAAM,IAAI,KAAK,EAAE,UAAU,CAAC,SAAS,GAAG,IAAI,KAAK,EAAE,UAAU,CAAC,SAAS,CAEhE,CAAC,MAAM,GAAG,IAAI;;;;;CAM7B,MAAM,kBAAkB,OAA8C;EACpE,MAAM,MAAM,KAAK,IAAI,KAAK,IAAI,SAAS,IAAI,EAAE,EAAE,IAAI;EACnD,MAAM,OAAO,MAAM,KAAK,YAAY,SAAS;EAC7C,MAAM,WAAW,IAAI,IAAgC,KAAK,KAAK,MAAM,CAAC,EAAE,IAAI,EAAE,KAAK,CAAU,CAAC;AAC9F,SAAO,KAAK,YAAY,YAAY,KAAK,SAAS;;;;;CAMpD,MAAM,aAAmC;EACvC,MAAM,OAAO,MAAM,KAAK,YAAY,SAAS;EAC7C,MAAM,UAAU,KAAK,QAAQ,MAAM,EAAE,QAAQ;EAE7C,IAAI;AAEJ,OAAK,MAAM,OAAO,QAChB,KAAI;GACF,MAAM,UAAU,IAAI,WAAW,EAAE,IAAI,IAAI,UAAU,GAAG,KAAA;GAEtD,MAAM,OADW,qBAAqB,MAAM,IAAI,UAAU,QACrC,CAAC,MAAM;AAE5B,OAAI,CAAC,oBAAoB,KAAK,SAAS,GAAG,iBAAiB,MAAM,SAAS,CACxE,oBAAmB;IACjB,IAAI,IAAI;IACR,MAAM,IAAI;IACV,OAAO,KAAK,QAAQ;IACrB;UAEG;AAKV,SAAO;GACL,WAAW,KAAK;GAChB,aAAa,KAAK,MAAM;GACxB,aAAa,QAAQ;GACrB,gBAAgB;GAChB,kBAAkB;GAClB;GACD;;;;;CAMH,aAAa,SAAuB;AAClC,MAAI,MAAM,qEAAqE;;;;;CAMjF,MAAM,cAAmC;EACvC,MAAM,SAAmB,EAAE;AAG3B,MAAI,CAAC,KAAK,YACR,QAAO,KAAK,0BAA0B;EAIxC,MAAM,OAAO,MAAM,KAAK,YAAY,SAAS;AAC7C,OAAK,MAAM,OAAO,KAChB,KAAI,CAAC,SAAS,SAAS,IAAI,SAAS,CAClC,QAAO,KAAK,OAAO,IAAI,GAAG,uBAAuB;AAKrD,OAAK,MAAM,OAAO,KAChB,KAAI,IAAI,WAAW,IAAI,kBAAkB,cAAc,CAAC,KAAK,cAAc;AACzE,UAAO,KAAK,OAAO,IAAI,GAAG,6CAA6C;AACvE;;EAKJ,IAAI,SAA+B;AACnC,MAAI,OAAO,SAAS,EAClB,UAAS,OAAO,SAAS,IAAI,cAAc;AAG7C,SAAO;GAAE;GAAQ;GAAQ;;;;;CAM3B,MAAM,UAAU,IAA2B;EACzC,MAAM,MAAM,MAAM,KAAK,YAAY,OAAO,GAAG;AAC7C,MAAI,CAAC,IAAK,OAAM,IAAI,MAAM,kBAAkB,KAAK;AACjD,MAAI,CAAC,IAAI,QAAS,OAAM,IAAI,MAAM,oBAAoB,KAAK;AAE3D,QAAM,KAAK,WAAW,IAAI;;;;;CAM5B,MAAM,KAAK,SAAyE;EAClF,MAAM,UAAU,SAAS,WAAW;AAGpC,OAAK,MAAM,CAAC,IAAI,SAAS,KAAK,OAAO;AACnC,QAAK,MAAM;AAGX,QAAK,SAAS,UAAU,GAAG;;AAE7B,OAAK,MAAM,OAAO;AAGlB,MAAI,SAAS,gBAAgB;GAC3B,MAAM,QAAQ,KAAK,KAAK;AACxB,UAAO,KAAK,KAAK,GAAG,QAAQ,SAAS;AAEnC,QADgB,KAAK,SAAS,sBACnB,CAAC,WAAW,EAAG;AAC1B,UAAM,IAAI,SAAS,MAAM,WAAW,GAAG,IAAI,CAAC;;;AAKhD,QAAM,KAAK,YAAY,OAAO;AAE9B,MAAI,KAAK,sBAAsB;;;;;CAMjC,MAAc,cAA6B;EACzC,MAAM,OAAO,MAAM,KAAK,YAAY,SAAS;AAE7C,OAAK,MAAM,OAAO,KAChB,KAAI,IAAI,QACN,MAAK,YAAY,IAAI;AAIzB,MAAI,MAAM,EAAE,OAAO,KAAK,MAAM,MAAM,EAAE,cAAc;;;;;CAMtD,YAAoB,KAAoB;AAEtC,OAAK,WAAW,IAAI,GAAG;AAGvB,MAAI,CAAC,SAAS,SAAS,IAAI,SAAS,EAAE;AACpC,OAAI,MAAM;IAAE,OAAO,IAAI;IAAI,UAAU,IAAI;IAAU,EAAE,0BAA0B;AAC/E;;EAGF,MAAM,UAAU,IAAI,WAAW,EAAE,UAAU,IAAI,UAAU,GAAG,KAAA;EAE5D,MAAM,OAAO,SAAS,SACpB,IAAI,UACJ,YAAY;AACV,SAAM,KAAK,WAAW,IAAI;KAE5B,QACD;AAED,OAAK,MAAM,IAAI,IAAI,IAAI,KAAK;AAC5B,MAAI,MAAM;GAAE,OAAO,IAAI;GAAI,UAAU,IAAI;GAAU,EAAE,gBAAgB;;;;;CAMvE,MAAc,WAAW,KAA6B;AAEpD,MAAI,KAAK,SAAS,UAAU,IAAI,GAAG,EAAE;AACnC,OAAI,KAAK,EAAE,OAAO,IAAI,IAAI,EAAE,gCAAgC;AAC5D;;EAGF,MAAM,aAAa,IAAI,iBAAiB;AAExC,MAAI;AACF,SAAM,KAAK,SAAS,QAAQ,KAAK,WAAW,OAAO;WAC5C,OAAO;AACd,OAAI,MAAM;IAAE,OAAO,IAAI;IAAI,KAAK;IAAgB,EAAE,uBAAuB;;;;;;CAQ7E,WAAmB,IAAkB;EACnC,MAAM,OAAO,KAAK,MAAM,IAAI,GAAG;AAC/B,MAAI,MAAM;AACR,QAAK,MAAM;AACX,QAAK,MAAM,OAAO,GAAG;AACrB,OAAI,MAAM,EAAE,OAAO,IAAI,EAAE,iBAAiB"}
1
+ {"version":3,"file":"service.js","names":[],"sources":["../../../src/cron/service.ts"],"sourcesContent":["import { randomUUID } from 'node:crypto';\n\nimport { createLogger } from '../utils/logger.js';\nimport type { Config } from '../config/schema.js';\nimport { DEFAULT_AGENT_ID, normalizeAgentId } from '../agent/agent-scope.js';\nimport { buildSessionKey } from '../routing/session-key.js';\nimport {\n deleteCronJob,\n getCronJob,\n listCronJobs,\n saveCronJob,\n saveCronJobs,\n} from '../storage/sqlite/index.js';\nimport { DefaultJobExecutor } from './executor.js';\nimport { CronRunLogStore } from './run-log-store.js';\nimport {\n computeNextRunAtMs,\n describeSchedule,\n timerDelayUntil,\n} from './schedule.js';\nimport type {\n AddJobOptions,\n CronHealth,\n CronJobCreate,\n CronJobPatch,\n CronMetrics,\n CronRunHistoryRow,\n JobData,\n JobExecution,\n JobExecutorDeps,\n} from './types.js';\nimport {\n AddJobRequestSchema,\n JobDataSchema,\n UpdateJobRequestSchema,\n} from './validation.js';\n\nconst log = createLogger('CronService');\n\nexport interface CronServiceConfig {\n dbPath?: string;\n agentService?: unknown;\n messageBus?: unknown;\n maxConcurrentJobs?: number;\n missedJobStaggerMs?: number;\n}\n\ntype TimerHandle = ReturnType<typeof setTimeout> & { unref?: () => void };\n\nconst DEFAULT_MAX_CONCURRENT_JOBS = 5;\nconst DEFAULT_MISSED_JOB_STAGGER_MS = 5_000;\n\nexport class CronJobAlreadyRunningError extends Error {\n readonly jobId: string;\n readonly runningSessionKey?: string;\n\n constructor(jobId: string, runningSessionKey?: string) {\n super(`Job is already running: ${jobId}`);\n this.name = 'CronJobAlreadyRunningError';\n this.jobId = jobId;\n this.runningSessionKey = runningSessionKey;\n }\n}\n\nexport interface CronJobRunNowResult {\n job: JobData;\n history: JobExecution[];\n}\n\nfunction nowMs(): number {\n return Date.now();\n}\n\nfunction runStatusFromExecution(status: JobExecution['status']): 'ok' | 'error' | 'skipped' {\n if (status === 'success') return 'ok';\n if (status === 'cancelled' || status === 'skipped') return 'skipped';\n return 'error';\n}\n\nasync function postFailureWebhook(url: string, payload: unknown): Promise<void> {\n const res = await fetch(url, {\n method: 'POST',\n headers: { 'content-type': 'application/json' },\n body: JSON.stringify(payload),\n });\n if (!res.ok) {\n const text = await res.text().catch(() => '');\n throw new Error(`Cron failure webhook failed: HTTP ${res.status}${text ? ` ${text.slice(0, 200)}` : ''}`);\n }\n}\n\nfunction inferJobName(input: Pick<CronJobCreate, 'name' | 'payload' | 'schedule'>): string {\n if (input.name?.trim()) return input.name.trim();\n if (input.payload.kind === 'agentTurn') return input.payload.message.slice(0, 60) || 'Agent task';\n if (input.payload.kind === 'systemEvent') return input.payload.text.slice(0, 60) || 'System event';\n if (input.payload.kind === 'workflowRun') return `Workflow ${input.payload.definitionId}`;\n if (input.payload.kind === 'goalContinue') return `Goal ${input.payload.goalId}`;\n return describeSchedule(input.schedule);\n}\n\nfunction resolveRunningSessionKey(job: JobData, deps: JobExecutorDeps): string | undefined {\n if (job.payload.kind !== 'agentTurn') return undefined;\n if (job.sessionTarget.startsWith('session:')) {\n return job.sessionTarget.slice('session:'.length).trim() || undefined;\n }\n if (job.sessionTarget === 'current') {\n return job.sessionKey?.trim() || undefined;\n }\n if (job.sessionTarget !== 'isolated') {\n return undefined;\n }\n const aid = job.agentId?.trim();\n const fallbackAgentId = deps.getDefaultCronAgentId?.() ?? DEFAULT_AGENT_ID;\n return buildSessionKey({\n agentId: normalizeAgentId(aid || fallbackAgentId),\n source: 'cron',\n accountId: 'default',\n peerKind: 'dm',\n peerId: `${job.id}-${randomUUID().slice(0, 8)}`,\n });\n}\n\nexport class CronService {\n private executor = new DefaultJobExecutor();\n private runLogStore: CronRunLogStore;\n private initialized = false;\n private stopped = false;\n private running = false;\n private timer: TimerHandle | null = null;\n private deps: JobExecutorDeps = {};\n private maxConcurrentJobs: number;\n private missedJobStaggerMs: number;\n\n constructor(config?: CronServiceConfig) {\n this.runLogStore = new CronRunLogStore(config?.dbPath);\n this.executor.setRunLogStore(this.runLogStore);\n this.maxConcurrentJobs = Math.max(1, Math.floor(config?.maxConcurrentJobs ?? DEFAULT_MAX_CONCURRENT_JOBS));\n this.missedJobStaggerMs = Math.max(0, Math.floor(config?.missedJobStaggerMs ?? DEFAULT_MISSED_JOB_STAGGER_MS));\n if (config?.agentService || config?.messageBus) {\n this.setDeps({ agentService: config.agentService, messageBus: config.messageBus });\n }\n }\n\n setDeps(deps: JobExecutorDeps): void {\n this.deps = { ...this.deps, ...deps };\n this.executor.setDeps(this.deps);\n log.debug('CronService dependencies set');\n }\n\n async initialize(): Promise<void> {\n if (this.initialized) return;\n this.stopped = false;\n await this.recomputeAllNextRuns({ catchUp: true });\n this.initialized = true;\n this.armTimer();\n log.info('CronService initialized');\n }\n\n async addJob(scheduleOrInput: AddJobOptions['schedule'], options?: Omit<AddJobOptions, 'schedule'>): Promise<{ id: string; schedule: AddJobOptions['schedule'] }> {\n const raw = options ? { ...options, schedule: scheduleOrInput } : scheduleOrInput;\n const parsed = AddJobRequestSchema.parse(raw) as AddJobOptions;\n const ts = nowMs();\n const id = parsed.id?.trim() || randomUUID().slice(0, 12);\n const job = JobDataSchema.parse({\n ...parsed,\n id,\n name: inferJobName(parsed),\n enabled: parsed.enabled ?? true,\n deleteAfterRun: parsed.deleteAfterRun ?? parsed.schedule.kind === 'at',\n createdAtMs: ts,\n updatedAtMs: ts,\n sessionTarget: parsed.sessionTarget ?? (parsed.payload.kind === 'systemEvent' ? 'main' : 'isolated'),\n wakeMode: parsed.wakeMode ?? 'now',\n state: {\n ...(parsed.state ?? {}),\n },\n }) as JobData;\n job.state.nextRunAtMs = computeNextRunAtMs(job, ts);\n saveCronJob(job);\n this.armTimer();\n log.info({ jobId: job.id, name: job.name, schedule: job.schedule }, 'Cron job added');\n return { id: job.id, schedule: job.schedule };\n }\n\n async listJobs(): Promise<JobData[]> {\n return listCronJobs();\n }\n\n async getJob(id: string): Promise<JobData | null> {\n return getCronJob(id);\n }\n\n async updateJob(id: string, updates: CronJobPatch): Promise<boolean> {\n const parsed = UpdateJobRequestSchema.parse(updates) as CronJobPatch;\n const current = getCronJob(id);\n if (!current) return false;\n const ts = nowMs();\n const next = JobDataSchema.parse({\n ...current,\n ...parsed,\n id: current.id,\n createdAtMs: current.createdAtMs,\n updatedAtMs: ts,\n state: {\n ...current.state,\n ...(parsed.state ?? {}),\n },\n }) as JobData;\n if ('schedule' in parsed || 'enabled' in parsed) {\n next.state.nextRunAtMs = computeNextRunAtMs(next, ts);\n delete next.state.runningAtMs;\n }\n if ('agentId' in updates && updates.agentId?.trim() === '') {\n delete next.agentId;\n }\n if ('workingDirectory' in updates && updates.workingDirectory?.trim() === '') {\n delete next.workingDirectory;\n }\n saveCronJob(next);\n this.armTimer();\n log.info({ jobId: id }, 'Cron job updated');\n return true;\n }\n\n async removeJob(id: string): Promise<boolean> {\n const removed = deleteCronJob(id);\n if (removed) {\n this.executor.cancelJob(id);\n await this.runLogStore.deleteJobRuns(id);\n this.armTimer();\n log.info({ jobId: id }, 'Cron job removed');\n }\n return removed;\n }\n\n async toggleJob(id: string, enabled: boolean): Promise<boolean> {\n return this.updateJob(id, { enabled });\n }\n\n async getJobHistory(jobId: string, limit?: number): Promise<JobExecution[]> {\n return this.runLogStore.readJobHistory(jobId, Math.min(Math.max(limit ?? 10, 1), 500));\n }\n\n async getAllRunsHistory(limit?: number): Promise<CronRunHistoryRow[]> {\n const cap = Math.min(Math.max(limit ?? 50, 1), 500);\n const jobs = listCronJobs();\n const names = new Map(jobs.map((job) => [job.id, job.name] as const));\n return this.runLogStore.readAllRuns(cap, names);\n }\n\n async getMetrics(): Promise<CronMetrics> {\n const jobs = listCronJobs();\n const enabled = jobs.filter((job) => job.enabled);\n const next = enabled\n .filter((job) => job.state.nextRunAtMs != null)\n .toSorted((a, b) => (a.state.nextRunAtMs ?? 0) - (b.state.nextRunAtMs ?? 0))[0];\n return {\n totalJobs: jobs.length,\n runningJobs: jobs.filter((job) => job.state.runningAtMs != null).length,\n enabledJobs: enabled.length,\n failedLastHour: jobs.filter(\n (job) => job.state.lastRunStatus === 'error' && (job.state.lastRunAtMs ?? 0) >= nowMs() - 60 * 60_000,\n ).length,\n avgExecutionTime: 0,\n nextScheduledJob: next?.state.nextRunAtMs\n ? { id: next.id, name: next.name, runAt: new Date(next.state.nextRunAtMs) }\n : undefined,\n };\n }\n\n updateConfig(config: Config): void {\n this.maxConcurrentJobs = Math.max(1, Math.floor(config.cron?.maxConcurrentJobs ?? DEFAULT_MAX_CONCURRENT_JOBS));\n this.armTimer();\n }\n\n async healthCheck(): Promise<CronHealth> {\n const issues: string[] = [];\n if (!this.initialized) issues.push('Service not initialized');\n for (const job of listCronJobs()) {\n const parsed = JobDataSchema.safeParse(job);\n if (!parsed.success) issues.push(`Job ${job.id} is invalid`);\n if (job.enabled && job.state.nextRunAtMs == null && job.schedule.kind !== 'at') {\n issues.push(`Job ${job.id} has no next run`);\n }\n }\n return {\n status: issues.length === 0 ? 'healthy' : issues.length > 5 ? 'unhealthy' : 'degraded',\n issues,\n };\n }\n\n async runJobNow(id: string): Promise<CronJobRunNowResult> {\n const job = getCronJob(id);\n if (!job) throw new Error(`Job not found: ${id}`);\n if (job.state.runningAtMs != null) {\n throw new CronJobAlreadyRunningError(id, job.state.runningSessionKey);\n }\n const started = this.startSingleJob(job, { manual: true });\n return { job: started, history: await this.getJobHistory(id, 20) };\n }\n\n async stop(options?: { waitForRunning?: boolean; timeout?: number }): Promise<void> {\n this.stopped = true;\n if (this.timer) {\n clearTimeout(this.timer);\n this.timer = null;\n }\n for (const job of listCronJobs()) {\n this.executor.cancelJob(job.id);\n }\n if (options?.waitForRunning) {\n const started = nowMs();\n const timeout = options.timeout ?? 30_000;\n while (nowMs() - started < timeout) {\n if (listCronJobs().every((job) => job.state.runningAtMs == null)) break;\n await new Promise((resolve) => setTimeout(resolve, 100));\n }\n }\n log.info('CronService stopped');\n }\n\n private async recomputeAllNextRuns(opts?: { catchUp?: boolean }): Promise<void> {\n const ts = nowMs();\n const jobs = listCronJobs().map((job, index) => {\n const next = { ...job, state: { ...job.state } };\n if (next.state.runningAtMs != null) {\n next.state.lastRunStatus = 'error';\n next.state.lastError = 'Interrupted by gateway restart';\n next.state.consecutiveErrors = (next.state.consecutiveErrors ?? 0) + 1;\n delete next.state.runningAtMs;\n }\n if (next.enabled) {\n const existingNext = next.state.nextRunAtMs;\n if (opts?.catchUp && existingNext != null && existingNext <= ts) {\n next.state.nextRunAtMs = ts + index * this.missedJobStaggerMs;\n } else {\n next.state.nextRunAtMs = computeNextRunAtMs(next, ts);\n }\n } else {\n next.state.nextRunAtMs = undefined;\n }\n return next;\n });\n saveCronJobs(jobs);\n }\n\n private armTimer(): void {\n if (this.stopped) return;\n if (this.timer) {\n clearTimeout(this.timer);\n this.timer = null;\n }\n const next = listCronJobs()\n .filter((job) => job.enabled && job.state.nextRunAtMs != null)\n .toSorted((a, b) => (a.state.nextRunAtMs ?? 0) - (b.state.nextRunAtMs ?? 0))[0];\n if (!next?.state.nextRunAtMs) return;\n this.timer = setTimeout(() => {\n void this.onTimer();\n }, timerDelayUntil(next.state.nextRunAtMs)) as TimerHandle;\n this.timer.unref?.();\n }\n\n private async onTimer(): Promise<void> {\n if (this.stopped) return;\n if (this.running) {\n this.armTimer();\n return;\n }\n this.running = true;\n try {\n const ts = nowMs();\n const jobs = listCronJobs();\n const due = jobs\n .filter((job) => job.enabled && job.state.nextRunAtMs != null && job.state.nextRunAtMs <= ts && job.state.runningAtMs == null)\n .slice(0, this.maxConcurrentJobs);\n if (due.length === 0) return;\n const reserved = due.map((job) => ({\n ...job,\n state: { ...job.state, runningAtMs: ts },\n }));\n saveCronJobs(reserved);\n await Promise.all(reserved.map((job) => this.runSingleJob(job)));\n } finally {\n this.running = false;\n this.armTimer();\n }\n }\n\n private startSingleJob(job: JobData, opts?: { manual?: boolean }): JobData {\n const started = nowMs();\n const runningSessionKey = resolveRunningSessionKey(job, this.deps);\n const reserved: JobData = {\n ...job,\n state: { ...job.state, runningAtMs: started, ...(runningSessionKey ? { runningSessionKey } : {}) },\n };\n saveCronJob(reserved);\n void this.runReservedJob(reserved, started, runningSessionKey, opts).catch((err) => {\n log.error({ err, jobId: job.id }, `Background cron job failed: ${err instanceof Error ? err.message : String(err)}`);\n });\n return reserved;\n }\n\n private async runSingleJob(job: JobData, opts?: { manual?: boolean }): Promise<void> {\n const started = nowMs();\n const runningSessionKey = resolveRunningSessionKey(job, this.deps);\n const reserved: JobData = {\n ...job,\n state: { ...job.state, runningAtMs: started, ...(runningSessionKey ? { runningSessionKey } : {}) },\n };\n saveCronJob(reserved);\n await this.runReservedJob(reserved, started, runningSessionKey, opts);\n }\n\n private async runReservedJob(\n reserved: JobData,\n started: number,\n runningSessionKey: string | undefined,\n opts?: { manual?: boolean },\n ): Promise<void> {\n const controller = new AbortController();\n await this.executor.execute(\n runningSessionKey ? { ...reserved, sessionKey: runningSessionKey } : reserved,\n controller.signal,\n this.deps,\n );\n const latestRun = (await this.getJobHistory(reserved.id, 1))[0];\n const finished = nowMs();\n const status = latestRun ? runStatusFromExecution(latestRun.status) : 'error';\n const latest = getCronJob(reserved.id);\n if (!latest) return;\n\n const next: JobData = {\n ...latest,\n state: {\n ...latest.state,\n lastRunAtMs: finished,\n lastRunStatus: status,\n lastError: latestRun?.error,\n lastDurationMs: finished - started,\n consecutiveErrors: status === 'error' ? (latest.state.consecutiveErrors ?? 0) + 1 : 0,\n consecutiveSkipped: status === 'skipped' ? (latest.state.consecutiveSkipped ?? 0) + 1 : 0,\n lastDeliveryStatus: latest.delivery?.mode && latest.delivery.mode !== 'none' ? 'unknown' : 'not-requested',\n },\n };\n delete next.state.runningAtMs;\n delete next.state.runningSessionKey;\n if (!opts?.manual && next.deleteAfterRun && status === 'ok') {\n await this.removeJob(next.id);\n return;\n }\n next.state.nextRunAtMs = computeNextRunAtMs(next, finished);\n saveCronJob(next);\n await this.maybeEmitFailureAlert(next);\n }\n\n private async maybeEmitFailureAlert(job: JobData): Promise<void> {\n if (!job.failureAlert) return;\n if (job.state.lastRunStatus !== 'error') return;\n const threshold = job.failureAlert.after ?? 1;\n if ((job.state.consecutiveErrors ?? 0) < threshold) return;\n const ts = nowMs();\n const cooldownMs = job.failureAlert.cooldownMs ?? 60 * 60_000;\n if (job.state.lastFailureAlertAtMs && ts - job.state.lastFailureAlertAtMs < cooldownMs) return;\n const channel = job.failureAlert.channel || job.delivery?.channel;\n const to = job.failureAlert.to || job.delivery?.to;\n if (!to) return;\n if (job.failureAlert.mode === 'webhook') {\n await postFailureWebhook(to, {\n jobId: job.id,\n jobName: job.name,\n status: job.state.lastRunStatus,\n error: job.state.lastError ?? 'Unknown error',\n consecutiveErrors: job.state.consecutiveErrors ?? 0,\n lastRunAtMs: job.state.lastRunAtMs,\n });\n job.state.lastFailureAlertAtMs = ts;\n saveCronJob(job);\n return;\n }\n if (!this.deps.messageBus || !channel) return;\n await this.deps.messageBus.publishOutbound({\n channel,\n chat_id: to,\n type: 'message',\n content: `Cron job failed: ${job.name}\\n${job.state.lastError ?? 'Unknown error'}`,\n });\n job.state.lastFailureAlertAtMs = ts;\n saveCronJob(job);\n }\n}\n"],"mappings":"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"}
@@ -1,13 +1,40 @@
1
- import type { SessionStore } from '../session/store.js';
1
+ import type { SessionListReader } from '../session/store-reader.js';
2
2
  import type { WorkflowRunInputEnvelope, WorkflowRunSource, WorkflowRunView } from '../workflows/domain/index.js';
3
3
  import type { StartWorkflowRunServiceParams, WorkflowRunServiceResult } from '../workflows/service/workflow-run-service.types.js';
4
4
  export type { CronRunHistoryRow, CronRunOutcome, CronRunStatus, CronUsageSummary, JobExecution, } from './execution-types.js';
5
- export type CronDeliveryMode = 'none' | 'announce' | 'direct';
5
+ export type CronSchedule = {
6
+ kind: 'at';
7
+ at: string;
8
+ } | {
9
+ kind: 'every';
10
+ everyMs: number;
11
+ anchorMs?: number;
12
+ } | {
13
+ kind: 'cron';
14
+ expr: string;
15
+ tz?: string;
16
+ staggerMs?: number;
17
+ };
18
+ export type CronSessionTarget = 'main' | 'isolated' | 'current' | `session:${string}`;
19
+ export type CronWakeMode = 'now' | 'next-heartbeat';
20
+ export type CronDeliveryMode = 'none' | 'announce' | 'webhook';
6
21
  export interface CronDelivery {
7
22
  mode: CronDeliveryMode;
8
23
  channel?: string;
9
24
  to?: string;
25
+ accountId?: string;
26
+ threadId?: string | number;
10
27
  bestEffort?: boolean;
28
+ completionDestination?: {
29
+ mode: 'webhook';
30
+ to: string;
31
+ };
32
+ failureDestination?: {
33
+ mode?: 'announce' | 'webhook';
34
+ channel?: string;
35
+ to?: string;
36
+ accountId?: string;
37
+ };
11
38
  }
12
39
  export type CronPayload = {
13
40
  kind: 'systemEvent';
@@ -16,6 +43,8 @@ export type CronPayload = {
16
43
  kind: 'agentTurn';
17
44
  message: string;
18
45
  model?: string;
46
+ thinking?: string;
47
+ toolsAllow?: string[];
19
48
  timeoutSeconds?: number;
20
49
  } | CronGoalContinuePayload | CronWorkflowRunPayload;
21
50
  export interface CronGoalContinuePayload {
@@ -32,46 +61,67 @@ export interface CronWorkflowRunPayload {
32
61
  goal?: string;
33
62
  agentId?: string;
34
63
  sessionKey?: string;
35
- /** When true (default), cron waits for terminal workflow status before marking the job result. */
64
+ maxRetries?: number;
36
65
  waitForCompletion?: boolean;
37
66
  source?: Partial<Extract<WorkflowRunSource, {
38
67
  kind: 'cron';
39
68
  }>>;
40
69
  }
41
- export type CronSessionTarget = 'main' | 'isolated';
42
- export interface JobData {
43
- id: string;
44
- name?: string;
45
- schedule: string;
46
- enabled: boolean;
47
- timezone?: string;
48
- maxRetries: number;
49
- timeout: number;
50
- created_at: string;
51
- updated_at: string;
52
- sessionTarget?: CronSessionTarget;
53
- /** When set, isolated agent runs use this agent id in the session key (multi-agent). */
54
- agentId?: string;
55
- /**
56
- * Optional absolute workspace root for isolated agent runs (same semantics as chat working directory).
57
- * Omit to use the effective agent profile default workspace.
58
- */
59
- workingDirectory?: string;
60
- payload: CronPayload;
61
- delivery?: CronDelivery;
62
- model?: string;
63
- state?: JobState;
70
+ export type CronRunStatusValue = 'ok' | 'error' | 'skipped';
71
+ export type CronDeliveryStatus = 'delivered' | 'not-delivered' | 'unknown' | 'not-requested';
72
+ export interface CronFailureAlert {
73
+ after?: number;
74
+ cooldownMs?: number;
75
+ includeSkipped?: boolean;
76
+ mode?: 'announce' | 'webhook';
77
+ channel?: string;
78
+ to?: string;
79
+ accountId?: string;
64
80
  }
65
81
  export interface JobState {
66
82
  nextRunAtMs?: number;
67
83
  runningAtMs?: number;
84
+ runningSessionKey?: string;
68
85
  lastRunAtMs?: number;
69
- lastStatus?: 'ok' | 'error' | 'skipped';
86
+ lastRunStatus?: CronRunStatusValue;
70
87
  lastError?: string;
71
88
  lastDurationMs?: number;
72
89
  consecutiveErrors?: number;
73
- scheduleErrorCount?: number;
90
+ consecutiveSkipped?: number;
91
+ lastDeliveryStatus?: CronDeliveryStatus;
92
+ lastDeliveryError?: string;
93
+ lastFailureAlertAtMs?: number;
94
+ }
95
+ export interface JobData {
96
+ id: string;
97
+ name: string;
98
+ description?: string;
99
+ enabled: boolean;
100
+ deleteAfterRun?: boolean;
101
+ createdAtMs: number;
102
+ updatedAtMs: number;
103
+ schedule: CronSchedule;
104
+ sessionTarget: CronSessionTarget;
105
+ wakeMode: CronWakeMode;
106
+ agentId?: string;
107
+ sessionKey?: string;
108
+ workingDirectory?: string;
109
+ payload: CronPayload;
110
+ delivery?: CronDelivery;
111
+ failureAlert?: CronFailureAlert | false;
112
+ state: JobState;
74
113
  }
114
+ export type CronJobCreate = Omit<JobData, 'id' | 'createdAtMs' | 'updatedAtMs' | 'state' | 'enabled' | 'sessionTarget' | 'wakeMode' | 'name'> & {
115
+ id?: string;
116
+ name?: string;
117
+ enabled?: boolean;
118
+ sessionTarget?: CronSessionTarget;
119
+ wakeMode?: CronWakeMode;
120
+ state?: Partial<JobState>;
121
+ };
122
+ export type CronJobPatch = Partial<Omit<JobData, 'id' | 'createdAtMs' | 'updatedAtMs' | 'state'>> & {
123
+ state?: Partial<JobState>;
124
+ };
75
125
  export interface CronWorkflowRunStarter {
76
126
  startWorkflowRun(params: StartWorkflowRunServiceParams): Promise<WorkflowRunServiceResult>;
77
127
  readWorkflowRunView?(agentId: string, runId: string): Promise<WorkflowRunView | null>;
@@ -80,7 +130,6 @@ export interface CronWorkflowRunStarter {
80
130
  runId: string;
81
131
  }): Promise<WorkflowRunServiceResult>;
82
132
  }
83
- /** Optional hook after a successful cron run (e.g. wake gateway heartbeat). */
84
133
  export interface HeartbeatWakeSink {
85
134
  requestNow(opts?: {
86
135
  reason?: string;
@@ -90,12 +139,7 @@ export interface JobExecutorDeps {
90
139
  agentService?: any;
91
140
  messageBus?: any;
92
141
  heartbeatService?: HeartbeatWakeSink;
93
- /** When set, weixin cron `delivery.to` may be a bare ilink user id; accountId is inferred from sessions. */
94
- sessionStore?: SessionStore;
95
- /**
96
- * When a job has no `agentId`, isolated cron runs use this id for the session key
97
- * (same as {@link JobData.agentId} set to the default agent). Typically `getDefaultAgentId(config)`.
98
- */
142
+ sessionStore?: SessionListReader;
99
143
  getDefaultCronAgentId?: () => string;
100
144
  workflowRunService?: CronWorkflowRunStarter;
101
145
  goalRunner?: {
@@ -131,21 +175,7 @@ export interface CronHealth {
131
175
  issues: string[];
132
176
  lastError?: string;
133
177
  }
134
- export interface AddJobOptions {
135
- name?: string;
136
- timezone?: string;
137
- maxRetries?: number;
138
- timeout?: number;
139
- sessionTarget?: CronSessionTarget;
140
- agentId?: string;
141
- workingDirectory?: string;
142
- payload: CronPayload;
143
- delivery?: CronDelivery;
144
- model?: string;
145
- }
146
- export interface JobWithNextRun extends Omit<JobData, 'created_at' | 'updated_at' | 'state'> {
147
- next_run?: string;
148
- }
178
+ export type AddJobOptions = CronJobCreate;
149
179
  export interface JobHistoryQuery {
150
180
  jobId: string;
151
181
  limit?: number;