@xopcai/xopc 0.0.94 → 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 (433) 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-OqhbJkMf.js → agents-DmIuSaOE.js} +3 -3
  19. package/dist/gateway/static/root/assets/{apps-page-OHXW9XP8.js → apps-page-DFcHBxLw.js} +1 -1
  20. package/dist/gateway/static/root/assets/{channels-settings-4N2R-jof.js → channels-settings-DDUf55C5.js} +1 -1
  21. package/dist/gateway/static/root/assets/{channels-status-swr-Bv6f9kDq.js → channels-status-swr-BxF-_nzD.js} +1 -1
  22. package/dist/gateway/static/root/assets/{cron-api-BtaQaHJq.js → cron-api-DylQtnb_.js} +1 -1
  23. package/dist/gateway/static/root/assets/{cron-page-Dah32HJK.js → cron-page-BO0d9Pf-.js} +1 -1
  24. package/dist/gateway/static/root/assets/{dist-BJfD9Qvs.js → dist-BskF0qDS.js} +1 -1
  25. package/dist/gateway/static/root/assets/{extension-debug-page-DnYuMzmH.js → extension-debug-page-BcZdTdjJ.js} +1 -1
  26. package/dist/gateway/static/root/assets/{extension-page-CJfc-6XV.js → extension-page-D2iuDa1D.js} +1 -1
  27. package/dist/gateway/static/root/assets/{extension-settings-page-BxdfYQMG.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-DOLHwowi.js → field-primitives-2PekrGZF.js} +1 -1
  30. package/dist/gateway/static/root/assets/{heartbeat-config-api-Bj2INAf5.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-DuQ1XPoA.js → index-Db9fd_X4.js} +74 -74
  33. package/dist/gateway/static/root/assets/{logs-page-AsOgLNJE.js → logs-page-B3I1a26m.js} +1 -1
  34. package/dist/gateway/static/root/assets/{note-detail-page-24J4mVP-.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-JBszYV3s.js → note-time-CjUGtqKr.js} +1 -1
  37. package/dist/gateway/static/root/assets/notes-page-BB8-I0Of.js +1 -0
  38. package/dist/gateway/static/root/assets/{sessions-page-DX9huWsA.js → sessions-page-BcH-1K9i.js} +1 -1
  39. package/dist/gateway/static/root/assets/{settings-advanced-gate-DWvhsTuz.js → settings-advanced-gate-Czn8nnjN.js} +2 -2
  40. package/dist/gateway/static/root/assets/{settings-form-section-CxMjaMiy.js → settings-form-section-ZZWDwgVe.js} +1 -1
  41. package/dist/gateway/static/root/assets/settings-page-BX8c_zrN.js +3 -0
  42. package/dist/gateway/static/root/assets/share-preview-page-Ch3_6Qah.js +2 -0
  43. package/dist/gateway/static/root/assets/{skills-page-CGKGKfwe.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-BmlcxR2j.js → utils-uTYKh54l.js} +1 -1
  47. package/dist/gateway/static/root/assets/{voice-api-key-field-DaGm2N4J.js → voice-api-key-field-BIAYHRs-.js} +1 -1
  48. package/dist/gateway/static/root/assets/{workflow-page.utils-D0vsIGHD.js → workflow-page.utils-BbWhqD36.js} +1 -1
  49. package/dist/gateway/static/root/assets/{workflows-page-BFCrD3nw.js → workflows-page-D4RIF7E1.js} +2 -2
  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/heartbeat/service.js +1 -1
  224. package/dist/src/gateway/hono/lib/config-payload.js +1 -1
  225. package/dist/src/gateway/hono/lib/extension-store.js +2 -2
  226. package/dist/src/gateway/hono/lib/static-ui.js +2 -2
  227. package/dist/src/gateway/hono/oauth.js +1 -1
  228. package/dist/src/gateway/hono/routes/agents.js +1 -1
  229. package/dist/src/gateway/hono/routes/auth-registry-extensions.js +1 -1
  230. package/dist/src/gateway/hono/routes/config-patch/misc.js +1 -1
  231. package/dist/src/gateway/hono/routes/dreaming.js +1 -1
  232. package/dist/src/gateway/hono/routes/host-fs.js +2 -2
  233. package/dist/src/gateway/hono/routes/models.js +1 -1
  234. package/dist/src/gateway/hono/routes/shares.js +1 -1
  235. package/dist/src/gateway/hono/routes/workspace.js +2 -2
  236. package/dist/src/gateway/lock.js +3 -3
  237. package/dist/src/gateway/ports.js +1 -1
  238. package/dist/src/gateway/service/agent-runner.js +2 -2
  239. package/dist/src/gateway/service/marketplace-service.js +2 -2
  240. package/dist/src/gateway/service.js +5 -1
  241. package/dist/src/gateway/service.js.map +1 -1
  242. package/dist/src/gateway/session-reset-service.d.ts +1 -1
  243. package/dist/src/gateway/session-reset-service.js +1 -1
  244. package/dist/src/gateway/session-reset-service.js.map +1 -1
  245. package/dist/src/gateway/workspace-fs-file-list.js +1 -1
  246. package/dist/src/heartbeat/index.js +1 -1
  247. package/dist/src/infra/brew.js +1 -1
  248. package/dist/src/infra/node-sqlite.d.ts +1 -0
  249. package/dist/src/infra/node-sqlite.js +17 -0
  250. package/dist/src/infra/node-sqlite.js.map +1 -0
  251. package/dist/src/infra/package-json.js +1 -1
  252. package/dist/src/infra/package-update-steps.js +1 -1
  253. package/dist/src/infra/path-env.js +2 -2
  254. package/dist/src/infra/restart.js +2 -2
  255. package/dist/src/infra/sqlite-errors.d.ts +1 -0
  256. package/dist/src/infra/sqlite-errors.js +77 -0
  257. package/dist/src/infra/sqlite-errors.js.map +1 -0
  258. package/dist/src/infra/stable-node-path.js +1 -1
  259. package/dist/src/infra/unhandled-rejections.d.ts +1 -0
  260. package/dist/src/infra/unhandled-rejections.js +25 -0
  261. package/dist/src/infra/unhandled-rejections.js.map +1 -0
  262. package/dist/src/infra/update-check.js +1 -1
  263. package/dist/src/infra/update-global.js +1 -1
  264. package/dist/src/infra/update-lock.js +3 -3
  265. package/dist/src/infra/update-runner.js +1 -1
  266. package/dist/src/infra/update-startup.js +2 -2
  267. package/dist/src/infra/warning-filter.d.ts +7 -0
  268. package/dist/src/infra/warning-filter.js +59 -0
  269. package/dist/src/infra/warning-filter.js.map +1 -0
  270. package/dist/src/infra/write-file-atomic.js +2 -2
  271. package/dist/src/notes/store.d.ts +3 -9
  272. package/dist/src/notes/store.js +22 -196
  273. package/dist/src/notes/store.js.map +1 -1
  274. package/dist/src/providers/auth-runtime/auth-profile-store.js +1 -1
  275. package/dist/src/providers/index.js +2 -2
  276. package/dist/src/providers/model-registry.js +1 -1
  277. package/dist/src/session/config-store.d.ts +6 -75
  278. package/dist/src/session/config-store.js +38 -144
  279. package/dist/src/session/config-store.js.map +1 -1
  280. package/dist/src/session/config-types.d.ts +15 -0
  281. package/dist/src/session/config-types.js +1 -0
  282. package/dist/src/session/index.d.ts +1 -3
  283. package/dist/src/session/index.js +3 -5
  284. package/dist/src/session/init-session-turn.d.ts +0 -6
  285. package/dist/src/session/init-session-turn.js +18 -18
  286. package/dist/src/session/init-session-turn.js.map +1 -1
  287. package/dist/src/session/lifecycle-timestamps.d.ts +5 -2
  288. package/dist/src/session/lifecycle-timestamps.js.map +1 -1
  289. package/dist/src/session/{parity/load-jsonl-entries.js → load-jsonl-entries.js} +1 -1
  290. package/dist/src/session/load-jsonl-entries.js.map +1 -0
  291. package/dist/src/session/manager.d.ts +5 -3
  292. package/dist/src/session/manager.js +1 -5
  293. package/dist/src/session/manager.js.map +1 -1
  294. package/dist/src/session/resolve-session.d.ts +3 -6
  295. package/dist/src/session/resolve-session.js +26 -31
  296. package/dist/src/session/resolve-session.js.map +1 -1
  297. package/dist/src/session/session-context-for-llm.js +5 -1
  298. package/dist/src/session/session-context-for-llm.js.map +1 -1
  299. package/dist/src/session/session-id.js +12 -0
  300. package/dist/src/session/session-id.js.map +1 -0
  301. package/dist/src/session/session-title.js +2 -2
  302. package/dist/src/session/session-workspace.d.ts +1 -1
  303. package/dist/src/session/session-workspace.js.map +1 -1
  304. package/dist/src/session/store.d.ts +14 -63
  305. package/dist/src/session/store.js +172 -847
  306. package/dist/src/session/store.js.map +1 -1
  307. package/dist/src/session/stored-rows-to-file-entries.d.ts +11 -0
  308. package/dist/src/session/stored-rows-to-file-entries.js +95 -0
  309. package/dist/src/session/stored-rows-to-file-entries.js.map +1 -0
  310. package/dist/src/session/transcript-events.d.ts +1 -2
  311. package/dist/src/session/transcript-events.js +5 -12
  312. package/dist/src/session/transcript-events.js.map +1 -1
  313. package/dist/src/session/transcript-format.d.ts +1 -1
  314. package/dist/src/session/transcript-format.js.map +1 -1
  315. package/dist/src/session/transcript-stats.d.ts +1 -0
  316. package/dist/src/session/transcript-stats.js +10 -0
  317. package/dist/src/session/transcript-stats.js.map +1 -0
  318. package/dist/src/share/share-auto.js +2 -2
  319. package/dist/src/share/share-store.js +3 -3
  320. package/dist/src/share/share-thumbnail.js +2 -2
  321. package/dist/src/share/share-zip.js +1 -1
  322. package/dist/src/share/site-share-store.js +3 -3
  323. package/dist/src/share/site-static-serve.js +1 -1
  324. package/dist/src/storage/sqlite/config-repository.d.ts +6 -0
  325. package/dist/src/storage/sqlite/config-repository.js +56 -0
  326. package/dist/src/storage/sqlite/config-repository.js.map +1 -0
  327. package/dist/src/storage/sqlite/connection.d.ts +38 -0
  328. package/dist/src/storage/sqlite/connection.js +258 -0
  329. package/dist/src/storage/sqlite/connection.js.map +1 -0
  330. package/dist/src/storage/sqlite/cron-run-repository.d.ts +5 -0
  331. package/dist/src/storage/sqlite/cron-run-repository.js +97 -0
  332. package/dist/src/storage/sqlite/cron-run-repository.js.map +1 -0
  333. package/dist/src/storage/sqlite/fts.d.ts +2 -0
  334. package/dist/src/storage/sqlite/fts.js +11 -0
  335. package/dist/src/storage/sqlite/fts.js.map +1 -0
  336. package/dist/src/storage/sqlite/index.d.ts +12 -0
  337. package/dist/src/storage/sqlite/index.js +13 -0
  338. package/dist/src/storage/sqlite/memory-index-repository.d.ts +18 -0
  339. package/dist/src/storage/sqlite/memory-index-repository.js +132 -0
  340. package/dist/src/storage/sqlite/memory-index-repository.js.map +1 -0
  341. package/dist/src/storage/sqlite/notes-repository.d.ts +11 -0
  342. package/dist/src/storage/sqlite/notes-repository.js +191 -0
  343. package/dist/src/storage/sqlite/notes-repository.js.map +1 -0
  344. package/dist/src/storage/sqlite/paths.d.ts +1 -0
  345. package/dist/src/storage/sqlite/paths.js +7 -0
  346. package/dist/src/storage/sqlite/paths.js.map +1 -0
  347. package/dist/src/storage/sqlite/row-mappers.d.ts +82 -0
  348. package/dist/src/storage/sqlite/row-mappers.js +164 -0
  349. package/dist/src/storage/sqlite/row-mappers.js.map +1 -0
  350. package/dist/src/storage/sqlite/schema.d.ts +5 -0
  351. package/dist/src/storage/sqlite/schema.js +43 -0
  352. package/dist/src/storage/sqlite/schema.js.map +1 -0
  353. package/dist/src/storage/sqlite/schema.sql +195 -0
  354. package/dist/src/storage/sqlite/session-metadata.d.ts +8 -0
  355. package/dist/src/storage/sqlite/session-metadata.js +83 -0
  356. package/dist/src/storage/sqlite/session-metadata.js.map +1 -0
  357. package/dist/src/storage/sqlite/session-repository.d.ts +29 -0
  358. package/dist/src/storage/sqlite/session-repository.js +268 -0
  359. package/dist/src/storage/sqlite/session-repository.js.map +1 -0
  360. package/dist/src/storage/sqlite/transaction.d.ts +11 -0
  361. package/dist/src/storage/sqlite/transaction.js +115 -0
  362. package/dist/src/storage/sqlite/transaction.js.map +1 -0
  363. package/dist/src/storage/sqlite/transcript-repository.d.ts +34 -0
  364. package/dist/src/storage/sqlite/transcript-repository.js +241 -0
  365. package/dist/src/storage/sqlite/transcript-repository.js.map +1 -0
  366. package/dist/src/tui/clipboard-image.js +3 -3
  367. package/dist/src/tui/theme-manager.js +1 -1
  368. package/dist/src/tui/tui-keybindings-file.js +1 -1
  369. package/dist/src/tui/tui-scoped-models.js +2 -2
  370. package/dist/src/tui/tui-settings.js +1 -1
  371. package/dist/src/tui/tui.js +3 -3
  372. package/dist/src/tunnel/frpc-binary.js +3 -3
  373. package/dist/src/tunnel/frpc-config.js +1 -1
  374. package/dist/src/tunnel/frpc-extract.js +1 -1
  375. package/dist/src/tunnel/tunnel-state.js +1 -1
  376. package/dist/src/utils/logger/audit.js +1 -1
  377. package/dist/src/utils/logger/log-store.js +1 -1
  378. package/dist/src/utils/logger/rotation.js +1 -1
  379. package/dist/src/voice/tts/audio.js +1 -1
  380. package/dist/src/voice/tts/providers/edge-speech.js +2 -2
  381. package/dist/src/workflows/service/workflow-session-bridge.js +41 -64
  382. package/dist/src/workflows/service/workflow-session-bridge.js.map +1 -1
  383. package/dist/src/workflows/store/event-store.js +1 -1
  384. package/dist/src/workflows/store/run-store.js +1 -1
  385. package/package.json +3 -3
  386. package/dist/gateway/static/root/assets/index-Bj_l8QDp.css +0 -1
  387. package/dist/gateway/static/root/assets/notes-page-BApAirFB.js +0 -1
  388. package/dist/gateway/static/root/assets/settings-page-4VmUTzQs.js +0 -3
  389. package/dist/gateway/static/root/assets/share-preview-page-IX0TJvRd.js +0 -2
  390. package/dist/gateway/static/root/assets/url-BHHmdJYc.js +0 -3
  391. package/dist/src/agent/embedded/session-manager-cache.d.ts +0 -19
  392. package/dist/src/agent/embedded/session-manager-cache.js +0 -48
  393. package/dist/src/agent/embedded/session-manager-cache.js.map +0 -1
  394. package/dist/src/session/parity/artifacts.d.ts +0 -16
  395. package/dist/src/session/parity/artifacts.js +0 -80
  396. package/dist/src/session/parity/artifacts.js.map +0 -1
  397. package/dist/src/session/parity/jsonl-transcript-io.d.ts +0 -54
  398. package/dist/src/session/parity/jsonl-transcript-io.js +0 -236
  399. package/dist/src/session/parity/jsonl-transcript-io.js.map +0 -1
  400. package/dist/src/session/parity/load-jsonl-entries.js.map +0 -1
  401. package/dist/src/session/parity/session-id.js +0 -18
  402. package/dist/src/session/parity/session-id.js.map +0 -1
  403. package/dist/src/session/parity/sessions-json-cache.d.ts +0 -14
  404. package/dist/src/session/parity/sessions-json-cache.js +0 -98
  405. package/dist/src/session/parity/sessions-json-cache.js.map +0 -1
  406. package/dist/src/session/parity/sessions-json-file-read.d.ts +0 -6
  407. package/dist/src/session/parity/sessions-json-file-read.js +0 -19
  408. package/dist/src/session/parity/sessions-json-file-read.js.map +0 -1
  409. package/dist/src/session/parity/sessions-json-file.d.ts +0 -11
  410. package/dist/src/session/parity/sessions-json-file.js +0 -52
  411. package/dist/src/session/parity/sessions-json-file.js.map +0 -1
  412. package/dist/src/session/parity/sessions-json-patch.d.ts +0 -14
  413. package/dist/src/session/parity/sessions-json-patch.js +0 -40
  414. package/dist/src/session/parity/sessions-json-patch.js.map +0 -1
  415. package/dist/src/session/parity/transcript-file-lock.d.ts +0 -22
  416. package/dist/src/session/parity/transcript-file-lock.js +0 -142
  417. package/dist/src/session/parity/transcript-file-lock.js.map +0 -1
  418. package/dist/src/session/parity/transcript-pagination.d.ts +0 -29
  419. package/dist/src/session/parity/transcript-pagination.js +0 -132
  420. package/dist/src/session/parity/transcript-pagination.js.map +0 -1
  421. package/dist/src/session/parity/transcript-paths.d.ts +0 -13
  422. package/dist/src/session/parity/transcript-paths.js +0 -64
  423. package/dist/src/session/parity/transcript-paths.js.map +0 -1
  424. package/dist/src/session/parity/xopc-session-disk-entry.d.ts +0 -22
  425. package/dist/src/session/search-index-cache.d.ts +0 -6
  426. package/dist/src/session/search-index-cache.js +0 -44
  427. package/dist/src/session/search-index-cache.js.map +0 -1
  428. package/dist/src/session/search-index.d.ts +0 -20
  429. package/dist/src/session/search-index.js +0 -124
  430. package/dist/src/session/search-index.js.map +0 -1
  431. /package/dist/src/{session/parity/xopc-session-disk-entry.js → cron/execution-types.js} +0 -0
  432. /package/dist/src/session/{parity/load-jsonl-entries.d.ts → load-jsonl-entries.d.ts} +0 -0
  433. /package/dist/src/session/{parity/session-id.d.ts → session-id.d.ts} +0 -0
