@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
@@ -6,8 +6,8 @@ import { parseNoteMarkdown } from "./note-markdown.js";
6
6
  import { NotesStore } from "./store.js";
7
7
  import { partitionAttachmentsByReference } from "./note-attachment-sync.js";
8
8
  import { buildNoteAgentContextArtifact, getCachedNoteAgentContextArtifact } from "./agent-context.js";
9
- import { randomUUID } from "node:crypto";
10
9
  import { complete } from "@earendil-works/pi-ai";
10
+ import { randomUUID } from "node:crypto";
11
11
  //#region src/notes/service.ts
12
12
  init_providers();
13
13
  init_logger();
@@ -1,15 +1,15 @@
1
+ import { init_write_file_atomic, writeTextAtomic } from "../infra/write-file-atomic.js";
1
2
  import { createLogger } from "../utils/logger/index.js";
2
3
  import { init_logger } from "../utils/logger.js";
3
- import { init_write_file_atomic, writeTextAtomic } from "../infra/write-file-atomic.js";
4
4
  import { requireXopcDatabase } from "../storage/sqlite/connection.js";
5
5
  import { buildNoteIndexMeta } from "./note-index-meta.js";
6
6
  import { deleteNoteRecord, getNoteRecord, listNoteRecords, upsertNoteRecord } from "../storage/sqlite/notes-repository.js";
7
7
  import { deleteNoteAgentContextRecord } from "../storage/sqlite/note-agent-context-repository.js";
8
8
  import "../storage/sqlite/index.js";
9
9
  import { resolveNoteHistoryDir, resolveNoteMediaDir } from "./paths.js";
10
- import { join } from "node:path";
11
10
  import { randomUUID } from "node:crypto";
12
11
  import { mkdir, readFile, readdir, rm, writeFile } from "node:fs/promises";
12
+ import { join } from "node:path";
13
13
  //#region src/notes/store.ts
14
14
  init_write_file_atomic();
15
15
  init_logger();
@@ -1,8 +1,8 @@
1
1
  import { resolveStateDir } from "../config/paths-state.js";
2
2
  import { init_paths } from "../config/paths.js";
3
- import { homedir } from "node:os";
4
- import { dirname, join, resolve } from "node:path";
5
3
  import { existsSync, mkdirSync, readFileSync, realpathSync, writeFileSync } from "node:fs";
4
+ import { dirname, join, resolve } from "node:path";
5
+ import { homedir } from "node:os";
6
6
  import lockfile from "proper-lockfile";
7
7
  //#region src/project-trust/trust-store.ts
8
8
  init_paths();
@@ -1,7 +1,7 @@
1
1
  import { createLogger } from "../../utils/logger/index.js";
2
2
  import { init_logger } from "../../utils/logger.js";
3
- import { dirname, join } from "node:path";
4
3
  import { existsSync, mkdirSync, readFileSync, renameSync, writeFileSync } from "node:fs";
4
+ import { dirname, join } from "node:path";
5
5
  //#region src/providers/auth-runtime/auth-profile-store.ts
