@xopcai/xopc 0.0.95 → 0.0.96

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 (428) hide show
  1. package/dist/browser-ext/manifest.json +1 -1
  2. package/dist/extensions/feishu/src/outbound/media-load.js +1 -1
  3. package/dist/extensions/feishu/src/workflow-progress.js +1 -1
  4. package/dist/extensions/telegram/src/plugin.js +1 -1
  5. package/dist/extensions/telegram/src/routing-integration.js +2 -2
  6. package/dist/extensions/telegram/src/workflow-progress.js +1 -1
  7. package/dist/extensions/telegram/xopc.extension.json +1 -1
  8. package/dist/extensions/weixin/src/api/api.js +2 -2
  9. package/dist/extensions/weixin/src/auth/accounts.js +1 -1
  10. package/dist/extensions/weixin/src/cdn/upload.js +1 -1
  11. package/dist/extensions/weixin/src/media/data-url.js +1 -1
  12. package/dist/extensions/weixin/src/messaging/debug-mode.js +1 -1
  13. package/dist/extensions/weixin/src/messaging/inbound.js +1 -1
  14. package/dist/extensions/weixin/src/messaging/process-message.js +1 -1
  15. package/dist/extensions/weixin/src/plugin.js +1 -1
  16. package/dist/extensions/weixin/src/storage/sync-buf.js +1 -1
  17. package/dist/extensions/weixin/src/workflow-progress.js +1 -1
  18. package/dist/gateway/static/root/assets/{agents-CKe2LMnz.js → agents-DmIuSaOE.js} +2 -2
  19. package/dist/gateway/static/root/assets/{apps-page-Mi9mMIZ1.js → apps-page-DFcHBxLw.js} +1 -1
  20. package/dist/gateway/static/root/assets/{channels-settings-BrdyC101.js → channels-settings-DDUf55C5.js} +1 -1
  21. package/dist/gateway/static/root/assets/{channels-status-swr-D55Bu0nn.js → channels-status-swr-BxF-_nzD.js} +1 -1
  22. package/dist/gateway/static/root/assets/{cron-api-CPpx2l-E.js → cron-api-DylQtnb_.js} +1 -1
  23. package/dist/gateway/static/root/assets/{cron-page-Bx2jB0YN.js → cron-page-BO0d9Pf-.js} +1 -1
  24. package/dist/gateway/static/root/assets/{dist-D_AiG_Kg.js → dist-BskF0qDS.js} +1 -1
  25. package/dist/gateway/static/root/assets/{extension-debug-page-6ieHsxRE.js → extension-debug-page-BcZdTdjJ.js} +1 -1
  26. package/dist/gateway/static/root/assets/{extension-page-B8nywHRO.js → extension-page-D2iuDa1D.js} +1 -1
  27. package/dist/gateway/static/root/assets/{extension-settings-page-DrskdEIV.js → extension-settings-page-BKpQCgLc.js} +1 -1
  28. package/dist/gateway/static/root/assets/{fetch-B0aeeY0q.js → fetch-CtNDpjij.js} +1 -1
  29. package/dist/gateway/static/root/assets/{field-primitives--9ooY8Xl.js → field-primitives-2PekrGZF.js} +1 -1
  30. package/dist/gateway/static/root/assets/{heartbeat-config-api-DUZ_W1w-.js → heartbeat-config-api-D3D7SW8A.js} +1 -1
  31. package/dist/gateway/static/root/assets/index-BvEhL9RQ.css +1 -0
  32. package/dist/gateway/static/root/assets/{index-Dj9FuxCm.js → index-Db9fd_X4.js} +74 -74
  33. package/dist/gateway/static/root/assets/{logs-page-CaXqhpKf.js → logs-page-B3I1a26m.js} +1 -1
  34. package/dist/gateway/static/root/assets/{note-detail-page-DYzym2B0.js → note-detail-page-BOizhtJ8.js} +54 -53
  35. package/dist/gateway/static/root/assets/{note-detail-page-B91pLkEI.css → note-detail-page-D4ZIVQbk.css} +1 -1
  36. package/dist/gateway/static/root/assets/{note-time-B-vSi2dR.js → note-time-CjUGtqKr.js} +1 -1
  37. package/dist/gateway/static/root/assets/{notes-page-BkhWdGiT.js → notes-page-BB8-I0Of.js} +1 -1
  38. package/dist/gateway/static/root/assets/{sessions-page-53YFokoe.js → sessions-page-BcH-1K9i.js} +1 -1
  39. package/dist/gateway/static/root/assets/{settings-advanced-gate-BaZmaklx.js → settings-advanced-gate-Czn8nnjN.js} +1 -1
  40. package/dist/gateway/static/root/assets/{settings-form-section-DIJPKpTR.js → settings-form-section-ZZWDwgVe.js} +1 -1
  41. package/dist/gateway/static/root/assets/{settings-page-Dvb230FF.js → settings-page-BX8c_zrN.js} +1 -1
  42. package/dist/gateway/static/root/assets/{share-preview-page-CRyjTAG6.js → share-preview-page-Ch3_6Qah.js} +1 -1
  43. package/dist/gateway/static/root/assets/{skills-page-C5ZJbfAe.js → skills-page-WO0bbJ54.js} +1 -1
  44. package/dist/gateway/static/root/assets/{theme-store-Cg_SuBw0.js → theme-store-XxRFRZDX.js} +1 -1
  45. package/dist/gateway/static/root/assets/url-6zpynn1R.js +3 -0
  46. package/dist/gateway/static/root/assets/{utils-lMYoWhqo.js → utils-uTYKh54l.js} +1 -1
  47. package/dist/gateway/static/root/assets/{voice-api-key-field-Dda2pcUU.js → voice-api-key-field-BIAYHRs-.js} +1 -1
  48. package/dist/gateway/static/root/assets/{workflow-page.utils-KIladUrU.js → workflow-page.utils-BbWhqD36.js} +1 -1
  49. package/dist/gateway/static/root/assets/{workflows-page-BTis4Z7Y.js → workflows-page-D4RIF7E1.js} +1 -1
  50. package/dist/gateway/static/root/index.html +5 -5
  51. package/dist/package.js +1 -1
  52. package/dist/src/agent/agent-manager.js +15 -9
  53. package/dist/src/agent/agent-manager.js.map +1 -1
  54. package/dist/src/agent/agent-scope.d.ts +0 -1
  55. package/dist/src/agent/agent-scope.js +2 -5
  56. package/dist/src/agent/agent-scope.js.map +1 -1
  57. package/dist/src/agent/bootstrap/bootstrap-cache.d.ts +3 -0
  58. package/dist/src/agent/bootstrap/bootstrap-cache.js +13 -3
  59. package/dist/src/agent/bootstrap/bootstrap-cache.js.map +1 -1
  60. package/dist/src/agent/bootstrap/bootstrap-files.d.ts +6 -0
  61. package/dist/src/agent/bootstrap/bootstrap-files.js +35 -12
  62. package/dist/src/agent/bootstrap/bootstrap-files.js.map +1 -1
  63. package/dist/src/agent/bootstrap/load-bootstrap-files.d.ts +5 -2
  64. package/dist/src/agent/bootstrap/load-bootstrap-files.js +12 -3
  65. package/dist/src/agent/bootstrap/load-bootstrap-files.js.map +1 -1
  66. package/dist/src/agent/context/workspace-seed.js +8 -4
  67. package/dist/src/agent/context/workspace-seed.js.map +1 -1
  68. package/dist/src/agent/context/workspace-state.d.ts +52 -0
  69. package/dist/src/agent/context/workspace-state.js +101 -0
  70. package/dist/src/agent/context/workspace-state.js.map +1 -0
  71. package/dist/src/agent/embedded/index.d.ts +2 -2
  72. package/dist/src/agent/embedded/index.js +3 -3
  73. package/dist/src/agent/embedded/run-turn.js +0 -3
  74. package/dist/src/agent/embedded/run-turn.js.map +1 -1
  75. package/dist/src/agent/embedded/session-manager-init.d.ts +0 -17
  76. package/dist/src/agent/embedded/session-manager-init.js +1 -36
  77. package/dist/src/agent/embedded/session-manager-init.js.map +1 -1
  78. package/dist/src/agent/embedded/session-runner.d.ts +3 -12
  79. package/dist/src/agent/embedded/session-runner.js +12 -26
  80. package/dist/src/agent/embedded/session-runner.js.map +1 -1
  81. package/dist/src/agent/embedded/session-tool-result-guard.js +2 -4
  82. package/dist/src/agent/embedded/session-tool-result-guard.js.map +1 -1
  83. package/dist/src/agent/embedded/sqlite-hydrating-session-manager.d.ts +10 -0
  84. package/dist/src/agent/embedded/sqlite-hydrating-session-manager.js +34 -0
  85. package/dist/src/agent/embedded/sqlite-hydrating-session-manager.js.map +1 -0
  86. package/dist/src/agent/goals/goal-run-store.js +4 -4
  87. package/dist/src/agent/goals/persistent-goal-service.js +8 -15
  88. package/dist/src/agent/goals/persistent-goal-service.js.map +1 -1
  89. package/dist/src/agent/goals/post-turn.js +2 -2
  90. package/dist/src/agent/image/load-image-media.js +2 -2
  91. package/dist/src/agent/ipc/bus.js +1 -1
  92. package/dist/src/agent/ipc/inbox.js +2 -2
  93. package/dist/src/agent/ipc/socket.js +1 -1
  94. package/dist/src/agent/mcp/bundle-mcp-materialize.js +1 -1
  95. package/dist/src/agent/mcp/bundle-mcp-runtime.js +2 -2
  96. package/dist/src/agent/mcp/mcp-transport-config.js +1 -1
  97. package/dist/src/agent/mcp/mcp-transport.js +1 -1
  98. package/dist/src/agent/memory/builtin-memory-store.js +1 -1
  99. package/dist/src/agent/memory/dreaming/deep-promotion.js +1 -1
  100. package/dist/src/agent/memory/dreaming/events.js +1 -1
  101. package/dist/src/agent/memory/dreaming/last-run.js +1 -1
  102. package/dist/src/agent/memory/dreaming/light-sweep.js +1 -1
  103. package/dist/src/agent/memory/dreaming/preview.js +1 -1
  104. package/dist/src/agent/memory/dreaming/rem-patterns.js +1 -1
  105. package/dist/src/agent/memory/dreaming/short-term-store.js +1 -1
  106. package/dist/src/agent/memory/dreaming/utils.js +1 -1
  107. package/dist/src/agent/memory/plugin-discovery.js +1 -1
  108. package/dist/src/agent/models/manager.js +1 -1
  109. package/dist/src/agent/prompt/memory/index.d.ts +1 -0
  110. package/dist/src/agent/prompt/memory/index.js +34 -80
  111. package/dist/src/agent/prompt/memory/index.js.map +1 -1
  112. package/dist/src/agent/prompt/service-prompt-builder.js +2 -2
  113. package/dist/src/agent/reply/post-compaction-context.js +1 -1
  114. package/dist/src/agent/reply/workspace-boundary-read.js +1 -1
  115. package/dist/src/agent/sandbox/path-policy.js +2 -2
  116. package/dist/src/agent/service/build-direct-message-content.js +1 -1
  117. package/dist/src/agent/service/process-direct-one-shot.js +8 -17
  118. package/dist/src/agent/service/process-direct-one-shot.js.map +1 -1
  119. package/dist/src/agent/service/process-direct-streaming.js +14 -23
  120. package/dist/src/agent/service/process-direct-streaming.js.map +1 -1
  121. package/dist/src/agent/service.js +7 -11
  122. package/dist/src/agent/service.js.map +1 -1
  123. package/dist/src/agent/session/session-inspector.js +1 -1
  124. package/dist/src/agent/skills/config.js +1 -1
  125. package/dist/src/agent/skills/hub-hash.js +2 -2
  126. package/dist/src/agent/skills/hub-lock.js +1 -1
  127. package/dist/src/agent/skills/hub-pull.js +3 -3
  128. package/dist/src/agent/skills/index.js +1 -1
  129. package/dist/src/agent/skills/managed-store.js +1 -1
  130. package/dist/src/agent/skills/scanner.js +1 -1
  131. package/dist/src/agent/skills/skill-manage-ops.js +1 -1
  132. package/dist/src/agent/skills/skill-manager.js +1 -1
  133. package/dist/src/agent/tools/dreaming-tool.js +1 -1
  134. package/dist/src/agent/tools/factory.js +1 -1
  135. package/dist/src/agent/tools/image-generate-tool.js +1 -1
  136. package/dist/src/agent/tools/index.d.ts +0 -1
  137. package/dist/src/agent/tools/index.js +1 -2
  138. package/dist/src/agent/tools/send-media.js +1 -1
  139. package/dist/src/agent/tools/session-search-tool.d.ts +0 -1
  140. package/dist/src/agent/tools/session-search-tool.js +11 -6
  141. package/dist/src/agent/tools/session-search-tool.js.map +1 -1
  142. package/dist/src/agent/tools/skill-manage-tool.js +1 -1
  143. package/dist/src/agent/tools/workflow-tool.js +1 -1
  144. package/dist/src/agent/tools/write.js +1 -1
  145. package/dist/src/agent/workflow/catalog.js +1 -1
  146. package/dist/src/auth/credentials.js +3 -3
  147. package/dist/src/auth/profiles/store.js +1 -1
  148. package/dist/src/auth/sync-provider-auth.js +1 -1
  149. package/dist/src/browser/cache-dir-policy.js +1 -1
  150. package/dist/src/browser/cdp-local-launcher.js +2 -2
  151. package/dist/src/browser/providers/browser-ext-install.js +4 -4
  152. package/dist/src/browser/providers/cloakbrowser.js +4 -4
  153. package/dist/src/browser/providers/playwright-doctor.js +1 -1
  154. package/dist/src/browser/stealth.js +1 -1
  155. package/dist/src/channels/attachments/inbound-persist.js +1 -1
  156. package/dist/src/channels/attachments/outbound-tts-persist.js +1 -1
  157. package/dist/src/channels/outbound/persist-store.js +1 -1
  158. package/dist/src/channels/pairing/allow-from-file.js +1 -1
  159. package/dist/src/channels/pairing/pairing-store.js +2 -2
  160. package/dist/src/chat-commands/agent-edit.js +2 -2
  161. package/dist/src/chat-commands/builtins/config.js +2 -2
  162. package/dist/src/chat-commands/context.js +1 -1
  163. package/dist/src/cli/commands/config.js +1 -1
  164. package/dist/src/cli/commands/doctor/checks/config-health.js +1 -1
  165. package/dist/src/cli/commands/doctor/checks/provider-auth.js +1 -1
  166. package/dist/src/cli/commands/doctor/checks/session-integrity.js +32 -95
  167. package/dist/src/cli/commands/doctor/checks/session-integrity.js.map +1 -1
  168. package/dist/src/cli/commands/doctor/checks/state-integrity.js +1 -1
  169. package/dist/src/cli/commands/doctor/checks/workspace-status.js +1 -1
  170. package/dist/src/cli/commands/extension-dev.js +1 -1
  171. package/dist/src/cli/commands/extension-marketplace.js +1 -1
  172. package/dist/src/cli/commands/extension-pack.js +1 -1
  173. package/dist/src/cli/commands/gateway/logs.js +1 -1
  174. package/dist/src/cli/commands/image.js +1 -1
  175. package/dist/src/cli/commands/init.js +5 -7
  176. package/dist/src/cli/commands/init.js.map +1 -1
  177. package/dist/src/cli/commands/onboard.js +1 -1
  178. package/dist/src/cli/utils/init-workspace-core.js +2 -2
  179. package/dist/src/commands/agents.config.js +1 -1
  180. package/dist/src/config/agent-profile.js +1 -1
  181. package/dist/src/config/gateway-bind.js +1 -1
  182. package/dist/src/config/index.js +7 -8
  183. package/dist/src/config/index.js.map +1 -1
  184. package/dist/src/config/loader.js +2 -2
  185. package/dist/src/config/models-json.js +2 -2
  186. package/dist/src/config/paths-state.d.ts +3 -0
  187. package/dist/src/config/paths-state.js +7 -3
  188. package/dist/src/config/paths-state.js.map +1 -1
  189. package/dist/src/config/paths.d.ts +5 -35
  190. package/dist/src/config/paths.js +6 -50
  191. package/dist/src/config/paths.js.map +1 -1
  192. package/dist/src/config/profile.js +2 -2
  193. package/dist/src/config/schema.d.ts +15 -0
  194. package/dist/src/config/schema.js +11 -0
  195. package/dist/src/config/schema.js.map +1 -1
  196. package/dist/src/config/workspace-path.js +1 -1
  197. package/dist/src/cron/execution-types.d.ts +42 -0
  198. package/dist/src/cron/executor.js +2 -2
  199. package/dist/src/cron/persistence.js +1 -1
  200. package/dist/src/cron/run-log-store.d.ts +4 -8
  201. package/dist/src/cron/run-log-store.js +26 -78
  202. package/dist/src/cron/run-log-store.js.map +1 -1
  203. package/dist/src/cron/service.d.ts +3 -3
  204. package/dist/src/cron/service.js +2 -2
  205. package/dist/src/cron/service.js.map +1 -1
  206. package/dist/src/cron/types.d.ts +1 -42
  207. package/dist/src/daemon/constants.js +1 -1
  208. package/dist/src/daemon/install-plan.js +2 -2
  209. package/dist/src/daemon/launchd.js +2 -2
  210. package/dist/src/daemon/schtasks.js +2 -2
  211. package/dist/src/daemon/systemd.js +2 -2
  212. package/dist/src/extensions/bundle-mcp.js +1 -1
  213. package/dist/src/extensions/discover-extensions.js +1 -1
  214. package/dist/src/extensions/health.js +1 -1
  215. package/dist/src/extensions/loader.js +1 -1
  216. package/dist/src/extensions/lockfile.js +2 -2
  217. package/dist/src/extensions/update.js +1 -1
  218. package/dist/src/gateway/agents-admin.js +8 -3
  219. package/dist/src/gateway/agents-admin.js.map +1 -1
  220. package/dist/src/gateway/file-path-classifier.d.ts +0 -1
  221. package/dist/src/gateway/file-path-classifier.js +2 -8
  222. package/dist/src/gateway/file-path-classifier.js.map +1 -1
  223. package/dist/src/gateway/hono/lib/config-payload.js +1 -1
  224. package/dist/src/gateway/hono/lib/extension-store.js +2 -2
  225. package/dist/src/gateway/hono/lib/static-ui.js +2 -2
  226. package/dist/src/gateway/hono/oauth.js +1 -1
  227. package/dist/src/gateway/hono/routes/agents.js +1 -1
  228. package/dist/src/gateway/hono/routes/auth-registry-extensions.js +1 -1
  229. package/dist/src/gateway/hono/routes/config-patch/misc.js +1 -1
  230. package/dist/src/gateway/hono/routes/dreaming.js +1 -1
  231. package/dist/src/gateway/hono/routes/host-fs.js +2 -2
  232. package/dist/src/gateway/hono/routes/models.js +1 -1
  233. package/dist/src/gateway/hono/routes/shares.js +1 -1
  234. package/dist/src/gateway/hono/routes/workspace.js +2 -2
  235. package/dist/src/gateway/lock.js +3 -3
  236. package/dist/src/gateway/ports.js +1 -1
  237. package/dist/src/gateway/service/agent-runner.js +2 -2
  238. package/dist/src/gateway/service/marketplace-service.js +2 -2
  239. package/dist/src/gateway/service.js +5 -1
  240. package/dist/src/gateway/service.js.map +1 -1
  241. package/dist/src/gateway/session-reset-service.d.ts +1 -1
  242. package/dist/src/gateway/session-reset-service.js +1 -1
  243. package/dist/src/gateway/session-reset-service.js.map +1 -1
  244. package/dist/src/gateway/workspace-fs-file-list.js +1 -1
  245. package/dist/src/infra/brew.js +1 -1
  246. package/dist/src/infra/node-sqlite.d.ts +1 -0
  247. package/dist/src/infra/node-sqlite.js +17 -0
  248. package/dist/src/infra/node-sqlite.js.map +1 -0
  249. package/dist/src/infra/package-json.js +1 -1
  250. package/dist/src/infra/package-update-steps.js +1 -1
  251. package/dist/src/infra/path-env.js +2 -2
  252. package/dist/src/infra/restart.js +2 -2
  253. package/dist/src/infra/sqlite-errors.d.ts +1 -0
  254. package/dist/src/infra/sqlite-errors.js +77 -0
  255. package/dist/src/infra/sqlite-errors.js.map +1 -0
  256. package/dist/src/infra/stable-node-path.js +1 -1
  257. package/dist/src/infra/unhandled-rejections.d.ts +1 -0
  258. package/dist/src/infra/unhandled-rejections.js +25 -0
  259. package/dist/src/infra/unhandled-rejections.js.map +1 -0
  260. package/dist/src/infra/update-check.js +1 -1
  261. package/dist/src/infra/update-global.js +1 -1
  262. package/dist/src/infra/update-lock.js +3 -3
  263. package/dist/src/infra/update-runner.js +1 -1
  264. package/dist/src/infra/update-startup.js +2 -2
  265. package/dist/src/infra/warning-filter.d.ts +7 -0
  266. package/dist/src/infra/warning-filter.js +59 -0
  267. package/dist/src/infra/warning-filter.js.map +1 -0
  268. package/dist/src/infra/write-file-atomic.js +2 -2
  269. package/dist/src/notes/store.d.ts +3 -9
  270. package/dist/src/notes/store.js +22 -196
  271. package/dist/src/notes/store.js.map +1 -1
  272. package/dist/src/providers/auth-runtime/auth-profile-store.js +1 -1
  273. package/dist/src/providers/index.js +2 -2
  274. package/dist/src/providers/model-registry.js +1 -1
  275. package/dist/src/session/config-store.d.ts +6 -75
  276. package/dist/src/session/config-store.js +38 -144
  277. package/dist/src/session/config-store.js.map +1 -1
  278. package/dist/src/session/config-types.d.ts +15 -0
  279. package/dist/src/session/config-types.js +1 -0
  280. package/dist/src/session/index.d.ts +1 -3
  281. package/dist/src/session/index.js +3 -5
  282. package/dist/src/session/init-session-turn.d.ts +0 -6
  283. package/dist/src/session/init-session-turn.js +18 -18
  284. package/dist/src/session/init-session-turn.js.map +1 -1
  285. package/dist/src/session/lifecycle-timestamps.d.ts +5 -2
  286. package/dist/src/session/lifecycle-timestamps.js.map +1 -1
  287. package/dist/src/session/{parity/load-jsonl-entries.js → load-jsonl-entries.js} +1 -1
  288. package/dist/src/session/load-jsonl-entries.js.map +1 -0
  289. package/dist/src/session/manager.d.ts +5 -3
  290. package/dist/src/session/manager.js +1 -5
  291. package/dist/src/session/manager.js.map +1 -1
  292. package/dist/src/session/resolve-session.d.ts +3 -6
  293. package/dist/src/session/resolve-session.js +26 -31
  294. package/dist/src/session/resolve-session.js.map +1 -1
  295. package/dist/src/session/session-context-for-llm.js +5 -1
  296. package/dist/src/session/session-context-for-llm.js.map +1 -1
  297. package/dist/src/session/session-id.js +12 -0
  298. package/dist/src/session/session-id.js.map +1 -0
  299. package/dist/src/session/session-title.js +2 -2
  300. package/dist/src/session/session-workspace.d.ts +1 -1
  301. package/dist/src/session/session-workspace.js.map +1 -1
  302. package/dist/src/session/store.d.ts +14 -63
  303. package/dist/src/session/store.js +172 -847
  304. package/dist/src/session/store.js.map +1 -1
  305. package/dist/src/session/stored-rows-to-file-entries.d.ts +11 -0
  306. package/dist/src/session/stored-rows-to-file-entries.js +95 -0
  307. package/dist/src/session/stored-rows-to-file-entries.js.map +1 -0
  308. package/dist/src/session/transcript-events.d.ts +1 -2
  309. package/dist/src/session/transcript-events.js +5 -12
  310. package/dist/src/session/transcript-events.js.map +1 -1
  311. package/dist/src/session/transcript-format.d.ts +1 -1
  312. package/dist/src/session/transcript-format.js.map +1 -1
  313. package/dist/src/session/transcript-stats.d.ts +1 -0
  314. package/dist/src/session/transcript-stats.js +10 -0
  315. package/dist/src/session/transcript-stats.js.map +1 -0
  316. package/dist/src/share/share-auto.js +2 -2
  317. package/dist/src/share/share-store.js +3 -3
  318. package/dist/src/share/share-thumbnail.js +2 -2
  319. package/dist/src/share/share-zip.js +1 -1
  320. package/dist/src/share/site-share-store.js +3 -3
  321. package/dist/src/share/site-static-serve.js +1 -1
  322. package/dist/src/storage/sqlite/config-repository.d.ts +6 -0
  323. package/dist/src/storage/sqlite/config-repository.js +56 -0
  324. package/dist/src/storage/sqlite/config-repository.js.map +1 -0
  325. package/dist/src/storage/sqlite/connection.d.ts +38 -0
  326. package/dist/src/storage/sqlite/connection.js +258 -0
  327. package/dist/src/storage/sqlite/connection.js.map +1 -0
  328. package/dist/src/storage/sqlite/cron-run-repository.d.ts +5 -0
  329. package/dist/src/storage/sqlite/cron-run-repository.js +97 -0
  330. package/dist/src/storage/sqlite/cron-run-repository.js.map +1 -0
  331. package/dist/src/storage/sqlite/fts.d.ts +2 -0
  332. package/dist/src/storage/sqlite/fts.js +11 -0
  333. package/dist/src/storage/sqlite/fts.js.map +1 -0
  334. package/dist/src/storage/sqlite/index.d.ts +12 -0
  335. package/dist/src/storage/sqlite/index.js +13 -0
  336. package/dist/src/storage/sqlite/memory-index-repository.d.ts +18 -0
  337. package/dist/src/storage/sqlite/memory-index-repository.js +132 -0
  338. package/dist/src/storage/sqlite/memory-index-repository.js.map +1 -0
  339. package/dist/src/storage/sqlite/notes-repository.d.ts +11 -0
  340. package/dist/src/storage/sqlite/notes-repository.js +191 -0
  341. package/dist/src/storage/sqlite/notes-repository.js.map +1 -0
  342. package/dist/src/storage/sqlite/paths.d.ts +1 -0
  343. package/dist/src/storage/sqlite/paths.js +7 -0
  344. package/dist/src/storage/sqlite/paths.js.map +1 -0
  345. package/dist/src/storage/sqlite/row-mappers.d.ts +82 -0
  346. package/dist/src/storage/sqlite/row-mappers.js +164 -0
  347. package/dist/src/storage/sqlite/row-mappers.js.map +1 -0
  348. package/dist/src/storage/sqlite/schema.d.ts +5 -0
  349. package/dist/src/storage/sqlite/schema.js +43 -0
  350. package/dist/src/storage/sqlite/schema.js.map +1 -0
  351. package/dist/src/storage/sqlite/schema.sql +195 -0
  352. package/dist/src/storage/sqlite/session-metadata.d.ts +8 -0
  353. package/dist/src/storage/sqlite/session-metadata.js +83 -0
  354. package/dist/src/storage/sqlite/session-metadata.js.map +1 -0
  355. package/dist/src/storage/sqlite/session-repository.d.ts +29 -0
  356. package/dist/src/storage/sqlite/session-repository.js +268 -0
  357. package/dist/src/storage/sqlite/session-repository.js.map +1 -0
  358. package/dist/src/storage/sqlite/transaction.d.ts +11 -0
  359. package/dist/src/storage/sqlite/transaction.js +115 -0
  360. package/dist/src/storage/sqlite/transaction.js.map +1 -0
  361. package/dist/src/storage/sqlite/transcript-repository.d.ts +34 -0
  362. package/dist/src/storage/sqlite/transcript-repository.js +241 -0
  363. package/dist/src/storage/sqlite/transcript-repository.js.map +1 -0
  364. package/dist/src/tui/clipboard-image.js +3 -3
  365. package/dist/src/tui/theme-manager.js +1 -1
  366. package/dist/src/tui/tui-keybindings-file.js +1 -1
  367. package/dist/src/tui/tui-scoped-models.js +2 -2
  368. package/dist/src/tui/tui-settings.js +1 -1
  369. package/dist/src/tui/tui.js +3 -3
  370. package/dist/src/tunnel/frpc-binary.js +3 -3
  371. package/dist/src/tunnel/frpc-config.js +1 -1
  372. package/dist/src/tunnel/frpc-extract.js +1 -1
  373. package/dist/src/tunnel/tunnel-state.js +1 -1
  374. package/dist/src/utils/logger/audit.js +1 -1
  375. package/dist/src/utils/logger/log-store.js +1 -1
  376. package/dist/src/utils/logger/rotation.js +1 -1
  377. package/dist/src/voice/tts/audio.js +1 -1
  378. package/dist/src/voice/tts/providers/edge-speech.js +2 -2
  379. package/dist/src/workflows/service/workflow-session-bridge.js +41 -64
  380. package/dist/src/workflows/service/workflow-session-bridge.js.map +1 -1
  381. package/dist/src/workflows/store/event-store.js +1 -1
  382. package/dist/src/workflows/store/run-store.js +1 -1
  383. package/package.json +2 -2
  384. package/dist/gateway/static/root/assets/index-Bj_l8QDp.css +0 -1
  385. package/dist/gateway/static/root/assets/url-BHHmdJYc.js +0 -3
  386. package/dist/src/agent/embedded/session-manager-cache.d.ts +0 -19
  387. package/dist/src/agent/embedded/session-manager-cache.js +0 -48
  388. package/dist/src/agent/embedded/session-manager-cache.js.map +0 -1
  389. package/dist/src/session/parity/artifacts.d.ts +0 -16
  390. package/dist/src/session/parity/artifacts.js +0 -80
  391. package/dist/src/session/parity/artifacts.js.map +0 -1
  392. package/dist/src/session/parity/jsonl-transcript-io.d.ts +0 -54
  393. package/dist/src/session/parity/jsonl-transcript-io.js +0 -236
  394. package/dist/src/session/parity/jsonl-transcript-io.js.map +0 -1
  395. package/dist/src/session/parity/load-jsonl-entries.js.map +0 -1
  396. package/dist/src/session/parity/session-id.js +0 -18
  397. package/dist/src/session/parity/session-id.js.map +0 -1
  398. package/dist/src/session/parity/sessions-json-cache.d.ts +0 -14
  399. package/dist/src/session/parity/sessions-json-cache.js +0 -98
  400. package/dist/src/session/parity/sessions-json-cache.js.map +0 -1
  401. package/dist/src/session/parity/sessions-json-file-read.d.ts +0 -6
  402. package/dist/src/session/parity/sessions-json-file-read.js +0 -19
  403. package/dist/src/session/parity/sessions-json-file-read.js.map +0 -1
  404. package/dist/src/session/parity/sessions-json-file.d.ts +0 -11
  405. package/dist/src/session/parity/sessions-json-file.js +0 -52
  406. package/dist/src/session/parity/sessions-json-file.js.map +0 -1
  407. package/dist/src/session/parity/sessions-json-patch.d.ts +0 -14
  408. package/dist/src/session/parity/sessions-json-patch.js +0 -40
  409. package/dist/src/session/parity/sessions-json-patch.js.map +0 -1
  410. package/dist/src/session/parity/transcript-file-lock.d.ts +0 -22
  411. package/dist/src/session/parity/transcript-file-lock.js +0 -142
  412. package/dist/src/session/parity/transcript-file-lock.js.map +0 -1
  413. package/dist/src/session/parity/transcript-pagination.d.ts +0 -29
  414. package/dist/src/session/parity/transcript-pagination.js +0 -132
  415. package/dist/src/session/parity/transcript-pagination.js.map +0 -1
  416. package/dist/src/session/parity/transcript-paths.d.ts +0 -13
  417. package/dist/src/session/parity/transcript-paths.js +0 -64
  418. package/dist/src/session/parity/transcript-paths.js.map +0 -1
  419. package/dist/src/session/parity/xopc-session-disk-entry.d.ts +0 -22
  420. package/dist/src/session/search-index-cache.d.ts +0 -6
  421. package/dist/src/session/search-index-cache.js +0 -44
  422. package/dist/src/session/search-index-cache.js.map +0 -1
  423. package/dist/src/session/search-index.d.ts +0 -20
  424. package/dist/src/session/search-index.js +0 -124
  425. package/dist/src/session/search-index.js.map +0 -1
  426. /package/dist/src/{session/parity/xopc-session-disk-entry.js → cron/execution-types.js} +0 -0
  427. /package/dist/src/session/{parity/load-jsonl-entries.d.ts → load-jsonl-entries.d.ts} +0 -0
  428. /package/dist/src/session/{parity/session-id.d.ts → session-id.d.ts} +0 -0