@@ -1 +0,0 @@
1
- {"version":3,"file":"sessions-json-cache.js","names":[],"sources":["../../../../src/session/parity/sessions-json-cache.ts"],"sourcesContent":["import { stat } from 'node:fs/promises';\nimport { existsSync } from 'node:fs';\n\nimport { readSessionsJsonFileRaw } from './sessions-json-file-read.js';\n\ntype ReadCacheEntry = {\n mtimeMs: number;\n sizeBytes: number;\n parsed: Record<string, unknown>;\n serialized: string;\n};\n\nconst readCache = new Map<string, ReadCacheEntry>();\nconst serializedWriteCache = new Map<string, string>();\n\nlet writeStats = {\n performed: 0,\n skippedUnchanged: 0,\n};\n\nexport function getSessionsJsonWriteStats(): Readonly<typeof writeStats> {\n return writeStats;\n}\n\nexport function resetSessionsJsonCacheForTest(): void {\n readCache.clear();\n serializedWriteCache.clear();\n writeStats = { performed: 0, skippedUnchanged: 0 };\n}\n\nexport function invalidateSessionsJsonCache(storePath: string): void {\n readCache.delete(storePath);\n serializedWriteCache.delete(storePath);\n}\n\nfunction serializeSessionsJson(store: Record<string, unknown>): string {\n return `${JSON.stringify(store, null, 2)}\\n`;\n}\n\nexport async function readSessionsJsonCached(\n storePath: string,\n): Promise<{ store: Record<string, unknown>; serialized: string }> {\n if (!existsSync(storePath)) {\n return { store: {}, serialized: '{}\\n' };\n }\n\n let mtimeMs = 0;\n let sizeBytes = 0;\n try {\n const st = await stat(storePath);\n mtimeMs = st.mtimeMs;\n sizeBytes = st.size;\n } catch {\n return { store: {}, serialized: '{}\\n' };\n }\n\n const cached = readCache.get(storePath);\n if (cached && cached.mtimeMs === mtimeMs && cached.sizeBytes === sizeBytes) {\n return { store: structuredClone(cached.parsed), serialized: cached.serialized };\n }\n\n const store = await readSessionsJsonFileRaw(storePath);\n const serialized = serializeSessionsJson(store);\n readCache.set(storePath, { mtimeMs, sizeBytes, parsed: structuredClone(store), serialized });\n serializedWriteCache.set(storePath, serialized);\n return { store: structuredClone(store), serialized };\n}\n\nexport function commitSessionsJsonWrite(\n storePath: string,\n store: Record<string, unknown>,\n serialized: string,\n): boolean {\n const previous = serializedWriteCache.get(storePath);\n if (previous === serialized) {\n writeStats.skippedUnchanged += 1;\n readCache.set(storePath, {\n mtimeMs: readCache.get(storePath)?.mtimeMs ?? Date.now(),\n sizeBytes: serialized.length,\n parsed: structuredClone(store),\n serialized,\n });\n return false;\n }\n\n serializedWriteCache.set(storePath, serialized);\n writeStats.performed += 1;\n readCache.set(storePath, {\n mtimeMs: Date.now(),\n sizeBytes: serialized.length,\n parsed: structuredClone(store),\n serialized,\n });\n return true;\n}\n\nexport function noteSessionsJsonWritten(storePath: string, serialized: string, store: Record<string, unknown>): void {\n serializedWriteCache.set(storePath, serialized);\n readCache.set(storePath, {\n mtimeMs: Date.now(),\n sizeBytes: serialized.length,\n parsed: structuredClone(store),\n serialized,\n });\n}\n"],"mappings":";;;;AAYA,MAAM,4BAAY,IAAI,KAA6B;AACnD,MAAM,uCAAuB,IAAI,KAAqB;AAEtD,IAAI,aAAa;CACf,WAAW;CACX,kBAAkB;CACnB;AAED,SAAgB,4BAAyD;AACvE,QAAO;;AAGT,SAAgB,gCAAsC;AACpD,WAAU,OAAO;AACjB,sBAAqB,OAAO;AAC5B,cAAa;EAAE,WAAW;EAAG,kBAAkB;EAAG;;AAGpD,SAAgB,4BAA4B,WAAyB;AACnE,WAAU,OAAO,UAAU;AAC3B,sBAAqB,OAAO,UAAU;;AAGxC,SAAS,sBAAsB,OAAwC;AACrE,QAAO,GAAG,KAAK,UAAU,OAAO,MAAM,EAAE,CAAC;;AAG3C,eAAsB,uBACpB,WACiE;AACjE,KAAI,CAAC,WAAW,UAAU,CACxB,QAAO;EAAE,OAAO,EAAE;EAAE,YAAY;EAAQ;CAG1C,IAAI,UAAU;CACd,IAAI,YAAY;AAChB,KAAI;EACF,MAAM,KAAK,MAAM,KAAK,UAAU;AAChC,YAAU,GAAG;AACb,cAAY,GAAG;SACT;AACN,SAAO;GAAE,OAAO,EAAE;GAAE,YAAY;GAAQ;;CAG1C,MAAM,SAAS,UAAU,IAAI,UAAU;AACvC,KAAI,UAAU,OAAO,YAAY,WAAW,OAAO,cAAc,UAC/D,QAAO;EAAE,OAAO,gBAAgB,OAAO,OAAO;EAAE,YAAY,OAAO;EAAY;CAGjF,MAAM,QAAQ,MAAM,wBAAwB,UAAU;CACtD,MAAM,aAAa,sBAAsB,MAAM;AAC/C,WAAU,IAAI,WAAW;EAAE;EAAS;EAAW,QAAQ,gBAAgB,MAAM;EAAE;EAAY,CAAC;AAC5F,sBAAqB,IAAI,WAAW,WAAW;AAC/C,QAAO;EAAE,OAAO,gBAAgB,MAAM;EAAE;EAAY;;AAGtD,SAAgB,wBACd,WACA,OACA,YACS;AAET,KADiB,qBAAqB,IAAI,UAC9B,KAAK,YAAY;AAC3B,aAAW,oBAAoB;AAC/B,YAAU,IAAI,WAAW;GACvB,SAAS,UAAU,IAAI,UAAU,EAAE,WAAW,KAAK,KAAK;GACxD,WAAW,WAAW;GACtB,QAAQ,gBAAgB,MAAM;GAC9B;GACD,CAAC;AACF,SAAO;;AAGT,sBAAqB,IAAI,WAAW,WAAW;AAC/C,YAAW,aAAa;AACxB,WAAU,IAAI,WAAW;EACvB,SAAS,KAAK,KAAK;EACnB,WAAW,WAAW;EACtB,QAAQ,gBAAgB,MAAM;EAC9B;EACD,CAAC;AACF,QAAO;;AAGT,SAAgB,wBAAwB,WAAmB,YAAoB,OAAsC;AACnH,sBAAqB,IAAI,WAAW,WAAW;AAC/C,WAAU,IAAI,WAAW;EACvB,SAAS,KAAK,KAAK;EACnB,WAAW,WAAW;EACtB,QAAQ,gBAAgB,MAAM;EAC9B;EACD,CAAC"}
@@ -1,6 +0,0 @@
1
- type SessionsJsonMap<T> = Record<string, T>;
2
- /**
3
- * Raw disk read for sessions.json (no in-memory cache).
4
- */
5
- export declare function readSessionsJsonFileRaw<T extends Record<string, unknown>>(storePath: string): Promise<SessionsJsonMap<T>>;
6
- export {};
@@ -1,19 +0,0 @@
1
- import { readFile } from "node:fs/promises";
2
- //#region src/session/parity/sessions-json-file-read.ts
3
- /**
4
- * Raw disk read for sessions.json (no in-memory cache).
5
- */
6
- async function readSessionsJsonFileRaw(storePath) {
7
- try {
8
- const raw = await readFile(storePath, "utf-8");
9
- const parsed = JSON.parse(raw);
10
- if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) return {};
11
- return parsed;
12
- } catch {
13
- return {};
14
- }
15
- }
16
- //#endregion
17
- export { readSessionsJsonFileRaw };
18
-
19
- //# sourceMappingURL=sessions-json-file-read.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"sessions-json-file-read.js","names":[],"sources":["../../../../src/session/parity/sessions-json-file-read.ts"],"sourcesContent":["import { readFile } from 'node:fs/promises';\n\n// Type duplicated inline — `sessions-json-file.ts` imports a value from this\n// file (cache.ts → file-read.ts → file.ts), so re-importing the type back\n// would close the loop. The shape is trivial so we declare it locally.\ntype SessionsJsonMap<T> = Record<string, T>;\n\n/**\n * Raw disk read for sessions.json (no in-memory cache).\n */\nexport async function readSessionsJsonFileRaw<T extends Record<string, unknown>>(\n storePath: string,\n): Promise<SessionsJsonMap<T>> {\n try {\n const raw = await readFile(storePath, 'utf-8');\n const parsed = JSON.parse(raw) as unknown;\n if (!parsed || typeof parsed !== 'object' || Array.isArray(parsed)) {\n return {};\n }\n return parsed as SessionsJsonMap<T>;\n } catch {\n return {};\n }\n}\n"],"mappings":";;;;;AAUA,eAAsB,wBACpB,WAC6B;AAC7B,KAAI;EACF,MAAM,MAAM,MAAM,SAAS,WAAW,QAAQ;EAC9C,MAAM,SAAS,KAAK,MAAM,IAAI;AAC9B,MAAI,CAAC,UAAU,OAAO,WAAW,YAAY,MAAM,QAAQ,OAAO,CAChE,QAAO,EAAE;AAEX,SAAO;SACD;AACN,SAAO,EAAE"}
@@ -1,11 +0,0 @@
1
- export type SessionsJsonMap<T> = Record<string, T>;
2
- /**
3
- * Read JSON object from `sessions.json`. Missing file → `{}`.
4
- * Uses mtime/size cache when enabled.
5
- */
6
- export declare function readSessionsJsonFile<T extends Record<string, unknown>>(storePath: string): Promise<SessionsJsonMap<T>>;
7
- /**
8
- * Exclusive update: lock → read → mutate → atomic write (skipped when serialized unchanged) → unlock.
9
- */
10
- export declare function withSessionsJsonLock<T>(storePath: string, fn: (store: SessionsJsonMap<Record<string, unknown>>) => Promise<T>): Promise<T>;
11
- export { invalidateSessionsJsonCache, getSessionsJsonWriteStats, resetSessionsJsonCacheForTest } from './sessions-json-cache.js';
@@ -1,52 +0,0 @@
1
- import { init_write_file_atomic, writeTextAtomic } from "../../infra/write-file-atomic.js";
2
- import { readSessionsJsonFileRaw } from "./sessions-json-file-read.js";
3
- import { commitSessionsJsonWrite, getSessionsJsonWriteStats, invalidateSessionsJsonCache, noteSessionsJsonWritten, readSessionsJsonCached, resetSessionsJsonCacheForTest } from "./sessions-json-cache.js";
4
- import { dirname } from "node:path";
5
- import { existsSync } from "node:fs";
6
- import { mkdir } from "node:fs/promises";
7
- import lockfile from "proper-lockfile";
8
- //#region src/session/parity/sessions-json-file.ts
9
- init_write_file_atomic();
10
- async function ensureDirForFile(filePath) {
11
- await mkdir(dirname(filePath), { recursive: true });
12
- }
13
- function serializeSessionsJson(store) {
14
- return `${JSON.stringify(store, null, 2)}\n`;
15
- }
16
- /**
17
- * Read JSON object from `sessions.json`. Missing file → `{}`.
18
- * Uses mtime/size cache when enabled.
19
- */
20
- async function readSessionsJsonFile(storePath) {
21
- if (!existsSync(storePath)) return {};
22
- const { store } = await readSessionsJsonCached(storePath);
23
- return store;
24
- }
25
- /**
26
- * Exclusive update: lock → read → mutate → atomic write (skipped when serialized unchanged) → unlock.
27
- */
28
- async function withSessionsJsonLock(storePath, fn) {
29
- await ensureDirForFile(storePath);
30
- if (!existsSync(storePath)) {
31
- await writeTextAtomic(storePath, "{}\n");
32
- noteSessionsJsonWritten(storePath, "{}\n", {});
33
- }
34
- const release = await lockfile.lock(storePath, { retries: {
35
- retries: 30,
36
- minTimeout: 50,
37
- maxTimeout: 500
38
- } });
39
- try {
40
- const data = existsSync(storePath) ? await readSessionsJsonFileRaw(storePath) : {};
41
- const result = await fn(data);
42
- const serialized = serializeSessionsJson(data);
43
- if (commitSessionsJsonWrite(storePath, data, serialized)) await writeTextAtomic(storePath, serialized);
44
- return result;
45
- } finally {
46
- await release();
47
- }
48
- }
49
- //#endregion
50
- export { getSessionsJsonWriteStats, invalidateSessionsJsonCache, readSessionsJsonFile, resetSessionsJsonCacheForTest, withSessionsJsonLock };
51
-
52
- //# sourceMappingURL=sessions-json-file.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"sessions-json-file.js","names":[],"sources":["../../../../src/session/parity/sessions-json-file.ts"],"sourcesContent":["import { mkdir } from 'node:fs/promises';\nimport { dirname } from 'node:path';\nimport { existsSync } from 'node:fs';\n\nimport lockfile from 'proper-lockfile';\n\nimport { writeTextAtomic } from '../../infra/write-file-atomic.js';\nimport {\n commitSessionsJsonWrite,\n noteSessionsJsonWritten,\n readSessionsJsonCached,\n} from './sessions-json-cache.js';\nimport { readSessionsJsonFileRaw } from './sessions-json-file-read.js';\n\nexport type SessionsJsonMap<T> = Record<string, T>;\n\nasync function ensureDirForFile(filePath: string): Promise<void> {\n await mkdir(dirname(filePath), { recursive: true });\n}\n\nfunction serializeSessionsJson(store: Record<string, unknown>): string {\n return `${JSON.stringify(store, null, 2)}\\n`;\n}\n\n/**\n * Read JSON object from `sessions.json`. Missing file → `{}`.\n * Uses mtime/size cache when enabled.\n */\nexport async function readSessionsJsonFile<T extends Record<string, unknown>>(\n storePath: string,\n): Promise<SessionsJsonMap<T>> {\n if (!existsSync(storePath)) {\n return {};\n }\n const { store } = await readSessionsJsonCached(storePath);\n return store as SessionsJsonMap<T>;\n}\n\n/**\n * Exclusive update: lock → read → mutate → atomic write (skipped when serialized unchanged) → unlock.\n */\nexport async function withSessionsJsonLock<T>(\n storePath: string,\n fn: (store: SessionsJsonMap<Record<string, unknown>>) => Promise<T>,\n): Promise<T> {\n await ensureDirForFile(storePath);\n if (!existsSync(storePath)) {\n await writeTextAtomic(storePath, '{}\\n');\n noteSessionsJsonWritten(storePath, '{}\\n', {});\n }\n const release = await lockfile.lock(storePath, {\n retries: {\n retries: 30,\n minTimeout: 50,\n maxTimeout: 500,\n },\n });\n try {\n const data = existsSync(storePath)\n ? await readSessionsJsonFileRaw<Record<string, unknown>>(storePath)\n : {};\n const result = await fn(data);\n const serialized = serializeSessionsJson(data);\n if (commitSessionsJsonWrite(storePath, data, serialized)) {\n await writeTextAtomic(storePath, serialized);\n }\n return result;\n } finally {\n await release();\n }\n}\n\nexport { invalidateSessionsJsonCache, getSessionsJsonWriteStats, resetSessionsJsonCacheForTest } from './sessions-json-cache.js';\n"],"mappings":";;;;;;;;wBAMmE;AAUnE,eAAe,iBAAiB,UAAiC;AAC/D,OAAM,MAAM,QAAQ,SAAS,EAAE,EAAE,WAAW,MAAM,CAAC;;AAGrD,SAAS,sBAAsB,OAAwC;AACrE,QAAO,GAAG,KAAK,UAAU,OAAO,MAAM,EAAE,CAAC;;;;;;AAO3C,eAAsB,qBACpB,WAC6B;AAC7B,KAAI,CAAC,WAAW,UAAU,CACxB,QAAO,EAAE;CAEX,MAAM,EAAE,UAAU,MAAM,uBAAuB,UAAU;AACzD,QAAO;;;;;AAMT,eAAsB,qBACpB,WACA,IACY;AACZ,OAAM,iBAAiB,UAAU;AACjC,KAAI,CAAC,WAAW,UAAU,EAAE;AAC1B,QAAM,gBAAgB,WAAW,OAAO;AACxC,0BAAwB,WAAW,QAAQ,EAAE,CAAC;;CAEhD,MAAM,UAAU,MAAM,SAAS,KAAK,WAAW,EAC7C,SAAS;EACP,SAAS;EACT,YAAY;EACZ,YAAY;EACb,EACF,CAAC;AACF,KAAI;EACF,MAAM,OAAO,WAAW,UAAU,GAC9B,MAAM,wBAAiD,UAAU,GACjE,EAAE;EACN,MAAM,SAAS,MAAM,GAAG,KAAK;EAC7B,MAAM,aAAa,sBAAsB,KAAK;AAC9C,MAAI,wBAAwB,WAAW,MAAM,WAAW,CACtD,OAAM,gBAAgB,WAAW,WAAW;AAE9C,SAAO;WACC;AACR,QAAM,SAAS"}
@@ -1,14 +0,0 @@
1
- import type { XopcSessionDiskEntry } from './xopc-session-disk-entry.js';
2
- export type SessionsJsonStatsPatch = {
3
- messageCount: number;
4
- estimatedTokens: number;
5
- lastTurnAt: number;
6
- };
7
- export declare function buildSessionsJsonStatsPatch(messageCount: number, estimatedTokens: number): SessionsJsonStatsPatch;
8
- /** Apply stats + timestamps to a single sessions.json entry (in-memory patch). */
9
- export declare function patchSessionsJsonEntryStats(entry: XopcSessionDiskEntry, stats: SessionsJsonStatsPatch): void;
10
- export declare function isAppendOnlyLlmTranscriptMessage(message: unknown): boolean;
11
- /** Increment stats for a single appended LLM row (hot path). */
12
- export declare function incrementSessionsJsonStatsForAppend(entry: XopcSessionDiskEntry, opts?: {
13
- tokenDelta?: number;
14
- }): void;
@@ -1,40 +0,0 @@
1
- //#region src/session/parity/sessions-json-patch.ts
2
- function buildSessionsJsonStatsPatch(messageCount, estimatedTokens) {
3
- return {
4
- messageCount,
5
- estimatedTokens,
6
- lastTurnAt: Date.now()
7
- };
8
- }
9
- /** Apply stats + timestamps to a single sessions.json entry (in-memory patch). */
10
- function patchSessionsJsonEntryStats(entry, stats) {
11
- if (!entry.pluginExtensions?.xopc?.metadata) return;
12
- const meta = entry.pluginExtensions.xopc.metadata;
13
- meta.messageCount = stats.messageCount;
14
- meta.estimatedTokens = stats.estimatedTokens;
15
- meta.updatedAt = (/* @__PURE__ */ new Date()).toISOString();
16
- meta.lastAccessedAt = meta.updatedAt;
17
- meta.stats = {
18
- messageCount: stats.messageCount,
19
- tokenCount: stats.estimatedTokens,
20
- lastTurnAt: stats.lastTurnAt
21
- };
22
- entry.updatedAt = stats.lastTurnAt;
23
- }
24
- function isAppendOnlyLlmTranscriptMessage(message) {
25
- if (!message || typeof message !== "object") return false;
26
- const role = message.role;
27
- return role === "user" || role === "assistant" || role === "tool" || role === "toolResult";
28
- }
29
- /** Increment stats for a single appended LLM row (hot path). */
30
- function incrementSessionsJsonStatsForAppend(entry, opts) {
31
- if (!entry.pluginExtensions?.xopc?.metadata) return;
32
- const meta = entry.pluginExtensions.xopc.metadata;
33
- const nextCount = (meta.messageCount ?? 0) + 1;
34
- const tokenDelta = opts?.tokenDelta ?? 0;
35
- patchSessionsJsonEntryStats(entry, buildSessionsJsonStatsPatch(nextCount, (meta.estimatedTokens ?? 0) + tokenDelta));
36
- }
37
- //#endregion
38
- export { buildSessionsJsonStatsPatch, incrementSessionsJsonStatsForAppend, isAppendOnlyLlmTranscriptMessage, patchSessionsJsonEntryStats };
39
-
40
- //# sourceMappingURL=sessions-json-patch.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"sessions-json-patch.js","names":[],"sources":["../../../../src/session/parity/sessions-json-patch.ts"],"sourcesContent":["import type { XopcSessionDiskEntry } from './xopc-session-disk-entry.js';\n\nexport type SessionsJsonStatsPatch = {\n messageCount: number;\n estimatedTokens: number;\n lastTurnAt: number;\n};\n\nexport function buildSessionsJsonStatsPatch(\n messageCount: number,\n estimatedTokens: number,\n): SessionsJsonStatsPatch {\n const now = Date.now();\n return {\n messageCount,\n estimatedTokens,\n lastTurnAt: now,\n };\n}\n\n/** Apply stats + timestamps to a single sessions.json entry (in-memory patch). */\nexport function patchSessionsJsonEntryStats(\n entry: XopcSessionDiskEntry,\n stats: SessionsJsonStatsPatch,\n): void {\n if (!entry.pluginExtensions?.xopc?.metadata) {\n return;\n }\n const meta = entry.pluginExtensions.xopc.metadata;\n meta.messageCount = stats.messageCount;\n meta.estimatedTokens = stats.estimatedTokens;\n meta.updatedAt = new Date().toISOString();\n meta.lastAccessedAt = meta.updatedAt;\n meta.stats = {\n messageCount: stats.messageCount,\n tokenCount: stats.estimatedTokens,\n lastTurnAt: stats.lastTurnAt,\n };\n entry.updatedAt = stats.lastTurnAt;\n}\n\nexport function isAppendOnlyLlmTranscriptMessage(message: unknown): boolean {\n if (!message || typeof message !== 'object') {\n return false;\n }\n const role = (message as { role?: string }).role;\n return role === 'user' || role === 'assistant' || role === 'tool' || role === 'toolResult';\n}\n\n/** Increment stats for a single appended LLM row (hot path). */\nexport function incrementSessionsJsonStatsForAppend(\n entry: XopcSessionDiskEntry,\n opts?: { tokenDelta?: number },\n): void {\n if (!entry.pluginExtensions?.xopc?.metadata) {\n return;\n }\n const meta = entry.pluginExtensions.xopc.metadata;\n const nextCount = (meta.messageCount ?? 0) + 1;\n const tokenDelta = opts?.tokenDelta ?? 0;\n const nextTokens = (meta.estimatedTokens ?? 0) + tokenDelta;\n patchSessionsJsonEntryStats(entry, buildSessionsJsonStatsPatch(nextCount, nextTokens));\n}\n"],"mappings":";AAQA,SAAgB,4BACd,cACA,iBACwB;AAExB,QAAO;EACL;EACA;EACA,YAJU,KAAK,KAIA;EAChB;;;AAIH,SAAgB,4BACd,OACA,OACM;AACN,KAAI,CAAC,MAAM,kBAAkB,MAAM,SACjC;CAEF,MAAM,OAAO,MAAM,iBAAiB,KAAK;AACzC,MAAK,eAAe,MAAM;AAC1B,MAAK,kBAAkB,MAAM;AAC7B,MAAK,6BAAY,IAAI,MAAM,EAAC,aAAa;AACzC,MAAK,iBAAiB,KAAK;AAC3B,MAAK,QAAQ;EACX,cAAc,MAAM;EACpB,YAAY,MAAM;EAClB,YAAY,MAAM;EACnB;AACD,OAAM,YAAY,MAAM;;AAG1B,SAAgB,iCAAiC,SAA2B;AAC1E,KAAI,CAAC,WAAW,OAAO,YAAY,SACjC,QAAO;CAET,MAAM,OAAQ,QAA8B;AAC5C,QAAO,SAAS,UAAU,SAAS,eAAe,SAAS,UAAU,SAAS;;;AAIhF,SAAgB,oCACd,OACA,MACM;AACN,KAAI,CAAC,MAAM,kBAAkB,MAAM,SACjC;CAEF,MAAM,OAAO,MAAM,iBAAiB,KAAK;CACzC,MAAM,aAAa,KAAK,gBAAgB,KAAK;CAC7C,MAAM,aAAa,MAAM,cAAc;AAEvC,6BAA4B,OAAO,4BAA4B,YAD3C,KAAK,mBAAmB,KAAK,WACoC,CAAC"}
@@ -1,22 +0,0 @@
1
- /**
2
- * Cross-process (and re-entrant same-process) advisory lock for session transcript JSONL.
3
- * Aligns with the goal of safe concurrent gateway/CLI access; same idea as OpenClaw's
4
- * session write lock, but scoped to a single transcript path with a smaller surface area.
5
- */
6
- export type TranscriptFileLock = {
7
- release: () => Promise<void>;
8
- };
9
- /**
10
- * Acquire an exclusive lock for mutations to `transcriptAbsPath`.
11
- * Re-entrant on the same path in the same process (nested `withTranscriptFileLock`).
12
- */
13
- export declare function acquireTranscriptFileLock(transcriptAbsPath: string, opts?: {
14
- timeoutMs?: number;
15
- staleMs?: number;
16
- }): Promise<TranscriptFileLock>;
17
- export declare function withTranscriptFileLock<T>(transcriptAbsPath: string, fn: () => Promise<T>, opts?: {
18
- timeoutMs?: number;
19
- staleMs?: number;
20
- }): Promise<T>;
21
- /** Best-effort: remove a stale lock without acquiring (e.g. doctor tooling). */
22
- export declare function tryRemoveStaleTranscriptLock(transcriptAbsPath: string, staleMs?: number): Promise<boolean>;
@@ -1,142 +0,0 @@
1
- import path from "node:path";
2
- import { existsSync } from "node:fs";
3
- import { createHash } from "node:crypto";
4
- import { mkdir, open, readFile, rm, stat } from "node:fs/promises";
5
- //#region src/session/parity/transcript-file-lock.ts
6
- /**
7
- * Cross-process (and re-entrant same-process) advisory lock for session transcript JSONL.
8
- * Aligns with the goal of safe concurrent gateway/CLI access; same idea as OpenClaw's
9
- * session write lock, but scoped to a single transcript path with a smaller surface area.
10
- */
11
- const DEFAULT_TIMEOUT_MS = 6e4;
12
- const DEFAULT_STALE_MS = 1800 * 1e3;
13
- const heldLocks = /* @__PURE__ */ new Map();
14
- /** Same-process serialization for acquire; cross-process exclusion uses the lock file. */
15
- const acquireChains = /* @__PURE__ */ new Map();
16
- function chainPerTranscript(normalized, fn) {
17
- const run = (acquireChains.get(normalized) ?? Promise.resolve()).then(() => fn());
18
- acquireChains.set(normalized, run.then(() => void 0).catch(() => void 0));
19
- return run;
20
- }
21
- function normalizeTranscriptPath(transcriptAbsPath) {
22
- return path.resolve(transcriptAbsPath);
23
- }
24
- function lockPathFor(transcriptAbsPath) {
25
- const dir = path.dirname(transcriptAbsPath);
26
- const base = path.basename(transcriptAbsPath);
27
- const hash = createHash("sha256").update(transcriptAbsPath).digest("hex").slice(0, 16);
28
- return path.join(dir, `.${base}.${hash}.xopc-transcript.lock`);
29
- }
30
- function isPidAlive(pid) {
31
- if (!Number.isFinite(pid) || pid <= 0) return false;
32
- try {
33
- process.kill(pid, 0);
34
- return true;
35
- } catch {
36
- return false;
37
- }
38
- }
39
- async function readPayload(lockFile) {
40
- try {
41
- const raw = await readFile(lockFile, "utf8");
42
- return JSON.parse(raw);
43
- } catch {
44
- return null;
45
- }
46
- }
47
- async function isStaleLock(lockFile, staleMs) {
48
- let st;
49
- try {
50
- st = await stat(lockFile);
51
- } catch {
52
- return true;
53
- }
54
- if (Date.now() - st.mtimeMs > staleMs) return true;
55
- const payload = await readPayload(lockFile);
56
- const pid = typeof payload?.pid === "number" ? payload.pid : void 0;
57
- if (pid != null && pid !== process.pid && !isPidAlive(pid)) return true;
58
- return false;
59
- }
60
- async function releaseHeldLock(normalized, held) {
61
- held.refcount -= 1;
62
- if (held.refcount > 0) return;
63
- heldLocks.delete(normalized);
64
- try {
65
- await held.handle.close();
66
- } catch {}
67
- try {
68
- await rm(held.lockFile, { force: true });
69
- } catch {}
70
- }
71
- /**
72
- * Acquire an exclusive lock for mutations to `transcriptAbsPath`.
73
- * Re-entrant on the same path in the same process (nested `withTranscriptFileLock`).
74
- */
75
- async function acquireTranscriptFileLock(transcriptAbsPath, opts) {
76
- const normalized = normalizeTranscriptPath(transcriptAbsPath);
77
- return chainPerTranscript(normalized, () => acquireTranscriptFileLockBody(normalized, opts));
78
- }
79
- async function acquireTranscriptFileLockBody(normalized, opts) {
80
- const timeoutMs = opts?.timeoutMs ?? DEFAULT_TIMEOUT_MS;
81
- const staleMs = opts?.staleMs ?? DEFAULT_STALE_MS;
82
- const existing = heldLocks.get(normalized);
83
- if (existing) {
84
- existing.refcount += 1;
85
- return { release: async () => {
86
- await releaseHeldLock(normalized, existing);
87
- } };
88
- }
89
- const lockFile = lockPathFor(normalized);
90
- await mkdir(path.dirname(lockFile), { recursive: true });
91
- const started = Date.now();
92
- let handle = null;
93
- while (Date.now() - started < timeoutMs) try {
94
- handle = await open(lockFile, "wx", 384);
95
- break;
96
- } catch (err) {
97
- if (err.code === "EEXIST") {
98
- if (await isStaleLock(lockFile, staleMs)) {
99
- await rm(lockFile, { force: true });
100
- continue;
101
- }
102
- await new Promise((r) => setTimeout(r, 50 + Math.floor(Math.random() * 40)));
103
- continue;
104
- }
105
- throw err;
106
- }
107
- if (!handle) throw new Error(`timeout acquiring transcript lock: ${lockFile}`);
108
- const payload = {
109
- pid: process.pid,
110
- createdAt: (/* @__PURE__ */ new Date()).toISOString()
111
- };
112
- await handle.writeFile(JSON.stringify(payload, null, 2), "utf8");
113
- const held = {
114
- refcount: 1,
115
- handle,
116
- lockFile
117
- };
118
- heldLocks.set(normalized, held);
119
- return { release: async () => {
120
- await releaseHeldLock(normalized, held);
121
- } };
122
- }
123
- async function withTranscriptFileLock(transcriptAbsPath, fn, opts) {
124
- const lock = await acquireTranscriptFileLock(transcriptAbsPath, opts);
125
- try {
126
- return await fn();
127
- } finally {
128
- await lock.release();
129
- }
130
- }
131
- /** Best-effort: remove a stale lock without acquiring (e.g. doctor tooling). */
132
- async function tryRemoveStaleTranscriptLock(transcriptAbsPath, staleMs = DEFAULT_STALE_MS) {
133
- const lockFile = lockPathFor(normalizeTranscriptPath(transcriptAbsPath));
134
- if (!existsSync(lockFile)) return false;
135
- if (!await isStaleLock(lockFile, staleMs)) return false;
136
- await rm(lockFile, { force: true });
137
- return true;
138
- }
139
- //#endregion
140
- export { acquireTranscriptFileLock, tryRemoveStaleTranscriptLock, withTranscriptFileLock };
141
-
142
- //# sourceMappingURL=transcript-file-lock.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"transcript-file-lock.js","names":[],"sources":["../../../../src/session/parity/transcript-file-lock.ts"],"sourcesContent":["/**\n * Cross-process (and re-entrant same-process) advisory lock for session transcript JSONL.\n * Aligns with the goal of safe concurrent gateway/CLI access; same idea as OpenClaw's\n * session write lock, but scoped to a single transcript path with a smaller surface area.\n */\n\nimport { createHash } from 'node:crypto';\nimport type { FileHandle } from 'node:fs/promises';\nimport { existsSync } from 'node:fs';\nimport { mkdir, open, readFile, rm, stat } from 'node:fs/promises';\nimport path from 'node:path';\n\nconst DEFAULT_TIMEOUT_MS = 60_000;\nconst DEFAULT_STALE_MS = 30 * 60 * 1000;\n\ntype LockPayload = { pid?: number; createdAt?: string };\n\ntype HeldTranscriptLock = {\n refcount: number;\n handle: FileHandle;\n lockFile: string;\n};\n\nconst heldLocks = new Map<string, HeldTranscriptLock>();\n\n/** Same-process serialization for acquire; cross-process exclusion uses the lock file. */\nconst acquireChains = new Map<string, Promise<void>>();\n\nfunction chainPerTranscript<T>(normalized: string, fn: () => Promise<T>): Promise<T> {\n const prev = acquireChains.get(normalized) ?? Promise.resolve();\n const run = prev.then(() => fn());\n acquireChains.set(\n normalized,\n run.then(() => undefined).catch(() => undefined),\n );\n return run;\n}\n\nfunction normalizeTranscriptPath(transcriptAbsPath: string): string {\n return path.resolve(transcriptAbsPath);\n}\n\nfunction lockPathFor(transcriptAbsPath: string): string {\n const dir = path.dirname(transcriptAbsPath);\n const base = path.basename(transcriptAbsPath);\n const hash = createHash('sha256').update(transcriptAbsPath).digest('hex').slice(0, 16);\n return path.join(dir, `.${base}.${hash}.xopc-transcript.lock`);\n}\n\nfunction isPidAlive(pid: number): boolean {\n if (!Number.isFinite(pid) || pid <= 0) {\n return false;\n }\n try {\n process.kill(pid, 0);\n return true;\n } catch {\n return false;\n }\n}\n\nasync function readPayload(lockFile: string): Promise<LockPayload | null> {\n try {\n const raw = await readFile(lockFile, 'utf8');\n return JSON.parse(raw) as LockPayload;\n } catch {\n return null;\n }\n}\n\nasync function isStaleLock(lockFile: string, staleMs: number): Promise<boolean> {\n let st;\n try {\n st = await stat(lockFile);\n } catch {\n return true;\n }\n const age = Date.now() - st.mtimeMs;\n if (age > staleMs) {\n return true;\n }\n const payload = await readPayload(lockFile);\n const pid = typeof payload?.pid === 'number' ? payload.pid : undefined;\n if (pid != null && pid !== process.pid && !isPidAlive(pid)) {\n return true;\n }\n return false;\n}\n\nasync function releaseHeldLock(normalized: string, held: HeldTranscriptLock): Promise<void> {\n held.refcount -= 1;\n if (held.refcount > 0) {\n return;\n }\n heldLocks.delete(normalized);\n try {\n await held.handle.close();\n } catch {\n /* ignore */\n }\n try {\n await rm(held.lockFile, { force: true });\n } catch {\n /* ignore */\n }\n}\n\nexport type TranscriptFileLock = { release: () => Promise<void> };\n\n/**\n * Acquire an exclusive lock for mutations to `transcriptAbsPath`.\n * Re-entrant on the same path in the same process (nested `withTranscriptFileLock`).\n */\nexport async function acquireTranscriptFileLock(\n transcriptAbsPath: string,\n opts?: { timeoutMs?: number; staleMs?: number },\n): Promise<TranscriptFileLock> {\n const normalized = normalizeTranscriptPath(transcriptAbsPath);\n return chainPerTranscript(normalized, () => acquireTranscriptFileLockBody(normalized, opts));\n}\n\nasync function acquireTranscriptFileLockBody(\n normalized: string,\n opts?: { timeoutMs?: number; staleMs?: number },\n): Promise<TranscriptFileLock> {\n const timeoutMs = opts?.timeoutMs ?? DEFAULT_TIMEOUT_MS;\n const staleMs = opts?.staleMs ?? DEFAULT_STALE_MS;\n\n const existing = heldLocks.get(normalized);\n if (existing) {\n existing.refcount += 1;\n return {\n release: async () => {\n await releaseHeldLock(normalized, existing);\n },\n };\n }\n\n const lockFile = lockPathFor(normalized);\n await mkdir(path.dirname(lockFile), { recursive: true });\n\n const started = Date.now();\n let handle: FileHandle | null = null;\n\n while (Date.now() - started < timeoutMs) {\n try {\n handle = await open(lockFile, 'wx', 0o600);\n break;\n } catch (err) {\n const code = (err as NodeJS.ErrnoException).code;\n if (code === 'EEXIST') {\n if (await isStaleLock(lockFile, staleMs)) {\n await rm(lockFile, { force: true });\n continue;\n }\n await new Promise((r) => setTimeout(r, 50 + Math.floor(Math.random() * 40)));\n continue;\n }\n throw err;\n }\n }\n\n if (!handle) {\n throw new Error(`timeout acquiring transcript lock: ${lockFile}`);\n }\n\n const payload: LockPayload = { pid: process.pid, createdAt: new Date().toISOString() };\n await handle.writeFile(JSON.stringify(payload, null, 2), 'utf8');\n\n const held: HeldTranscriptLock = { refcount: 1, handle, lockFile };\n heldLocks.set(normalized, held);\n\n return {\n release: async () => {\n await releaseHeldLock(normalized, held);\n },\n };\n}\n\nexport async function withTranscriptFileLock<T>(\n transcriptAbsPath: string,\n fn: () => Promise<T>,\n opts?: { timeoutMs?: number; staleMs?: number },\n): Promise<T> {\n const lock = await acquireTranscriptFileLock(transcriptAbsPath, opts);\n try {\n return await fn();\n } finally {\n await lock.release();\n }\n}\n\n/** Best-effort: remove a stale lock without acquiring (e.g. doctor tooling). */\nexport async function tryRemoveStaleTranscriptLock(\n transcriptAbsPath: string,\n staleMs: number = DEFAULT_STALE_MS,\n): Promise<boolean> {\n const lockFile = lockPathFor(normalizeTranscriptPath(transcriptAbsPath));\n if (!existsSync(lockFile)) {\n return false;\n }\n if (!(await isStaleLock(lockFile, staleMs))) {\n return false;\n }\n await rm(lockFile, { force: true });\n return true;\n}\n"],"mappings":"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"}
@@ -1,29 +0,0 @@
1
- import type { AgentMessage } from '@earendil-works/pi-agent-core';
2
- import type { TranscriptStoredRow } from '../session-context-for-llm.js';
3
- export type TranscriptPageOptions = {
4
- limit: number;
5
- /** Exclusive end index into display message rows (default: total). */
6
- beforeIndex?: number;
7
- /** Tail offset (used when `beforeIndex` is omitted). */
8
- offset?: number;
9
- };
10
- export type TranscriptPageResult = {
11
- rows: TranscriptStoredRow[];
12
- total: number;
13
- startIndex: number;
14
- endIndex: number;
15
- };
16
- /**
17
- * Count persisted pi `type: message` rows (excludes context custom rows).
18
- */
19
- export declare function countTranscriptMessageRows(absPath: string): Promise<number>;
20
- /**
21
- * Read a page of display messages from transcript tail (newest page when cursors omitted).
22
- */
23
- export declare function readDisplayMessagePageFromTranscriptFile(absPath: string, options: TranscriptPageOptions): Promise<TranscriptPageResult & {
24
- messages: AgentMessage[];
25
- }>;
26
- /**
27
- * Read a page of transcript rows from the tail (newest page when `beforeIndex` omitted).
28
- */
29
- export declare function readTranscriptRowsPageFromFile(absPath: string, options: TranscriptPageOptions): Promise<TranscriptPageResult>;
@@ -1,132 +0,0 @@
1
- import "./jsonl-transcript-io.js";
2
- import { existsSync } from "node:fs";
3
- import { readFile } from "node:fs/promises";
4
- //#region src/session/parity/transcript-pagination.ts
5
- function classifyLine(line) {
6
- const trimmed = line.trim();
7
- if (!trimmed) return "other";
8
- if (trimmed.includes("\"type\":\"session\"") || trimmed.includes("\"type\": \"session\"")) return "session";
9
- if (trimmed.includes("\"type\":\"message\"") || trimmed.includes("\"type\": \"message\"")) return "message";
10
- if (trimmed.includes(`"xopc:transcript-row"`) || trimmed.includes("\"type\":\"custom\"")) return "context";
11
- return "other";
12
- }
13
- function parseStoredRow(line, kind) {
14
- try {
15
- const parsed = JSON.parse(line);
16
- if (kind === "message" && parsed.message) return parsed.message;
17
- if (kind === "context" && parsed.type === "custom") {
18
- const data = parsed.data;
19
- if (!data || data.kind !== "context") return null;
20
- return {
21
- kind: "context",
22
- id: typeof data.id === "string" ? data.id : void 0,
23
- text: typeof data.text === "string" ? data.text : void 0,
24
- data: data.data,
25
- createdAt: typeof data.createdAt === "string" ? data.createdAt : void 0
26
- };
27
- }
28
- } catch {
29
- return null;
30
- }
31
- return null;
32
- }
33
- /**
34
- * Count persisted pi `type: message` rows (excludes context custom rows).
35
- */
36
- async function countTranscriptMessageRows(absPath) {
37
- if (!existsSync(absPath)) return 0;
38
- const content = await readFile(absPath, "utf8");
39
- let count = 0;
40
- for (const line of content.split("\n")) if (classifyLine(line) === "message") count += 1;
41
- return count;
42
- }
43
- function isCompactionSummaryLine(line) {
44
- return line.includes("[Previous conversation summary]");
45
- }
46
- /**
47
- * Read a page of display messages from transcript tail (newest page when cursors omitted).
48
- */
49
- async function readDisplayMessagePageFromTranscriptFile(absPath, options) {
50
- if (!existsSync(absPath)) return {
51
- rows: [],
52
- messages: [],
53
- total: 0,
54
- startIndex: 0,
55
- endIndex: 0
56
- };
57
- const limit = Math.max(1, Math.trunc(options.limit));
58
- const content = await readFile(absPath, "utf8");
59
- const displayLines = [];
60
- for (const line of content.split("\n")) {
61
- const kind = classifyLine(line);
62
- if (kind !== "message") continue;
63
- if (isCompactionSummaryLine(line)) continue;
64
- displayLines.push({
65
- line,
66
- kind
67
- });
68
- }
69
- const total = displayLines.length;
70
- const offset = Math.max(0, Math.trunc(options.offset ?? 0));
71
- const endExclusive = options.beforeIndex !== void 0 ? Math.min(total, Math.max(0, Math.trunc(options.beforeIndex))) : Math.max(0, total - offset);
72
- const startInclusive = Math.max(0, endExclusive - limit);
73
- const slice = displayLines.slice(startInclusive, endExclusive);
74
- const rows = [];
75
- const messages = [];
76
- for (const item of slice) {
77
- const row = parseStoredRow(item.line, item.kind);
78
- if (row && typeof row.role === "string") {
79
- rows.push(row);
80
- messages.push(row);
81
- }
82
- }
83
- return {
84
- rows,
85
- messages,
86
- total,
87
- startIndex: startInclusive,
88
- endIndex: endExclusive
89
- };
90
- }
91
- /**
92
- * Read a page of transcript rows from the tail (newest page when `beforeIndex` omitted).
93
- */
94
- async function readTranscriptRowsPageFromFile(absPath, options) {
95
- if (!existsSync(absPath)) return {
96
- rows: [],
97
- total: 0,
98
- startIndex: 0,
99
- endIndex: 0
100
- };
101
- const limit = Math.max(1, Math.trunc(options.limit));
102
- const content = await readFile(absPath, "utf8");
103
- const parsedLines = [];
104
- for (const line of content.split("\n")) {
105
- const kind = classifyLine(line);
106
- if (kind === "session" || kind === "other") continue;
107
- parsedLines.push({
108
- line,
109
- kind
110
- });
111
- }
112
- const total = parsedLines.length;
113
- const offset = Math.max(0, Math.trunc(options.offset ?? 0));
114
- const endExclusive = options.beforeIndex !== void 0 ? Math.min(total, Math.max(0, Math.trunc(options.beforeIndex))) : Math.max(0, total - offset);
115
- const startInclusive = Math.max(0, endExclusive - limit);
116
- const slice = parsedLines.slice(startInclusive, endExclusive);
117
- const rows = [];
118
- for (const item of slice) {
119
- const row = parseStoredRow(item.line, item.kind);
120
- if (row) rows.push(row);
121
- }
122
- return {
123
- rows,
124
- total,
125
- startIndex: startInclusive,
126
- endIndex: endExclusive
127
- };
128
- }
129
- //#endregion
130
- export { countTranscriptMessageRows, readDisplayMessagePageFromTranscriptFile, readTranscriptRowsPageFromFile };
131
-
132
- //# sourceMappingURL=transcript-pagination.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"transcript-pagination.js","names":[],"sources":["../../../../src/session/parity/transcript-pagination.ts"],"sourcesContent":["import { readFile } from 'node:fs/promises';\nimport { existsSync } from 'node:fs';\n\nimport type { AgentMessage } from '@earendil-works/pi-agent-core';\n\nimport type { TranscriptStoredRow, XopcTranscriptContextEntry } from '../session-context-for-llm.js';\nimport { XOPC_CONTEXT_CUSTOM_TYPE } from './jsonl-transcript-io.js';\n\nexport type TranscriptPageOptions = {\n limit: number;\n /** Exclusive end index into display message rows (default: total). */\n beforeIndex?: number;\n /** Tail offset (used when `beforeIndex` is omitted). */\n offset?: number;\n};\n\nexport type TranscriptPageResult = {\n rows: TranscriptStoredRow[];\n total: number;\n startIndex: number;\n endIndex: number;\n};\n\ntype ParsedLine = {\n line: string;\n kind: 'session' | 'message' | 'context' | 'other';\n};\n\nfunction classifyLine(line: string): ParsedLine['kind'] {\n const trimmed = line.trim();\n if (!trimmed) {\n return 'other';\n }\n if (trimmed.includes('\"type\":\"session\"') || trimmed.includes('\"type\": \"session\"')) {\n return 'session';\n }\n if (trimmed.includes('\"type\":\"message\"') || trimmed.includes('\"type\": \"message\"')) {\n return 'message';\n }\n if (trimmed.includes(`\"${XOPC_CONTEXT_CUSTOM_TYPE}\"`) || trimmed.includes('\"type\":\"custom\"')) {\n return 'context';\n }\n return 'other';\n}\n\nfunction parseStoredRow(line: string, kind: ParsedLine['kind']): TranscriptStoredRow | null {\n try {\n const parsed = JSON.parse(line) as Record<string, unknown>;\n if (kind === 'message' && parsed.message) {\n return parsed.message as AgentMessage;\n }\n if (kind === 'context' && parsed.type === 'custom') {\n const data = parsed.data as Record<string, unknown> | undefined;\n if (!data || data.kind !== 'context') {\n return null;\n }\n return {\n kind: 'context',\n id: typeof data.id === 'string' ? data.id : undefined,\n text: typeof data.text === 'string' ? data.text : undefined,\n data: data.data as Record<string, unknown> | undefined,\n createdAt: typeof data.createdAt === 'string' ? data.createdAt : undefined,\n } satisfies XopcTranscriptContextEntry;\n }\n } catch {\n return null;\n }\n return null;\n}\n\n/**\n * Count persisted pi `type: message` rows (excludes context custom rows).\n */\nexport async function countTranscriptMessageRows(absPath: string): Promise<number> {\n if (!existsSync(absPath)) {\n return 0;\n }\n const content = await readFile(absPath, 'utf8');\n let count = 0;\n for (const line of content.split('\\n')) {\n const kind = classifyLine(line);\n if (kind === 'message') {\n count += 1;\n }\n }\n return count;\n}\n\nfunction isCompactionSummaryLine(line: string): boolean {\n return line.includes('[Previous conversation summary]');\n}\n\n/**\n * Read a page of display messages from transcript tail (newest page when cursors omitted).\n */\nexport async function readDisplayMessagePageFromTranscriptFile(\n absPath: string,\n options: TranscriptPageOptions,\n): Promise<TranscriptPageResult & { messages: AgentMessage[] }> {\n if (!existsSync(absPath)) {\n return { rows: [], messages: [], total: 0, startIndex: 0, endIndex: 0 };\n }\n\n const limit = Math.max(1, Math.trunc(options.limit));\n const content = await readFile(absPath, 'utf8');\n const displayLines: ParsedLine[] = [];\n for (const line of content.split('\\n')) {\n const kind = classifyLine(line);\n if (kind !== 'message') {\n continue;\n }\n if (isCompactionSummaryLine(line)) {\n continue;\n }\n displayLines.push({ line, kind });\n }\n\n const total = displayLines.length;\n const offset = Math.max(0, Math.trunc(options.offset ?? 0));\n const endExclusive =\n options.beforeIndex !== undefined\n ? Math.min(total, Math.max(0, Math.trunc(options.beforeIndex)))\n : Math.max(0, total - offset);\n const startInclusive = Math.max(0, endExclusive - limit);\n const slice = displayLines.slice(startInclusive, endExclusive);\n const rows: TranscriptStoredRow[] = [];\n const messages: AgentMessage[] = [];\n for (const item of slice) {\n const row = parseStoredRow(item.line, item.kind);\n if (row && typeof (row as AgentMessage).role === 'string') {\n rows.push(row);\n messages.push(row as AgentMessage);\n }\n }\n\n return {\n rows,\n messages,\n total,\n startIndex: startInclusive,\n endIndex: endExclusive,\n };\n}\n\n/**\n * Read a page of transcript rows from the tail (newest page when `beforeIndex` omitted).\n */\nexport async function readTranscriptRowsPageFromFile(\n absPath: string,\n options: TranscriptPageOptions,\n): Promise<TranscriptPageResult> {\n if (!existsSync(absPath)) {\n return { rows: [], total: 0, startIndex: 0, endIndex: 0 };\n }\n\n const limit = Math.max(1, Math.trunc(options.limit));\n const content = await readFile(absPath, 'utf8');\n const parsedLines: ParsedLine[] = [];\n for (const line of content.split('\\n')) {\n const kind = classifyLine(line);\n if (kind === 'session' || kind === 'other') {\n continue;\n }\n parsedLines.push({ line, kind });\n }\n\n const total = parsedLines.length;\n const offset = Math.max(0, Math.trunc(options.offset ?? 0));\n const endExclusive =\n options.beforeIndex !== undefined\n ? Math.min(total, Math.max(0, Math.trunc(options.beforeIndex)))\n : Math.max(0, total - offset);\n const startInclusive = Math.max(0, endExclusive - limit);\n const slice = parsedLines.slice(startInclusive, endExclusive);\n const rows: TranscriptStoredRow[] = [];\n for (const item of slice) {\n const row = parseStoredRow(item.line, item.kind);\n if (row) {\n rows.push(row);\n }\n }\n\n return {\n rows,\n total,\n startIndex: startInclusive,\n endIndex: endExclusive,\n };\n}\n"],"mappings":"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"}
@@ -1,13 +0,0 @@
1
- export type SessionFilePathOptions = {
2
- agentId?: string;
3
- sessionsDir?: string;
4
- };
5
- export declare function resolveSessionTranscriptPathInDir(sessionId: string, sessionsDir: string, topicId?: string | number): string;
6
- export declare function resolveSessionFilePath(sessionId: string, entry?: {
7
- sessionFile?: string;
8
- }, opts?: SessionFilePathOptions): string;
9
- /**
10
- * Candidate transcript paths for a session (xopc state only — no external legacy dirs).
11
- */
12
- export declare function resolveSessionTranscriptCandidates(sessionId: string, storePath: string | undefined, sessionFile?: string, _agentId?: string): string[];
13
- export declare function archiveFileOnDisk(filePath: string, reason: 'reset' | 'deleted' | 'bak'): string;
@@ -1,64 +0,0 @@
1
- import { __esmMin } from "../../../_virtual/_rolldown/runtime.js";
2
- import { formatSessionArchiveTimestamp, init_artifacts } from "./artifacts.js";
3
- import { init_session_id, validateSessionId } from "./session-id.js";
4
- import { dirname, relative, resolve } from "node:path";
5
- import fs from "node:fs";
6
- //#region src/session/parity/transcript-paths.ts
7
- function resolveSessionsDir(opts) {
8
- const sessionsDir = opts?.sessionsDir?.trim();
9
- if (!sessionsDir) throw new Error("sessionsDir is required for session transcript path resolution");
10
- return resolve(sessionsDir);
11
- }
12
- function resolvePathWithinSessionsDir(sessionsDir, candidate) {
13
- const trimmed = candidate.trim();
14
- if (!trimmed) throw new Error("Session file path must not be empty");
15
- const resolvedBase = resolve(sessionsDir);
16
- const normalized = resolve(resolvedBase, trimmed);
17
- const rel = relative(resolvedBase, normalized);
18
- if (rel.startsWith("..") || rel === "") throw new Error("Session file path must be within sessions directory");
19
- return normalized;
20
- }
21
- function resolveSessionTranscriptPathInDir(sessionId, sessionsDir, topicId) {
22
- const safeSessionId = validateSessionId(sessionId);
23
- const safeTopicId = typeof topicId === "string" ? encodeURIComponent(topicId) : typeof topicId === "number" ? String(topicId) : void 0;
24
- return resolvePathWithinSessionsDir(sessionsDir, safeTopicId !== void 0 ? `${safeSessionId}-topic-${safeTopicId}.jsonl` : `${safeSessionId}.jsonl`);
25
- }
26
- function resolveSessionFilePath(sessionId, entry, opts) {
27
- const sessionsDir = resolveSessionsDir(opts);
28
- const candidate = entry?.sessionFile?.trim();
29
- if (candidate) try {
30
- return resolvePathWithinSessionsDir(sessionsDir, candidate);
31
- } catch {}
32
- return resolveSessionTranscriptPathInDir(sessionId, sessionsDir);
33
- }
34
- /**
35
- * Candidate transcript paths for a session (xopc state only — no external legacy dirs).
36
- */
37
- function resolveSessionTranscriptCandidates(sessionId, storePath, sessionFile, _agentId) {
38
- const candidates = [];
39
- const push = (p) => {
40
- if (!candidates.includes(p)) candidates.push(p);
41
- };
42
- if (storePath) {
43
- const sessionsDir = dirname(storePath);
44
- if (sessionFile?.trim()) try {
45
- push(resolveSessionFilePath(sessionId, { sessionFile }, { sessionsDir }));
46
- } catch {}
47
- push(resolveSessionTranscriptPathInDir(sessionId, sessionsDir));
48
- } else if (sessionFile?.trim()) push(resolve(sessionFile.trim()));
49
- return candidates;
50
- }
51
- function archiveFileOnDisk(filePath, reason) {
52
- const archived = `${filePath}.${reason}.${formatSessionArchiveTimestamp()}`;
53
- fs.renameSync(filePath, archived);
54
- return archived;
55
- }
56
- var init_transcript_paths = __esmMin((() => {
57
- init_artifacts();
58
- init_session_id();
59
- }));
60
- //#endregion
61
- init_transcript_paths();
62
- export { archiveFileOnDisk, init_transcript_paths, resolveSessionFilePath, resolveSessionTranscriptCandidates, resolveSessionTranscriptPathInDir };
63
-
64
- //# sourceMappingURL=transcript-paths.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"transcript-paths.js","names":[],"sources":["../../../../src/session/parity/transcript-paths.ts"],"sourcesContent":["import fs from 'node:fs';\nimport { dirname, relative, resolve } from 'node:path';\n\nimport { formatSessionArchiveTimestamp } from './artifacts.js';\nimport { validateSessionId } from './session-id.js';\n\nexport type SessionFilePathOptions = {\n agentId?: string;\n sessionsDir?: string;\n};\n\nfunction resolveSessionsDir(opts?: SessionFilePathOptions): string {\n const sessionsDir = opts?.sessionsDir?.trim();\n if (!sessionsDir) {\n throw new Error('sessionsDir is required for session transcript path resolution');\n }\n return resolve(sessionsDir);\n}\n\nfunction resolvePathWithinSessionsDir(sessionsDir: string, candidate: string): string {\n const trimmed = candidate.trim();\n if (!trimmed) {\n throw new Error('Session file path must not be empty');\n }\n const resolvedBase = resolve(sessionsDir);\n const normalized = resolve(resolvedBase, trimmed);\n const rel = relative(resolvedBase, normalized);\n if (rel.startsWith('..') || rel === '') {\n throw new Error('Session file path must be within sessions directory');\n }\n return normalized;\n}\n\nexport function resolveSessionTranscriptPathInDir(\n sessionId: string,\n sessionsDir: string,\n topicId?: string | number,\n): string {\n const safeSessionId = validateSessionId(sessionId);\n const safeTopicId =\n typeof topicId === 'string'\n ? encodeURIComponent(topicId)\n : typeof topicId === 'number'\n ? String(topicId)\n : undefined;\n const fileName =\n safeTopicId !== undefined\n ? `${safeSessionId}-topic-${safeTopicId}.jsonl`\n : `${safeSessionId}.jsonl`;\n return resolvePathWithinSessionsDir(sessionsDir, fileName);\n}\n\nexport function resolveSessionFilePath(\n sessionId: string,\n entry?: { sessionFile?: string },\n opts?: SessionFilePathOptions,\n): string {\n const sessionsDir = resolveSessionsDir(opts);\n const candidate = entry?.sessionFile?.trim();\n if (candidate) {\n try {\n return resolvePathWithinSessionsDir(sessionsDir, candidate);\n } catch {\n /* fall through */\n }\n }\n return resolveSessionTranscriptPathInDir(sessionId, sessionsDir);\n}\n\n/**\n * Candidate transcript paths for a session (xopc state only — no external legacy dirs).\n */\nexport function resolveSessionTranscriptCandidates(\n sessionId: string,\n storePath: string | undefined,\n sessionFile?: string,\n _agentId?: string,\n): string[] {\n const candidates: string[] = [];\n const push = (p: string): void => {\n if (!candidates.includes(p)) {\n candidates.push(p);\n }\n };\n\n if (storePath) {\n const sessionsDir = dirname(storePath);\n if (sessionFile?.trim()) {\n try {\n push(resolveSessionFilePath(sessionId, { sessionFile }, { sessionsDir }));\n } catch {\n /* ignore */\n }\n }\n push(resolveSessionTranscriptPathInDir(sessionId, sessionsDir));\n } else if (sessionFile?.trim()) {\n push(resolve(sessionFile.trim()));\n }\n\n return candidates;\n}\n\nexport function archiveFileOnDisk(filePath: string, reason: 'reset' | 'deleted' | 'bak'): string {\n const ts = formatSessionArchiveTimestamp();\n const archived = `${filePath}.${reason}.${ts}`;\n fs.renameSync(filePath, archived);\n return archived;\n}\n"],"mappings":";;;;;;AAWA,SAAS,mBAAmB,MAAuC;CACjE,MAAM,cAAc,MAAM,aAAa,MAAM;AAC7C,KAAI,CAAC,YACH,OAAM,IAAI,MAAM,iEAAiE;AAEnF,QAAO,QAAQ,YAAY;;AAG7B,SAAS,6BAA6B,aAAqB,WAA2B;CACpF,MAAM,UAAU,UAAU,MAAM;AAChC,KAAI,CAAC,QACH,OAAM,IAAI,MAAM,sCAAsC;CAExD,MAAM,eAAe,QAAQ,YAAY;CACzC,MAAM,aAAa,QAAQ,cAAc,QAAQ;CACjD,MAAM,MAAM,SAAS,cAAc,WAAW;AAC9C,KAAI,IAAI,WAAW,KAAK,IAAI,QAAQ,GAClC,OAAM,IAAI,MAAM,sDAAsD;AAExE,QAAO;;AAGT,SAAgB,kCACd,WACA,aACA,SACQ;CACR,MAAM,gBAAgB,kBAAkB,UAAU;CAClD,MAAM,cACJ,OAAO,YAAY,WACf,mBAAmB,QAAQ,GAC3B,OAAO,YAAY,WACjB,OAAO,QAAQ,GACf,KAAA;AAKR,QAAO,6BAA6B,aAHlC,gBAAgB,KAAA,IACZ,GAAG,cAAc,SAAS,YAAY,UACtC,GAAG,cAAc,QACmC;;AAG5D,SAAgB,uBACd,WACA,OACA,MACQ;CACR,MAAM,cAAc,mBAAmB,KAAK;CAC5C,MAAM,YAAY,OAAO,aAAa,MAAM;AAC5C,KAAI,UACF,KAAI;AACF,SAAO,6BAA6B,aAAa,UAAU;SACrD;AAIV,QAAO,kCAAkC,WAAW,YAAY;;;;;AAMlE,SAAgB,mCACd,WACA,WACA,aACA,UACU;CACV,MAAM,aAAuB,EAAE;CAC/B,MAAM,QAAQ,MAAoB;AAChC,MAAI,CAAC,WAAW,SAAS,EAAE,CACzB,YAAW,KAAK,EAAE;;AAItB,KAAI,WAAW;EACb,MAAM,cAAc,QAAQ,UAAU;AACtC,MAAI,aAAa,MAAM,CACrB,KAAI;AACF,QAAK,uBAAuB,WAAW,EAAE,aAAa,EAAE,EAAE,aAAa,CAAC,CAAC;UACnE;AAIV,OAAK,kCAAkC,WAAW,YAAY,CAAC;YACtD,aAAa,MAAM,CAC5B,MAAK,QAAQ,YAAY,MAAM,CAAC,CAAC;AAGnC,QAAO;;AAGT,SAAgB,kBAAkB,UAAkB,QAA6C;CAE/F,MAAM,WAAW,GAAG,SAAS,GAAG,OAAO,GAD5B,+BACiC;AAC5C,IAAG,WAAW,UAAU,SAAS;AACjC,QAAO;;;iBAvGsD;kBACX"}