@xopcai/xopc 0.0.95 → 0.0.97

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 (442) 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-B_YUvNi6.js} +2 -2
  19. package/dist/gateway/static/root/assets/{apps-page-Mi9mMIZ1.js → apps-page-BmwG5aur.js} +1 -1
  20. package/dist/gateway/static/root/assets/{channels-settings-BrdyC101.js → channels-settings-BiwkeKPb.js} +1 -1
  21. package/dist/gateway/static/root/assets/{channels-status-swr-D55Bu0nn.js → channels-status-swr-ChyN473C.js} +1 -1
  22. package/dist/gateway/static/root/assets/{cron-api-CPpx2l-E.js → cron-api-CvSifIfJ.js} +1 -1
  23. package/dist/gateway/static/root/assets/{cron-page-Bx2jB0YN.js → cron-page-BDqTDFy6.js} +1 -1
  24. package/dist/gateway/static/root/assets/{dist-D_AiG_Kg.js → dist-DxsUrjpy.js} +1 -1
  25. package/dist/gateway/static/root/assets/{extension-debug-page-6ieHsxRE.js → extension-debug-page-DV_Av5Jq.js} +1 -1
  26. package/dist/gateway/static/root/assets/{extension-page-B8nywHRO.js → extension-page-CwZwRhWw.js} +1 -1
  27. package/dist/gateway/static/root/assets/{extension-settings-page-DrskdEIV.js → extension-settings-page-Bb7TR1Se.js} +1 -1
  28. package/dist/gateway/static/root/assets/{fetch-B0aeeY0q.js → fetch-BLLOP2CM.js} +1 -1
  29. package/dist/gateway/static/root/assets/{field-primitives--9ooY8Xl.js → field-primitives-CyqVu1QR.js} +1 -1
  30. package/dist/gateway/static/root/assets/{heartbeat-config-api-DUZ_W1w-.js → heartbeat-config-api-Cd4M1eHt.js} +1 -1
  31. package/dist/gateway/static/root/assets/{index-Dj9FuxCm.js → index-0tS9lV85.js} +74 -74
  32. package/dist/gateway/static/root/assets/index-BJDmBCSl.css +1 -0
  33. package/dist/gateway/static/root/assets/{logs-page-CaXqhpKf.js → logs-page-BsAOSowN.js} +1 -1
  34. package/dist/gateway/static/root/assets/{note-detail-page-B91pLkEI.css → note-detail-page-D4ZIVQbk.css} +1 -1
  35. package/dist/gateway/static/root/assets/{note-detail-page-DYzym2B0.js → note-detail-page-Dlxoy6Ap.js} +54 -53
  36. package/dist/gateway/static/root/assets/{note-time-B-vSi2dR.js → note-time-B-r8yTpQ.js} +1 -1
  37. package/dist/gateway/static/root/assets/{notes-page-BkhWdGiT.js → notes-page-CHFcyqYW.js} +1 -1
  38. package/dist/gateway/static/root/assets/{sessions-page-53YFokoe.js → sessions-page-Ctu0kgt7.js} +1 -1
  39. package/dist/gateway/static/root/assets/{settings-advanced-gate-BaZmaklx.js → settings-advanced-gate-Dh0TyOOg.js} +1 -1
  40. package/dist/gateway/static/root/assets/{settings-form-section-DIJPKpTR.js → settings-form-section-DXMCEW1d.js} +1 -1
  41. package/dist/gateway/static/root/assets/{settings-page-Dvb230FF.js → settings-page-CIkZ7233.js} +1 -1
  42. package/dist/gateway/static/root/assets/{share-preview-page-CRyjTAG6.js → share-preview-page-7RV65xhJ.js} +1 -1
  43. package/dist/gateway/static/root/assets/{skills-page-C5ZJbfAe.js → skills-page-D_Az1SlU.js} +1 -1
  44. package/dist/gateway/static/root/assets/{theme-store-Cg_SuBw0.js → theme-store-e2q2yjs4.js} +1 -1
  45. package/dist/gateway/static/root/assets/url-DpFBIyN9.js +3 -0
  46. package/dist/gateway/static/root/assets/{utils-lMYoWhqo.js → utils-OA_b1q0Q.js} +1 -1
  47. package/dist/gateway/static/root/assets/{voice-api-key-field-Dda2pcUU.js → voice-api-key-field-SJml1hAt.js} +1 -1
  48. package/dist/gateway/static/root/assets/{workflow-page.utils-KIladUrU.js → workflow-page.utils-D90VVCzC.js} +1 -1
  49. package/dist/gateway/static/root/assets/{workflows-page-BTis4Z7Y.js → workflows-page-y7Btji0J.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 +12 -8
  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 +2 -0
  58. package/dist/src/agent/bootstrap/bootstrap-cache.js +10 -1
  59. package/dist/src/agent/bootstrap/bootstrap-cache.js.map +1 -1
  60. package/dist/src/agent/bootstrap/bootstrap-files.d.ts +2 -1
  61. package/dist/src/agent/bootstrap/bootstrap-files.js +34 -12
  62. package/dist/src/agent/bootstrap/bootstrap-files.js.map +1 -1
  63. package/dist/src/agent/bootstrap/load-bootstrap-files.d.ts +1 -2
  64. package/dist/src/agent/bootstrap/load-bootstrap-files.js +6 -12
  65. package/dist/src/agent/bootstrap/load-bootstrap-files.js.map +1 -1
  66. package/dist/src/agent/bootstrap/types.d.ts +5 -5
  67. package/dist/src/agent/context/workspace-seed.js +6 -6
  68. package/dist/src/agent/context/workspace-seed.js.map +1 -1
  69. package/dist/src/agent/context/workspace-state.d.ts +20 -0
  70. package/dist/src/agent/context/workspace-state.js +57 -0
  71. package/dist/src/agent/context/workspace-state.js.map +1 -0
  72. package/dist/src/agent/context/workspace-templates/AGENTS.md +0 -4
  73. package/dist/src/agent/embedded/index.d.ts +2 -2
  74. package/dist/src/agent/embedded/index.js +3 -3
  75. package/dist/src/agent/embedded/run-turn.js +0 -3
  76. package/dist/src/agent/embedded/run-turn.js.map +1 -1
  77. package/dist/src/agent/embedded/session-manager-init.d.ts +0 -17
  78. package/dist/src/agent/embedded/session-manager-init.js +1 -36
  79. package/dist/src/agent/embedded/session-manager-init.js.map +1 -1
  80. package/dist/src/agent/embedded/session-runner.d.ts +3 -12
  81. package/dist/src/agent/embedded/session-runner.js +12 -26
  82. package/dist/src/agent/embedded/session-runner.js.map +1 -1
  83. package/dist/src/agent/embedded/session-tool-result-guard.js +2 -4
  84. package/dist/src/agent/embedded/session-tool-result-guard.js.map +1 -1
  85. package/dist/src/agent/embedded/sqlite-hydrating-session-manager.d.ts +10 -0
  86. package/dist/src/agent/embedded/sqlite-hydrating-session-manager.js +34 -0
  87. package/dist/src/agent/embedded/sqlite-hydrating-session-manager.js.map +1 -0
  88. package/dist/src/agent/goals/goal-run-store.js +4 -4
  89. package/dist/src/agent/goals/persistent-goal-service.js +8 -15
  90. package/dist/src/agent/goals/persistent-goal-service.js.map +1 -1
  91. package/dist/src/agent/goals/post-turn.js +2 -2
  92. package/dist/src/agent/image/load-image-media.js +2 -2
  93. package/dist/src/agent/ipc/bus.js +1 -1
  94. package/dist/src/agent/ipc/inbox.js +2 -2
  95. package/dist/src/agent/ipc/socket.js +1 -1
  96. package/dist/src/agent/mcp/bundle-mcp-materialize.js +1 -1
  97. package/dist/src/agent/mcp/bundle-mcp-runtime.js +2 -2
  98. package/dist/src/agent/mcp/mcp-transport-config.js +1 -1
  99. package/dist/src/agent/mcp/mcp-transport.js +1 -1
  100. package/dist/src/agent/memory/builtin-memory-store.js +1 -1
  101. package/dist/src/agent/memory/dreaming/deep-promotion.js +1 -1
  102. package/dist/src/agent/memory/dreaming/events.js +1 -1
  103. package/dist/src/agent/memory/dreaming/last-run.js +1 -1
  104. package/dist/src/agent/memory/dreaming/light-sweep.js +1 -1
  105. package/dist/src/agent/memory/dreaming/preview.js +1 -1
  106. package/dist/src/agent/memory/dreaming/rem-patterns.js +1 -1
  107. package/dist/src/agent/memory/dreaming/short-term-store.js +1 -1
  108. package/dist/src/agent/memory/dreaming/utils.js +1 -1
  109. package/dist/src/agent/memory/plugin-discovery.js +1 -1
  110. package/dist/src/agent/models/manager.js +1 -1
  111. package/dist/src/agent/prompt/memory/index.d.ts +1 -0
  112. package/dist/src/agent/prompt/memory/index.js +34 -80
  113. package/dist/src/agent/prompt/memory/index.js.map +1 -1
  114. package/dist/src/agent/prompt/service-prompt-builder.js +2 -2
  115. package/dist/src/agent/prompt/system-prompt.js +0 -1
  116. package/dist/src/agent/prompt/system-prompt.js.map +1 -1
  117. package/dist/src/agent/reply/post-compaction-context.js +1 -1
  118. package/dist/src/agent/reply/workspace-boundary-read.js +1 -1
  119. package/dist/src/agent/sandbox/path-policy.js +2 -2
  120. package/dist/src/agent/service/build-direct-message-content.js +1 -1
  121. package/dist/src/agent/service/process-direct-one-shot.js +8 -17
  122. package/dist/src/agent/service/process-direct-one-shot.js.map +1 -1
  123. package/dist/src/agent/service/process-direct-streaming.js +14 -23
  124. package/dist/src/agent/service/process-direct-streaming.js.map +1 -1
  125. package/dist/src/agent/service.js +7 -11
  126. package/dist/src/agent/service.js.map +1 -1
  127. package/dist/src/agent/session/session-inspector.js +1 -1
  128. package/dist/src/agent/skills/config.js +1 -1
  129. package/dist/src/agent/skills/hub-hash.js +2 -2
  130. package/dist/src/agent/skills/hub-lock.js +1 -1
  131. package/dist/src/agent/skills/hub-pull.js +3 -3
  132. package/dist/src/agent/skills/index.js +1 -1
  133. package/dist/src/agent/skills/managed-store.js +1 -1
  134. package/dist/src/agent/skills/scanner.js +1 -1
  135. package/dist/src/agent/skills/skill-manage-ops.js +1 -1
  136. package/dist/src/agent/skills/skill-manager.js +1 -1
  137. package/dist/src/agent/tools/dreaming-tool.js +1 -1
  138. package/dist/src/agent/tools/factory.js +1 -1
  139. package/dist/src/agent/tools/image-generate-tool.js +1 -1
  140. package/dist/src/agent/tools/index.d.ts +0 -1
  141. package/dist/src/agent/tools/index.js +1 -2
  142. package/dist/src/agent/tools/send-media.js +1 -1
  143. package/dist/src/agent/tools/session-search-tool.d.ts +0 -1
  144. package/dist/src/agent/tools/session-search-tool.js +11 -6
  145. package/dist/src/agent/tools/session-search-tool.js.map +1 -1
  146. package/dist/src/agent/tools/skill-manage-tool.js +1 -1
  147. package/dist/src/agent/tools/tool-paths.js +1 -3
  148. package/dist/src/agent/tools/tool-paths.js.map +1 -1
  149. package/dist/src/agent/tools/workflow-tool.js +1 -1
  150. package/dist/src/agent/tools/write.js +1 -1
  151. package/dist/src/agent/workflow/catalog.js +1 -1
  152. package/dist/src/auth/credentials.js +3 -3
  153. package/dist/src/auth/profiles/store.js +1 -1
  154. package/dist/src/auth/sync-provider-auth.js +1 -1
  155. package/dist/src/browser/cache-dir-policy.js +1 -1
  156. package/dist/src/browser/cdp-local-launcher.js +2 -2
  157. package/dist/src/browser/providers/browser-ext-install.js +4 -4
  158. package/dist/src/browser/providers/cloakbrowser.js +4 -4
  159. package/dist/src/browser/providers/playwright-doctor.js +1 -1
  160. package/dist/src/browser/stealth.js +1 -1
  161. package/dist/src/channels/attachments/inbound-persist.js +1 -1
  162. package/dist/src/channels/attachments/outbound-tts-persist.js +1 -1
  163. package/dist/src/channels/outbound/persist-store.js +1 -1
  164. package/dist/src/channels/pairing/allow-from-file.js +1 -1
  165. package/dist/src/channels/pairing/pairing-store.js +2 -2
  166. package/dist/src/chat-commands/agent-edit.js +3 -4
  167. package/dist/src/chat-commands/agent-edit.js.map +1 -1
  168. package/dist/src/chat-commands/builtins/config.js +2 -2
  169. package/dist/src/chat-commands/context.js +1 -1
  170. package/dist/src/cli/commands/config.js +1 -1
  171. package/dist/src/cli/commands/doctor/checks/config-health.js +1 -1
  172. package/dist/src/cli/commands/doctor/checks/provider-auth.js +1 -1
  173. package/dist/src/cli/commands/doctor/checks/session-integrity.js +32 -95
  174. package/dist/src/cli/commands/doctor/checks/session-integrity.js.map +1 -1
  175. package/dist/src/cli/commands/doctor/checks/state-integrity.js +1 -1
  176. package/dist/src/cli/commands/doctor/checks/workspace-status.js +1 -1
  177. package/dist/src/cli/commands/extension-dev.js +1 -1
  178. package/dist/src/cli/commands/extension-marketplace.js +1 -1
  179. package/dist/src/cli/commands/extension-pack.js +1 -1
  180. package/dist/src/cli/commands/gateway/logs.js +1 -1
  181. package/dist/src/cli/commands/image.js +1 -1
  182. package/dist/src/cli/commands/init.js +5 -7
  183. package/dist/src/cli/commands/init.js.map +1 -1
  184. package/dist/src/cli/commands/onboard.js +0 -8
  185. package/dist/src/cli/commands/onboard.js.map +1 -1
  186. package/dist/src/cli/templates.d.ts +3 -10
  187. package/dist/src/cli/templates.js +4 -32
  188. package/dist/src/cli/templates.js.map +1 -1
  189. package/dist/src/cli/utils/init-workspace-core.js +2 -2
  190. package/dist/src/commands/agents.config.js +1 -1
  191. package/dist/src/config/agent-profile.js +1 -1
  192. package/dist/src/config/gateway-bind.js +1 -1
  193. package/dist/src/config/index.js +7 -8
  194. package/dist/src/config/index.js.map +1 -1
  195. package/dist/src/config/loader.js +2 -2
  196. package/dist/src/config/models-json.js +2 -2
  197. package/dist/src/config/paths-state.d.ts +3 -0
  198. package/dist/src/config/paths-state.js +7 -3
  199. package/dist/src/config/paths-state.js.map +1 -1
  200. package/dist/src/config/paths.d.ts +5 -36
  201. package/dist/src/config/paths.js +7 -52
  202. package/dist/src/config/paths.js.map +1 -1
  203. package/dist/src/config/profile.js +2 -2
  204. package/dist/src/config/schema.d.ts +15 -0
  205. package/dist/src/config/schema.js +11 -0
  206. package/dist/src/config/schema.js.map +1 -1
  207. package/dist/src/config/workspace-path.js +1 -1
  208. package/dist/src/cron/execution-types.d.ts +42 -0
  209. package/dist/src/cron/executor.js +2 -2
  210. package/dist/src/cron/persistence.js +1 -1
  211. package/dist/src/cron/run-log-store.d.ts +4 -8
  212. package/dist/src/cron/run-log-store.js +26 -78
  213. package/dist/src/cron/run-log-store.js.map +1 -1
  214. package/dist/src/cron/service.d.ts +3 -3
  215. package/dist/src/cron/service.js +2 -2
  216. package/dist/src/cron/service.js.map +1 -1
  217. package/dist/src/cron/types.d.ts +1 -42
  218. package/dist/src/daemon/constants.js +1 -1
  219. package/dist/src/daemon/install-plan.js +2 -2
  220. package/dist/src/daemon/launchd.js +2 -2
  221. package/dist/src/daemon/schtasks.js +2 -2
  222. package/dist/src/daemon/systemd.js +2 -2
  223. package/dist/src/extensions/bundle-mcp.js +1 -1
  224. package/dist/src/extensions/discover-extensions.js +1 -1
  225. package/dist/src/extensions/health.js +1 -1
  226. package/dist/src/extensions/loader.js +1 -1
  227. package/dist/src/extensions/lockfile.js +2 -2
  228. package/dist/src/extensions/update.js +1 -1
  229. package/dist/src/gateway/agents-admin.js +4 -4
  230. package/dist/src/gateway/agents-admin.js.map +1 -1
  231. package/dist/src/gateway/file-path-classifier.d.ts +0 -1
  232. package/dist/src/gateway/file-path-classifier.js +2 -8
  233. package/dist/src/gateway/file-path-classifier.js.map +1 -1
  234. package/dist/src/gateway/heartbeat/service.js +1 -1
  235. package/dist/src/gateway/hono/lib/config-payload.js +1 -1
  236. package/dist/src/gateway/hono/lib/extension-store.js +2 -2
  237. package/dist/src/gateway/hono/lib/static-ui.js +2 -2
  238. package/dist/src/gateway/hono/oauth.js +1 -1
  239. package/dist/src/gateway/hono/routes/agents.js +1 -1
  240. package/dist/src/gateway/hono/routes/auth-registry-extensions.js +1 -1
  241. package/dist/src/gateway/hono/routes/config-patch/misc.js +1 -1
  242. package/dist/src/gateway/hono/routes/dreaming.js +1 -1
  243. package/dist/src/gateway/hono/routes/host-fs.js +2 -2
  244. package/dist/src/gateway/hono/routes/models.js +1 -1
  245. package/dist/src/gateway/hono/routes/shares.js +1 -1
  246. package/dist/src/gateway/hono/routes/workspace.js +2 -2
  247. package/dist/src/gateway/lock.js +3 -3
  248. package/dist/src/gateway/ports.js +1 -1
  249. package/dist/src/gateway/service/agent-runner.js +2 -2
  250. package/dist/src/gateway/service/marketplace-service.js +2 -2
  251. package/dist/src/gateway/service.js +5 -1
  252. package/dist/src/gateway/service.js.map +1 -1
  253. package/dist/src/gateway/session-reset-service.d.ts +1 -1
  254. package/dist/src/gateway/session-reset-service.js +1 -1
  255. package/dist/src/gateway/session-reset-service.js.map +1 -1
  256. package/dist/src/gateway/workspace-fs-file-list.js +1 -1
  257. package/dist/src/heartbeat/index.js +1 -1
  258. package/dist/src/infra/brew.js +1 -1
  259. package/dist/src/infra/node-sqlite.d.ts +1 -0
  260. package/dist/src/infra/node-sqlite.js +17 -0
  261. package/dist/src/infra/node-sqlite.js.map +1 -0
  262. package/dist/src/infra/package-json.js +1 -1
  263. package/dist/src/infra/package-update-steps.js +1 -1
  264. package/dist/src/infra/path-env.js +2 -2
  265. package/dist/src/infra/restart.js +2 -2
  266. package/dist/src/infra/sqlite-errors.d.ts +1 -0
  267. package/dist/src/infra/sqlite-errors.js +77 -0
  268. package/dist/src/infra/sqlite-errors.js.map +1 -0
  269. package/dist/src/infra/stable-node-path.js +1 -1
  270. package/dist/src/infra/unhandled-rejections.d.ts +1 -0
  271. package/dist/src/infra/unhandled-rejections.js +25 -0
  272. package/dist/src/infra/unhandled-rejections.js.map +1 -0
  273. package/dist/src/infra/update-check.js +1 -1
  274. package/dist/src/infra/update-global.js +1 -1
  275. package/dist/src/infra/update-lock.js +3 -3
  276. package/dist/src/infra/update-runner.js +1 -1
  277. package/dist/src/infra/update-startup.js +2 -2
  278. package/dist/src/infra/warning-filter.d.ts +7 -0
  279. package/dist/src/infra/warning-filter.js +59 -0
  280. package/dist/src/infra/warning-filter.js.map +1 -0
  281. package/dist/src/infra/write-file-atomic.js +2 -2
  282. package/dist/src/notes/store.d.ts +3 -9
  283. package/dist/src/notes/store.js +22 -196
  284. package/dist/src/notes/store.js.map +1 -1
  285. package/dist/src/providers/auth-runtime/auth-profile-store.js +1 -1
  286. package/dist/src/providers/index.js +2 -2
  287. package/dist/src/providers/model-registry.js +1 -1
  288. package/dist/src/session/config-store.d.ts +6 -75
  289. package/dist/src/session/config-store.js +38 -144
  290. package/dist/src/session/config-store.js.map +1 -1
  291. package/dist/src/session/config-types.d.ts +15 -0
  292. package/dist/src/session/config-types.js +1 -0
  293. package/dist/src/session/index.d.ts +1 -3
  294. package/dist/src/session/index.js +3 -5
  295. package/dist/src/session/init-session-turn.d.ts +0 -6
  296. package/dist/src/session/init-session-turn.js +18 -18
  297. package/dist/src/session/init-session-turn.js.map +1 -1
  298. package/dist/src/session/lifecycle-timestamps.d.ts +5 -2
  299. package/dist/src/session/lifecycle-timestamps.js.map +1 -1
  300. package/dist/src/session/{parity/load-jsonl-entries.js → load-jsonl-entries.js} +1 -1
  301. package/dist/src/session/load-jsonl-entries.js.map +1 -0
  302. package/dist/src/session/manager.d.ts +5 -3
  303. package/dist/src/session/manager.js +1 -5
  304. package/dist/src/session/manager.js.map +1 -1
  305. package/dist/src/session/resolve-session.d.ts +3 -6
  306. package/dist/src/session/resolve-session.js +26 -31
  307. package/dist/src/session/resolve-session.js.map +1 -1
  308. package/dist/src/session/session-context-for-llm.js +5 -1
  309. package/dist/src/session/session-context-for-llm.js.map +1 -1
  310. package/dist/src/session/session-id.js +12 -0
  311. package/dist/src/session/session-id.js.map +1 -0
  312. package/dist/src/session/session-title.js +2 -2
  313. package/dist/src/session/session-workspace.d.ts +1 -1
  314. package/dist/src/session/session-workspace.js.map +1 -1
  315. package/dist/src/session/store.d.ts +14 -63
  316. package/dist/src/session/store.js +172 -847
  317. package/dist/src/session/store.js.map +1 -1
  318. package/dist/src/session/stored-rows-to-file-entries.d.ts +11 -0
  319. package/dist/src/session/stored-rows-to-file-entries.js +95 -0
  320. package/dist/src/session/stored-rows-to-file-entries.js.map +1 -0
  321. package/dist/src/session/transcript-events.d.ts +1 -2
  322. package/dist/src/session/transcript-events.js +5 -12
  323. package/dist/src/session/transcript-events.js.map +1 -1
  324. package/dist/src/session/transcript-format.d.ts +1 -1
  325. package/dist/src/session/transcript-format.js.map +1 -1
  326. package/dist/src/session/transcript-stats.d.ts +1 -0
  327. package/dist/src/session/transcript-stats.js +10 -0
  328. package/dist/src/session/transcript-stats.js.map +1 -0
  329. package/dist/src/share/share-auto.js +2 -2
  330. package/dist/src/share/share-store.js +3 -3
  331. package/dist/src/share/share-thumbnail.js +2 -2
  332. package/dist/src/share/share-zip.js +1 -1
  333. package/dist/src/share/site-share-store.js +3 -3
  334. package/dist/src/share/site-static-serve.js +1 -1
  335. package/dist/src/storage/sqlite/config-repository.d.ts +6 -0
  336. package/dist/src/storage/sqlite/config-repository.js +56 -0
  337. package/dist/src/storage/sqlite/config-repository.js.map +1 -0
  338. package/dist/src/storage/sqlite/connection.d.ts +38 -0
  339. package/dist/src/storage/sqlite/connection.js +258 -0
  340. package/dist/src/storage/sqlite/connection.js.map +1 -0
  341. package/dist/src/storage/sqlite/cron-run-repository.d.ts +5 -0
  342. package/dist/src/storage/sqlite/cron-run-repository.js +97 -0
  343. package/dist/src/storage/sqlite/cron-run-repository.js.map +1 -0
  344. package/dist/src/storage/sqlite/fts.d.ts +2 -0
  345. package/dist/src/storage/sqlite/fts.js +11 -0
  346. package/dist/src/storage/sqlite/fts.js.map +1 -0
  347. package/dist/src/storage/sqlite/index.d.ts +12 -0
  348. package/dist/src/storage/sqlite/index.js +13 -0
  349. package/dist/src/storage/sqlite/memory-index-repository.d.ts +18 -0
  350. package/dist/src/storage/sqlite/memory-index-repository.js +132 -0
  351. package/dist/src/storage/sqlite/memory-index-repository.js.map +1 -0
  352. package/dist/src/storage/sqlite/notes-repository.d.ts +11 -0
  353. package/dist/src/storage/sqlite/notes-repository.js +191 -0
  354. package/dist/src/storage/sqlite/notes-repository.js.map +1 -0
  355. package/dist/src/storage/sqlite/paths.d.ts +1 -0
  356. package/dist/src/storage/sqlite/paths.js +7 -0
  357. package/dist/src/storage/sqlite/paths.js.map +1 -0
  358. package/dist/src/storage/sqlite/row-mappers.d.ts +82 -0
  359. package/dist/src/storage/sqlite/row-mappers.js +164 -0
  360. package/dist/src/storage/sqlite/row-mappers.js.map +1 -0
  361. package/dist/src/storage/sqlite/schema.d.ts +5 -0
  362. package/dist/src/storage/sqlite/schema.js +43 -0
  363. package/dist/src/storage/sqlite/schema.js.map +1 -0
  364. package/dist/src/storage/sqlite/schema.sql +195 -0
  365. package/dist/src/storage/sqlite/session-metadata.d.ts +8 -0
  366. package/dist/src/storage/sqlite/session-metadata.js +83 -0
  367. package/dist/src/storage/sqlite/session-metadata.js.map +1 -0
  368. package/dist/src/storage/sqlite/session-repository.d.ts +29 -0
  369. package/dist/src/storage/sqlite/session-repository.js +268 -0
  370. package/dist/src/storage/sqlite/session-repository.js.map +1 -0
  371. package/dist/src/storage/sqlite/transaction.d.ts +11 -0
  372. package/dist/src/storage/sqlite/transaction.js +115 -0
  373. package/dist/src/storage/sqlite/transaction.js.map +1 -0
  374. package/dist/src/storage/sqlite/transcript-repository.d.ts +34 -0
  375. package/dist/src/storage/sqlite/transcript-repository.js +241 -0
  376. package/dist/src/storage/sqlite/transcript-repository.js.map +1 -0
  377. package/dist/src/tui/clipboard-image.js +3 -3
  378. package/dist/src/tui/theme-manager.js +1 -1
  379. package/dist/src/tui/tui-keybindings-file.js +1 -1
  380. package/dist/src/tui/tui-scoped-models.js +2 -2
  381. package/dist/src/tui/tui-settings.js +1 -1
  382. package/dist/src/tui/tui.js +3 -3
  383. package/dist/src/tunnel/frpc-binary.js +3 -3
  384. package/dist/src/tunnel/frpc-config.js +1 -1
  385. package/dist/src/tunnel/frpc-extract.js +1 -1
  386. package/dist/src/tunnel/tunnel-state.js +1 -1
  387. package/dist/src/utils/logger/audit.js +1 -1
  388. package/dist/src/utils/logger/log-store.js +1 -1
  389. package/dist/src/utils/logger/rotation.js +1 -1
  390. package/dist/src/voice/tts/audio.js +1 -1
  391. package/dist/src/voice/tts/providers/edge-speech.js +2 -2
  392. package/dist/src/workflows/service/workflow-session-bridge.js +41 -64
  393. package/dist/src/workflows/service/workflow-session-bridge.js.map +1 -1
  394. package/dist/src/workflows/store/event-store.js +1 -1
  395. package/dist/src/workflows/store/run-store.js +1 -1
  396. package/package.json +2 -2
  397. package/dist/gateway/static/root/assets/index-Bj_l8QDp.css +0 -1
  398. package/dist/gateway/static/root/assets/url-BHHmdJYc.js +0 -3
  399. package/dist/src/agent/context/workspace-templates/BOOTSTRAP.md +0 -61
  400. package/dist/src/agent/embedded/session-manager-cache.d.ts +0 -19
  401. package/dist/src/agent/embedded/session-manager-cache.js +0 -48
  402. package/dist/src/agent/embedded/session-manager-cache.js.map +0 -1
  403. package/dist/src/session/parity/artifacts.d.ts +0 -16
  404. package/dist/src/session/parity/artifacts.js +0 -80
  405. package/dist/src/session/parity/artifacts.js.map +0 -1
  406. package/dist/src/session/parity/jsonl-transcript-io.d.ts +0 -54
  407. package/dist/src/session/parity/jsonl-transcript-io.js +0 -236
  408. package/dist/src/session/parity/jsonl-transcript-io.js.map +0 -1
  409. package/dist/src/session/parity/load-jsonl-entries.js.map +0 -1
  410. package/dist/src/session/parity/session-id.js +0 -18
  411. package/dist/src/session/parity/session-id.js.map +0 -1
  412. package/dist/src/session/parity/sessions-json-cache.d.ts +0 -14
  413. package/dist/src/session/parity/sessions-json-cache.js +0 -98
  414. package/dist/src/session/parity/sessions-json-cache.js.map +0 -1
  415. package/dist/src/session/parity/sessions-json-file-read.d.ts +0 -6
  416. package/dist/src/session/parity/sessions-json-file-read.js +0 -19
  417. package/dist/src/session/parity/sessions-json-file-read.js.map +0 -1
  418. package/dist/src/session/parity/sessions-json-file.d.ts +0 -11
  419. package/dist/src/session/parity/sessions-json-file.js +0 -52
  420. package/dist/src/session/parity/sessions-json-file.js.map +0 -1
  421. package/dist/src/session/parity/sessions-json-patch.d.ts +0 -14
  422. package/dist/src/session/parity/sessions-json-patch.js +0 -40
  423. package/dist/src/session/parity/sessions-json-patch.js.map +0 -1
  424. package/dist/src/session/parity/transcript-file-lock.d.ts +0 -22
  425. package/dist/src/session/parity/transcript-file-lock.js +0 -142
  426. package/dist/src/session/parity/transcript-file-lock.js.map +0 -1
  427. package/dist/src/session/parity/transcript-pagination.d.ts +0 -29
  428. package/dist/src/session/parity/transcript-pagination.js +0 -132
  429. package/dist/src/session/parity/transcript-pagination.js.map +0 -1
  430. package/dist/src/session/parity/transcript-paths.d.ts +0 -13
  431. package/dist/src/session/parity/transcript-paths.js +0 -64
  432. package/dist/src/session/parity/transcript-paths.js.map +0 -1
  433. package/dist/src/session/parity/xopc-session-disk-entry.d.ts +0 -22
  434. package/dist/src/session/search-index-cache.d.ts +0 -6
  435. package/dist/src/session/search-index-cache.js +0 -44
  436. package/dist/src/session/search-index-cache.js.map +0 -1
  437. package/dist/src/session/search-index.d.ts +0 -20
  438. package/dist/src/session/search-index.js +0 -124
  439. package/dist/src/session/search-index.js.map +0 -1
  440. /package/dist/src/{session/parity/xopc-session-disk-entry.js → cron/execution-types.js} +0 -0
  441. /package/dist/src/session/{parity/load-jsonl-entries.d.ts → load-jsonl-entries.d.ts} +0 -0
  442. /package/dist/src/session/{parity/session-id.d.ts → session-id.d.ts} +0 -0
@@ -0,0 +1,56 @@
1
+ import { getSqliteDatabase, runSqliteWriteTransaction } from "./transaction.js";
2
+ import { sessionConfigRowToConfig } from "./row-mappers.js";
3
+ import { ensureSessionInTransaction } from "./session-repository.js";
4
+ //#region src/storage/sqlite/config-repository.ts
5
+ function readConfigRow(db, sessionKey) {
6
+ return db.prepare(`SELECT session_key, thinking_level, reasoning_level, verbose_level, elevated_mode,
7
+ model_override, provider_override, working_directory_override, updated_at
8
+ FROM session_config WHERE session_key = ?`).get(sessionKey);
9
+ }
10
+ function getSessionConfig(sessionKey) {
11
+ const row = readConfigRow(getSqliteDatabase(), sessionKey);
12
+ if (!row) return null;
13
+ return sessionConfigRowToConfig(row);
14
+ }
15
+ function setSessionConfig(sessionKey, config, cwd) {
16
+ return runSqliteWriteTransaction((db) => {
17
+ ensureSessionInTransaction(db, sessionKey, cwd);
18
+ const updatedAt = Date.now();
19
+ const next = {
20
+ ...config,
21
+ updatedAt
22
+ };
23
+ db.prepare(`INSERT INTO session_config (
24
+ session_key, thinking_level, reasoning_level, verbose_level, elevated_mode,
25
+ model_override, provider_override, working_directory_override, updated_at
26
+ ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)
27
+ ON CONFLICT(session_key) DO UPDATE SET
28
+ thinking_level = excluded.thinking_level,
29
+ reasoning_level = excluded.reasoning_level,
30
+ verbose_level = excluded.verbose_level,
31
+ elevated_mode = excluded.elevated_mode,
32
+ model_override = excluded.model_override,
33
+ provider_override = excluded.provider_override,
34
+ working_directory_override = excluded.working_directory_override,
35
+ updated_at = excluded.updated_at`).run(sessionKey, next.thinkingLevel ?? null, next.reasoningLevel ?? null, next.verboseLevel ?? null, next.elevatedMode ?? null, next.modelOverride ?? null, next.providerOverride ?? null, next.workingDirectoryOverride ?? null, updatedAt);
36
+ return next;
37
+ });
38
+ }
39
+ function updateSessionConfig(sessionKey, partial, cwd) {
40
+ return setSessionConfig(sessionKey, {
41
+ ...getSessionConfig(sessionKey),
42
+ ...partial
43
+ }, cwd);
44
+ }
45
+ function deleteSessionConfig(sessionKey) {
46
+ runSqliteWriteTransaction((db) => {
47
+ db.prepare(`DELETE FROM session_config WHERE session_key = ?`).run(sessionKey);
48
+ });
49
+ }
50
+ function hasSessionConfig(sessionKey) {
51
+ return getSqliteDatabase().prepare(`SELECT 1 AS ok FROM session_config WHERE session_key = ?`).get(sessionKey)?.ok === 1;
52
+ }
53
+ //#endregion
54
+ export { deleteSessionConfig, getSessionConfig, hasSessionConfig, setSessionConfig, updateSessionConfig };
55
+
56
+ //# sourceMappingURL=config-repository.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config-repository.js","names":[],"sources":["../../../../src/storage/sqlite/config-repository.ts"],"sourcesContent":["import type { DatabaseSync } from 'node:sqlite';\n\nimport type { SessionAgentConfig } from '../../session/config-types.js';\nimport { sessionConfigRowToConfig, type SessionConfigRow } from './row-mappers.js';\nimport { ensureSessionInTransaction } from './session-repository.js';\nimport { getSqliteDatabase, runSqliteWriteTransaction } from './transaction.js';\n\nfunction readConfigRow(db: DatabaseSync, sessionKey: string): SessionConfigRow | undefined {\n return db\n .prepare(\n `SELECT session_key, thinking_level, reasoning_level, verbose_level, elevated_mode,\n model_override, provider_override, working_directory_override, updated_at\n FROM session_config WHERE session_key = ?`,\n )\n .get(sessionKey) as SessionConfigRow | undefined;\n}\n\nexport function getSessionConfig(sessionKey: string): SessionAgentConfig | null {\n const db = getSqliteDatabase();\n const row = readConfigRow(db, sessionKey);\n if (!row) {\n return null;\n }\n return sessionConfigRowToConfig(row);\n}\n\nexport function setSessionConfig(sessionKey: string, config: SessionAgentConfig, cwd: string): SessionAgentConfig {\n return runSqliteWriteTransaction((db) => {\n ensureSessionInTransaction(db, sessionKey, cwd);\n const updatedAt = Date.now();\n const next = { ...config, updatedAt };\n db.prepare(\n `INSERT INTO session_config (\n session_key, thinking_level, reasoning_level, verbose_level, elevated_mode,\n model_override, provider_override, working_directory_override, updated_at\n ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)\n ON CONFLICT(session_key) DO UPDATE SET\n thinking_level = excluded.thinking_level,\n reasoning_level = excluded.reasoning_level,\n verbose_level = excluded.verbose_level,\n elevated_mode = excluded.elevated_mode,\n model_override = excluded.model_override,\n provider_override = excluded.provider_override,\n working_directory_override = excluded.working_directory_override,\n updated_at = excluded.updated_at`,\n ).run(\n sessionKey,\n next.thinkingLevel ?? null,\n next.reasoningLevel ?? null,\n next.verboseLevel ?? null,\n next.elevatedMode ?? null,\n next.modelOverride ?? null,\n next.providerOverride ?? null,\n next.workingDirectoryOverride ?? null,\n updatedAt,\n );\n return next;\n });\n}\n\nexport function updateSessionConfig(\n sessionKey: string,\n partial: Partial<SessionAgentConfig>,\n cwd: string,\n): SessionAgentConfig {\n const existing = getSessionConfig(sessionKey);\n return setSessionConfig(sessionKey, { ...existing, ...partial }, cwd);\n}\n\nexport function deleteSessionConfig(sessionKey: string): void {\n runSqliteWriteTransaction((db) => {\n db.prepare(`DELETE FROM session_config WHERE session_key = ?`).run(sessionKey);\n });\n}\n\nexport function hasSessionConfig(sessionKey: string): boolean {\n const db = getSqliteDatabase();\n const row = db\n .prepare(`SELECT 1 AS ok FROM session_config WHERE session_key = ?`)\n .get(sessionKey) as { ok?: number } | undefined;\n return row?.ok === 1;\n}\n"],"mappings":";;;;AAOA,SAAS,cAAc,IAAkB,YAAkD;AACzF,QAAO,GACJ,QACC;;kDAGD,CACA,IAAI,WAAW;;AAGpB,SAAgB,iBAAiB,YAA+C;CAE9E,MAAM,MAAM,cADD,mBACiB,EAAE,WAAW;AACzC,KAAI,CAAC,IACH,QAAO;AAET,QAAO,yBAAyB,IAAI;;AAGtC,SAAgB,iBAAiB,YAAoB,QAA4B,KAAiC;AAChH,QAAO,2BAA2B,OAAO;AACvC,6BAA2B,IAAI,YAAY,IAAI;EAC/C,MAAM,YAAY,KAAK,KAAK;EAC5B,MAAM,OAAO;GAAE,GAAG;GAAQ;GAAW;AACrC,KAAG,QACD;;;;;;;;;;;;0CAaD,CAAC,IACA,YACA,KAAK,iBAAiB,MACtB,KAAK,kBAAkB,MACvB,KAAK,gBAAgB,MACrB,KAAK,gBAAgB,MACrB,KAAK,iBAAiB,MACtB,KAAK,oBAAoB,MACzB,KAAK,4BAA4B,MACjC,UACD;AACD,SAAO;GACP;;AAGJ,SAAgB,oBACd,YACA,SACA,KACoB;AAEpB,QAAO,iBAAiB,YAAY;EAAE,GADrB,iBAAiB,WACe;EAAE,GAAG;EAAS,EAAE,IAAI;;AAGvE,SAAgB,oBAAoB,YAA0B;AAC5D,4BAA2B,OAAO;AAChC,KAAG,QAAQ,mDAAmD,CAAC,IAAI,WAAW;GAC9E;;AAGJ,SAAgB,iBAAiB,YAA6B;AAK5D,QAJW,mBACG,CACX,QAAQ,2DAA2D,CACnE,IAAI,WACG,EAAE,OAAO"}
@@ -0,0 +1,38 @@
1
+ import type { DatabaseSync } from 'node:sqlite';
2
+ type SqliteWalCheckpointMode = 'PASSIVE' | 'FULL' | 'RESTART' | 'TRUNCATE';
3
+ export type SqliteWalMaintenance = {
4
+ checkpoint: () => boolean;
5
+ close: () => boolean;
6
+ };
7
+ export type SqliteConnectionPragmaOptions = {
8
+ autoCheckpointPages?: number;
9
+ checkpointIntervalMs?: number;
10
+ checkpointMode?: SqliteWalCheckpointMode;
11
+ busyTimeoutMs?: number;
12
+ foreignKeys?: boolean;
13
+ synchronous?: 'NORMAL';
14
+ databasePath?: string;
15
+ onCheckpointError?: (error: unknown) => void;
16
+ };
17
+ export type XopcDatabase = {
18
+ db: DatabaseSync;
19
+ path: string;
20
+ walMaintenance: SqliteWalMaintenance;
21
+ };
22
+ export type OpenXopcDatabaseOptions = {
23
+ path?: string;
24
+ env?: NodeJS.ProcessEnv;
25
+ };
26
+ export declare function openXopcDatabase(options?: OpenXopcDatabaseOptions): XopcDatabase;
27
+ export declare function getXopcDatabase(): XopcDatabase;
28
+ /**
29
+ * Ensure the xopc SQLite database is open and return it.
30
+ * Opens with default path if not already open. Use this instead of
31
+ * the repetitive `if (!isXopcDatabaseOpen()) { openXopcDatabase(); }` pattern.
32
+ */
33
+ export declare function requireXopcDatabase(options?: OpenXopcDatabaseOptions): XopcDatabase;
34
+ export declare function isXopcDatabaseOpen(): boolean;
35
+ export declare function closeXopcDatabase(): void;
36
+ /** Test-only: reset singleton without touching files on disk. */
37
+ export declare function resetXopcDatabaseSingletonForTest(): void;
38
+ export {};
@@ -0,0 +1,258 @@
1
+ import { createLogger } from "../../utils/logger/index.js";
2
+ import { init_logger } from "../../utils/logger.js";
3
+ import { resolveXopcDatabasePath } from "../../config/paths-state.js";
4
+ import { ensureXopcDatabaseSchema } from "./schema.js";
5
+ import { requireNodeSqlite } from "../../infra/node-sqlite.js";
6
+ import { installSqliteTransientRejectionHandler } from "../../infra/unhandled-rejections.js";
7
+ import fs from "node:fs";
8
+ import path from "node:path";
9
+ import childProcess from "node:child_process";
10
+ //#region src/storage/sqlite/connection.ts
11
+ init_logger();
12
+ const log = createLogger("Sqlite:Connection");
13
+ const XOPC_SQLITE_BUSY_TIMEOUT_MS = 3e4;
14
+ const DB_DIR_MODE = 448;
15
+ const DB_FILE_MODE = 384;
16
+ const DB_SIDECAR_SUFFIXES = [
17
+ "",
18
+ "-shm",
19
+ "-wal"
20
+ ];
21
+ const LINUX_NFS_SUPER_MAGIC = 26985;
22
+ const PROC_MOUNTINFO_PATH = "/proc/self/mountinfo";
23
+ const MAX_TIMER_TIMEOUT_MS = 2 ** 31 - 1;
24
+ function normalizeNonNegativeInteger(value, label) {
25
+ if (!Number.isInteger(value) || value < 0) throw new Error(`${label} must be a non-negative integer`);
26
+ return value;
27
+ }
28
+ function findExistingVolumePath(targetPath) {
29
+ let current = path.resolve(targetPath);
30
+ while (true) try {
31
+ return fs.statSync(current).isDirectory() ? current : path.dirname(current);
32
+ } catch {
33
+ const parent = path.dirname(current);
34
+ if (parent === current) return null;
35
+ current = parent;
36
+ }
37
+ }
38
+ function decodeMountPath(value) {
39
+ return value.replace(/\\([0-7]{3})/g, (_match, octal) => String.fromCharCode(Number.parseInt(octal, 8)));
40
+ }
41
+ function parseProcMountInfoEntries(contents) {
42
+ const entries = [];
43
+ for (const line of contents.split("\n")) {
44
+ const separator = line.indexOf(" - ");
45
+ if (separator === -1) continue;
46
+ const fields = line.slice(0, separator).split(" ");
47
+ const suffixFields = line.slice(separator + 3).split(" ");
48
+ const mountPoint = fields[4];
49
+ const fsType = suffixFields[0];
50
+ if (mountPoint && fsType) entries.push({
51
+ mountPoint: decodeMountPath(mountPoint),
52
+ fsType
53
+ });
54
+ }
55
+ return entries;
56
+ }
57
+ function parseMountCommandEntries(contents) {
58
+ const entries = [];
59
+ for (const line of contents.split("\n")) {
60
+ const linuxMatch = /^.* on (.+) type ([^,\s)]+) \(/.exec(line);
61
+ if (linuxMatch) {
62
+ entries.push({
63
+ mountPoint: linuxMatch[1],
64
+ fsType: linuxMatch[2]
65
+ });
66
+ continue;
67
+ }
68
+ const bsdMatch = /^.* on (.+) \(([^,\s)]+)/.exec(line);
69
+ if (bsdMatch) entries.push({
70
+ mountPoint: bsdMatch[1],
71
+ fsType: bsdMatch[2]
72
+ });
73
+ }
74
+ return entries;
75
+ }
76
+ function readMountEntries() {
77
+ try {
78
+ return parseProcMountInfoEntries(fs.readFileSync(PROC_MOUNTINFO_PATH, "utf8"));
79
+ } catch {}
80
+ try {
81
+ return parseMountCommandEntries(String(childProcess.execFileSync("mount", [])));
82
+ } catch {
83
+ return [];
84
+ }
85
+ }
86
+ function isPathWithinMount(targetPath, mountPoint) {
87
+ const resolvedTarget = path.resolve(targetPath);
88
+ const resolvedMountPoint = path.resolve(mountPoint);
89
+ return resolvedTarget === resolvedMountPoint || resolvedMountPoint === path.parse(resolvedMountPoint).root || resolvedTarget.startsWith(`${resolvedMountPoint}${path.sep}`);
90
+ }
91
+ function isNfsMountType(fsType) {
92
+ return fsType.toLowerCase().startsWith("nfs");
93
+ }
94
+ function isNfsMountEntryPath(targetPath) {
95
+ const mountEntry = readMountEntries().filter((entry) => isPathWithinMount(targetPath, entry.mountPoint)).toSorted((a, b) => b.mountPoint.length - a.mountPoint.length)[0];
96
+ return mountEntry ? isNfsMountType(mountEntry.fsType) : false;
97
+ }
98
+ function isNfsBackedPath(targetPath) {
99
+ if (typeof fs.statfsSync !== "function") return isNfsMountEntryPath(targetPath);
100
+ const checkedPath = findExistingVolumePath(targetPath);
101
+ if (!checkedPath) return false;
102
+ try {
103
+ if (fs.statfsSync(checkedPath).type === LINUX_NFS_SUPER_MAGIC) return true;
104
+ } catch {
105
+ return isNfsMountEntryPath(checkedPath);
106
+ }
107
+ return isNfsMountEntryPath(checkedPath);
108
+ }
109
+ function readJournalModeResult(row) {
110
+ if (!row || typeof row !== "object") return null;
111
+ const record = row;
112
+ const value = record.journal_mode ?? Object.values(record)[0];
113
+ return typeof value === "string" ? value.toLowerCase() : null;
114
+ }
115
+ function requireRollbackJournalMode(db, dbPath) {
116
+ const mode = readJournalModeResult(db.prepare("PRAGMA journal_mode = DELETE;").get());
117
+ if (mode !== "delete") throw new Error(`xopc.db at ${dbPath} is on an NFS-backed volume but SQLite kept journal_mode=${mode ?? "unknown"}. WAL mode is unsafe on NFS. Move ~/.xopc to a local filesystem, or set XOPC_STATE_DIR to a local path.`);
118
+ }
119
+ function configureSqliteConnectionPragmas(db, options = {}) {
120
+ const busyTimeoutMs = options.busyTimeoutMs ?? XOPC_SQLITE_BUSY_TIMEOUT_MS;
121
+ db.exec(`PRAGMA busy_timeout = ${normalizeNonNegativeInteger(busyTimeoutMs, "busyTimeoutMs")};`);
122
+ if (options.databasePath && isNfsBackedPath(options.databasePath)) {
123
+ requireRollbackJournalMode(db, options.databasePath);
124
+ return {
125
+ checkpoint: () => true,
126
+ close: () => true
127
+ };
128
+ }
129
+ db.exec("PRAGMA journal_mode = WAL;");
130
+ const autoCheckpointPages = normalizeNonNegativeInteger(options.autoCheckpointPages ?? 1e3, "autoCheckpointPages");
131
+ db.exec(`PRAGMA wal_autocheckpoint = ${autoCheckpointPages};`);
132
+ if (options.synchronous) db.exec(`PRAGMA synchronous = ${options.synchronous};`);
133
+ if (options.foreignKeys) db.exec("PRAGMA foreign_keys = ON;");
134
+ const checkpointMode = options.checkpointMode ?? "TRUNCATE";
135
+ const periodicCheckpointMode = options.checkpointMode ?? "PASSIVE";
136
+ const checkpointIntervalMs = normalizeNonNegativeInteger(options.checkpointIntervalMs ?? 1800 * 1e3, "checkpointIntervalMs");
137
+ const runCheckpoint = (mode) => {
138
+ try {
139
+ db.exec(`PRAGMA wal_checkpoint(${mode});`);
140
+ return true;
141
+ } catch (error) {
142
+ options.onCheckpointError?.(error);
143
+ return false;
144
+ }
145
+ };
146
+ let timer = null;
147
+ if (checkpointIntervalMs > 0) {
148
+ timer = setInterval(() => runCheckpoint(periodicCheckpointMode), Math.min(checkpointIntervalMs, MAX_TIMER_TIMEOUT_MS));
149
+ timer.unref?.();
150
+ }
151
+ return {
152
+ checkpoint: () => runCheckpoint(checkpointMode),
153
+ close: () => {
154
+ if (timer) {
155
+ clearInterval(timer);
156
+ timer = null;
157
+ }
158
+ return runCheckpoint(checkpointMode);
159
+ }
160
+ };
161
+ }
162
+ let cachedDatabase = null;
163
+ function ensureDatabasePermissions(pathname) {
164
+ const dir = pathname.slice(0, Math.max(pathname.lastIndexOf("/"), pathname.lastIndexOf("\\")));
165
+ if (dir) {
166
+ fs.mkdirSync(dir, { recursive: true });
167
+ fs.chmodSync(dir, DB_DIR_MODE);
168
+ }
169
+ for (const suffix of DB_SIDECAR_SUFFIXES) {
170
+ const candidate = `${pathname}${suffix}`;
171
+ if (!fs.existsSync(candidate)) continue;
172
+ fs.chmodSync(candidate, DB_FILE_MODE);
173
+ }
174
+ }
175
+ function openDatabaseAtPath(pathname) {
176
+ installSqliteTransientRejectionHandler();
177
+ ensureDatabasePermissions(pathname);
178
+ const { DatabaseSync } = requireNodeSqlite();
179
+ const db = new DatabaseSync(pathname);
180
+ const walMaintenance = configureSqliteConnectionPragmas(db, {
181
+ databasePath: pathname,
182
+ synchronous: "NORMAL",
183
+ foreignKeys: true,
184
+ onCheckpointError: (error) => {
185
+ const em = error instanceof Error ? error.message : String(error);
186
+ log.warn({
187
+ err: error instanceof Error ? error : void 0,
188
+ errorMessage: em
189
+ }, `SQLite WAL checkpoint failed: ${em}`);
190
+ }
191
+ });
192
+ ensureXopcDatabaseSchema(db);
193
+ ensureDatabasePermissions(pathname);
194
+ log.info({ path: pathname }, "Opened xopc SQLite database");
195
+ return {
196
+ db,
197
+ path: pathname,
198
+ walMaintenance
199
+ };
200
+ }
201
+ function openXopcDatabase(options = {}) {
202
+ const env = options.env ?? process.env;
203
+ const pathname = options.path ?? resolveXopcDatabasePath(env);
204
+ if (cachedDatabase && cachedDatabase.path === pathname) return cachedDatabase;
205
+ if (cachedDatabase) closeXopcDatabase();
206
+ cachedDatabase = openDatabaseAtPath(pathname);
207
+ return cachedDatabase;
208
+ }
209
+ function getXopcDatabase() {
210
+ if (!cachedDatabase) throw new Error("xopc SQLite database is not open; call openXopcDatabase() first");
211
+ return cachedDatabase;
212
+ }
213
+ /**
214
+ * Ensure the xopc SQLite database is open and return it.
215
+ * Opens with default path if not already open. Use this instead of
216
+ * the repetitive `if (!isXopcDatabaseOpen()) { openXopcDatabase(); }` pattern.
217
+ */
218
+ function requireXopcDatabase(options) {
219
+ if (!cachedDatabase) openXopcDatabase(options ?? {});
220
+ return cachedDatabase;
221
+ }
222
+ function isXopcDatabaseOpen() {
223
+ return cachedDatabase !== null;
224
+ }
225
+ function closeXopcDatabase() {
226
+ if (!cachedDatabase) return;
227
+ const { db, path, walMaintenance } = cachedDatabase;
228
+ try {
229
+ walMaintenance.close();
230
+ } catch (error) {
231
+ const em = error instanceof Error ? error.message : String(error);
232
+ log.warn({
233
+ err: error instanceof Error ? error : void 0,
234
+ errorMessage: em,
235
+ path
236
+ }, `SQLite close checkpoint failed: ${em}`);
237
+ }
238
+ try {
239
+ db.close();
240
+ } catch (error) {
241
+ const em = error instanceof Error ? error.message : String(error);
242
+ log.warn({
243
+ err: error instanceof Error ? error : void 0,
244
+ errorMessage: em,
245
+ path
246
+ }, `SQLite database close failed: ${em}`);
247
+ }
248
+ cachedDatabase = null;
249
+ log.debug({ path }, "Closed xopc SQLite database");
250
+ }
251
+ /** Test-only: reset singleton without touching files on disk. */
252
+ function resetXopcDatabaseSingletonForTest() {
253
+ cachedDatabase = null;
254
+ }
255
+ //#endregion
256
+ export { closeXopcDatabase, getXopcDatabase, isXopcDatabaseOpen, openXopcDatabase, requireXopcDatabase, resetXopcDatabaseSingletonForTest };
257
+
258
+ //# sourceMappingURL=connection.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"connection.js","names":[],"sources":["../../../../src/storage/sqlite/connection.ts"],"sourcesContent":["import fs from 'node:fs';\nimport childProcess from 'node:child_process';\nimport path from 'node:path';\nimport type { DatabaseSync } from 'node:sqlite';\n\nimport { requireNodeSqlite } from '../../infra/node-sqlite.js';\nimport { installSqliteTransientRejectionHandler } from '../../infra/unhandled-rejections.js';\nimport { createLogger } from '../../utils/logger.js';\nimport { resolveXopcDatabasePath } from './paths.js';\nimport { ensureXopcDatabaseSchema } from './schema.js';\n\nconst log = createLogger('Sqlite:Connection');\n\nconst XOPC_SQLITE_BUSY_TIMEOUT_MS = 30_000;\nconst DB_DIR_MODE = 0o700;\nconst DB_FILE_MODE = 0o600;\nconst DB_SIDECAR_SUFFIXES = ['', '-shm', '-wal'] as const;\nconst LINUX_NFS_SUPER_MAGIC = 0x6969;\nconst PROC_MOUNTINFO_PATH = '/proc/self/mountinfo';\nconst MAX_TIMER_TIMEOUT_MS = 2 ** 31 - 1;\n\ntype IntervalHandle = ReturnType<typeof setInterval> & { unref?: () => void };\ntype SqliteWalCheckpointMode = 'PASSIVE' | 'FULL' | 'RESTART' | 'TRUNCATE';\n\nexport type SqliteWalMaintenance = {\n checkpoint: () => boolean;\n close: () => boolean;\n};\n\nexport type SqliteConnectionPragmaOptions = {\n autoCheckpointPages?: number;\n checkpointIntervalMs?: number;\n checkpointMode?: SqliteWalCheckpointMode;\n busyTimeoutMs?: number;\n foreignKeys?: boolean;\n synchronous?: 'NORMAL';\n databasePath?: string;\n onCheckpointError?: (error: unknown) => void;\n};\n\nfunction normalizeNonNegativeInteger(value: number, label: string): number {\n if (!Number.isInteger(value) || value < 0) {\n throw new Error(`${label} must be a non-negative integer`);\n }\n return value;\n}\n\n// ---------------------------------------------------------------------------\n// NFS detection — refuse WAL on NFS-backed volumes (openclaw parity)\n// ---------------------------------------------------------------------------\n\nfunction findExistingVolumePath(targetPath: string): string | null {\n let current = path.resolve(targetPath);\n while (true) {\n try {\n const stats = fs.statSync(current);\n return stats.isDirectory() ? current : path.dirname(current);\n } catch {\n const parent = path.dirname(current);\n if (parent === current) return null;\n current = parent;\n }\n }\n}\n\nfunction decodeMountPath(value: string): string {\n return value.replace(/\\\\([0-7]{3})/g, (_match, octal: string) =>\n String.fromCharCode(Number.parseInt(octal, 8)),\n );\n}\n\nfunction parseProcMountInfoEntries(\n contents: string,\n): Array<{ mountPoint: string; fsType: string }> {\n const entries: Array<{ mountPoint: string; fsType: string }> = [];\n for (const line of contents.split('\\n')) {\n const separator = line.indexOf(' - ');\n if (separator === -1) continue;\n const fields = line.slice(0, separator).split(' ');\n const suffixFields = line.slice(separator + 3).split(' ');\n const mountPoint = fields[4];\n const fsType = suffixFields[0];\n if (mountPoint && fsType) {\n entries.push({ mountPoint: decodeMountPath(mountPoint), fsType });\n }\n }\n return entries;\n}\n\nfunction parseMountCommandEntries(contents: string): Array<{ mountPoint: string; fsType: string }> {\n const entries: Array<{ mountPoint: string; fsType: string }> = [];\n for (const line of contents.split('\\n')) {\n // Linux: /dev/sda1 on /mnt type ext4 (rw,relatime)\n const linuxMatch = /^.* on (.+) type ([^,\\s)]+) \\(/.exec(line);\n if (linuxMatch) {\n entries.push({ mountPoint: linuxMatch[1], fsType: linuxMatch[2] });\n continue;\n }\n // macOS/BSD: //host/share on /Volumes/share (nfs, nodev, nosuid)\n const bsdMatch = /^.* on (.+) \\(([^,\\s)]+)/.exec(line);\n if (bsdMatch) {\n entries.push({ mountPoint: bsdMatch[1], fsType: bsdMatch[2] });\n }\n }\n return entries;\n}\n\nfunction readMountEntries(): Array<{ mountPoint: string; fsType: string }> {\n try {\n return parseProcMountInfoEntries(fs.readFileSync(PROC_MOUNTINFO_PATH, 'utf8'));\n } catch {\n // macOS/BSD: fall through to mount command\n }\n try {\n return parseMountCommandEntries(String(childProcess.execFileSync('mount', [])));\n } catch {\n return [];\n }\n}\n\nfunction isPathWithinMount(targetPath: string, mountPoint: string): boolean {\n const resolvedTarget = path.resolve(targetPath);\n const resolvedMountPoint = path.resolve(mountPoint);\n return (\n resolvedTarget === resolvedMountPoint ||\n resolvedMountPoint === path.parse(resolvedMountPoint).root ||\n resolvedTarget.startsWith(`${resolvedMountPoint}${path.sep}`)\n );\n}\n\nfunction isNfsMountType(fsType: string): boolean {\n return fsType.toLowerCase().startsWith('nfs');\n}\n\nfunction isNfsMountEntryPath(targetPath: string): boolean {\n const mountEntry = readMountEntries()\n .filter((entry) => isPathWithinMount(targetPath, entry.mountPoint))\n .toSorted((a, b) => b.mountPoint.length - a.mountPoint.length)[0];\n return mountEntry ? isNfsMountType(mountEntry.fsType) : false;\n}\n\nfunction isNfsBackedPath(targetPath: string): boolean {\n if (typeof fs.statfsSync !== 'function') {\n return isNfsMountEntryPath(targetPath);\n }\n const checkedPath = findExistingVolumePath(targetPath);\n if (!checkedPath) return false;\n try {\n if (fs.statfsSync(checkedPath).type === LINUX_NFS_SUPER_MAGIC) return true;\n } catch {\n return isNfsMountEntryPath(checkedPath);\n }\n return isNfsMountEntryPath(checkedPath);\n}\n\nfunction readJournalModeResult(row: unknown): string | null {\n if (!row || typeof row !== 'object') return null;\n const record = row as Record<string, unknown>;\n const value = record.journal_mode ?? Object.values(record)[0];\n return typeof value === 'string' ? value.toLowerCase() : null;\n}\n\nfunction requireRollbackJournalMode(db: DatabaseSync, dbPath: string): void {\n const row = db.prepare('PRAGMA journal_mode = DELETE;').get();\n const mode = readJournalModeResult(row);\n if (mode !== 'delete') {\n throw new Error(\n `xopc.db at ${dbPath} is on an NFS-backed volume but SQLite kept journal_mode=${mode ?? 'unknown'}. ` +\n `WAL mode is unsafe on NFS. Move ~/.xopc to a local filesystem, or set XOPC_STATE_DIR to a local path.`,\n );\n }\n}\n\n// ---------------------------------------------------------------------------\n// Unified PRAGMA + WAL configuration (openclaw parity)\n// ---------------------------------------------------------------------------\n\nfunction configureSqliteConnectionPragmas(\n db: DatabaseSync,\n options: SqliteConnectionPragmaOptions = {},\n): SqliteWalMaintenance {\n // Set busy_timeout before journal_mode to avoid lock-retry ordering issues\n const busyTimeoutMs = options.busyTimeoutMs ?? XOPC_SQLITE_BUSY_TIMEOUT_MS;\n db.exec(`PRAGMA busy_timeout = ${normalizeNonNegativeInteger(busyTimeoutMs, 'busyTimeoutMs')};`);\n\n // NFS detection: refuse WAL, force DELETE mode\n if (options.databasePath && isNfsBackedPath(options.databasePath)) {\n requireRollbackJournalMode(db, options.databasePath);\n // No WAL checkpoint timer needed on DELETE mode\n return { checkpoint: () => true, close: () => true };\n }\n\n // WAL setup\n db.exec('PRAGMA journal_mode = WAL;');\n const autoCheckpointPages = normalizeNonNegativeInteger(\n options.autoCheckpointPages ?? 1000,\n 'autoCheckpointPages',\n );\n db.exec(`PRAGMA wal_autocheckpoint = ${autoCheckpointPages};`);\n\n // Remaining pragmas in safe order\n if (options.synchronous) db.exec(`PRAGMA synchronous = ${options.synchronous};`);\n if (options.foreignKeys) db.exec('PRAGMA foreign_keys = ON;');\n\n // Periodic checkpoint timer\n const checkpointMode = options.checkpointMode ?? 'TRUNCATE';\n const periodicCheckpointMode = options.checkpointMode ?? 'PASSIVE';\n const checkpointIntervalMs = normalizeNonNegativeInteger(\n options.checkpointIntervalMs ?? 30 * 60 * 1000,\n 'checkpointIntervalMs',\n );\n\n const runCheckpoint = (mode: SqliteWalCheckpointMode): boolean => {\n try {\n db.exec(`PRAGMA wal_checkpoint(${mode});`);\n return true;\n } catch (error) {\n options.onCheckpointError?.(error);\n return false;\n }\n };\n\n let timer: IntervalHandle | null = null;\n if (checkpointIntervalMs > 0) {\n const timerIntervalMs = Math.min(checkpointIntervalMs, MAX_TIMER_TIMEOUT_MS);\n timer = setInterval(() => runCheckpoint(periodicCheckpointMode), timerIntervalMs) as IntervalHandle;\n timer.unref?.();\n }\n\n return {\n checkpoint: () => runCheckpoint(checkpointMode),\n close: () => {\n if (timer) { clearInterval(timer); timer = null; }\n return runCheckpoint(checkpointMode);\n },\n };\n}\n\n// ---------------------------------------------------------------------------\n// Database lifecycle\n// ---------------------------------------------------------------------------\n\nexport type XopcDatabase = {\n db: DatabaseSync;\n path: string;\n walMaintenance: SqliteWalMaintenance;\n};\n\nexport type OpenXopcDatabaseOptions = {\n path?: string;\n env?: NodeJS.ProcessEnv;\n};\n\nlet cachedDatabase: XopcDatabase | null = null;\n\nfunction ensureDatabasePermissions(pathname: string): void {\n const dir = pathname.slice(0, Math.max(pathname.lastIndexOf('/'), pathname.lastIndexOf('\\\\')));\n if (dir) {\n fs.mkdirSync(dir, { recursive: true });\n fs.chmodSync(dir, DB_DIR_MODE);\n }\n for (const suffix of DB_SIDECAR_SUFFIXES) {\n const candidate = `${pathname}${suffix}`;\n if (!fs.existsSync(candidate)) continue;\n fs.chmodSync(candidate, DB_FILE_MODE);\n }\n}\n\nfunction openDatabaseAtPath(pathname: string): XopcDatabase {\n installSqliteTransientRejectionHandler();\n ensureDatabasePermissions(pathname);\n\n const { DatabaseSync } = requireNodeSqlite();\n const db = new DatabaseSync(pathname);\n\n // Single call: busy_timeout (30s) → WAL/NFS detection → synchronous → foreign_keys → checkpoint timer\n const walMaintenance = configureSqliteConnectionPragmas(db, {\n databasePath: pathname,\n synchronous: 'NORMAL',\n foreignKeys: true,\n onCheckpointError: (error) => {\n const em = error instanceof Error ? error.message : String(error);\n log.warn({ err: error instanceof Error ? error : undefined, errorMessage: em }, `SQLite WAL checkpoint failed: ${em}`);\n },\n });\n\n ensureXopcDatabaseSchema(db);\n ensureDatabasePermissions(pathname);\n\n log.info({ path: pathname }, 'Opened xopc SQLite database');\n return { db, path: pathname, walMaintenance };\n}\n\nexport function openXopcDatabase(options: OpenXopcDatabaseOptions = {}): XopcDatabase {\n const env = options.env ?? process.env;\n const pathname = options.path ?? resolveXopcDatabasePath(env);\n\n if (cachedDatabase && cachedDatabase.path === pathname) {\n return cachedDatabase;\n }\n\n if (cachedDatabase) {\n closeXopcDatabase();\n }\n\n cachedDatabase = openDatabaseAtPath(pathname);\n return cachedDatabase;\n}\n\nexport function getXopcDatabase(): XopcDatabase {\n if (!cachedDatabase) {\n throw new Error('xopc SQLite database is not open; call openXopcDatabase() first');\n }\n return cachedDatabase;\n}\n\n/**\n * Ensure the xopc SQLite database is open and return it.\n * Opens with default path if not already open. Use this instead of\n * the repetitive `if (!isXopcDatabaseOpen()) { openXopcDatabase(); }` pattern.\n */\nexport function requireXopcDatabase(options?: OpenXopcDatabaseOptions): XopcDatabase {\n if (!cachedDatabase) {\n openXopcDatabase(options ?? {});\n }\n return cachedDatabase!;\n}\n\nexport function isXopcDatabaseOpen(): boolean {\n return cachedDatabase !== null;\n}\n\nexport function closeXopcDatabase(): void {\n if (!cachedDatabase) {\n return;\n }\n\n const { db, path, walMaintenance } = cachedDatabase;\n try {\n walMaintenance.close();\n } catch (error) {\n const em = error instanceof Error ? error.message : String(error);\n log.warn({ err: error instanceof Error ? error : undefined, errorMessage: em, path }, `SQLite close checkpoint failed: ${em}`);\n }\n\n try {\n db.close();\n } catch (error) {\n const em = error instanceof Error ? error.message : String(error);\n log.warn({ err: error instanceof Error ? error : undefined, errorMessage: em, path }, `SQLite database close failed: ${em}`);\n }\n\n cachedDatabase = null;\n log.debug({ path }, 'Closed xopc SQLite database');\n}\n\n/** Test-only: reset singleton without touching files on disk. */\nexport function resetXopcDatabaseSingletonForTest(): void {\n cachedDatabase = null;\n}\n"],"mappings":"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"}
@@ -0,0 +1,5 @@
1
+ import type { JobExecution } from '../../cron/execution-types.js';
2
+ export declare function appendCronRun(execution: JobExecution): void;
3
+ export declare function readCronJobHistory(jobId: string, limit: number): JobExecution[];
4
+ export declare function readAllCronRuns(limit: number): JobExecution[];
5
+ export declare function deleteCronRunsForJob(jobId: string): void;
@@ -0,0 +1,97 @@
1
+ import { getSqliteDatabase, runSqliteWriteTransaction } from "./transaction.js";
2
+ //#region src/storage/sqlite/cron-run-repository.ts
3
+ const MAX_RUNS_PER_JOB = 2e3;
4
+ const TRIM_TO_RUNS = 1500;
5
+ function rowToExecution(row) {
6
+ return {
7
+ id: row.run_id,
8
+ jobId: row.job_id,
9
+ status: row.status,
10
+ startedAt: new Date(row.started_at).toISOString(),
11
+ endedAt: row.ended_at != null ? new Date(row.ended_at).toISOString() : void 0,
12
+ duration: row.duration_ms ?? void 0,
13
+ error: row.error ?? void 0,
14
+ output: row.output ?? void 0,
15
+ retryCount: row.retry_count,
16
+ summary: row.summary ?? void 0,
17
+ sessionId: row.session_id ?? void 0,
18
+ sessionKey: row.session_key ?? void 0,
19
+ sessionType: row.session_type ?? void 0,
20
+ model: row.model ?? void 0,
21
+ provider: row.provider ?? void 0,
22
+ usage: row.usage_json ? JSON.parse(row.usage_json) : void 0,
23
+ workflowRunId: row.workflow_run_id ?? void 0
24
+ };
25
+ }
26
+ function executionToInsert(execution) {
27
+ const startedAt = Date.parse(execution.startedAt);
28
+ const endedAt = execution.endedAt ? Date.parse(execution.endedAt) : null;
29
+ return {
30
+ run_id: execution.id,
31
+ job_id: execution.jobId,
32
+ status: execution.status,
33
+ started_at: startedAt,
34
+ ended_at: endedAt,
35
+ duration_ms: execution.duration ?? null,
36
+ error: execution.error ?? null,
37
+ output: execution.output ?? null,
38
+ retry_count: execution.retryCount,
39
+ summary: execution.summary ?? null,
40
+ session_id: execution.sessionId ?? null,
41
+ session_key: execution.sessionKey ?? null,
42
+ session_type: execution.sessionType ?? null,
43
+ model: execution.model ?? null,
44
+ provider: execution.provider ?? null,
45
+ usage_json: execution.usage ? JSON.stringify(execution.usage) : null,
46
+ workflow_run_id: execution.workflowRunId ?? null
47
+ };
48
+ }
49
+ function trimJobRuns(db, jobId) {
50
+ const countRow = db.prepare(`SELECT COUNT(*) AS count FROM cron_runs WHERE job_id = ?`).get(jobId);
51
+ if (countRow.count <= MAX_RUNS_PER_JOB) return;
52
+ const excess = countRow.count - TRIM_TO_RUNS;
53
+ db.prepare(`DELETE FROM cron_runs WHERE run_id IN (
54
+ SELECT run_id FROM cron_runs WHERE job_id = ?
55
+ ORDER BY started_at ASC LIMIT ?
56
+ )`).run(jobId, excess);
57
+ }
58
+ function appendCronRun(execution) {
59
+ if (execution.status === "running") return;
60
+ const row = executionToInsert(execution);
61
+ runSqliteWriteTransaction((db) => {
62
+ db.prepare(`INSERT OR REPLACE INTO cron_runs (
63
+ run_id, job_id, status, started_at, ended_at, duration_ms,
64
+ error, output, retry_count, summary, session_id, session_key,
65
+ session_type, model, provider, usage_json, workflow_run_id
66
+ ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`).run(row.run_id, row.job_id, row.status, row.started_at, row.ended_at, row.duration_ms, row.error, row.output, row.retry_count, row.summary, row.session_id, row.session_key, row.session_type, row.model, row.provider, row.usage_json, row.workflow_run_id);
67
+ trimJobRuns(db, row.job_id);
68
+ });
69
+ }
70
+ function readCronJobHistory(jobId, limit) {
71
+ if (limit <= 0) return [];
72
+ return getSqliteDatabase().prepare(`SELECT run_id, job_id, status, started_at, ended_at, duration_ms,
73
+ error, output, retry_count, summary, session_id, session_key,
74
+ session_type, model, provider, usage_json, workflow_run_id
75
+ FROM cron_runs
76
+ WHERE job_id = ?
77
+ ORDER BY started_at DESC
78
+ LIMIT ?`).all(jobId, limit).map(rowToExecution);
79
+ }
80
+ function readAllCronRuns(limit) {
81
+ if (limit <= 0) return [];
82
+ return getSqliteDatabase().prepare(`SELECT run_id, job_id, status, started_at, ended_at, duration_ms,
83
+ error, output, retry_count, summary, session_id, session_key,
84
+ session_type, model, provider, usage_json, workflow_run_id
85
+ FROM cron_runs
86
+ ORDER BY started_at DESC
87
+ LIMIT ?`).all(limit).map(rowToExecution);
88
+ }
89
+ function deleteCronRunsForJob(jobId) {
90
+ runSqliteWriteTransaction((db) => {
91
+ db.prepare(`DELETE FROM cron_runs WHERE job_id = ?`).run(jobId);
92
+ });
93
+ }
94
+ //#endregion
95
+ export { appendCronRun, deleteCronRunsForJob, readAllCronRuns, readCronJobHistory };
96
+
97
+ //# sourceMappingURL=cron-run-repository.js.map
@@ -0,0 +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"}
@@ -0,0 +1,2 @@
1
+ /** Quote a user query for FTS5 phrase/prefix-safe matching. */
2
+ export declare function escapeFts5Query(raw: string): string;
@@ -0,0 +1,11 @@
1
+ //#region src/storage/sqlite/fts.ts
2
+ /** Quote a user query for FTS5 phrase/prefix-safe matching. */
3
+ function escapeFts5Query(raw) {
4
+ const trimmed = raw.trim();
5
+ if (!trimmed) return "";
6
+ return `"${trimmed.replace(/"/g, "\"\"")}"`;
7
+ }
8
+ //#endregion
9
+ export { escapeFts5Query };
10
+
11
+ //# sourceMappingURL=fts.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fts.js","names":[],"sources":["../../../../src/storage/sqlite/fts.ts"],"sourcesContent":["/** Quote a user query for FTS5 phrase/prefix-safe matching. */\nexport function escapeFts5Query(raw: string): string {\n const trimmed = raw.trim();\n if (!trimmed) {\n return '';\n }\n return `\"${trimmed.replace(/\"/g, '\"\"')}\"`;\n}\n"],"mappings":";;AACA,SAAgB,gBAAgB,KAAqB;CACnD,MAAM,UAAU,IAAI,MAAM;AAC1B,KAAI,CAAC,QACH,QAAO;AAET,QAAO,IAAI,QAAQ,QAAQ,MAAM,OAAK,CAAC"}
@@ -0,0 +1,12 @@
1
+ export { resolveXopcDatabasePath, XOPC_DB_FILENAME } from './paths.js';
2
+ export { XOPC_DB_SCHEMA_VERSION, SCHEMA_META_SCHEMA_VERSION_KEY, ensureXopcDatabaseSchema, readSchemaVersionForTest, } from './schema.js';
3
+ export { closeXopcDatabase, getXopcDatabase, isXopcDatabaseOpen, openXopcDatabase, requireXopcDatabase, resetXopcDatabaseSingletonForTest, type OpenXopcDatabaseOptions, type XopcDatabase, } from './connection.js';
4
+ export { getSqliteDatabase, runSqliteWriteTransaction } from './transaction.js';
5
+ export { buildDefaultSessionMetadata, extractRoutingFromSessionKey, parseSessionKeySource, resolveAgentIdFromSessionKey, } from './session-metadata.js';
6
+ export { buildGlobalSessionStats, classifyStoredRow, estimateTokensFromMessages, extractFtsContent, metadataToSessionInsert, sessionConfigRowToConfig, sessionRowToMetadata, transcriptEntryRowToStoredRow, type SessionConfigRow, type SessionRow, type TranscriptEntryRow, } from './row-mappers.js';
7
+ export { deleteSessionRecord, ensureSessionRecord, getCurrentTranscriptId, getGlobalSessionStats, findSessionKeyByTranscriptId, getSessionPersistedLevels, getSessionMetadata, incrementSessionStatsOnAppend, listSessionMetadata, listSessionsByAgent, patchSessionMetadata, resetSessionRecord, resolveSessionAgentId, updateSessionStats, } from './session-repository.js';
8
+ export { appendTranscriptEntry, captureCompactionCheckpoint, getCompactionCheckpointDetail, listCompactionCheckpoints, loadCheckpointRows, loadLlmMessagesForSession, loadTranscriptRows, loadTranscriptRowsForSession, paginateTranscriptMessages, replaceTranscriptRows, restoreCompactionCheckpoint, } from './transcript-repository.js';
9
+ export { appendCronRun, deleteCronRunsForJob, readAllCronRuns, readCronJobHistory, } from './cron-run-repository.js';
10
+ export { deleteNoteRecord, getNoteRecord, listNoteRecords, upsertNoteRecord, } from './notes-repository.js';
11
+ export { resolveAgentIdFromMemoriesDir, searchMemoryIndex, syncMemoryIndex, type MemorySearchHit, } from './memory-index-repository.js';
12
+ export { deleteSessionConfig, getSessionConfig, hasSessionConfig, setSessionConfig, updateSessionConfig, } from './config-repository.js';
@@ -0,0 +1,13 @@
1
+ import { XOPC_DB_FILENAME, resolveXopcDatabasePath } from "../../config/paths-state.js";
2
+ import { SCHEMA_META_SCHEMA_VERSION_KEY, XOPC_DB_SCHEMA_VERSION, ensureXopcDatabaseSchema, readSchemaVersionForTest } from "./schema.js";
3
+ import { closeXopcDatabase, getXopcDatabase, isXopcDatabaseOpen, openXopcDatabase, requireXopcDatabase, resetXopcDatabaseSingletonForTest } from "./connection.js";
4
+ import { getSqliteDatabase, runSqliteWriteTransaction } from "./transaction.js";
5
+ import { buildDefaultSessionMetadata, extractRoutingFromSessionKey, parseSessionKeySource, resolveAgentIdFromSessionKey } from "./session-metadata.js";
6
+ import { buildGlobalSessionStats, classifyStoredRow, estimateTokensFromMessages, extractFtsContent, metadataToSessionInsert, sessionConfigRowToConfig, sessionRowToMetadata, transcriptEntryRowToStoredRow } from "./row-mappers.js";
7
+ import { deleteSessionRecord, ensureSessionRecord, findSessionKeyByTranscriptId, getCurrentTranscriptId, getGlobalSessionStats, getSessionMetadata, getSessionPersistedLevels, incrementSessionStatsOnAppend, listSessionMetadata, listSessionsByAgent, patchSessionMetadata, resetSessionRecord, resolveSessionAgentId, updateSessionStats } from "./session-repository.js";
8
+ import { appendTranscriptEntry, captureCompactionCheckpoint, getCompactionCheckpointDetail, listCompactionCheckpoints, loadCheckpointRows, loadLlmMessagesForSession, loadTranscriptRows, loadTranscriptRowsForSession, paginateTranscriptMessages, replaceTranscriptRows, restoreCompactionCheckpoint } from "./transcript-repository.js";
9
+ import { appendCronRun, deleteCronRunsForJob, readAllCronRuns, readCronJobHistory } from "./cron-run-repository.js";
10
+ import { deleteNoteRecord, getNoteRecord, listNoteRecords, upsertNoteRecord } from "./notes-repository.js";
11
+ import { resolveAgentIdFromMemoriesDir, searchMemoryIndex, syncMemoryIndex } from "./memory-index-repository.js";
12
+ import { deleteSessionConfig, getSessionConfig, hasSessionConfig, setSessionConfig, updateSessionConfig } from "./config-repository.js";
13
+ export { SCHEMA_META_SCHEMA_VERSION_KEY, XOPC_DB_FILENAME, XOPC_DB_SCHEMA_VERSION, appendCronRun, appendTranscriptEntry, buildDefaultSessionMetadata, buildGlobalSessionStats, captureCompactionCheckpoint, classifyStoredRow, closeXopcDatabase, deleteCronRunsForJob, deleteNoteRecord, deleteSessionConfig, deleteSessionRecord, ensureSessionRecord, ensureXopcDatabaseSchema, estimateTokensFromMessages, extractFtsContent, extractRoutingFromSessionKey, findSessionKeyByTranscriptId, getCompactionCheckpointDetail, getCurrentTranscriptId, getGlobalSessionStats, getNoteRecord, getSessionConfig, getSessionMetadata, getSessionPersistedLevels, getSqliteDatabase, getXopcDatabase, hasSessionConfig, incrementSessionStatsOnAppend, isXopcDatabaseOpen, listCompactionCheckpoints, listNoteRecords, listSessionMetadata, listSessionsByAgent, loadCheckpointRows, loadLlmMessagesForSession, loadTranscriptRows, loadTranscriptRowsForSession, metadataToSessionInsert, openXopcDatabase, paginateTranscriptMessages, parseSessionKeySource, patchSessionMetadata, readAllCronRuns, readCronJobHistory, readSchemaVersionForTest, replaceTranscriptRows, requireXopcDatabase, resetSessionRecord, resetXopcDatabaseSingletonForTest, resolveAgentIdFromMemoriesDir, resolveAgentIdFromSessionKey, resolveSessionAgentId, resolveXopcDatabasePath, restoreCompactionCheckpoint, runSqliteWriteTransaction, searchMemoryIndex, sessionConfigRowToConfig, sessionRowToMetadata, setSessionConfig, syncMemoryIndex, transcriptEntryRowToStoredRow, updateSessionConfig, updateSessionStats, upsertNoteRecord };
@@ -0,0 +1,18 @@
1
+ export type MemorySearchHit = {
2
+ path: string;
3
+ lines: string;
4
+ score: number;
5
+ lineNumbers: number[];
6
+ };
7
+ export declare function resolveAgentIdFromMemoriesDir(memoriesDir: string | undefined): string;
8
+ export declare function syncMemoryIndex(params: {
9
+ agentId: string;
10
+ workspaceDir: string;
11
+ memoriesDir?: string;
12
+ }): void;
13
+ export declare function searchMemoryIndex(params: {
14
+ agentId: string;
15
+ query: string;
16
+ maxResults?: number;
17
+ minScore?: number;
18
+ }): MemorySearchHit[];