6
6
  /**
7
7
  * {@link AuthProfileStore} implementations.
@@ -1,8 +1,8 @@
1
1
  import { __esmMin, __exportAll } from "../../_virtual/_rolldown/runtime.js";
2
- import { hasProviderAuthOnDiskSync, init_sync_provider_auth } from "../auth/sync-provider-auth.js";
3
2
  import { PROVIDER_ENV_MAP, getApiKeyFromEnv, init_env_keys } from "./env-keys.js";
4
3
  import { ModelRegistry, getModelRegistry, init_model_registry, prewarmModelRegistry, resetModelRegistry } from "./model-registry.js";
5
4
  import { CredentialResolver, hasCredentials, init_credentials, resolveApiKey } from "../auth/credentials.js";
5
+ import { hasProviderAuthOnDiskSync, init_sync_provider_auth } from "../auth/sync-provider-auth.js";
6
6
  import { getProviderRegistry, init_plugin_registry } from "./plugin-registry.js";
7
7
  import { getModel, getModels, getProviders } from "@earendil-works/pi-ai";
8
8
  //#region src/providers/index.ts
@@ -1,12 +1,12 @@
1
1
  import { __esmMin } from "../../_virtual/_rolldown/runtime.js";
2
- import { createLogger } from "../utils/logger/index.js";
3
- import { init_logger } from "../utils/logger.js";
4
- import { resolveModelsJsonPath } from "../config/paths.js";
5
2
  import { init_resolve_config_value, resolveConfigValue, resolveHeaders } from "../config/resolve-config-value.js";
3
+ import { resolveModelsJsonPath } from "../config/paths.js";
6
4
  import { getDefaultModelValues, init_models_json, validateModelsConfig } from "../config/models-json.js";
5
+ import { createLogger } from "../utils/logger/index.js";
6
+ import { init_logger } from "../utils/logger.js";
7
7
  import { getApiKeyFromEnv, init_env_keys } from "./env-keys.js";
8
- import { existsSync, readFileSync } from "fs";
9
8
  import { getModels, getProviders } from "@earendil-works/pi-ai";
9
+ import { existsSync, readFileSync } from "fs";
10
10
  //#region src/providers/model-registry.ts
11
11
  /**
12
12
  * Model Registry - manages built-in and custom models from models.json
@@ -1,7 +1,7 @@
1
- import { SessionConfigSchema, init_schema } from "../config/schema.js";
2
- import { init_session_key, parseSessionKey } from "../routing/session-key.js";
3
1
  import { createLogger } from "../utils/logger/index.js";
4
2
  import { init_logger } from "../utils/logger.js";
3
+ import { SessionConfigSchema, init_schema } from "../config/schema.js";
4
+ import { init_session_key, parseSessionKey } from "../routing/session-key.js";
5
5
  import { requireXopcDatabase } from "../storage/sqlite/connection.js";
6
6
  import "../storage/sqlite/index.js";
7
7
  import { evaluateSessionFreshness, resolveSessionResetPolicy } from "./reset-policy.js";
@@ -1,9 +1,9 @@
1
- import { SessionConfigSchema, init_schema } from "../config/schema.js";
2
1
  import { init_agent_scope, resolveDefaultAgentId } from "../agent/agent-scope.js";
3
- import { init_agent_session_key, normalizeAgentId, resolveAgentIdFromSessionKey } from "../routing/agent-session-key.js";
4
- import { init_session_key, parseSessionKey } from "../routing/session-key.js";
5
2
  import { createLogger } from "../utils/logger/index.js";
6
3
  import { init_logger } from "../utils/logger.js";
4
+ import { SessionConfigSchema, init_schema } from "../config/schema.js";
5
+ import { init_agent_session_key, normalizeAgentId, resolveAgentIdFromSessionKey } from "../routing/agent-session-key.js";
6
+ import { init_session_key, parseSessionKey } from "../routing/session-key.js";
7
7
  import { requireXopcDatabase } from "../storage/sqlite/connection.js";
8
8
  import { findSessionKeyByTranscriptId, getSessionMetadata, getSessionPersistedLevels } from "../storage/sqlite/session-repository.js";
9
9
  import "../storage/sqlite/index.js";
@@ -1,7 +1,7 @@
1
- import { isCronSessionKey } from "../routing/session-key-utils.js";
2
- import { init_session_key, parseSessionKey } from "../routing/session-key.js";
3
1
  import { createLogger } from "../utils/logger/index.js";
4
2
  import { init_logger } from "../utils/logger.js";
3
+ import { isCronSessionKey } from "../routing/session-key-utils.js";
4
+ import { init_session_key, parseSessionKey } from "../routing/session-key.js";
5
5
  import { init_providers, resolveModel } from "../providers/index.js";
6
6
  import { readAgentMessageContent } from "../agent/memory/agent-message-access.js";
7
7
  import { stripSessionStartupContextFromUserText } from "../agent/reply/startup-context.js";
@@ -0,0 +1,5 @@
1
+ import type { PaginatedResult, SessionListQuery, SessionMetadata } from './types.js';
2
+ /** Minimal session index reader needed by channel delivery adapters. */
3
+ export interface SessionListReader {
4
+ list(query?: SessionListQuery): Promise<PaginatedResult<SessionMetadata>>;
5
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -1,7 +1,7 @@
1
1
  import { init_paths_state, resolveStateDir } from "../config/paths-state.js";
2
- import { resolveEffectiveAgentProfileForSession } from "../config/agent-profile.js";
3
2
  import { createLogger } from "../utils/logger/index.js";
4
3
  import { init_logger } from "../utils/logger.js";
4
+ import { resolveEffectiveAgentProfileForSession } from "../config/agent-profile.js";
5
5
  import { requireXopcDatabase } from "../storage/sqlite/connection.js";
6
6
  import "./types.js";
7
7
  import { buildSessionContextForLlm, mergeLlmMessagesPreservingContextRows, transcriptRowsFromJsonArray } from "./session-context-for-llm.js";
@@ -1,8 +1,8 @@
1
1
  import { resolveMimeType } from "./share-store.js";
2
- import { basename, join, resolve } from "node:path";
3
- import { readdirSync } from "node:fs";
4
2
  import { randomUUID } from "node:crypto";
3
+ import { readdirSync } from "node:fs";
5
4
  import { copyFile, mkdir, rm, stat } from "node:fs/promises";
5
+ import { basename, join, resolve } from "node:path";
6
6
  //#region src/share/share-auto.ts
7
7
  /**
8
8
  * Smart-share decision layer.
@@ -1,14 +1,14 @@
1
1
  import { resolveStateDir } from "../config/paths-state.js";
2
+ import { init_paths } from "../config/paths.js";
2
3
  import { createLogger } from "../utils/logger/index.js";
3
4
  import { init_logger } from "../utils/logger.js";
4
- import { init_paths } from "../config/paths.js";
5
5
  import { SHARE_CONFIG_DEFAULTS } from "./share-types.js";
6
6
  import { isPathUnderWorkspace } from "../gateway/workspace-editor-path.js";
7
7
  import { logShareAudit } from "./share-audit.js";
8
- import { join, relative, resolve } from "node:path";
9
- import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
10
8
  import { randomBytes, randomUUID } from "node:crypto";
9
+ import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
11
10
  import { lstat, readdir, realpath, stat } from "node:fs/promises";
11
+ import { join, relative, resolve } from "node:path";
12
12
  //#region src/share/share-store.ts
13
13
  init_paths();
14
14
  init_logger();
@@ -1,12 +1,12 @@
1
1
  import { resolveStateDir } from "../config/paths-state.js";
2
+ import { init_paths } from "../config/paths.js";
2
3
  import { createLogger } from "../utils/logger/index.js";
3
4
  import { init_logger } from "../utils/logger.js";
4
- import { init_paths } from "../config/paths.js";
5
5
  import { getShareStore } from "./share-store.js";
6
6
  import { getSiteShareStore } from "./site-share-store.js";
7
7
  import { loadPlaywrightCoreModule } from "../browser/providers/playwright-doctor.js";
8
- import { join } from "node:path";
9
8
  import { mkdir, readFile, stat, unlink, writeFile } from "node:fs/promises";
9
+ import { join } from "node:path";
10
10
  //#region src/share/share-thumbnail.ts
11
11
  /**
12
12
  * Thumbnail generator for shares.
@@ -1,7 +1,7 @@
1
1
  import { isPathUnderWorkspace } from "../gateway/workspace-editor-path.js";
2
- import { relative, resolve } from "node:path";
3
2
  import { createReadStream } from "node:fs";
4
3
  import { lstat, readdir, realpath, stat } from "node:fs/promises";
4
+ import { relative, resolve } from "node:path";
5
5
  import { Readable, Transform } from "node:stream";
6
6
  import { pipeline } from "node:stream/promises";
7
7
  import { crc32, createDeflateRaw } from "node:zlib";
@@ -1,13 +1,13 @@
1
1
  import { resolveStateDir } from "../config/paths-state.js";
2
+ import { init_paths } from "../config/paths.js";
2
3
  import { createLogger } from "../utils/logger/index.js";
3
4
  import { init_logger } from "../utils/logger.js";
4
- import { init_paths } from "../config/paths.js";
5
5
  import { SITE_SHARE_CONFIG_DEFAULTS } from "./site-share-types.js";
6
6
  import { isPathUnderWorkspace } from "../gateway/workspace-editor-path.js";
7
- import { join, relative, resolve } from "node:path";
8
- import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
9
7
  import { randomBytes, randomUUID } from "node:crypto";
8
+ import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
10
9
  import { lstat, readdir, realpath, stat } from "node:fs/promises";
10
+ import { join, relative, resolve } from "node:path";
11
11
  //#region src/share/site-share-store.ts
12
12
  init_paths();
13
13
  init_logger();
@@ -1,8 +1,8 @@
1
1
  import { isPathUnderWorkspace } from "../gateway/workspace-editor-path.js";
2
2
  import { resolveMimeType, shareResponseContentType } from "./share-store.js";
3
- import { join, relative, resolve } from "node:path";
4
3
  import { createReadStream } from "node:fs";
5
4
  import { readFile, stat } from "node:fs/promises";
5
+ import { join, relative, resolve } from "node:path";
6
6
  import { Readable } from "node:stream";
7
7
  //#region src/share/site-static-serve.ts
8
8
  const HASHED_ASSET_RE = /\.[a-f0-9]{8,}\.(?:js|mjs|css|woff2?|ttf|otf|svg|png|jpg|jpeg|gif|webp|avif|ico)$/i;
@@ -4,8 +4,8 @@ import { init_logger } from "../../utils/logger.js";
4
4
  import { ensureXopcDatabaseSchema } from "./schema.js";
5
5
  import { requireNodeSqlite } from "../../infra/node-sqlite.js";
6
6
  import { installSqliteTransientRejectionHandler } from "../../infra/unhandled-rejections.js";
7
- import path from "node:path";
8
7
  import fs from "node:fs";
8
+ import path from "node:path";
9
9
  import childProcess from "node:child_process";
10
10
  //#region src/storage/sqlite/connection.ts
11
11
  init_logger();
@@ -0,0 +1,6 @@
1
+ import type { JobData } from '../../cron/types.js';
2
+ export declare function listCronJobs(): JobData[];
3
+ export declare function getCronJob(jobId: string): JobData | null;
4
+ export declare function saveCronJob(job: JobData): void;
5
+ export declare function saveCronJobs(jobs: JobData[]): void;
6
+ export declare function deleteCronJob(jobId: string): boolean;
@@ -0,0 +1,70 @@
1
+ import { getSqliteDatabase, runSqliteWriteTransaction } from "./transaction.js";
2
+ import { JobDataSchema } from "../../cron/validation.js";
3
+ //#region src/storage/sqlite/cron-job-repository.ts
4
+ function parseJson(value) {
5
+ if (!value) return void 0;
6
+ return JSON.parse(value);
7
+ }
8
+ function rowToCronJob(row) {
9
+ return JobDataSchema.parse({
10
+ id: row.job_id,
11
+ name: row.name,
12
+ description: row.description ?? void 0,
13
+ enabled: row.enabled !== 0,
14
+ deleteAfterRun: row.delete_after_run == null ? void 0 : row.delete_after_run !== 0,
15
+ createdAtMs: row.created_at_ms,
16
+ updatedAtMs: row.updated_at_ms,
17
+ schedule: parseJson(row.schedule_json),
18
+ sessionTarget: row.session_target,
19
+ wakeMode: row.wake_mode,
20
+ agentId: row.agent_id ?? void 0,
21
+ sessionKey: row.session_key ?? void 0,
22
+ workingDirectory: row.working_directory ?? void 0,
23
+ payload: parseJson(row.payload_json),
24
+ delivery: parseJson(row.delivery_json),
25
+ failureAlert: parseJson(row.failure_alert_json),
26
+ state: parseJson(row.state_json) ?? {}
27
+ });
28
+ }
29
+ function bindJson(value) {
30
+ return value === void 0 ? null : JSON.stringify(value);
31
+ }
32
+ function upsertJob(db, job) {
33
+ db.prepare(`INSERT OR REPLACE INTO cron_jobs (
34
+ job_id, name, description, enabled, delete_after_run, created_at_ms, updated_at_ms,
35
+ schedule_json, session_target, wake_mode, agent_id, session_key, working_directory,
36
+ payload_json, delivery_json, failure_alert_json, state_json
37
+ ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`).run(job.id, job.name, job.description ?? null, job.enabled ? 1 : 0, job.deleteAfterRun == null ? null : job.deleteAfterRun ? 1 : 0, job.createdAtMs, job.updatedAtMs, JSON.stringify(job.schedule), job.sessionTarget, job.wakeMode, job.agentId ?? null, job.sessionKey ?? null, job.workingDirectory ?? null, JSON.stringify(job.payload), bindJson(job.delivery), bindJson(job.failureAlert), JSON.stringify(job.state ?? {}));
38
+ }
39
+ function listCronJobs() {
40
+ return getSqliteDatabase().prepare(`SELECT job_id, name, description, enabled, delete_after_run, created_at_ms, updated_at_ms,
41
+ schedule_json, session_target, wake_mode, agent_id, session_key, working_directory,
42
+ payload_json, delivery_json, failure_alert_json, state_json
43
+ FROM cron_jobs
44
+ ORDER BY created_at_ms DESC`).all().map(rowToCronJob);
45
+ }
46
+ function getCronJob(jobId) {
47
+ const row = getSqliteDatabase().prepare(`SELECT job_id, name, description, enabled, delete_after_run, created_at_ms, updated_at_ms,
48
+ schedule_json, session_target, wake_mode, agent_id, session_key, working_directory,
49
+ payload_json, delivery_json, failure_alert_json, state_json
50
+ FROM cron_jobs
51
+ WHERE job_id = ?`).get(jobId);
52
+ return row ? rowToCronJob(row) : null;
53
+ }
54
+ function saveCronJob(job) {
55
+ runSqliteWriteTransaction((db) => upsertJob(db, job));
56
+ }
57
+ function saveCronJobs(jobs) {
58
+ runSqliteWriteTransaction((db) => {
59
+ for (const job of jobs) upsertJob(db, job);
60
+ });
61
+ }
62
+ function deleteCronJob(jobId) {
63
+ return runSqliteWriteTransaction((db) => {
64
+ return db.prepare(`DELETE FROM cron_jobs WHERE job_id = ?`).run(jobId).changes > 0;
65
+ });
66
+ }
67
+ //#endregion
68
+ export { deleteCronJob, getCronJob, listCronJobs, saveCronJob, saveCronJobs };
69
+
70
+ //# sourceMappingURL=cron-job-repository.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cron-job-repository.js","names":[],"sources":["../../../../src/storage/sqlite/cron-job-repository.ts"],"sourcesContent":["import type { JobData } from '../../cron/types.js';\nimport { JobDataSchema } from '../../cron/validation.js';\nimport { getSqliteDatabase, runSqliteWriteTransaction } from './transaction.js';\n\ntype CronJobRow = {\n job_id: string;\n name: string;\n description: string | null;\n enabled: number;\n delete_after_run: number | null;\n created_at_ms: number;\n updated_at_ms: number;\n schedule_json: string;\n session_target: string;\n wake_mode: string;\n agent_id: string | null;\n session_key: string | null;\n working_directory: string | null;\n payload_json: string;\n delivery_json: string | null;\n failure_alert_json: string | null;\n state_json: string;\n};\n\nfunction parseJson(value: string | null): unknown {\n if (!value) return undefined;\n return JSON.parse(value);\n}\n\nfunction rowToCronJob(row: CronJobRow): JobData {\n const parsed = JobDataSchema.parse({\n id: row.job_id,\n name: row.name,\n description: row.description ?? undefined,\n enabled: row.enabled !== 0,\n deleteAfterRun: row.delete_after_run == null ? undefined : row.delete_after_run !== 0,\n createdAtMs: row.created_at_ms,\n updatedAtMs: row.updated_at_ms,\n schedule: parseJson(row.schedule_json),\n sessionTarget: row.session_target,\n wakeMode: row.wake_mode,\n agentId: row.agent_id ?? undefined,\n sessionKey: row.session_key ?? undefined,\n workingDirectory: row.working_directory ?? undefined,\n payload: parseJson(row.payload_json),\n delivery: parseJson(row.delivery_json),\n failureAlert: parseJson(row.failure_alert_json),\n state: parseJson(row.state_json) ?? {},\n });\n return parsed as JobData;\n}\n\nfunction bindJson(value: unknown): string | null {\n return value === undefined ? null : JSON.stringify(value);\n}\n\nfunction upsertJob(db: ReturnType<typeof getSqliteDatabase>, job: JobData): void {\n db.prepare(\n `INSERT OR REPLACE INTO cron_jobs (\n job_id, name, description, enabled, delete_after_run, created_at_ms, updated_at_ms,\n schedule_json, session_target, wake_mode, agent_id, session_key, working_directory,\n payload_json, delivery_json, failure_alert_json, state_json\n ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,\n ).run(\n job.id,\n job.name,\n job.description ?? null,\n job.enabled ? 1 : 0,\n job.deleteAfterRun == null ? null : job.deleteAfterRun ? 1 : 0,\n job.createdAtMs,\n job.updatedAtMs,\n JSON.stringify(job.schedule),\n job.sessionTarget,\n job.wakeMode,\n job.agentId ?? null,\n job.sessionKey ?? null,\n job.workingDirectory ?? null,\n JSON.stringify(job.payload),\n bindJson(job.delivery),\n bindJson(job.failureAlert),\n JSON.stringify(job.state ?? {}),\n );\n}\n\nexport function listCronJobs(): JobData[] {\n const rows = getSqliteDatabase()\n .prepare(\n `SELECT job_id, name, description, enabled, delete_after_run, created_at_ms, updated_at_ms,\n schedule_json, session_target, wake_mode, agent_id, session_key, working_directory,\n payload_json, delivery_json, failure_alert_json, state_json\n FROM cron_jobs\n ORDER BY created_at_ms DESC`,\n )\n .all() as CronJobRow[];\n return rows.map(rowToCronJob);\n}\n\nexport function getCronJob(jobId: string): JobData | null {\n const row = getSqliteDatabase()\n .prepare(\n `SELECT job_id, name, description, enabled, delete_after_run, created_at_ms, updated_at_ms,\n schedule_json, session_target, wake_mode, agent_id, session_key, working_directory,\n payload_json, delivery_json, failure_alert_json, state_json\n FROM cron_jobs\n WHERE job_id = ?`,\n )\n .get(jobId) as CronJobRow | undefined;\n return row ? rowToCronJob(row) : null;\n}\n\nexport function saveCronJob(job: JobData): void {\n runSqliteWriteTransaction((db) => upsertJob(db, job));\n}\n\nexport function saveCronJobs(jobs: JobData[]): void {\n runSqliteWriteTransaction((db) => {\n for (const job of jobs) upsertJob(db, job);\n });\n}\n\nexport function deleteCronJob(jobId: string): boolean {\n return runSqliteWriteTransaction((db) => {\n const result = db.prepare(`DELETE FROM cron_jobs WHERE job_id = ?`).run(jobId);\n return result.changes > 0;\n });\n}\n"],"mappings":";;;AAwBA,SAAS,UAAU,OAA+B;AAChD,KAAI,CAAC,MAAO,QAAO,KAAA;AACnB,QAAO,KAAK,MAAM,MAAM;;AAG1B,SAAS,aAAa,KAA0B;AAoB9C,QAnBe,cAAc,MAAM;EACjC,IAAI,IAAI;EACR,MAAM,IAAI;EACV,aAAa,IAAI,eAAe,KAAA;EAChC,SAAS,IAAI,YAAY;EACzB,gBAAgB,IAAI,oBAAoB,OAAO,KAAA,IAAY,IAAI,qBAAqB;EACpF,aAAa,IAAI;EACjB,aAAa,IAAI;EACjB,UAAU,UAAU,IAAI,cAAc;EACtC,eAAe,IAAI;EACnB,UAAU,IAAI;EACd,SAAS,IAAI,YAAY,KAAA;EACzB,YAAY,IAAI,eAAe,KAAA;EAC/B,kBAAkB,IAAI,qBAAqB,KAAA;EAC3C,SAAS,UAAU,IAAI,aAAa;EACpC,UAAU,UAAU,IAAI,cAAc;EACtC,cAAc,UAAU,IAAI,mBAAmB;EAC/C,OAAO,UAAU,IAAI,WAAW,IAAI,EAAE;EACvC,CACY;;AAGf,SAAS,SAAS,OAA+B;AAC/C,QAAO,UAAU,KAAA,IAAY,OAAO,KAAK,UAAU,MAAM;;AAG3D,SAAS,UAAU,IAA0C,KAAoB;AAC/E,IAAG,QACD;;;;kEAKD,CAAC,IACA,IAAI,IACJ,IAAI,MACJ,IAAI,eAAe,MACnB,IAAI,UAAU,IAAI,GAClB,IAAI,kBAAkB,OAAO,OAAO,IAAI,iBAAiB,IAAI,GAC7D,IAAI,aACJ,IAAI,aACJ,KAAK,UAAU,IAAI,SAAS,EAC5B,IAAI,eACJ,IAAI,UACJ,IAAI,WAAW,MACf,IAAI,cAAc,MAClB,IAAI,oBAAoB,MACxB,KAAK,UAAU,IAAI,QAAQ,EAC3B,SAAS,IAAI,SAAS,EACtB,SAAS,IAAI,aAAa,EAC1B,KAAK,UAAU,IAAI,SAAS,EAAE,CAAC,CAChC;;AAGH,SAAgB,eAA0B;AAUxC,QATa,mBAAmB,CAC7B,QACC;;;;oCAKD,CACA,KACQ,CAAC,IAAI,aAAa;;AAG/B,SAAgB,WAAW,OAA+B;CACxD,MAAM,MAAM,mBAAmB,CAC5B,QACC;;;;yBAKD,CACA,IAAI,MAAM;AACb,QAAO,MAAM,aAAa,IAAI,GAAG;;AAGnC,SAAgB,YAAY,KAAoB;AAC9C,4BAA2B,OAAO,UAAU,IAAI,IAAI,CAAC;;AAGvD,SAAgB,aAAa,MAAuB;AAClD,4BAA2B,OAAO;AAChC,OAAK,MAAM,OAAO,KAAM,WAAU,IAAI,IAAI;GAC1C;;AAGJ,SAAgB,cAAc,OAAwB;AACpD,QAAO,2BAA2B,OAAO;AAEvC,SADe,GAAG,QAAQ,yCAAyC,CAAC,IAAI,MAC3D,CAAC,UAAU;GACxB"}
@@ -56,7 +56,6 @@ function trimJobRuns(db, jobId) {
56
56
  )`).run(jobId, excess);
57
57
  }
58
58
  function appendCronRun(execution) {
59
- if (execution.status === "running") return;
60
59
  const row = executionToInsert(execution);
61
60
  runSqliteWriteTransaction((db) => {
62
61
  db.prepare(`INSERT OR REPLACE INTO cron_runs (
@@ -1 +1 @@
1
- {"version":3,"file":"cron-run-repository.js","names":[],"sources":["../../../../src/storage/sqlite/cron-run-repository.ts"],"sourcesContent":["import type { JobExecution } from '../../cron/execution-types.js';\nimport { getSqliteDatabase, runSqliteWriteTransaction } from './transaction.js';\n\nconst MAX_RUNS_PER_JOB = 2000;\nconst TRIM_TO_RUNS = 1500;\n\ntype CronRunRow = {\n run_id: string;\n job_id: string;\n status: string;\n started_at: number;\n ended_at: number | null;\n duration_ms: number | null;\n error: string | null;\n output: string | null;\n retry_count: number;\n summary: string | null;\n session_id: string | null;\n session_key: string | null;\n session_type: string | null;\n model: string | null;\n provider: string | null;\n usage_json: string | null;\n workflow_run_id: string | null;\n};\n\nfunction rowToExecution(row: CronRunRow): JobExecution {\n return {\n id: row.run_id,\n jobId: row.job_id,\n status: row.status as JobExecution['status'],\n startedAt: new Date(row.started_at).toISOString(),\n endedAt: row.ended_at != null ? new Date(row.ended_at).toISOString() : undefined,\n duration: row.duration_ms ?? undefined,\n error: row.error ?? undefined,\n output: row.output ?? undefined,\n retryCount: row.retry_count,\n summary: row.summary ?? undefined,\n sessionId: row.session_id ?? undefined,\n sessionKey: row.session_key ?? undefined,\n sessionType: row.session_type ?? undefined,\n model: row.model ?? undefined,\n provider: row.provider ?? undefined,\n usage: row.usage_json ? (JSON.parse(row.usage_json) as JobExecution['usage']) : undefined,\n workflowRunId: row.workflow_run_id ?? undefined,\n };\n}\n\nfunction executionToInsert(execution: JobExecution): CronRunRow {\n const startedAt = Date.parse(execution.startedAt);\n const endedAt = execution.endedAt ? Date.parse(execution.endedAt) : null;\n return {\n run_id: execution.id,\n job_id: execution.jobId,\n status: execution.status,\n started_at: startedAt,\n ended_at: endedAt,\n duration_ms: execution.duration ?? null,\n error: execution.error ?? null,\n output: execution.output ?? null,\n retry_count: execution.retryCount,\n summary: execution.summary ?? null,\n session_id: execution.sessionId ?? null,\n session_key: execution.sessionKey ?? null,\n session_type: execution.sessionType ?? null,\n model: execution.model ?? null,\n provider: execution.provider ?? null,\n usage_json: execution.usage ? JSON.stringify(execution.usage) : null,\n workflow_run_id: execution.workflowRunId ?? null,\n };\n}\n\nfunction trimJobRuns(db: ReturnType<typeof getSqliteDatabase>, jobId: string): void {\n const countRow = db\n .prepare(`SELECT COUNT(*) AS count FROM cron_runs WHERE job_id = ?`)\n .get(jobId) as { count: number };\n if (countRow.count <= MAX_RUNS_PER_JOB) {\n return;\n }\n const excess = countRow.count - TRIM_TO_RUNS;\n db.prepare(\n `DELETE FROM cron_runs WHERE run_id IN (\n SELECT run_id FROM cron_runs WHERE job_id = ?\n ORDER BY started_at ASC LIMIT ?\n )`,\n ).run(jobId, excess);\n}\n\nexport function appendCronRun(execution: JobExecution): void {\n if (execution.status === 'running') {\n return;\n }\n const row = executionToInsert(execution);\n runSqliteWriteTransaction((db) => {\n db.prepare(\n `INSERT OR REPLACE INTO cron_runs (\n run_id, job_id, status, started_at, ended_at, duration_ms,\n error, output, retry_count, summary, session_id, session_key,\n session_type, model, provider, usage_json, workflow_run_id\n ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,\n ).run(\n row.run_id,\n row.job_id,\n row.status,\n row.started_at,\n row.ended_at,\n row.duration_ms,\n row.error,\n row.output,\n row.retry_count,\n row.summary,\n row.session_id,\n row.session_key,\n row.session_type,\n row.model,\n row.provider,\n row.usage_json,\n row.workflow_run_id,\n );\n trimJobRuns(db, row.job_id);\n });\n}\n\nexport function readCronJobHistory(jobId: string, limit: number): JobExecution[] {\n if (limit <= 0) {\n return [];\n }\n const db = getSqliteDatabase();\n const rows = db\n .prepare(\n `SELECT run_id, job_id, status, started_at, ended_at, duration_ms,\n error, output, retry_count, summary, session_id, session_key,\n session_type, model, provider, usage_json, workflow_run_id\n FROM cron_runs\n WHERE job_id = ?\n ORDER BY started_at DESC\n LIMIT ?`,\n )\n .all(jobId, limit) as CronRunRow[];\n return rows.map(rowToExecution);\n}\n\nexport function readAllCronRuns(limit: number): JobExecution[] {\n if (limit <= 0) {\n return [];\n }\n const db = getSqliteDatabase();\n const rows = db\n .prepare(\n `SELECT run_id, job_id, status, started_at, ended_at, duration_ms,\n error, output, retry_count, summary, session_id, session_key,\n session_type, model, provider, usage_json, workflow_run_id\n FROM cron_runs\n ORDER BY started_at DESC\n LIMIT ?`,\n )\n .all(limit) as CronRunRow[];\n return rows.map(rowToExecution);\n}\n\nexport function deleteCronRunsForJob(jobId: string): void {\n runSqliteWriteTransaction((db) => {\n db.prepare(`DELETE FROM cron_runs WHERE job_id = ?`).run(jobId);\n });\n}\n"],"mappings":";;AAGA,MAAM,mBAAmB;AACzB,MAAM,eAAe;AAsBrB,SAAS,eAAe,KAA+B;AACrD,QAAO;EACL,IAAI,IAAI;EACR,OAAO,IAAI;EACX,QAAQ,IAAI;EACZ,WAAW,IAAI,KAAK,IAAI,WAAW,CAAC,aAAa;EACjD,SAAS,IAAI,YAAY,OAAO,IAAI,KAAK,IAAI,SAAS,CAAC,aAAa,GAAG,KAAA;EACvE,UAAU,IAAI,eAAe,KAAA;EAC7B,OAAO,IAAI,SAAS,KAAA;EACpB,QAAQ,IAAI,UAAU,KAAA;EACtB,YAAY,IAAI;EAChB,SAAS,IAAI,WAAW,KAAA;EACxB,WAAW,IAAI,cAAc,KAAA;EAC7B,YAAY,IAAI,eAAe,KAAA;EAC/B,aAAa,IAAI,gBAAgB,KAAA;EACjC,OAAO,IAAI,SAAS,KAAA;EACpB,UAAU,IAAI,YAAY,KAAA;EAC1B,OAAO,IAAI,aAAc,KAAK,MAAM,IAAI,WAAW,GAA6B,KAAA;EAChF,eAAe,IAAI,mBAAmB,KAAA;EACvC;;AAGH,SAAS,kBAAkB,WAAqC;CAC9D,MAAM,YAAY,KAAK,MAAM,UAAU,UAAU;CACjD,MAAM,UAAU,UAAU,UAAU,KAAK,MAAM,UAAU,QAAQ,GAAG;AACpE,QAAO;EACL,QAAQ,UAAU;EAClB,QAAQ,UAAU;EAClB,QAAQ,UAAU;EAClB,YAAY;EACZ,UAAU;EACV,aAAa,UAAU,YAAY;EACnC,OAAO,UAAU,SAAS;EAC1B,QAAQ,UAAU,UAAU;EAC5B,aAAa,UAAU;EACvB,SAAS,UAAU,WAAW;EAC9B,YAAY,UAAU,aAAa;EACnC,aAAa,UAAU,cAAc;EACrC,cAAc,UAAU,eAAe;EACvC,OAAO,UAAU,SAAS;EAC1B,UAAU,UAAU,YAAY;EAChC,YAAY,UAAU,QAAQ,KAAK,UAAU,UAAU,MAAM,GAAG;EAChE,iBAAiB,UAAU,iBAAiB;EAC7C;;AAGH,SAAS,YAAY,IAA0C,OAAqB;CAClF,MAAM,WAAW,GACd,QAAQ,2DAA2D,CACnE,IAAI,MAAM;AACb,KAAI,SAAS,SAAS,iBACpB;CAEF,MAAM,SAAS,SAAS,QAAQ;AAChC,IAAG,QACD;;;QAID,CAAC,IAAI,OAAO,OAAO;;AAGtB,SAAgB,cAAc,WAA+B;AAC3D,KAAI,UAAU,WAAW,UACvB;CAEF,MAAM,MAAM,kBAAkB,UAAU;AACxC,4BAA2B,OAAO;AAChC,KAAG,QACD;;;;oEAKD,CAAC,IACA,IAAI,QACJ,IAAI,QACJ,IAAI,QACJ,IAAI,YACJ,IAAI,UACJ,IAAI,aACJ,IAAI,OACJ,IAAI,QACJ,IAAI,aACJ,IAAI,SACJ,IAAI,YACJ,IAAI,aACJ,IAAI,cACJ,IAAI,OACJ,IAAI,UACJ,IAAI,YACJ,IAAI,gBACL;AACD,cAAY,IAAI,IAAI,OAAO;GAC3B;;AAGJ,SAAgB,mBAAmB,OAAe,OAA+B;AAC/E,KAAI,SAAS,EACX,QAAO,EAAE;AAcX,QAZW,mBACI,CACZ,QACC;;;;;;gBAOD,CACA,IAAI,OAAO,MACH,CAAC,IAAI,eAAe;;AAGjC,SAAgB,gBAAgB,OAA+B;AAC7D,KAAI,SAAS,EACX,QAAO,EAAE;AAaX,QAXW,mBACI,CACZ,QACC;;;;;gBAMD,CACA,IAAI,MACI,CAAC,IAAI,eAAe;;AAGjC,SAAgB,qBAAqB,OAAqB;AACxD,4BAA2B,OAAO;AAChC,KAAG,QAAQ,yCAAyC,CAAC,IAAI,MAAM;GAC/D"}
1
+ {"version":3,"file":"cron-run-repository.js","names":[],"sources":["../../../../src/storage/sqlite/cron-run-repository.ts"],"sourcesContent":["import type { JobExecution } from '../../cron/execution-types.js';\nimport { getSqliteDatabase, runSqliteWriteTransaction } from './transaction.js';\n\nconst MAX_RUNS_PER_JOB = 2000;\nconst TRIM_TO_RUNS = 1500;\n\ntype CronRunRow = {\n run_id: string;\n job_id: string;\n status: string;\n started_at: number;\n ended_at: number | null;\n duration_ms: number | null;\n error: string | null;\n output: string | null;\n retry_count: number;\n summary: string | null;\n session_id: string | null;\n session_key: string | null;\n session_type: string | null;\n model: string | null;\n provider: string | null;\n usage_json: string | null;\n workflow_run_id: string | null;\n};\n\nfunction rowToExecution(row: CronRunRow): JobExecution {\n return {\n id: row.run_id,\n jobId: row.job_id,\n status: row.status as JobExecution['status'],\n startedAt: new Date(row.started_at).toISOString(),\n endedAt: row.ended_at != null ? new Date(row.ended_at).toISOString() : undefined,\n duration: row.duration_ms ?? undefined,\n error: row.error ?? undefined,\n output: row.output ?? undefined,\n retryCount: row.retry_count,\n summary: row.summary ?? undefined,\n sessionId: row.session_id ?? undefined,\n sessionKey: row.session_key ?? undefined,\n sessionType: row.session_type ?? undefined,\n model: row.model ?? undefined,\n provider: row.provider ?? undefined,\n usage: row.usage_json ? (JSON.parse(row.usage_json) as JobExecution['usage']) : undefined,\n workflowRunId: row.workflow_run_id ?? undefined,\n };\n}\n\nfunction executionToInsert(execution: JobExecution): CronRunRow {\n const startedAt = Date.parse(execution.startedAt);\n const endedAt = execution.endedAt ? Date.parse(execution.endedAt) : null;\n return {\n run_id: execution.id,\n job_id: execution.jobId,\n status: execution.status,\n started_at: startedAt,\n ended_at: endedAt,\n duration_ms: execution.duration ?? null,\n error: execution.error ?? null,\n output: execution.output ?? null,\n retry_count: execution.retryCount,\n summary: execution.summary ?? null,\n session_id: execution.sessionId ?? null,\n session_key: execution.sessionKey ?? null,\n session_type: execution.sessionType ?? null,\n model: execution.model ?? null,\n provider: execution.provider ?? null,\n usage_json: execution.usage ? JSON.stringify(execution.usage) : null,\n workflow_run_id: execution.workflowRunId ?? null,\n };\n}\n\nfunction trimJobRuns(db: ReturnType<typeof getSqliteDatabase>, jobId: string): void {\n const countRow = db\n .prepare(`SELECT COUNT(*) AS count FROM cron_runs WHERE job_id = ?`)\n .get(jobId) as { count: number };\n if (countRow.count <= MAX_RUNS_PER_JOB) {\n return;\n }\n const excess = countRow.count - TRIM_TO_RUNS;\n db.prepare(\n `DELETE FROM cron_runs WHERE run_id IN (\n SELECT run_id FROM cron_runs WHERE job_id = ?\n ORDER BY started_at ASC LIMIT ?\n )`,\n ).run(jobId, excess);\n}\n\nexport function appendCronRun(execution: JobExecution): void {\n const row = executionToInsert(execution);\n runSqliteWriteTransaction((db) => {\n db.prepare(\n `INSERT OR REPLACE INTO cron_runs (\n run_id, job_id, status, started_at, ended_at, duration_ms,\n error, output, retry_count, summary, session_id, session_key,\n session_type, model, provider, usage_json, workflow_run_id\n ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,\n ).run(\n row.run_id,\n row.job_id,\n row.status,\n row.started_at,\n row.ended_at,\n row.duration_ms,\n row.error,\n row.output,\n row.retry_count,\n row.summary,\n row.session_id,\n row.session_key,\n row.session_type,\n row.model,\n row.provider,\n row.usage_json,\n row.workflow_run_id,\n );\n trimJobRuns(db, row.job_id);\n });\n}\n\nexport function readCronJobHistory(jobId: string, limit: number): JobExecution[] {\n if (limit <= 0) {\n return [];\n }\n const db = getSqliteDatabase();\n const rows = db\n .prepare(\n `SELECT run_id, job_id, status, started_at, ended_at, duration_ms,\n error, output, retry_count, summary, session_id, session_key,\n session_type, model, provider, usage_json, workflow_run_id\n FROM cron_runs\n WHERE job_id = ?\n ORDER BY started_at DESC\n LIMIT ?`,\n )\n .all(jobId, limit) as CronRunRow[];\n return rows.map(rowToExecution);\n}\n\nexport function readAllCronRuns(limit: number): JobExecution[] {\n if (limit <= 0) {\n return [];\n }\n const db = getSqliteDatabase();\n const rows = db\n .prepare(\n `SELECT run_id, job_id, status, started_at, ended_at, duration_ms,\n error, output, retry_count, summary, session_id, session_key,\n session_type, model, provider, usage_json, workflow_run_id\n FROM cron_runs\n ORDER BY started_at DESC\n LIMIT ?`,\n )\n .all(limit) as CronRunRow[];\n return rows.map(rowToExecution);\n}\n\nexport function deleteCronRunsForJob(jobId: string): void {\n runSqliteWriteTransaction((db) => {\n db.prepare(`DELETE FROM cron_runs WHERE job_id = ?`).run(jobId);\n });\n}\n"],"mappings":";;AAGA,MAAM,mBAAmB;AACzB,MAAM,eAAe;AAsBrB,SAAS,eAAe,KAA+B;AACrD,QAAO;EACL,IAAI,IAAI;EACR,OAAO,IAAI;EACX,QAAQ,IAAI;EACZ,WAAW,IAAI,KAAK,IAAI,WAAW,CAAC,aAAa;EACjD,SAAS,IAAI,YAAY,OAAO,IAAI,KAAK,IAAI,SAAS,CAAC,aAAa,GAAG,KAAA;EACvE,UAAU,IAAI,eAAe,KAAA;EAC7B,OAAO,IAAI,SAAS,KAAA;EACpB,QAAQ,IAAI,UAAU,KAAA;EACtB,YAAY,IAAI;EAChB,SAAS,IAAI,WAAW,KAAA;EACxB,WAAW,IAAI,cAAc,KAAA;EAC7B,YAAY,IAAI,eAAe,KAAA;EAC/B,aAAa,IAAI,gBAAgB,KAAA;EACjC,OAAO,IAAI,SAAS,KAAA;EACpB,UAAU,IAAI,YAAY,KAAA;EAC1B,OAAO,IAAI,aAAc,KAAK,MAAM,IAAI,WAAW,GAA6B,KAAA;EAChF,eAAe,IAAI,mBAAmB,KAAA;EACvC;;AAGH,SAAS,kBAAkB,WAAqC;CAC9D,MAAM,YAAY,KAAK,MAAM,UAAU,UAAU;CACjD,MAAM,UAAU,UAAU,UAAU,KAAK,MAAM,UAAU,QAAQ,GAAG;AACpE,QAAO;EACL,QAAQ,UAAU;EAClB,QAAQ,UAAU;EAClB,QAAQ,UAAU;EAClB,YAAY;EACZ,UAAU;EACV,aAAa,UAAU,YAAY;EACnC,OAAO,UAAU,SAAS;EAC1B,QAAQ,UAAU,UAAU;EAC5B,aAAa,UAAU;EACvB,SAAS,UAAU,WAAW;EAC9B,YAAY,UAAU,aAAa;EACnC,aAAa,UAAU,cAAc;EACrC,cAAc,UAAU,eAAe;EACvC,OAAO,UAAU,SAAS;EAC1B,UAAU,UAAU,YAAY;EAChC,YAAY,UAAU,QAAQ,KAAK,UAAU,UAAU,MAAM,GAAG;EAChE,iBAAiB,UAAU,iBAAiB;EAC7C;;AAGH,SAAS,YAAY,IAA0C,OAAqB;CAClF,MAAM,WAAW,GACd,QAAQ,2DAA2D,CACnE,IAAI,MAAM;AACb,KAAI,SAAS,SAAS,iBACpB;CAEF,MAAM,SAAS,SAAS,QAAQ;AAChC,IAAG,QACD;;;QAID,CAAC,IAAI,OAAO,OAAO;;AAGtB,SAAgB,cAAc,WAA+B;CAC3D,MAAM,MAAM,kBAAkB,UAAU;AACxC,4BAA2B,OAAO;AAChC,KAAG,QACD;;;;oEAKD,CAAC,IACA,IAAI,QACJ,IAAI,QACJ,IAAI,QACJ,IAAI,YACJ,IAAI,UACJ,IAAI,aACJ,IAAI,OACJ,IAAI,QACJ,IAAI,aACJ,IAAI,SACJ,IAAI,YACJ,IAAI,aACJ,IAAI,cACJ,IAAI,OACJ,IAAI,UACJ,IAAI,YACJ,IAAI,gBACL;AACD,cAAY,IAAI,IAAI,OAAO;GAC3B;;AAGJ,SAAgB,mBAAmB,OAAe,OAA+B;AAC/E,KAAI,SAAS,EACX,QAAO,EAAE;AAcX,QAZW,mBACI,CACZ,QACC;;;;;;gBAOD,CACA,IAAI,OAAO,MACH,CAAC,IAAI,eAAe;;AAGjC,SAAgB,gBAAgB,OAA+B;AAC7D,KAAI,SAAS,EACX,QAAO,EAAE;AAaX,QAXW,mBACI,CACZ,QACC;;;;;gBAMD,CACA,IAAI,MACI,CAAC,IAAI,eAAe;;AAGjC,SAAgB,qBAAqB,OAAqB;AACxD,4BAA2B,OAAO;AAChC,KAAG,QAAQ,yCAAyC,CAAC,IAAI,MAAM;GAC/D"}
@@ -10,6 +10,7 @@ export { buildGlobalSessionStats, classifyStoredRow, estimateTokensFromMessages,
10
10
  export { deleteSessionRecord, ensureSessionRecord, getCurrentTranscriptId, getGlobalSessionStats, findSessionKeyByTranscriptId, getSessionPersistedLevels, getSessionMetadata, incrementSessionStatsOnAppend, listSessionMetadata, listSessionsByAgent, patchSessionMetadata, resetSessionRecord, resolveSessionAgentId, updateSessionStats, } from './session-repository.js';
11
11
  export { appendTranscriptEntry, captureCompactionCheckpoint, getCompactionCheckpointDetail, listCompactionCheckpoints, loadCheckpointRows, loadLlmMessagesForSession, loadTranscriptRows, loadTranscriptRowsForSession, paginateTranscriptMessages, replaceTranscriptRows, restoreCompactionCheckpoint, } from './transcript-repository.js';
12
12
  export { appendCronRun, deleteCronRunsForJob, readAllCronRuns, readCronJobHistory, } from './cron-run-repository.js';
13
+ export { deleteCronJob, getCronJob, listCronJobs, saveCronJob, saveCronJobs, } from './cron-job-repository.js';
13
14
  export { deleteNoteRecord, getNoteRecord, listNoteRecords, upsertNoteRecord, } from './notes-repository.js';
14
15
  export { deleteNoteAgentContextRecord, getNoteAgentContextRecord, upsertNoteAgentContextRecord, type NoteAgentContextRecord, } from './note-agent-context-repository.js';
15
16
  export { resolveAgentIdFromMemoriesDir, searchMemoryIndex, syncMemoryIndex, type MemorySearchHit, } from './memory-index-repository.js';
@@ -11,8 +11,9 @@ import { buildGlobalSessionStats, classifyStoredRow, estimateTokensFromMessages,
11
11
  import { deleteSessionRecord, ensureSessionRecord, findSessionKeyByTranscriptId, getCurrentTranscriptId, getGlobalSessionStats, getSessionMetadata, getSessionPersistedLevels, incrementSessionStatsOnAppend, listSessionMetadata, listSessionsByAgent, patchSessionMetadata, resetSessionRecord, resolveSessionAgentId, updateSessionStats } from "./session-repository.js";
12
12
  import { appendTranscriptEntry, captureCompactionCheckpoint, getCompactionCheckpointDetail, listCompactionCheckpoints, loadCheckpointRows, loadLlmMessagesForSession, loadTranscriptRows, loadTranscriptRowsForSession, paginateTranscriptMessages, replaceTranscriptRows, restoreCompactionCheckpoint } from "./transcript-repository.js";
13
13
  import { appendCronRun, deleteCronRunsForJob, readAllCronRuns, readCronJobHistory } from "./cron-run-repository.js";
14
+ import { deleteCronJob, getCronJob, listCronJobs, saveCronJob, saveCronJobs } from "./cron-job-repository.js";
14
15
  import { deleteNoteRecord, getNoteRecord, listNoteRecords, upsertNoteRecord } from "./notes-repository.js";
15
16
  import { deleteNoteAgentContextRecord, getNoteAgentContextRecord, upsertNoteAgentContextRecord } from "./note-agent-context-repository.js";
16
17
  import { resolveAgentIdFromMemoriesDir, searchMemoryIndex, syncMemoryIndex } from "./memory-index-repository.js";
17
18
  import { deleteSessionConfig, getSessionConfig, hasSessionConfig, setSessionConfig, updateSessionConfig } from "./config-repository.js";
18
- export { DatabaseSchemaMigrationGapError, DatabaseSchemaTooNewError, SCHEMA_META_SCHEMA_VERSION_KEY, XOPC_DB_BASELINE_SCHEMA_VERSION, XOPC_DB_FILENAME, XOPC_DB_SCHEMA_VERSION, appendCronRun, appendTranscriptEntry, applyPendingMigrations, buildDefaultSessionMetadata, buildGlobalSessionStats, captureCompactionCheckpoint, classifyStoredRow, closeXopcDatabase, deleteCronRunsForJob, deleteNoteAgentContextRecord, deleteNoteRecord, deleteSessionConfig, deleteSessionRecord, discoverSqlMigrations, ensureSessionRecord, ensureXopcDatabaseSchema, estimateTokensFromMessages, extractFtsContent, extractRoutingFromSessionKey, findSessionKeyByTranscriptId, getCompactionCheckpointDetail, getCurrentTranscriptId, getGlobalSessionStats, getNoteAgentContextRecord, getNoteRecord, getSessionConfig, getSessionMetadata, getSessionPersistedLevels, getSqliteDatabase, getXopcDatabase, hasSessionConfig, incrementSessionStatsOnAppend, inspectSchemaMigrationStatus, isXopcDatabaseOpen, listCompactionCheckpoints, listNoteRecords, listRegisteredMigrationTargets, listSessionMetadata, listSessionsByAgent, loadCheckpointRows, loadLlmMessagesForSession, loadTranscriptRows, loadTranscriptRowsForSession, metadataToSessionInsert, openXopcDatabase, paginateTranscriptMessages, parseSessionKeySource, patchSessionMetadata, readAllCronRuns, readCronJobHistory, readSchemaVersion, readSchemaVersionForTest, replaceTranscriptRows, requireXopcDatabase, resetSessionRecord, resetXopcDatabaseSingletonForTest, resolveAgentIdFromMemoriesDir, resolveAgentIdFromSessionKey, resolveMigrationsDir, resolveSessionAgentId, resolveXopcDatabasePath, restoreCompactionCheckpoint, runSqliteWriteTransaction, searchMemoryIndex, sessionConfigRowToConfig, sessionRowToMetadata, setSessionConfig, syncMemoryIndex, transcriptEntryRowToStoredRow, updateSessionConfig, updateSessionStats, upsertNoteAgentContextRecord, upsertNoteRecord };
19
+ export { DatabaseSchemaMigrationGapError, DatabaseSchemaTooNewError, SCHEMA_META_SCHEMA_VERSION_KEY, XOPC_DB_BASELINE_SCHEMA_VERSION, XOPC_DB_FILENAME, XOPC_DB_SCHEMA_VERSION, appendCronRun, appendTranscriptEntry, applyPendingMigrations, buildDefaultSessionMetadata, buildGlobalSessionStats, captureCompactionCheckpoint, classifyStoredRow, closeXopcDatabase, deleteCronJob, deleteCronRunsForJob, deleteNoteAgentContextRecord, deleteNoteRecord, deleteSessionConfig, deleteSessionRecord, discoverSqlMigrations, ensureSessionRecord, ensureXopcDatabaseSchema, estimateTokensFromMessages, extractFtsContent, extractRoutingFromSessionKey, findSessionKeyByTranscriptId, getCompactionCheckpointDetail, getCronJob, getCurrentTranscriptId, getGlobalSessionStats, getNoteAgentContextRecord, getNoteRecord, getSessionConfig, getSessionMetadata, getSessionPersistedLevels, getSqliteDatabase, getXopcDatabase, hasSessionConfig, incrementSessionStatsOnAppend, inspectSchemaMigrationStatus, isXopcDatabaseOpen, listCompactionCheckpoints, listCronJobs, listNoteRecords, listRegisteredMigrationTargets, listSessionMetadata, listSessionsByAgent, loadCheckpointRows, loadLlmMessagesForSession, loadTranscriptRows, loadTranscriptRowsForSession, metadataToSessionInsert, openXopcDatabase, paginateTranscriptMessages, parseSessionKeySource, patchSessionMetadata, readAllCronRuns, readCronJobHistory, readSchemaVersion, readSchemaVersionForTest, replaceTranscriptRows, requireXopcDatabase, resetSessionRecord, resetXopcDatabaseSingletonForTest, resolveAgentIdFromMemoriesDir, resolveAgentIdFromSessionKey, resolveMigrationsDir, resolveSessionAgentId, resolveXopcDatabasePath, restoreCompactionCheckpoint, runSqliteWriteTransaction, saveCronJob, saveCronJobs, searchMemoryIndex, sessionConfigRowToConfig, sessionRowToMetadata, setSessionConfig, syncMemoryIndex, transcriptEntryRowToStoredRow, updateSessionConfig, updateSessionStats, upsertNoteAgentContextRecord, upsertNoteRecord };
@@ -1,8 +1,8 @@
1
1
  import { getSqliteDatabase, runSqliteWriteTransaction } from "./transaction.js";
2
2
  import { escapeFts5Query } from "./fts.js";
3
- import { join, relative } from "node:path";
4
- import { existsSync, readFileSync, statSync } from "node:fs";
5
3
  import { createHash } from "node:crypto";
4
+ import { existsSync, readFileSync, statSync } from "node:fs";
5
+ import { join, relative } from "node:path";
6
6
  //#region src/storage/sqlite/memory-index-repository.ts
7
7
  const CURATED_MEMORY_FILENAMES = new Set(["MEMORY.md", "USER.md"]);
8
8
  const MEMORY_SYNC_CACHE_TTL_MS = 3e4;
@@ -0,0 +1,24 @@
1
+ CREATE TABLE IF NOT EXISTS cron_jobs (
2
+ job_id TEXT PRIMARY KEY,
3
+ name TEXT NOT NULL,
4
+ description TEXT,
5
+ enabled INTEGER NOT NULL,
6
+ delete_after_run INTEGER,
7
+ created_at_ms INTEGER NOT NULL,
8
+ updated_at_ms INTEGER NOT NULL,
9
+ schedule_json TEXT NOT NULL,
10
+ session_target TEXT NOT NULL,
11
+ wake_mode TEXT NOT NULL,
12
+ agent_id TEXT,
13
+ session_key TEXT,
14
+ working_directory TEXT,
15
+ payload_json TEXT NOT NULL,
16
+ delivery_json TEXT,
17
+ failure_alert_json TEXT,
18
+ state_json TEXT NOT NULL DEFAULT '{}'
19
+ );
20
+
21
+ CREATE INDEX IF NOT EXISTS idx_cron_jobs_enabled_next
22
+ ON cron_jobs(enabled, job_id);
23
+ CREATE INDEX IF NOT EXISTS idx_cron_jobs_updated
24
+ ON cron_jobs(updated_at_ms DESC);
@@ -1,5 +1,5 @@
1
- import { join } from "node:path";
2
1
  import { existsSync, readFileSync, readdirSync } from "node:fs";
2
+ import { join } from "node:path";
3
3
  //#region src/storage/sqlite/migrations/discover.ts
4
4
  /** Matches `002_add_notes_index.sql` → target version 2. */
5
5
  const MIGRATION_FILENAME = /^(\d{3})_[\w-]+\.sql$/;
@@ -3,7 +3,7 @@ import type { ApplyMigrationsOptions } from './types.js';
3
3
  /** Baseline schema version applied from schema.sql on first open. */
4
4
  export declare const XOPC_DB_BASELINE_SCHEMA_VERSION = 3;
5
5
  /** Latest schema version this release supports (increment when adding migrations). */
6
- export declare const XOPC_DB_SCHEMA_VERSION = 8;
6
+ export declare const XOPC_DB_SCHEMA_VERSION = 9;
7
7
  export declare function resolveMigrationsDir(override?: string): string;
8
8
  /**
9
9
  * Apply sequential SQL migrations from (currentVersion + 1) through targetVersion.
@@ -3,8 +3,8 @@ import { init_logger } from "../../../utils/logger.js";
3
3
  import { readSchemaVersion, setSchemaVersion } from "../schema-version.js";
4
4
  import { discoverSqlMigrations } from "./discover.js";
5
5
  import { DatabaseSchemaMigrationGapError, DatabaseSchemaTooNewError } from "./errors.js";
6
- import { dirname, join } from "node:path";
7
6
  import { existsSync } from "node:fs";
7
+ import { dirname, join } from "node:path";
8
8
  import { fileURLToPath } from "node:url";
9
9
  //#region src/storage/sqlite/migrations/runner.ts
10
10
  init_logger();
@@ -12,7 +12,7 @@ const log = createLogger("Sqlite:Migrations");
12
12
  /** Baseline schema version applied from schema.sql on first open. */
13
13
  const XOPC_DB_BASELINE_SCHEMA_VERSION = 3;
14
14
  /** Latest schema version this release supports (increment when adding migrations). */
15
- const XOPC_DB_SCHEMA_VERSION = 8;
15
+ const XOPC_DB_SCHEMA_VERSION = 9;
16
16
  const MODULE_DIR = dirname(fileURLToPath(import.meta.url));
17
17
  function resolveMigrationsDir(override) {
18
18
  if (override) return override;
@@ -46,7 +46,7 @@ function applySingleMigration(db, migration) {
46
46
  * Each step runs in its own transaction and updates schema_meta on success.
47
47
  */
48
48
  function applyPendingMigrations(db, options = {}) {
49
- const targetVersion = options.targetVersion ?? 8;
49
+ const targetVersion = options.targetVersion ?? 9;
50
50
  let currentVersion = readSchemaVersion(db);
51
51
  if (currentVersion > targetVersion) throw new DatabaseSchemaTooNewError(currentVersion, targetVersion);
52
52
  if (currentVersion >= targetVersion) return currentVersion;
@@ -62,7 +62,7 @@ function applyPendingMigrations(db, options = {}) {
62
62
  }
63
63
  /** Inspect schema version without mutating the database. */
64
64
  function inspectSchemaMigrationStatus(db, options = {}) {
65
- const appVersion = options.targetVersion ?? 8;
65
+ const appVersion = options.targetVersion ?? 9;
66
66
  const dbVersion = readSchemaVersion(db);
67
67
  if (dbVersion > appVersion) return {
68
68
  dbVersion,
@@ -1 +1 @@
1
- {"version":3,"file":"runner.js","names":[],"sources":["../../../../../src/storage/sqlite/migrations/runner.ts"],"sourcesContent":["import { existsSync } from 'node:fs';\nimport { dirname, join } from 'node:path';\nimport { fileURLToPath } from 'node:url';\n\nimport type { DatabaseSync } from 'node:sqlite';\n\nimport { createLogger } from '../../../utils/logger.js';\nimport { readSchemaVersion, setSchemaVersion } from '../schema-version.js';\nimport { discoverSqlMigrations } from './discover.js';\nimport {\n DatabaseSchemaMigrationGapError,\n DatabaseSchemaTooNewError,\n} from './errors.js';\nimport type { ApplyMigrationsOptions, SqlMigration } from './types.js';\n\nconst log = createLogger('Sqlite:Migrations');\n\n/** Baseline schema version applied from schema.sql on first open. */\nexport const XOPC_DB_BASELINE_SCHEMA_VERSION = 3;\n\n/** Latest schema version this release supports (increment when adding migrations). */\nexport const XOPC_DB_SCHEMA_VERSION = 8;\n\nconst MODULE_DIR = dirname(fileURLToPath(import.meta.url));\n\nexport function resolveMigrationsDir(override?: string): string {\n if (override) {\n return override;\n }\n // Packaged Electron gateway bundle: `out/server/index.js` + `out/server/migrations/`.\n const siblingDir = join(MODULE_DIR, 'migrations');\n if (existsSync(siblingDir)) {\n return siblingDir;\n }\n // Dev / dist: SQL files live next to `migrations/runner.js`.\n return MODULE_DIR;\n}\n\nfunction migrationByTarget(\n migrations: SqlMigration[],\n targetVersion: number,\n): SqlMigration | undefined {\n return migrations.find((migration) => migration.targetVersion === targetVersion);\n}\n\nfunction applySingleMigration(db: DatabaseSync, migration: SqlMigration): void {\n log.info({ targetVersion: migration.targetVersion, file: migration.filename }, 'Applying SQLite migration');\n db.exec('BEGIN IMMEDIATE');\n try {\n db.exec(migration.sql);\n setSchemaVersion(db, migration.targetVersion);\n db.exec('COMMIT');\n } catch (error) {\n try {\n db.exec('ROLLBACK');\n } catch {\n /* preserve original error */\n }\n const em = error instanceof Error ? error.message : String(error);\n throw new Error(\n `SQLite migration to v${migration.targetVersion} (${migration.filename}) failed: ${em}`,\n { cause: error },\n );\n }\n}\n\n/**\n * Apply sequential SQL migrations from (currentVersion + 1) through targetVersion.\n * Each step runs in its own transaction and updates schema_meta on success.\n */\nexport function applyPendingMigrations(\n db: DatabaseSync,\n options: ApplyMigrationsOptions = {},\n): number {\n const targetVersion = options.targetVersion ?? XOPC_DB_SCHEMA_VERSION;\n let currentVersion = readSchemaVersion(db);\n\n if (currentVersion > targetVersion) {\n throw new DatabaseSchemaTooNewError(currentVersion, targetVersion);\n }\n\n if (currentVersion >= targetVersion) {\n return currentVersion;\n }\n\n const migrations = discoverSqlMigrations(resolveMigrationsDir(options.migrationsDir));\n\n while (currentVersion < targetVersion) {\n const nextVersion = currentVersion + 1;\n const migration = migrationByTarget(migrations, nextVersion);\n if (!migration) {\n throw new DatabaseSchemaMigrationGapError(currentVersion, targetVersion, nextVersion);\n }\n applySingleMigration(db, migration);\n currentVersion = nextVersion;\n }\n\n return currentVersion;\n}\n\nexport type SchemaMigrationStatus = {\n dbVersion: number;\n appVersion: number;\n pendingVersions: number[];\n isTooNew: boolean;\n hasMigrationGap: boolean;\n missingVersion: number | null;\n};\n\n/** Inspect schema version without mutating the database. */\nexport function inspectSchemaMigrationStatus(\n db: DatabaseSync,\n options: Pick<ApplyMigrationsOptions, 'migrationsDir' | 'targetVersion'> = {},\n): SchemaMigrationStatus {\n const appVersion = options.targetVersion ?? XOPC_DB_SCHEMA_VERSION;\n const dbVersion = readSchemaVersion(db);\n const isTooNew = dbVersion > appVersion;\n\n if (isTooNew) {\n return {\n dbVersion,\n appVersion,\n pendingVersions: [],\n isTooNew: true,\n hasMigrationGap: false,\n missingVersion: null,\n };\n }\n\n const migrations = discoverSqlMigrations(resolveMigrationsDir(options.migrationsDir));\n const pendingVersions: number[] = [];\n let hasMigrationGap = false;\n let missingVersion: number | null = null;\n\n for (let version = dbVersion + 1; version <= appVersion; version++) {\n if (migrationByTarget(migrations, version)) {\n pendingVersions.push(version);\n } else {\n hasMigrationGap = true;\n missingVersion = version;\n break;\n }\n }\n\n return {\n dbVersion,\n appVersion,\n pendingVersions,\n isTooNew: false,\n hasMigrationGap,\n missingVersion,\n };\n}\n"],"mappings":";;;;;;;;;aAMwD;AASxD,MAAM,MAAM,aAAa,oBAAoB;;AAG7C,MAAa,kCAAkC;;AAG/C,MAAa,yBAAyB;AAEtC,MAAM,aAAa,QAAQ,cAAc,OAAO,KAAK,IAAI,CAAC;AAE1D,SAAgB,qBAAqB,UAA2B;AAC9D,KAAI,SACF,QAAO;CAGT,MAAM,aAAa,KAAK,YAAY,aAAa;AACjD,KAAI,WAAW,WAAW,CACxB,QAAO;AAGT,QAAO;;AAGT,SAAS,kBACP,YACA,eAC0B;AAC1B,QAAO,WAAW,MAAM,cAAc,UAAU,kBAAkB,cAAc;;AAGlF,SAAS,qBAAqB,IAAkB,WAA+B;AAC7E,KAAI,KAAK;EAAE,eAAe,UAAU;EAAe,MAAM,UAAU;EAAU,EAAE,4BAA4B;AAC3G,IAAG,KAAK,kBAAkB;AAC1B,KAAI;AACF,KAAG,KAAK,UAAU,IAAI;AACtB,mBAAiB,IAAI,UAAU,cAAc;AAC7C,KAAG,KAAK,SAAS;UACV,OAAO;AACd,MAAI;AACF,MAAG,KAAK,WAAW;UACb;EAGR,MAAM,KAAK,iBAAiB,QAAQ,MAAM,UAAU,OAAO,MAAM;AACjE,QAAM,IAAI,MACR,wBAAwB,UAAU,cAAc,IAAI,UAAU,SAAS,YAAY,MACnF,EAAE,OAAO,OAAO,CACjB;;;;;;;AAQL,SAAgB,uBACd,IACA,UAAkC,EAAE,EAC5B;CACR,MAAM,gBAAgB,QAAQ,iBAAA;CAC9B,IAAI,iBAAiB,kBAAkB,GAAG;AAE1C,KAAI,iBAAiB,cACnB,OAAM,IAAI,0BAA0B,gBAAgB,cAAc;AAGpE,KAAI,kBAAkB,cACpB,QAAO;CAGT,MAAM,aAAa,sBAAsB,qBAAqB,QAAQ,cAAc,CAAC;AAErF,QAAO,iBAAiB,eAAe;EACrC,MAAM,cAAc,iBAAiB;EACrC,MAAM,YAAY,kBAAkB,YAAY,YAAY;AAC5D,MAAI,CAAC,UACH,OAAM,IAAI,gCAAgC,gBAAgB,eAAe,YAAY;AAEvF,uBAAqB,IAAI,UAAU;AACnC,mBAAiB;;AAGnB,QAAO;;;AAaT,SAAgB,6BACd,IACA,UAA2E,EAAE,EACtD;CACvB,MAAM,aAAa,QAAQ,iBAAA;CAC3B,MAAM,YAAY,kBAAkB,GAAG;AAGvC,KAFiB,YAAY,WAG3B,QAAO;EACL;EACA;EACA,iBAAiB,EAAE;EACnB,UAAU;EACV,iBAAiB;EACjB,gBAAgB;EACjB;CAGH,MAAM,aAAa,sBAAsB,qBAAqB,QAAQ,cAAc,CAAC;CACrF,MAAM,kBAA4B,EAAE;CACpC,IAAI,kBAAkB;CACtB,IAAI,iBAAgC;AAEpC,MAAK,IAAI,UAAU,YAAY,GAAG,WAAW,YAAY,UACvD,KAAI,kBAAkB,YAAY,QAAQ,CACxC,iBAAgB,KAAK,QAAQ;MACxB;AACL,oBAAkB;AAClB,mBAAiB;AACjB;;AAIJ,QAAO;EACL;EACA;EACA;EACA,UAAU;EACV;EACA;EACD"}
1
+ {"version":3,"file":"runner.js","names":[],"sources":["../../../../../src/storage/sqlite/migrations/runner.ts"],"sourcesContent":["import { existsSync } from 'node:fs';\nimport { dirname, join } from 'node:path';\nimport { fileURLToPath } from 'node:url';\n\nimport type { DatabaseSync } from 'node:sqlite';\n\nimport { createLogger } from '../../../utils/logger.js';\nimport { readSchemaVersion, setSchemaVersion } from '../schema-version.js';\nimport { discoverSqlMigrations } from './discover.js';\nimport {\n DatabaseSchemaMigrationGapError,\n DatabaseSchemaTooNewError,\n} from './errors.js';\nimport type { ApplyMigrationsOptions, SqlMigration } from './types.js';\n\nconst log = createLogger('Sqlite:Migrations');\n\n/** Baseline schema version applied from schema.sql on first open. */\nexport const XOPC_DB_BASELINE_SCHEMA_VERSION = 3;\n\n/** Latest schema version this release supports (increment when adding migrations). */\nexport const XOPC_DB_SCHEMA_VERSION = 9;\n\nconst MODULE_DIR = dirname(fileURLToPath(import.meta.url));\n\nexport function resolveMigrationsDir(override?: string): string {\n if (override) {\n return override;\n }\n // Packaged Electron gateway bundle: `out/server/index.js` + `out/server/migrations/`.\n const siblingDir = join(MODULE_DIR, 'migrations');\n if (existsSync(siblingDir)) {\n return siblingDir;\n }\n // Dev / dist: SQL files live next to `migrations/runner.js`.\n return MODULE_DIR;\n}\n\nfunction migrationByTarget(\n migrations: SqlMigration[],\n targetVersion: number,\n): SqlMigration | undefined {\n return migrations.find((migration) => migration.targetVersion === targetVersion);\n}\n\nfunction applySingleMigration(db: DatabaseSync, migration: SqlMigration): void {\n log.info({ targetVersion: migration.targetVersion, file: migration.filename }, 'Applying SQLite migration');\n db.exec('BEGIN IMMEDIATE');\n try {\n db.exec(migration.sql);\n setSchemaVersion(db, migration.targetVersion);\n db.exec('COMMIT');\n } catch (error) {\n try {\n db.exec('ROLLBACK');\n } catch {\n /* preserve original error */\n }\n const em = error instanceof Error ? error.message : String(error);\n throw new Error(\n `SQLite migration to v${migration.targetVersion} (${migration.filename}) failed: ${em}`,\n { cause: error },\n );\n }\n}\n\n/**\n * Apply sequential SQL migrations from (currentVersion + 1) through targetVersion.\n * Each step runs in its own transaction and updates schema_meta on success.\n */\nexport function applyPendingMigrations(\n db: DatabaseSync,\n options: ApplyMigrationsOptions = {},\n): number {\n const targetVersion = options.targetVersion ?? XOPC_DB_SCHEMA_VERSION;\n let currentVersion = readSchemaVersion(db);\n\n if (currentVersion > targetVersion) {\n throw new DatabaseSchemaTooNewError(currentVersion, targetVersion);\n }\n\n if (currentVersion >= targetVersion) {\n return currentVersion;\n }\n\n const migrations = discoverSqlMigrations(resolveMigrationsDir(options.migrationsDir));\n\n while (currentVersion < targetVersion) {\n const nextVersion = currentVersion + 1;\n const migration = migrationByTarget(migrations, nextVersion);\n if (!migration) {\n throw new DatabaseSchemaMigrationGapError(currentVersion, targetVersion, nextVersion);\n }\n applySingleMigration(db, migration);\n currentVersion = nextVersion;\n }\n\n return currentVersion;\n}\n\nexport type SchemaMigrationStatus = {\n dbVersion: number;\n appVersion: number;\n pendingVersions: number[];\n isTooNew: boolean;\n hasMigrationGap: boolean;\n missingVersion: number | null;\n};\n\n/** Inspect schema version without mutating the database. */\nexport function inspectSchemaMigrationStatus(\n db: DatabaseSync,\n options: Pick<ApplyMigrationsOptions, 'migrationsDir' | 'targetVersion'> = {},\n): SchemaMigrationStatus {\n const appVersion = options.targetVersion ?? XOPC_DB_SCHEMA_VERSION;\n const dbVersion = readSchemaVersion(db);\n const isTooNew = dbVersion > appVersion;\n\n if (isTooNew) {\n return {\n dbVersion,\n appVersion,\n pendingVersions: [],\n isTooNew: true,\n hasMigrationGap: false,\n missingVersion: null,\n };\n }\n\n const migrations = discoverSqlMigrations(resolveMigrationsDir(options.migrationsDir));\n const pendingVersions: number[] = [];\n let hasMigrationGap = false;\n let missingVersion: number | null = null;\n\n for (let version = dbVersion + 1; version <= appVersion; version++) {\n if (migrationByTarget(migrations, version)) {\n pendingVersions.push(version);\n } else {\n hasMigrationGap = true;\n missingVersion = version;\n break;\n }\n }\n\n return {\n dbVersion,\n appVersion,\n pendingVersions,\n isTooNew: false,\n hasMigrationGap,\n missingVersion,\n };\n}\n"],"mappings":";;;;;;;;;aAMwD;AASxD,MAAM,MAAM,aAAa,oBAAoB;;AAG7C,MAAa,kCAAkC;;AAG/C,MAAa,yBAAyB;AAEtC,MAAM,aAAa,QAAQ,cAAc,OAAO,KAAK,IAAI,CAAC;AAE1D,SAAgB,qBAAqB,UAA2B;AAC9D,KAAI,SACF,QAAO;CAGT,MAAM,aAAa,KAAK,YAAY,aAAa;AACjD,KAAI,WAAW,WAAW,CACxB,QAAO;AAGT,QAAO;;AAGT,SAAS,kBACP,YACA,eAC0B;AAC1B,QAAO,WAAW,MAAM,cAAc,UAAU,kBAAkB,cAAc;;AAGlF,SAAS,qBAAqB,IAAkB,WAA+B;AAC7E,KAAI,KAAK;EAAE,eAAe,UAAU;EAAe,MAAM,UAAU;EAAU,EAAE,4BAA4B;AAC3G,IAAG,KAAK,kBAAkB;AAC1B,KAAI;AACF,KAAG,KAAK,UAAU,IAAI;AACtB,mBAAiB,IAAI,UAAU,cAAc;AAC7C,KAAG,KAAK,SAAS;UACV,OAAO;AACd,MAAI;AACF,MAAG,KAAK,WAAW;UACb;EAGR,MAAM,KAAK,iBAAiB,QAAQ,MAAM,UAAU,OAAO,MAAM;AACjE,QAAM,IAAI,MACR,wBAAwB,UAAU,cAAc,IAAI,UAAU,SAAS,YAAY,MACnF,EAAE,OAAO,OAAO,CACjB;;;;;;;AAQL,SAAgB,uBACd,IACA,UAAkC,EAAE,EAC5B;CACR,MAAM,gBAAgB,QAAQ,iBAAA;CAC9B,IAAI,iBAAiB,kBAAkB,GAAG;AAE1C,KAAI,iBAAiB,cACnB,OAAM,IAAI,0BAA0B,gBAAgB,cAAc;AAGpE,KAAI,kBAAkB,cACpB,QAAO;CAGT,MAAM,aAAa,sBAAsB,qBAAqB,QAAQ,cAAc,CAAC;AAErF,QAAO,iBAAiB,eAAe;EACrC,MAAM,cAAc,iBAAiB;EACrC,MAAM,YAAY,kBAAkB,YAAY,YAAY;AAC5D,MAAI,CAAC,UACH,OAAM,IAAI,gCAAgC,gBAAgB,eAAe,YAAY;AAEvF,uBAAqB,IAAI,UAAU;AACnC,mBAAiB;;AAGnB,QAAO;;;AAaT,SAAgB,6BACd,IACA,UAA2E,EAAE,EACtD;CACvB,MAAM,aAAa,QAAQ,iBAAA;CAC3B,MAAM,YAAY,kBAAkB,GAAG;AAGvC,KAFiB,YAAY,WAG3B,QAAO;EACL;EACA;EACA,iBAAiB,EAAE;EACnB,UAAU;EACV,iBAAiB;EACjB,gBAAgB;EACjB;CAGH,MAAM,aAAa,sBAAsB,qBAAqB,QAAQ,cAAc,CAAC;CACrF,MAAM,kBAA4B,EAAE;CACpC,IAAI,kBAAkB;CACtB,IAAI,iBAAgC;AAEpC,MAAK,IAAI,UAAU,YAAY,GAAG,WAAW,YAAY,UACvD,KAAI,kBAAkB,YAAY,QAAQ,CACxC,iBAAgB,KAAK,QAAQ;MACxB;AACL,oBAAkB;AAClB,mBAAiB;AACjB;;AAIJ,QAAO;EACL;EACA;EACA;EACA,UAAU;EACV;EACA;EACD"}
@@ -19,7 +19,7 @@ const log = createLogger('Sqlite:Migrations');
19
19
  export const XOPC_DB_BASELINE_SCHEMA_VERSION = 3;
20
20
 
21
21
  /** Latest schema version this release supports (increment when adding migrations). */
22
- export const XOPC_DB_SCHEMA_VERSION = 8;
22
+ export const XOPC_DB_SCHEMA_VERSION = 9;
23
23
 
24
24
  const MODULE_DIR = dirname(fileURLToPath(import.meta.url));
25
25
 
@@ -1,7 +1,7 @@
1
1
  import { SCHEMA_META_SCHEMA_VERSION_KEY, ensureSchemaMetaTable, readSchemaVersion, readSchemaVersionForTest, setSchemaVersion } from "./schema-version.js";
2
2
  import { XOPC_DB_BASELINE_SCHEMA_VERSION, XOPC_DB_SCHEMA_VERSION, applyPendingMigrations } from "./migrations/runner.js";
3
- import { dirname, join } from "node:path";
4
3
  import { readFileSync } from "node:fs";
4
+ import { dirname, join } from "node:path";
5
5
  import { fileURLToPath } from "node:url";
6
6
  //#region src/storage/sqlite/schema.ts
7
7
  const SCHEMA_DIR = dirname(fileURLToPath(import.meta.url));
@@ -31,7 +31,7 @@ function ensureXopcDatabaseSchema(db) {
31
31
  bootstrapFreshDatabase(db);
32
32
  currentVersion = 3;
33
33
  }
34
- applyPendingMigrations(db, { targetVersion: 8 });
34
+ applyPendingMigrations(db, { targetVersion: 9 });
35
35
  }
36
36
  //#endregion
37
37
  export { SCHEMA_META_SCHEMA_VERSION_KEY, XOPC_DB_BASELINE_SCHEMA_VERSION, XOPC_DB_SCHEMA_VERSION, ensureSchemaMetaTable, ensureXopcDatabaseSchema, readSchemaVersion, readSchemaVersionForTest, setSchemaVersion };
@@ -131,6 +131,31 @@ CREATE INDEX IF NOT EXISTS idx_cron_runs_job_started
131
131
  CREATE INDEX IF NOT EXISTS idx_cron_runs_started
132
132
  ON cron_runs(started_at DESC);
133
133
 
134
+ CREATE TABLE IF NOT EXISTS cron_jobs (
135
+ job_id TEXT PRIMARY KEY,
136
+ name TEXT NOT NULL,
137
+ description TEXT,
138
+ enabled INTEGER NOT NULL,
139
+ delete_after_run INTEGER,
140
+ created_at_ms INTEGER NOT NULL,
141
+ updated_at_ms INTEGER NOT NULL,
142
+ schedule_json TEXT NOT NULL,
143
+ session_target TEXT NOT NULL,
144
+ wake_mode TEXT NOT NULL,
145
+ agent_id TEXT,
146
+ session_key TEXT,
147
+ working_directory TEXT,
148
+ payload_json TEXT NOT NULL,
149
+ delivery_json TEXT,
150
+ failure_alert_json TEXT,
151
+ state_json TEXT NOT NULL DEFAULT '{}'
152
+ );
153
+
154
+ CREATE INDEX IF NOT EXISTS idx_cron_jobs_enabled_next
155
+ ON cron_jobs(enabled, job_id);
156
+ CREATE INDEX IF NOT EXISTS idx_cron_jobs_updated
157
+ ON cron_jobs(updated_at_ms DESC);
158
+
134
159
  CREATE TABLE IF NOT EXISTS workflow_runs (
135
160
  run_id TEXT PRIMARY KEY,
136
161
  agent_id TEXT NOT NULL,
@@ -1,7 +1,7 @@
1
- import { tmpdir } from "node:os";
2
- import { join } from "node:path";
3
- import { readFileSync, unlinkSync, writeFileSync } from "node:fs";
4
1
  import { randomUUID } from "node:crypto";
2
+ import { readFileSync, unlinkSync, writeFileSync } from "node:fs";
3
+ import { join } from "node:path";
4
+ import { tmpdir } from "node:os";
5
5
  import { spawnSync } from "node:child_process";
6
6
  //#region src/tui/clipboard-image.ts
7
7
  const SUPPORTED_IMAGE_MIME_TYPES = [