@@ -1,32 +1,25 @@
1
1
  import { createLogger } from "../utils/logger/index.js";
2
2
  import { init_logger } from "../utils/logger.js";
3
- import { init_paths, resolveCronRunsDir } from "../config/paths.js";
4
- import { join } from "path";
5
- import { appendFile, mkdir, readFile, readdir, unlink, writeFile } from "fs/promises";
3
+ import { requireXopcDatabase } from "../storage/sqlite/connection.js";
4
+ import { appendCronRun, deleteCronRunsForJob, readAllCronRuns, readCronJobHistory } from "../storage/sqlite/cron-run-repository.js";
5
+ import "../storage/sqlite/index.js";
6
6
  //#region src/cron/run-log-store.ts
7
- init_paths();
8
7
  init_logger();
9
8
  const log = createLogger("CronRunLog");
10
- const MAX_LINES_PER_FILE = 2e3;
11
- const TRIM_TO_LINES = 1500;
12
9
  var CronRunLogStore = class {
13
- dir;
14
- constructor(dir) {
15
- this.dir = dir ?? resolveCronRunsDir();
10
+ dbPath;
11
+ /** @param dbPath Optional SQLite path for tests (opens a dedicated DB). */
12
+ constructor(dbPath) {
13
+ this.dbPath = dbPath;
16
14
  }
17
- async ensureDir() {
18
- await mkdir(this.dir, { recursive: true });
19
- }
20
- jobFile(jobId) {
21
- return join(this.dir, `${jobId}.jsonl`);
15
+ requireDatabase() {
16
+ requireXopcDatabase(this.dbPath ? { path: this.dbPath } : void 0);
22
17
  }
23
18
  async appendCompleted(execution) {
24
19
  if (execution.status === "running") return;
25
20
  try {
26
- await this.ensureDir();
27
- const line = `${JSON.stringify(execution)}\n`;
28
- await appendFile(this.jobFile(execution.jobId), line, "utf8");
29
- await this.maybeTrimFile(execution.jobId);
21
+ this.requireDatabase();
22
+ appendCronRun(execution);
30
23
  } catch (err) {
31
24
  log.error({
32
25
  jobId: execution.jobId,
@@ -34,72 +27,27 @@ var CronRunLogStore = class {
34
27
  }, "Failed to persist cron run");
35
28
  }
36
29
  }
37
- async maybeTrimFile(jobId) {
38
- const file = this.jobFile(jobId);
39
- let content;
40
- try {
41
- content = await readFile(file, "utf8");
42
- } catch {
43
- return;
44
- }
45
- const lines = content.split("\n").filter((l) => l.trim().length > 0);
46
- if (lines.length <= MAX_LINES_PER_FILE) return;
47
- await writeFile(file, `${lines.slice(-TRIM_TO_LINES).join("\n")}\n`, "utf8");
48
- }
49
30
  async readJobHistory(jobId, limit) {
50
- if (limit <= 0) return [];
51
- let content;
52
- try {
53
- content = await readFile(this.jobFile(jobId), "utf8");
54
- } catch {
55
- return [];
56
- }
57
- const lines = content.split("\n").filter((l) => l.trim().length > 0);
58
- const parsed = [];
59
- for (const line of lines) try {
60
- parsed.push(JSON.parse(line));
61
- } catch {}
62
- parsed.sort((a, b) => new Date(b.startedAt).getTime() - new Date(a.startedAt).getTime());
63
- return parsed.slice(0, limit);
31
+ this.requireDatabase();
32
+ return readCronJobHistory(jobId, limit);
64
33
  }
65
- /**
66
- * Latest runs across all jobs (disk only). Caller supplies job names for display.
67
- */
68
34
  async readAllRuns(limit, jobNames) {
69
- if (limit <= 0) return [];
70
- let names;
71
- try {
72
- await this.ensureDir();
73
- names = await readdir(this.dir);
74
- } catch {
75
- return [];
76
- }
77
- const rows = [];
78
- for (const fname of names) {
79
- if (!fname.endsWith(".jsonl")) continue;
80
- const jobId = fname.slice(0, -6);
81
- let content;
82
- try {
83
- content = await readFile(join(this.dir, fname), "utf8");
84
- } catch {
85
- continue;
86
- }
87
- const lines = content.split("\n").filter((l) => l.trim().length > 0);
88
- for (const line of lines) try {
89
- const e = JSON.parse(line);
90
- rows.push({
91
- ...e,
92
- jobName: jobNames.get(jobId) ?? jobNames.get(e.jobId)
93
- });
94
- } catch {}
95
- }
96
- rows.sort((a, b) => new Date(b.startedAt).getTime() - new Date(a.startedAt).getTime());
97
- return rows.slice(0, limit);
35
+ this.requireDatabase();
36
+ return readAllCronRuns(limit).map((execution) => ({
37
+ ...execution,
38
+ jobName: jobNames.get(execution.jobId)
39
+ }));
98
40
  }
99
41
  async deleteJobRuns(jobId) {
100
42
  try {
101
- await unlink(this.jobFile(jobId));
102
- } catch {}
43
+ this.requireDatabase();
44
+ deleteCronRunsForJob(jobId);
45
+ } catch (err) {
46
+ log.warn({
47
+ jobId,
48
+ err
49
+ }, "Failed to delete cron runs");
50
+ }
103
51
  }
104
52
  };
105
53
  //#endregion
@@ -1 +1 @@
1
- {"version":3,"file":"run-log-store.js","names":[],"sources":["../../../src/cron/run-log-store.ts"],"sourcesContent":["// Append-only JSONL run history per job (durable across restarts)\nimport { appendFile, mkdir, readFile, readdir, unlink, writeFile } from 'fs/promises';\nimport { join } from 'path';\nimport { resolveCronRunsDir } from '../config/paths.js';\nimport { createLogger } from '../utils/logger.js';\nimport type { CronRunHistoryRow, JobExecution } from './types.js';\n\nconst log = createLogger('CronRunLog');\n\nconst MAX_LINES_PER_FILE = 2000;\nconst TRIM_TO_LINES = 1500;\n\nexport class CronRunLogStore {\n private readonly dir: string;\n\n constructor(dir?: string) {\n this.dir = dir ?? resolveCronRunsDir();\n }\n\n private async ensureDir(): Promise<void> {\n await mkdir(this.dir, { recursive: true });\n }\n\n private jobFile(jobId: string): string {\n return join(this.dir, `${jobId}.jsonl`);\n }\n\n async appendCompleted(execution: JobExecution): Promise<void> {\n if (execution.status === 'running') {\n return;\n }\n try {\n await this.ensureDir();\n const line = `${JSON.stringify(execution)}\\n`;\n await appendFile(this.jobFile(execution.jobId), line, 'utf8');\n await this.maybeTrimFile(execution.jobId);\n } catch (err) {\n log.error({ jobId: execution.jobId, err: err as Error }, 'Failed to persist cron run');\n }\n }\n\n private async maybeTrimFile(jobId: string): Promise<void> {\n const file = this.jobFile(jobId);\n let content: string;\n try {\n content = await readFile(file, 'utf8');\n } catch {\n return;\n }\n const lines = content.split('\\n').filter((l) => l.trim().length > 0);\n if (lines.length <= MAX_LINES_PER_FILE) {\n return;\n }\n const kept = lines.slice(-TRIM_TO_LINES);\n await writeFile(file, `${kept.join('\\n')}\\n`, 'utf8');\n }\n\n async readJobHistory(jobId: string, limit: number): Promise<JobExecution[]> {\n if (limit <= 0) {\n return [];\n }\n let content: string;\n try {\n content = await readFile(this.jobFile(jobId), 'utf8');\n } catch {\n return [];\n }\n const lines = content.split('\\n').filter((l) => l.trim().length > 0);\n const parsed: JobExecution[] = [];\n for (const line of lines) {\n try {\n parsed.push(JSON.parse(line) as JobExecution);\n } catch {\n // skip bad line\n }\n }\n parsed.sort((a, b) => new Date(b.startedAt).getTime() - new Date(a.startedAt).getTime());\n return parsed.slice(0, limit);\n }\n\n /**\n * Latest runs across all jobs (disk only). Caller supplies job names for display.\n */\n async readAllRuns(limit: number, jobNames: Map<string, string | undefined>): Promise<CronRunHistoryRow[]> {\n if (limit <= 0) {\n return [];\n }\n let names: string[];\n try {\n await this.ensureDir();\n names = await readdir(this.dir);\n } catch {\n return [];\n }\n\n const rows: CronRunHistoryRow[] = [];\n for (const fname of names) {\n if (!fname.endsWith('.jsonl')) {\n continue;\n }\n const jobId = fname.slice(0, -'.jsonl'.length);\n let content: string;\n try {\n content = await readFile(join(this.dir, fname), 'utf8');\n } catch {\n continue;\n }\n const lines = content.split('\\n').filter((l) => l.trim().length > 0);\n for (const line of lines) {\n try {\n const e = JSON.parse(line) as JobExecution;\n rows.push({\n ...e,\n jobName: jobNames.get(jobId) ?? jobNames.get(e.jobId),\n });\n } catch {\n // skip\n }\n }\n }\n\n rows.sort((a, b) => new Date(b.startedAt).getTime() - new Date(a.startedAt).getTime());\n return rows.slice(0, limit);\n }\n\n async deleteJobRuns(jobId: string): Promise<void> {\n try {\n await unlink(this.jobFile(jobId));\n } catch {\n // ignore missing\n }\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"run-log-store.js","names":[],"sources":["../../../src/cron/run-log-store.ts"],"sourcesContent":["// Durable cron run history in SQLite (`cron_runs` table).\nimport { createLogger } from '../utils/logger.js';\nimport {\n appendCronRun,\n deleteCronRunsForJob,\n requireXopcDatabase,\n readAllCronRuns,\n readCronJobHistory,\n} from '../storage/sqlite/index.js';\nimport type { CronRunHistoryRow, JobExecution } from './types.js';\n\nconst log = createLogger('CronRunLog');\n\nexport class CronRunLogStore {\n private readonly dbPath?: string;\n\n /** @param dbPath Optional SQLite path for tests (opens a dedicated DB). */\n constructor(dbPath?: string) {\n this.dbPath = dbPath;\n }\n\n private requireDatabase(): void {\n requireXopcDatabase(this.dbPath ? { path: this.dbPath } : undefined);\n }\n\n async appendCompleted(execution: JobExecution): Promise<void> {\n if (execution.status === 'running') {\n return;\n }\n try {\n this.requireDatabase();\n appendCronRun(execution);\n } catch (err) {\n log.error({ jobId: execution.jobId, err: err as Error }, 'Failed to persist cron run');\n }\n }\n\n async readJobHistory(jobId: string, limit: number): Promise<JobExecution[]> {\n this.requireDatabase();\n return readCronJobHistory(jobId, limit);\n }\n\n async readAllRuns(limit: number, jobNames: Map<string, string | undefined>): Promise<CronRunHistoryRow[]> {\n this.requireDatabase();\n const rows = readAllCronRuns(limit);\n return rows.map((execution) => ({\n ...execution,\n jobName: jobNames.get(execution.jobId),\n }));\n }\n\n async deleteJobRuns(jobId: string): Promise<void> {\n try {\n this.requireDatabase();\n deleteCronRunsForJob(jobId);\n } catch (err) {\n log.warn({ jobId, err: err as Error }, 'Failed to delete cron runs');\n }\n }\n}\n"],"mappings":";;;;;;aACkD;AAUlD,MAAM,MAAM,aAAa,aAAa;AAEtC,IAAa,kBAAb,MAA6B;CAC3B;;CAGA,YAAY,QAAiB;AAC3B,OAAK,SAAS;;CAGhB,kBAAgC;AAC9B,sBAAoB,KAAK,SAAS,EAAE,MAAM,KAAK,QAAQ,GAAG,KAAA,EAAU;;CAGtE,MAAM,gBAAgB,WAAwC;AAC5D,MAAI,UAAU,WAAW,UACvB;AAEF,MAAI;AACF,QAAK,iBAAiB;AACtB,iBAAc,UAAU;WACjB,KAAK;AACZ,OAAI,MAAM;IAAE,OAAO,UAAU;IAAY;IAAc,EAAE,6BAA6B;;;CAI1F,MAAM,eAAe,OAAe,OAAwC;AAC1E,OAAK,iBAAiB;AACtB,SAAO,mBAAmB,OAAO,MAAM;;CAGzC,MAAM,YAAY,OAAe,UAAyE;AACxG,OAAK,iBAAiB;AAEtB,SADa,gBAAgB,MAClB,CAAC,KAAK,eAAe;GAC9B,GAAG;GACH,SAAS,SAAS,IAAI,UAAU,MAAM;GACvC,EAAE;;CAGL,MAAM,cAAc,OAA8B;AAChD,MAAI;AACF,QAAK,iBAAiB;AACtB,wBAAqB,MAAM;WACpB,KAAK;AACZ,OAAI,KAAK;IAAE;IAAY;IAAc,EAAE,6BAA6B"}
@@ -4,8 +4,8 @@ export interface CronServiceConfig {
4
4
  filePath?: string;
5
5
  agentService?: any;
6
6
  messageBus?: any;
7
- /** Override run log directory (tests) */
8
- runsDir?: string;
7
+ /** Override SQLite database path (tests). */
8
+ dbPath?: string;
9
9
  }
10
10
  export declare class CronService {
11
11
  private persistence;
@@ -52,7 +52,7 @@ export declare class CronService {
52
52
  */
53
53
  toggleJob(id: string, enabled: boolean): Promise<boolean>;
54
54
  /**
55
- * Execution history for one job: merged in-memory (incl. running) + persisted JSONL.
55
+ * Execution history for one job: merged in-memory (incl. running) + persisted SQLite rows.
56
56
  */
57
57
  getJobHistory(jobId: string, limit?: number): Promise<JobExecution[]>;
58
58
  /**
@@ -24,7 +24,7 @@ var CronService = class {
24
24
  const filePath = config?.filePath || resolveCronJobsPath();
25
25
  this.persistence = new CronPersistence(filePath);
26
26
  this.executor = new DefaultJobExecutor();
27
- this.runLogStore = new CronRunLogStore(config?.runsDir);
27
+ this.runLogStore = new CronRunLogStore(config?.dbPath);
28
28
  this.executor.setRunLogStore(this.runLogStore);
29
29
  if (config?.agentService || config?.messageBus) this.setDeps({
30
30
  agentService: config.agentService,
@@ -192,7 +192,7 @@ var CronService = class {
192
192
  return true;
193
193
  }
194
194
  /**
195
- * Execution history for one job: merged in-memory (incl. running) + persisted JSONL.
195
+ * Execution history for one job: merged in-memory (incl. running) + persisted SQLite rows.
196
196
  */
197
197
  async getJobHistory(jobId, limit) {
198
198
  const cap = Math.min(Math.max(limit ?? 10, 1), 500);
@@ -1 +1 @@
1
- {"version":3,"file":"service.js","names":["uuidv4"],"sources":["../../../src/cron/service.ts"],"sourcesContent":["// CronService - Optimized with async I/O, caching, and execution tracking\nimport nodeCron from 'node-cron';\nimport { CronExpressionParser } from 'cron-parser';\nimport { v4 as uuidv4 } from 'uuid';\nimport { Config } from '../config/index.js';\nimport { resolveCronJobsPath } from '../config/paths.js';\nimport { createLogger } from '../utils/logger.js';\nimport { CronPersistence } from './persistence.js';\nimport { DefaultJobExecutor } from './executor.js';\nimport { CronRunLogStore } from './run-log-store.js';\nimport { z } from 'zod';\nimport { AddJobRequestSchema, UpdateJobRequestSchema } from './validation.js';\nimport type {\n JobData,\n JobExecution,\n JobExecutorDeps,\n CronMetrics,\n CronHealth,\n AddJobOptions,\n JobWithNextRun,\n CronRunHistoryRow,\n} from './types.js';\n\nconst log = createLogger('CronService');\n\ninterface ScheduledTask {\n stop: () => void;\n}\n\nexport interface CronServiceConfig {\n filePath?: string;\n agentService?: any;\n messageBus?: any;\n /** Override run log directory (tests) */\n runsDir?: string;\n}\n\nexport class CronService {\n private persistence: CronPersistence;\n private executor: DefaultJobExecutor;\n private runLogStore: CronRunLogStore;\n private tasks: Map<string, ScheduledTask> = new Map();\n private initialized = false;\n private agentService: any = null;\n private messageBus: any = null;\n\n constructor(config?: CronServiceConfig) {\n const filePath = config?.filePath || resolveCronJobsPath();\n this.persistence = new CronPersistence(filePath);\n this.executor = new DefaultJobExecutor();\n this.runLogStore = new CronRunLogStore(config?.runsDir);\n this.executor.setRunLogStore(this.runLogStore);\n\n // Set dependencies if provided\n if (config?.agentService || config?.messageBus) {\n this.setDeps({\n agentService: config.agentService,\n messageBus: config.messageBus,\n });\n }\n }\n\n /**\n * Set dependencies for the executor\n */\n setDeps(deps: JobExecutorDeps): void {\n this.agentService = deps.agentService;\n this.messageBus = deps.messageBus;\n this.executor.setDeps(deps);\n log.debug('CronService dependencies set');\n }\n\n /**\n * Initialize the service and load all jobs\n */\n async initialize(): Promise<void> {\n if (this.initialized) return;\n\n await this.persistence.initialize();\n await this.loadAllJobs();\n\n this.initialized = true;\n log.debug('CronService initialized');\n }\n\n /**\n * Add a new job\n */\n async addJob(schedule: string, options: AddJobOptions): Promise<{ id: string; schedule: string }> {\n const validationResult = AddJobRequestSchema.safeParse({\n schedule,\n ...options,\n });\n\n if (!validationResult.success) {\n const errorMsg = (validationResult as { error?: { errors: z.ZodIssue[] } }).error?.errors.map((e) => e.message).join(', ') || 'Unknown validation error';\n throw new Error(`Validation failed: ${errorMsg}`);\n }\n\n const data = validationResult.data;\n const id = uuidv4().slice(0, 8);\n const now = new Date().toISOString();\n const sessionTarget = data.sessionTarget ?? 'main';\n\n const job: JobData = {\n id,\n name: data.name,\n schedule: data.schedule,\n enabled: true,\n timezone: data.timezone,\n maxRetries: data.maxRetries ?? 3,\n timeout: data.timeout ?? 60000,\n created_at: now,\n updated_at: now,\n sessionTarget,\n ...(data.agentId ? { agentId: data.agentId } : {}),\n ...(data.workingDirectory ? { workingDirectory: data.workingDirectory } : {}),\n payload: data.payload,\n delivery: data.delivery,\n model: data.model,\n };\n\n // Save to persistence\n await this.persistence.addJob(job);\n\n // Schedule the job\n this.scheduleJob(job);\n\n log.info({ jobId: id, name: data.name, sessionTarget }, 'Job added');\n return { id, schedule: data.schedule };\n }\n\n /**\n * List all jobs with next run time\n */\n async listJobs(): Promise<JobWithNextRun[]> {\n const jobs = await this.persistence.getJobs();\n\n return jobs.map((job) => {\n let nextRun: string | undefined;\n\n if (job.enabled) {\n try {\n const options = job.timezone ? { tz: job.timezone } : undefined;\n const interval = CronExpressionParser.parse(job.schedule, options);\n nextRun = interval.next().toISOString();\n } catch (err) {\n log.debug({ jobId: job.id, err: err as Error }, 'Failed to parse cron for next run');\n }\n }\n\n return {\n id: job.id,\n name: job.name,\n schedule: job.schedule,\n enabled: job.enabled,\n timezone: job.timezone,\n maxRetries: job.maxRetries,\n timeout: job.timeout,\n sessionTarget: job.sessionTarget,\n ...(job.agentId ? { agentId: job.agentId } : {}),\n ...(job.workingDirectory ? { workingDirectory: job.workingDirectory } : {}),\n payload: job.payload,\n delivery: job.delivery,\n model: job.model,\n next_run: nextRun,\n };\n });\n }\n\n /**\n * Get a single job\n */\n async getJob(id: string): Promise<JobData | null> {\n return this.persistence.getJob(id);\n }\n\n /**\n * Update a job\n */\n async updateJob(id: string, updates: Partial<Omit<JobData, 'id' | 'created_at' | 'updated_at'>>): Promise<boolean> {\n // Validate updates\n const validationResult = UpdateJobRequestSchema.safeParse(updates);\n if (!validationResult.success) {\n const errorMsg = (validationResult as { error?: { errors: z.ZodIssue[] } }).error?.errors.map((e) => e.message).join(', ') || 'Unknown validation error';\n throw new Error(`Validation failed: ${errorMsg}`);\n }\n\n const job = await this.persistence.getJob(id);\n if (!job) return false;\n\n const validated = validationResult.data;\n const { agentId: agentIdPatch, workingDirectory: workingDirectoryPatch, ...rest } = validated;\n const patch: Partial<JobData> = { ...rest };\n let clearAgentId = false;\n if (agentIdPatch === null) {\n clearAgentId = true;\n } else if (agentIdPatch !== undefined) {\n patch.agentId = agentIdPatch;\n }\n\n let clearWorkingDirectory = false;\n if (workingDirectoryPatch === null) {\n clearWorkingDirectory = true;\n } else if (workingDirectoryPatch !== undefined) {\n patch.workingDirectory = workingDirectoryPatch;\n }\n\n // Cancel existing task if schedule changes\n if (patch.schedule && patch.schedule !== job.schedule) {\n this.cancelTask(id);\n }\n\n // Update persistence\n await this.persistence.updateJob(id, patch, { clearAgentId, clearWorkingDirectory });\n\n // Re-schedule if needed\n const updated = await this.persistence.getJob(id);\n if (updated && updated.enabled) {\n this.scheduleJob(updated);\n }\n\n log.info({ jobId: id }, 'Job updated');\n return true;\n }\n\n /**\n * Remove a job\n */\n async removeJob(id: string): Promise<boolean> {\n // Cancel task\n this.cancelTask(id);\n\n // Remove from persistence\n const removed = await this.persistence.removeJob(id);\n\n if (removed) {\n await this.runLogStore.deleteJobRuns(id);\n log.info({ jobId: id }, 'Job removed');\n }\n\n return removed;\n }\n\n /**\n * Toggle job enabled state\n */\n async toggleJob(id: string, enabled: boolean): Promise<boolean> {\n const job = await this.persistence.getJob(id);\n if (!job) return false;\n\n await this.persistence.updateJob(id, { enabled });\n\n if (enabled) {\n const updated = await this.persistence.getJob(id);\n if (updated) this.scheduleJob(updated);\n } else {\n this.cancelTask(id);\n }\n\n log.info({ jobId: id, enabled }, 'Job toggled');\n return true;\n }\n\n /**\n * Execution history for one job: merged in-memory (incl. running) + persisted JSONL.\n */\n async getJobHistory(jobId: string, limit?: number): Promise<JobExecution[]> {\n const cap = Math.min(Math.max(limit ?? 10, 1), 500);\n const [disk, memory] = await Promise.all([\n this.runLogStore.readJobHistory(jobId, cap * 2),\n Promise.resolve(this.executor.getHistory(jobId, cap * 2)),\n ]);\n const byId = new Map<string, JobExecution>();\n for (const e of memory) {\n byId.set(e.id, e);\n }\n for (const e of disk) {\n if (!byId.has(e.id)) {\n byId.set(e.id, e);\n }\n }\n const merged = [...byId.values()].sort(\n (a, b) => new Date(b.startedAt).getTime() - new Date(a.startedAt).getTime()\n );\n return merged.slice(0, cap);\n }\n\n /**\n * Latest runs across all jobs (persisted rows + optional job name).\n */\n async getAllRunsHistory(limit?: number): Promise<CronRunHistoryRow[]> {\n const cap = Math.min(Math.max(limit ?? 50, 1), 500);\n const jobs = await this.persistence.getJobs();\n const jobNames = new Map<string, string | undefined>(jobs.map((j) => [j.id, j.name] as const));\n return this.runLogStore.readAllRuns(cap, jobNames);\n }\n\n /**\n * Get service metrics\n */\n async getMetrics(): Promise<CronMetrics> {\n const jobs = await this.persistence.getJobs();\n const enabled = jobs.filter((j) => j.enabled);\n\n let nextScheduledJob: CronMetrics['nextScheduledJob'] | undefined;\n\n for (const job of enabled) {\n try {\n const options = job.timezone ? { tz: job.timezone } : undefined;\n const interval = CronExpressionParser.parse(job.schedule, options);\n const next = interval.next();\n\n if (!nextScheduledJob || next.getTime() < nextScheduledJob.runAt.getTime()) {\n nextScheduledJob = {\n id: job.id,\n name: job.name,\n runAt: next.toDate(),\n };\n }\n } catch {\n // Skip invalid schedules\n }\n }\n\n return {\n totalJobs: jobs.length,\n runningJobs: this.tasks.size,\n enabledJobs: enabled.length,\n failedLastHour: 0, // TODO: track from executor\n avgExecutionTime: 0, // TODO: track from executor\n nextScheduledJob,\n };\n }\n\n /**\n * Update config (hot reload)\n */\n updateConfig(_config: Config): void {\n log.debug('Cron config updated (jobs managed separately via addJob/removeJob)');\n }\n\n /**\n * Health check\n */\n async healthCheck(): Promise<CronHealth> {\n const issues: string[] = [];\n\n // Check if initialized\n if (!this.initialized) {\n issues.push('Service not initialized');\n }\n\n // Check for jobs with invalid schedules\n const jobs = await this.persistence.getJobs();\n for (const job of jobs) {\n if (!nodeCron.validate(job.schedule)) {\n issues.push(`Job ${job.id} has invalid schedule`);\n }\n }\n\n // Check if agent service is configured for isolated jobs\n for (const job of jobs) {\n if (job.enabled && job.sessionTarget === 'isolated' && !this.agentService) {\n issues.push(`Job ${job.id} requires agent service but none configured`);\n break;\n }\n }\n\n // Determine status\n let status: CronHealth['status'] = 'healthy';\n if (issues.length > 0) {\n status = issues.length > 5 ? 'unhealthy' : 'degraded';\n }\n\n return { status, issues };\n }\n\n /**\n * Run a job immediately (manual trigger)\n */\n async runJobNow(id: string): Promise<void> {\n const job = await this.persistence.getJob(id);\n if (!job) throw new Error(`Job not found: ${id}`);\n if (!job.enabled) throw new Error(`Job is disabled: ${id}`);\n\n await this.executeJob(job);\n }\n\n /**\n * Stop all jobs and cleanup\n */\n async stop(options?: { waitForRunning?: boolean; timeout?: number }): Promise<void> {\n const timeout = options?.timeout ?? 30000;\n\n // Cancel all scheduled tasks\n for (const [id, task] of this.tasks) {\n task.stop();\n\n // Cancel running executions\n this.executor.cancelJob(id);\n }\n this.tasks.clear();\n\n // Wait for running jobs if requested\n if (options?.waitForRunning) {\n const start = Date.now();\n while (Date.now() - start < timeout) {\n const running = this.executor.getRunningExecutions();\n if (running.length === 0) break;\n await new Promise((r) => setTimeout(r, 100));\n }\n }\n\n // Flush any pending writes\n await this.persistence.flush();\n\n log.info('CronService stopped');\n }\n\n /**\n * Load and schedule all enabled jobs\n */\n private async loadAllJobs(): Promise<void> {\n const jobs = await this.persistence.getJobs();\n\n for (const job of jobs) {\n if (job.enabled) {\n this.scheduleJob(job);\n }\n }\n\n log.debug({ count: this.tasks.size }, 'Jobs loaded');\n }\n\n /**\n * Schedule a job with node-cron\n */\n private scheduleJob(job: JobData): void {\n // Cancel existing if any\n this.cancelTask(job.id);\n\n // Validate schedule\n if (!nodeCron.validate(job.schedule)) {\n log.error({ jobId: job.id, schedule: job.schedule }, 'Invalid cron expression');\n return;\n }\n\n const options = job.timezone ? { timezone: job.timezone } : undefined;\n\n const task = nodeCron.schedule(\n job.schedule,\n async () => {\n await this.executeJob(job);\n },\n options\n );\n\n this.tasks.set(job.id, task);\n log.debug({ jobId: job.id, schedule: job.schedule }, 'Job scheduled');\n }\n\n /**\n * Execute a job with retry logic\n */\n private async executeJob(job: JobData): Promise<void> {\n // Prevent overlapping executions\n if (this.executor.isRunning(job.id)) {\n log.warn({ jobId: job.id }, 'Job already running, skipping');\n return;\n }\n\n const controller = new AbortController();\n\n try {\n await this.executor.execute(job, controller.signal);\n } catch (error) {\n log.error({ jobId: job.id, err: error as Error }, 'Job execution failed');\n // Retry logic can be added here based on error type\n }\n }\n\n /**\n * Cancel a scheduled task\n */\n private cancelTask(id: string): void {\n const task = this.tasks.get(id);\n if (task) {\n task.stop();\n this.tasks.delete(id);\n log.debug({ jobId: id }, 'Task cancelled');\n }\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"service.js","names":["uuidv4"],"sources":["../../../src/cron/service.ts"],"sourcesContent":["// CronService - Optimized with async I/O, caching, and execution tracking\nimport nodeCron from 'node-cron';\nimport { CronExpressionParser } from 'cron-parser';\nimport { v4 as uuidv4 } from 'uuid';\nimport { Config } from '../config/index.js';\nimport { resolveCronJobsPath } from '../config/paths.js';\nimport { createLogger } from '../utils/logger.js';\nimport { CronPersistence } from './persistence.js';\nimport { DefaultJobExecutor } from './executor.js';\nimport { CronRunLogStore } from './run-log-store.js';\nimport { z } from 'zod';\nimport { AddJobRequestSchema, UpdateJobRequestSchema } from './validation.js';\nimport type {\n JobData,\n JobExecution,\n JobExecutorDeps,\n CronMetrics,\n CronHealth,\n AddJobOptions,\n JobWithNextRun,\n CronRunHistoryRow,\n} from './types.js';\n\nconst log = createLogger('CronService');\n\ninterface ScheduledTask {\n stop: () => void;\n}\n\nexport interface CronServiceConfig {\n filePath?: string;\n agentService?: any;\n messageBus?: any;\n /** Override SQLite database path (tests). */\n dbPath?: string;\n}\n\nexport class CronService {\n private persistence: CronPersistence;\n private executor: DefaultJobExecutor;\n private runLogStore: CronRunLogStore;\n private tasks: Map<string, ScheduledTask> = new Map();\n private initialized = false;\n private agentService: any = null;\n private messageBus: any = null;\n\n constructor(config?: CronServiceConfig) {\n const filePath = config?.filePath || resolveCronJobsPath();\n this.persistence = new CronPersistence(filePath);\n this.executor = new DefaultJobExecutor();\n this.runLogStore = new CronRunLogStore(config?.dbPath);\n this.executor.setRunLogStore(this.runLogStore);\n\n // Set dependencies if provided\n if (config?.agentService || config?.messageBus) {\n this.setDeps({\n agentService: config.agentService,\n messageBus: config.messageBus,\n });\n }\n }\n\n /**\n * Set dependencies for the executor\n */\n setDeps(deps: JobExecutorDeps): void {\n this.agentService = deps.agentService;\n this.messageBus = deps.messageBus;\n this.executor.setDeps(deps);\n log.debug('CronService dependencies set');\n }\n\n /**\n * Initialize the service and load all jobs\n */\n async initialize(): Promise<void> {\n if (this.initialized) return;\n\n await this.persistence.initialize();\n await this.loadAllJobs();\n\n this.initialized = true;\n log.debug('CronService initialized');\n }\n\n /**\n * Add a new job\n */\n async addJob(schedule: string, options: AddJobOptions): Promise<{ id: string; schedule: string }> {\n const validationResult = AddJobRequestSchema.safeParse({\n schedule,\n ...options,\n });\n\n if (!validationResult.success) {\n const errorMsg = (validationResult as { error?: { errors: z.ZodIssue[] } }).error?.errors.map((e) => e.message).join(', ') || 'Unknown validation error';\n throw new Error(`Validation failed: ${errorMsg}`);\n }\n\n const data = validationResult.data;\n const id = uuidv4().slice(0, 8);\n const now = new Date().toISOString();\n const sessionTarget = data.sessionTarget ?? 'main';\n\n const job: JobData = {\n id,\n name: data.name,\n schedule: data.schedule,\n enabled: true,\n timezone: data.timezone,\n maxRetries: data.maxRetries ?? 3,\n timeout: data.timeout ?? 60000,\n created_at: now,\n updated_at: now,\n sessionTarget,\n ...(data.agentId ? { agentId: data.agentId } : {}),\n ...(data.workingDirectory ? { workingDirectory: data.workingDirectory } : {}),\n payload: data.payload,\n delivery: data.delivery,\n model: data.model,\n };\n\n // Save to persistence\n await this.persistence.addJob(job);\n\n // Schedule the job\n this.scheduleJob(job);\n\n log.info({ jobId: id, name: data.name, sessionTarget }, 'Job added');\n return { id, schedule: data.schedule };\n }\n\n /**\n * List all jobs with next run time\n */\n async listJobs(): Promise<JobWithNextRun[]> {\n const jobs = await this.persistence.getJobs();\n\n return jobs.map((job) => {\n let nextRun: string | undefined;\n\n if (job.enabled) {\n try {\n const options = job.timezone ? { tz: job.timezone } : undefined;\n const interval = CronExpressionParser.parse(job.schedule, options);\n nextRun = interval.next().toISOString();\n } catch (err) {\n log.debug({ jobId: job.id, err: err as Error }, 'Failed to parse cron for next run');\n }\n }\n\n return {\n id: job.id,\n name: job.name,\n schedule: job.schedule,\n enabled: job.enabled,\n timezone: job.timezone,\n maxRetries: job.maxRetries,\n timeout: job.timeout,\n sessionTarget: job.sessionTarget,\n ...(job.agentId ? { agentId: job.agentId } : {}),\n ...(job.workingDirectory ? { workingDirectory: job.workingDirectory } : {}),\n payload: job.payload,\n delivery: job.delivery,\n model: job.model,\n next_run: nextRun,\n };\n });\n }\n\n /**\n * Get a single job\n */\n async getJob(id: string): Promise<JobData | null> {\n return this.persistence.getJob(id);\n }\n\n /**\n * Update a job\n */\n async updateJob(id: string, updates: Partial<Omit<JobData, 'id' | 'created_at' | 'updated_at'>>): Promise<boolean> {\n // Validate updates\n const validationResult = UpdateJobRequestSchema.safeParse(updates);\n if (!validationResult.success) {\n const errorMsg = (validationResult as { error?: { errors: z.ZodIssue[] } }).error?.errors.map((e) => e.message).join(', ') || 'Unknown validation error';\n throw new Error(`Validation failed: ${errorMsg}`);\n }\n\n const job = await this.persistence.getJob(id);\n if (!job) return false;\n\n const validated = validationResult.data;\n const { agentId: agentIdPatch, workingDirectory: workingDirectoryPatch, ...rest } = validated;\n const patch: Partial<JobData> = { ...rest };\n let clearAgentId = false;\n if (agentIdPatch === null) {\n clearAgentId = true;\n } else if (agentIdPatch !== undefined) {\n patch.agentId = agentIdPatch;\n }\n\n let clearWorkingDirectory = false;\n if (workingDirectoryPatch === null) {\n clearWorkingDirectory = true;\n } else if (workingDirectoryPatch !== undefined) {\n patch.workingDirectory = workingDirectoryPatch;\n }\n\n // Cancel existing task if schedule changes\n if (patch.schedule && patch.schedule !== job.schedule) {\n this.cancelTask(id);\n }\n\n // Update persistence\n await this.persistence.updateJob(id, patch, { clearAgentId, clearWorkingDirectory });\n\n // Re-schedule if needed\n const updated = await this.persistence.getJob(id);\n if (updated && updated.enabled) {\n this.scheduleJob(updated);\n }\n\n log.info({ jobId: id }, 'Job updated');\n return true;\n }\n\n /**\n * Remove a job\n */\n async removeJob(id: string): Promise<boolean> {\n // Cancel task\n this.cancelTask(id);\n\n // Remove from persistence\n const removed = await this.persistence.removeJob(id);\n\n if (removed) {\n await this.runLogStore.deleteJobRuns(id);\n log.info({ jobId: id }, 'Job removed');\n }\n\n return removed;\n }\n\n /**\n * Toggle job enabled state\n */\n async toggleJob(id: string, enabled: boolean): Promise<boolean> {\n const job = await this.persistence.getJob(id);\n if (!job) return false;\n\n await this.persistence.updateJob(id, { enabled });\n\n if (enabled) {\n const updated = await this.persistence.getJob(id);\n if (updated) this.scheduleJob(updated);\n } else {\n this.cancelTask(id);\n }\n\n log.info({ jobId: id, enabled }, 'Job toggled');\n return true;\n }\n\n /**\n * Execution history for one job: merged in-memory (incl. running) + persisted SQLite rows.\n */\n async getJobHistory(jobId: string, limit?: number): Promise<JobExecution[]> {\n const cap = Math.min(Math.max(limit ?? 10, 1), 500);\n const [disk, memory] = await Promise.all([\n this.runLogStore.readJobHistory(jobId, cap * 2),\n Promise.resolve(this.executor.getHistory(jobId, cap * 2)),\n ]);\n const byId = new Map<string, JobExecution>();\n for (const e of memory) {\n byId.set(e.id, e);\n }\n for (const e of disk) {\n if (!byId.has(e.id)) {\n byId.set(e.id, e);\n }\n }\n const merged = [...byId.values()].sort(\n (a, b) => new Date(b.startedAt).getTime() - new Date(a.startedAt).getTime()\n );\n return merged.slice(0, cap);\n }\n\n /**\n * Latest runs across all jobs (persisted rows + optional job name).\n */\n async getAllRunsHistory(limit?: number): Promise<CronRunHistoryRow[]> {\n const cap = Math.min(Math.max(limit ?? 50, 1), 500);\n const jobs = await this.persistence.getJobs();\n const jobNames = new Map<string, string | undefined>(jobs.map((j) => [j.id, j.name] as const));\n return this.runLogStore.readAllRuns(cap, jobNames);\n }\n\n /**\n * Get service metrics\n */\n async getMetrics(): Promise<CronMetrics> {\n const jobs = await this.persistence.getJobs();\n const enabled = jobs.filter((j) => j.enabled);\n\n let nextScheduledJob: CronMetrics['nextScheduledJob'] | undefined;\n\n for (const job of enabled) {\n try {\n const options = job.timezone ? { tz: job.timezone } : undefined;\n const interval = CronExpressionParser.parse(job.schedule, options);\n const next = interval.next();\n\n if (!nextScheduledJob || next.getTime() < nextScheduledJob.runAt.getTime()) {\n nextScheduledJob = {\n id: job.id,\n name: job.name,\n runAt: next.toDate(),\n };\n }\n } catch {\n // Skip invalid schedules\n }\n }\n\n return {\n totalJobs: jobs.length,\n runningJobs: this.tasks.size,\n enabledJobs: enabled.length,\n failedLastHour: 0, // TODO: track from executor\n avgExecutionTime: 0, // TODO: track from executor\n nextScheduledJob,\n };\n }\n\n /**\n * Update config (hot reload)\n */\n updateConfig(_config: Config): void {\n log.debug('Cron config updated (jobs managed separately via addJob/removeJob)');\n }\n\n /**\n * Health check\n */\n async healthCheck(): Promise<CronHealth> {\n const issues: string[] = [];\n\n // Check if initialized\n if (!this.initialized) {\n issues.push('Service not initialized');\n }\n\n // Check for jobs with invalid schedules\n const jobs = await this.persistence.getJobs();\n for (const job of jobs) {\n if (!nodeCron.validate(job.schedule)) {\n issues.push(`Job ${job.id} has invalid schedule`);\n }\n }\n\n // Check if agent service is configured for isolated jobs\n for (const job of jobs) {\n if (job.enabled && job.sessionTarget === 'isolated' && !this.agentService) {\n issues.push(`Job ${job.id} requires agent service but none configured`);\n break;\n }\n }\n\n // Determine status\n let status: CronHealth['status'] = 'healthy';\n if (issues.length > 0) {\n status = issues.length > 5 ? 'unhealthy' : 'degraded';\n }\n\n return { status, issues };\n }\n\n /**\n * Run a job immediately (manual trigger)\n */\n async runJobNow(id: string): Promise<void> {\n const job = await this.persistence.getJob(id);\n if (!job) throw new Error(`Job not found: ${id}`);\n if (!job.enabled) throw new Error(`Job is disabled: ${id}`);\n\n await this.executeJob(job);\n }\n\n /**\n * Stop all jobs and cleanup\n */\n async stop(options?: { waitForRunning?: boolean; timeout?: number }): Promise<void> {\n const timeout = options?.timeout ?? 30000;\n\n // Cancel all scheduled tasks\n for (const [id, task] of this.tasks) {\n task.stop();\n\n // Cancel running executions\n this.executor.cancelJob(id);\n }\n this.tasks.clear();\n\n // Wait for running jobs if requested\n if (options?.waitForRunning) {\n const start = Date.now();\n while (Date.now() - start < timeout) {\n const running = this.executor.getRunningExecutions();\n if (running.length === 0) break;\n await new Promise((r) => setTimeout(r, 100));\n }\n }\n\n // Flush any pending writes\n await this.persistence.flush();\n\n log.info('CronService stopped');\n }\n\n /**\n * Load and schedule all enabled jobs\n */\n private async loadAllJobs(): Promise<void> {\n const jobs = await this.persistence.getJobs();\n\n for (const job of jobs) {\n if (job.enabled) {\n this.scheduleJob(job);\n }\n }\n\n log.debug({ count: this.tasks.size }, 'Jobs loaded');\n }\n\n /**\n * Schedule a job with node-cron\n */\n private scheduleJob(job: JobData): void {\n // Cancel existing if any\n this.cancelTask(job.id);\n\n // Validate schedule\n if (!nodeCron.validate(job.schedule)) {\n log.error({ jobId: job.id, schedule: job.schedule }, 'Invalid cron expression');\n return;\n }\n\n const options = job.timezone ? { timezone: job.timezone } : undefined;\n\n const task = nodeCron.schedule(\n job.schedule,\n async () => {\n await this.executeJob(job);\n },\n options\n );\n\n this.tasks.set(job.id, task);\n log.debug({ jobId: job.id, schedule: job.schedule }, 'Job scheduled');\n }\n\n /**\n * Execute a job with retry logic\n */\n private async executeJob(job: JobData): Promise<void> {\n // Prevent overlapping executions\n if (this.executor.isRunning(job.id)) {\n log.warn({ jobId: job.id }, 'Job already running, skipping');\n return;\n }\n\n const controller = new AbortController();\n\n try {\n await this.executor.execute(job, controller.signal);\n } catch (error) {\n log.error({ jobId: job.id, err: error as Error }, 'Job execution failed');\n // Retry logic can be added here based on error type\n }\n }\n\n /**\n * Cancel a scheduled task\n */\n private cancelTask(id: string): void {\n const task = this.tasks.get(id);\n if (task) {\n task.stop();\n this.tasks.delete(id);\n log.debug({ jobId: id }, 'Task cancelled');\n }\n }\n}\n"],"mappings":"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"}
@@ -1,6 +1,7 @@
1
1
  import type { SessionStore } from '../session/store.js';
2
2
  import type { WorkflowRunInputEnvelope, WorkflowRunSource, WorkflowRunView } from '../workflows/domain/index.js';
3
3
  import type { StartWorkflowRunServiceParams, WorkflowRunServiceResult } from '../workflows/service/workflow-run-service.types.js';
4
+ export type { CronRunHistoryRow, CronRunOutcome, CronRunStatus, CronUsageSummary, JobExecution, } from './execution-types.js';
4
5
  export type CronDeliveryMode = 'none' | 'announce' | 'direct';
5
6
  export interface CronDelivery {
6
7
  mode: CronDeliveryMode;
@@ -65,48 +66,6 @@ export interface JobState {
65
66
  consecutiveErrors?: number;
66
67
  scheduleErrorCount?: number;
67
68
  }
68
- export interface JobExecution {
69
- id: string;
70
- jobId: string;
71
- status: 'running' | 'success' | 'failed' | 'cancelled' | 'skipped';
72
- startedAt: string;
73
- endedAt?: string;
74
- duration?: number;
75
- error?: string;
76
- output?: string;
77
- retryCount: number;
78
- summary?: string;
79
- sessionId?: string;
80
- sessionKey?: string;
81
- /** Persisted for local run logs (e.g. `cron` for isolated agent jobs). */
82
- sessionType?: string;
83
- model?: string;
84
- provider?: string;
85
- usage?: CronUsageSummary;
86
- workflowRunId?: string;
87
- }
88
- export interface CronUsageSummary {
89
- input_tokens?: number;
90
- output_tokens?: number;
91
- total_tokens?: number;
92
- }
93
- /** One row for GET /api/cron/runs/history (optional display name from job definition). */
94
- export interface CronRunHistoryRow extends JobExecution {
95
- jobName?: string;
96
- }
97
- export type CronRunStatus = 'ok' | 'error' | 'skipped';
98
- export interface CronRunOutcome {
99
- status: CronRunStatus;
100
- error?: string;
101
- summary?: string;
102
- sessionId?: string;
103
- sessionKey?: string;
104
- sessionType?: string;
105
- model?: string;
106
- provider?: string;
107
- usage?: CronUsageSummary;
108
- workflowRunId?: string;
109
- }
110
69
  export interface CronWorkflowRunStarter {
111
70
  startWorkflowRun(params: StartWorkflowRunServiceParams): Promise<WorkflowRunServiceResult>;
112
71
  readWorkflowRunView?(agentId: string, runId: string): Promise<WorkflowRunView | null>;
@@ -1,5 +1,5 @@
1
- import os from "node:os";
2
1
  import path from "node:path";
2
+ import os from "node:os";
3
3
  //#region src/daemon/constants.ts
4
4
  /**
5
5
  * Daemon Constants - Service labels, paths, and configuration values
@@ -2,9 +2,9 @@ import { PACKAGE_VERSION, init_package_version } from "../package-version.js";
2
2
  import { createLogger } from "../utils/logger/index.js";
3
3
  import { init_logger } from "../utils/logger.js";
4
4
  import { SERVICE_VERSION_ENV_KEY, formatGatewayServiceDescription } from "./constants.js";
5
- import { homedir } from "node:os";
6
- import path from "node:path";
7
5
  import { existsSync } from "node:fs";
6
+ import path from "node:path";
7
+ import { homedir } from "node:os";
8
8
  //#region src/daemon/install-plan.ts
9
9
  /**
10
10
  * Install Plan Builder - Build gateway installation configuration
@@ -1,10 +1,10 @@
1
1
  import { createLogger } from "../utils/logger/index.js";
2
2
  import { init_logger } from "../utils/logger.js";
3
3
  import { resolveGatewayLaunchAgentLabel, resolveLaunchAgentPlistPath as resolveLaunchAgentPlistPath$1 } from "./constants.js";
4
- import os from "node:os";
5
- import path from "node:path";
6
4
  import { existsSync } from "node:fs";
7
5
  import { mkdir, readFile, rm, writeFile } from "node:fs/promises";
6
+ import path from "node:path";
7
+ import os from "node:os";
8
8
  import { spawn, spawnSync } from "node:child_process";
9
9
  //#region src/daemon/launchd.ts
10
10
  /**
@@ -1,9 +1,9 @@
1
1
  import { createLogger } from "../utils/logger/index.js";
2
2
  import { init_logger } from "../utils/logger.js";
3
3
  import { resolveGatewayWindowsTaskName } from "./constants.js";
4
- import os from "node:os";
5
- import path from "node:path";
6
4
  import { mkdirSync, readFileSync, rmSync, writeFileSync } from "node:fs";
5
+ import path from "node:path";
6
+ import os from "node:os";
7
7
  import { spawn, spawnSync } from "node:child_process";
8
8
  //#region src/daemon/schtasks.ts
9
9
  /**
@@ -1,10 +1,10 @@
1
1
  import { createLogger } from "../utils/logger/index.js";
2
2
  import { init_logger } from "../utils/logger.js";
3
3
  import { resolveGatewaySystemdServiceName, resolveSystemdUnitPath } from "./constants.js";
4
- import os from "node:os";
5
- import path from "node:path";
6
4
  import { existsSync } from "node:fs";
7
5
  import { access, constants as constants$1, mkdir, readFile, rm, writeFile } from "node:fs/promises";
6
+ import path from "node:path";
7
+ import os from "node:os";
8
8
  import { spawn, spawnSync } from "node:child_process";
9
9
  //#region src/daemon/systemd.ts
10
10
  /**
@@ -1,8 +1,8 @@
1
1
  import { init_paths, resolveBundledExtensionsDir, resolveExtensionsDir } from "../config/paths.js";
2
2
  import { isRecord } from "../utils/is-record.js";
3
3
  import { normalizeConfiguredMcpServers } from "../config/mcp-config-normalize.js";
4
- import { join } from "node:path";
5
4
  import { existsSync, readFileSync, readdirSync } from "node:fs";
5
+ import { join } from "node:path";
6
6
  //#region src/extensions/bundle-mcp.ts
7
7
  init_paths();
8
8
  function extractMcpServerMap(raw) {
@@ -1,6 +1,6 @@
1
- import { init_agent_scope, resolveDefaultAgentId } from "../agent/agent-scope.js";
2
1
  import { createLogger } from "../utils/logger/index.js";
3
2
  import { init_logger } from "../utils/logger.js";
3
+ import { init_agent_scope, resolveDefaultAgentId } from "../agent/agent-scope.js";
4
4
  import { init_paths, resolveBundledExtensionsDir, resolveExtensionsDir, resolveWorkspaceExtensionsDir } from "../config/paths.js";
5
5
  import { init_loader, loadConfig } from "../config/loader.js";
6
6
  import { normalizeExtensionManifest } from "./normalize-manifest.js";
@@ -1,8 +1,8 @@
1
1
  import { init_paths, resolveExtensionsDir } from "../config/paths.js";
2
2
  import { getExtensionLockfileManager } from "./lockfile.js";
3
+ import { readFile, readdir } from "fs/promises";
3
4
  import { join } from "path";
4
5
  import { existsSync } from "fs";
5
- import { readFile, readdir } from "fs/promises";
6
6
  //#region src/extensions/health.ts
7
7
  init_paths();
8
8
  var ExtensionHealthChecker = class {
@@ -1,7 +1,7 @@
1
1
  import { PACKAGE_VERSION, init_package_version } from "../package-version.js";
2
- import { init_agent_scope, resolveAgentWorkspaceDir, resolveDefaultAgentId } from "../agent/agent-scope.js";
3
2
  import { createLogger, createServiceLogger } from "../utils/logger/index.js";
4
3
  import { init_logger } from "../utils/logger.js";
4
+ import { init_agent_scope, resolveAgentWorkspaceDir, resolveDefaultAgentId } from "../agent/agent-scope.js";
5
5
  import { init_paths, resolveBundledExtensionsDir, resolveExtensionSdkPath, resolveExtensionsDir, resolveWorkspaceExtensionsDir } from "../config/paths.js";
6
6
  import { init_loader, loadConfig } from "../config/loader.js";
7
7
  import { getProviderRegistry, init_plugin_registry } from "../providers/plugin-registry.js";
@@ -1,10 +1,10 @@
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
4
  import { init_paths, resolveExtensionsDir, resolveExtensionsLockPath } from "../config/paths.js";
4
- import { init_write_file_atomic, writeTextAtomic } from "../infra/write-file-atomic.js";
5
+ import { mkdir, readFile } from "fs/promises";
5
6
  import { dirname, join } from "path";
6
7
  import { existsSync } from "fs";
7
- import { mkdir, readFile } from "fs/promises";
8
8
  import { createHash } from "crypto";
9
9
  //#region src/extensions/lockfile.ts
10
10
  init_write_file_atomic();
@@ -6,8 +6,8 @@ import { getExtensionLockfileManager } from "./lockfile.js";
6
6
  import { installExtensionFromStoreZip, installFromNpm } from "./install.js";
7
7
  import { findExtension } from "./marketplace.js";
8
8
  import { downloadExtensionStoreZipBuffer, resolveExtensionZipDownloadUrl, resolveExtensionsStoreBaseUrl } from "../agent/skills/marketplace/adapters/store/store-api-client.js";
9
- import { join } from "node:path";
10
9
  import { existsSync, readFileSync, readdirSync, rmSync } from "node:fs";
10
+ import { join } from "node:path";
11
11
  import semver from "semver";
12
12
  //#region src/extensions/update.ts
13
13
  /**
@@ -1,14 +1,15 @@
1
- import { init_localized_text, normalizeLocalizedText, resolveLocalizedText } from "../config/localized-text.js";
2
1
  import { DEFAULT_AGENT_ID, init_agent_scope, listAgentEntries, normalizeAgentId, resolveAgentDir, resolveAgentProfileDir, resolveAgentWorkspaceDir, resolveDefaultAgentId, resolveUserPath, validateAgentIdForNewAgent } from "../agent/agent-scope.js";
3
- import { resolveEffectiveAgentProfile } from "../config/agent-profile.js";
4
2
  import { WORKSPACE_FILES, init_paths } from "../config/paths.js";
3
+ import { init_localized_text, normalizeLocalizedText, resolveLocalizedText } from "../config/localized-text.js";
4
+ import { resolveEffectiveAgentProfile } from "../config/agent-profile.js";
5
5
  import { AGENT_PROFILE_MARKDOWN_SYSTEM_FILES } from "../agent/context/workspace.js";
6
+ import { isWorkspaceSetupCompleted, resolveAgentWorkspaceStatePath, syncBootstrapSetupCompletion } from "../agent/context/workspace-state.js";
6
7
  import { isPathUnderWorkspace, resolveWorkspaceSafePath } from "./workspace-editor-path.js";
7
8
  import { applyAgentConfig, findAgentEntryIndex, pruneAgentConfig, removeAgentDirsFromDisk } from "../commands/agents.config.js";
8
9
  import { GATEWAY_BUILTIN_TOOL_IDS } from "./agent-builtin-tools.js";
9
10
  import { seedAgentProfileMarkdownFiles } from "../agent/context/workspace-seed.js";
10
- import { join, resolve } from "node:path";
11
11
  import { cp, mkdir, readFile, readdir, realpath, stat, unlink, writeFile } from "node:fs/promises";
12
+ import { join, resolve } from "node:path";
12
13
  //#region src/gateway/agents-admin.ts
13
14
  /**
14
15
  * Gateway REST helpers for multi-agent management.
@@ -401,7 +402,11 @@ async function listAgentProfileFiles(cfg, agentId) {
401
402
  const root = await profileMarkdownRootReal(cfg, id);
402
403
  const names = [...EDITABLE_PROFILE_MARKDOWN_NAMES];
403
404
  const files = [];
405
+ const statePath = resolveAgentWorkspaceStatePath(cfg, id);
406
+ syncBootstrapSetupCompletion(statePath, root);
407
+ const setupCompleted = isWorkspaceSetupCompleted(statePath);
404
408
  for (const name of names.sort((a, b) => a.localeCompare(b))) {
409
+ if (name === WORKSPACE_FILES.BOOTSTRAP && setupCompleted) continue;
405
410
  const abs = resolveWorkspaceSafePath(root, name);
406
411
  if (!abs) continue;
407
412
  try {