@renxqoo/renx-code 0.0.3 → 0.0.5

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 (505) hide show
  1. package/README.md +58 -223
  2. package/bin/renx.cjs +50 -0
  3. package/package.json +12 -111
  4. package/src/App.tsx +297 -0
  5. package/src/agent/runtime/event-format.ts +258 -0
  6. package/src/agent/runtime/model-types.ts +13 -0
  7. package/src/agent/runtime/runtime.context-usage.test.ts +192 -0
  8. package/src/agent/runtime/runtime.error-handling.test.ts +235 -0
  9. package/src/agent/runtime/runtime.simple.test.ts +16 -0
  10. package/src/agent/runtime/runtime.test.ts +296 -0
  11. package/src/agent/runtime/runtime.ts +875 -0
  12. package/src/agent/runtime/runtime.usage-forwarding.test.ts +228 -0
  13. package/src/agent/runtime/source-modules.test.ts +38 -0
  14. package/src/agent/runtime/source-modules.ts +370 -0
  15. package/src/agent/runtime/tool-call-buffer.test.ts +65 -0
  16. package/src/agent/runtime/tool-call-buffer.ts +60 -0
  17. package/src/agent/runtime/tool-confirmation.test.ts +56 -0
  18. package/src/agent/runtime/tool-confirmation.ts +15 -0
  19. package/src/agent/runtime/types.ts +99 -0
  20. package/src/commands/slash-commands.test.ts +216 -0
  21. package/src/commands/slash-commands.ts +64 -0
  22. package/src/components/chat/assistant-reply.test.tsx +47 -0
  23. package/src/components/chat/assistant-reply.tsx +136 -0
  24. package/src/components/chat/assistant-segment.test.ts +99 -0
  25. package/src/components/chat/assistant-segment.tsx +125 -0
  26. package/src/components/chat/assistant-tool-group.tsx +900 -0
  27. package/src/components/chat/code-block.test.tsx +206 -0
  28. package/src/components/chat/code-block.tsx +313 -0
  29. package/src/components/chat/prompt-card.tsx +81 -0
  30. package/src/components/chat/segment-groups.test.ts +52 -0
  31. package/src/components/chat/segment-groups.ts +106 -0
  32. package/src/components/chat/turn-item.tsx +39 -0
  33. package/src/components/conversation-panel.tsx +43 -0
  34. package/src/components/file-mention-menu.tsx +77 -0
  35. package/src/components/file-picker-dialog.tsx +206 -0
  36. package/src/components/footer-hints.tsx +75 -0
  37. package/src/components/model-picker-dialog.tsx +248 -0
  38. package/src/components/prompt.tsx +233 -0
  39. package/src/components/slash-command-menu.tsx +65 -0
  40. package/src/components/tool-confirm-dialog-content.test.ts +103 -0
  41. package/src/components/tool-confirm-dialog-content.ts +186 -0
  42. package/src/components/tool-confirm-dialog.tsx +187 -0
  43. package/src/components/tool-display-config.ts +119 -0
  44. package/src/context-usage-regressions.test.ts +26 -0
  45. package/src/files/attachment-capabilities.test.ts +30 -0
  46. package/src/files/attachment-capabilities.ts +50 -0
  47. package/src/files/attachment-content.ts +153 -0
  48. package/src/files/file-mention-query.test.ts +34 -0
  49. package/src/files/file-mention-query.ts +32 -0
  50. package/src/files/prompt-display.ts +13 -0
  51. package/src/files/types.ts +5 -0
  52. package/src/files/workspace-files.ts +63 -0
  53. package/src/hooks/agent-event-handlers.test.ts +207 -0
  54. package/src/hooks/agent-event-handlers.ts +196 -0
  55. package/src/hooks/chat-local-replies.fixed.test.ts +119 -0
  56. package/src/hooks/chat-local-replies.test.ts +153 -0
  57. package/src/hooks/chat-local-replies.ts +63 -0
  58. package/src/hooks/turn-updater.test.ts +70 -0
  59. package/src/hooks/turn-updater.ts +166 -0
  60. package/src/hooks/use-agent-chat.context.test.ts +10 -0
  61. package/src/hooks/use-agent-chat.status.test.ts +14 -0
  62. package/src/hooks/use-agent-chat.test.ts +80 -0
  63. package/src/hooks/use-agent-chat.ts +621 -0
  64. package/src/hooks/use-file-mention-menu.ts +196 -0
  65. package/src/hooks/use-file-picker.ts +185 -0
  66. package/src/hooks/use-model-picker.ts +196 -0
  67. package/src/hooks/use-slash-command-menu.ts +154 -0
  68. package/src/index.tsx +55 -0
  69. package/src/runtime/clipboard.test.ts +43 -0
  70. package/src/runtime/clipboard.ts +89 -0
  71. package/src/runtime/exit.test.ts +177 -0
  72. package/src/runtime/exit.ts +98 -0
  73. package/src/runtime/runtime-support.test.ts +31 -0
  74. package/src/runtime/terminal-theme.test.ts +55 -0
  75. package/src/runtime/terminal-theme.ts +196 -0
  76. package/src/types/chat.ts +32 -0
  77. package/src/types/message-content.ts +48 -0
  78. package/src/ui/open-code-theme.ts +176 -0
  79. package/src/ui/opencode-markdown.ts +211 -0
  80. package/src/ui/theme.simple.test.ts +52 -0
  81. package/src/ui/theme.test.ts +151 -0
  82. package/src/ui/theme.ts +152 -0
  83. package/src/utils/time.test.ts +144 -0
  84. package/src/utils/time.ts +7 -0
  85. package/tsconfig.json +30 -0
  86. package/vendor/agent-root/src/agent/ENTERPRISE_ACCEPTANCE_CHECKLIST.md +95 -0
  87. package/vendor/agent-root/src/agent/ENTERPRISE_REALTIME.html +1345 -0
  88. package/vendor/agent-root/src/agent/ENTERPRISE_REALTIME.md +1353 -0
  89. package/vendor/agent-root/src/agent/ERROR_CONTRACT.md +60 -0
  90. package/vendor/agent-root/src/agent/TEST_COVERAGE_ANALYSIS.md +278 -0
  91. package/vendor/agent-root/src/agent/__test__/error-contract.test.ts +72 -0
  92. package/vendor/agent-root/src/agent/__test__/types.test.ts +137 -0
  93. package/vendor/agent-root/src/agent/agent/__test__/abort-runtime.test.ts +83 -0
  94. package/vendor/agent-root/src/agent/agent/__test__/callback-safety.test.ts +34 -0
  95. package/vendor/agent-root/src/agent/agent/__test__/compaction.test.ts +323 -0
  96. package/vendor/agent-root/src/agent/agent/__test__/concurrency.test.ts +290 -0
  97. package/vendor/agent-root/src/agent/agent/__test__/error-normalizer.test.ts +377 -0
  98. package/vendor/agent-root/src/agent/agent/__test__/error.test.ts +212 -0
  99. package/vendor/agent-root/src/agent/agent/__test__/fault-injection.test.ts +295 -0
  100. package/vendor/agent-root/src/agent/agent/__test__/index.test.ts +3607 -0
  101. package/vendor/agent-root/src/agent/agent/__test__/logger.test.ts +35 -0
  102. package/vendor/agent-root/src/agent/agent/__test__/message-utils.test.ts +517 -0
  103. package/vendor/agent-root/src/agent/agent/__test__/telemetry.test.ts +97 -0
  104. package/vendor/agent-root/src/agent/agent/__test__/timeout-budget.test.ts +479 -0
  105. package/vendor/agent-root/src/agent/agent/__test__/tool-call-merge.test.ts +80 -0
  106. package/vendor/agent-root/src/agent/agent/__test__/tool-execution-ledger.test.ts +76 -0
  107. package/vendor/agent-root/src/agent/agent/__test__/write-buffer.test.ts +173 -0
  108. package/vendor/agent-root/src/agent/agent/__test__/write-file-session.test.ts +109 -0
  109. package/vendor/agent-root/src/agent/agent/abort-runtime.ts +71 -0
  110. package/vendor/agent-root/src/agent/agent/callback-safety.ts +33 -0
  111. package/vendor/agent-root/src/agent/agent/compaction.ts +291 -0
  112. package/vendor/agent-root/src/agent/agent/concurrency.ts +103 -0
  113. package/vendor/agent-root/src/agent/agent/error-normalizer.ts +190 -0
  114. package/vendor/agent-root/src/agent/agent/error.ts +198 -0
  115. package/vendor/agent-root/src/agent/agent/index.ts +1772 -0
  116. package/vendor/agent-root/src/agent/agent/logger.ts +65 -0
  117. package/vendor/agent-root/src/agent/agent/message-utils.ts +101 -0
  118. package/vendor/agent-root/src/agent/agent/stream-events.ts +61 -0
  119. package/vendor/agent-root/src/agent/agent/telemetry.ts +123 -0
  120. package/vendor/agent-root/src/agent/agent/timeout-budget.ts +227 -0
  121. package/vendor/agent-root/src/agent/agent/tool-call-merge.ts +111 -0
  122. package/vendor/agent-root/src/agent/agent/tool-execution-ledger.ts +164 -0
  123. package/vendor/agent-root/src/agent/agent/write-buffer.ts +188 -0
  124. package/vendor/agent-root/src/agent/agent/write-file-session.ts +238 -0
  125. package/vendor/agent-root/src/agent/app/__test__/agent-app-service.test.ts +1053 -0
  126. package/vendor/agent-root/src/agent/app/__test__/minimal-agent-application.test.ts +158 -0
  127. package/vendor/agent-root/src/agent/app/__test__/sqlite-agent-app-store.test.ts +437 -0
  128. package/vendor/agent-root/src/agent/app/agent-app-service.ts +748 -0
  129. package/vendor/agent-root/src/agent/app/contracts.ts +109 -0
  130. package/vendor/agent-root/src/agent/app/index.ts +5 -0
  131. package/vendor/agent-root/src/agent/app/minimal-agent-application.ts +151 -0
  132. package/vendor/agent-root/src/agent/app/ports.ts +72 -0
  133. package/vendor/agent-root/src/agent/app/sqlite-agent-app-store.ts +1182 -0
  134. package/vendor/agent-root/src/agent/app/sqlite-client.ts +177 -0
  135. package/vendor/agent-root/src/agent/docs/cli-app-layer/00-README.md +36 -0
  136. package/vendor/agent-root/src/agent/docs/cli-app-layer/01-scope-and-goals.md +33 -0
  137. package/vendor/agent-root/src/agent/docs/cli-app-layer/02-architecture-overview.md +40 -0
  138. package/vendor/agent-root/src/agent/docs/cli-app-layer/03-domain-model-and-contracts.md +91 -0
  139. package/vendor/agent-root/src/agent/docs/cli-app-layer/04-ports-and-interfaces.md +116 -0
  140. package/vendor/agent-root/src/agent/docs/cli-app-layer/05-run-orchestration-and-state-machine.md +52 -0
  141. package/vendor/agent-root/src/agent/docs/cli-app-layer/06-cli-commands-and-ux.md +53 -0
  142. package/vendor/agent-root/src/agent/docs/cli-app-layer/07-storage-design-local.md +52 -0
  143. package/vendor/agent-root/src/agent/docs/cli-app-layer/08-error-and-observability.md +40 -0
  144. package/vendor/agent-root/src/agent/docs/cli-app-layer/09-security-and-policy-boundary.md +19 -0
  145. package/vendor/agent-root/src/agent/docs/cli-app-layer/10-test-plan-and-acceptance.md +28 -0
  146. package/vendor/agent-root/src/agent/docs/cli-app-layer/11-implementation-phases.md +26 -0
  147. package/vendor/agent-root/src/agent/docs/cli-app-layer/12-open-questions-and-risks.md +30 -0
  148. package/vendor/agent-root/src/agent/docs/cli-app-layer/13-sqlite-schema-fields-and-rationale.md +567 -0
  149. package/vendor/agent-root/src/agent/docs/cli-app-layer/14-project-flow-mermaid.md +583 -0
  150. package/vendor/agent-root/src/agent/docs/cli-app-layer/15-openclaw-style-project-blueprint.md +972 -0
  151. package/vendor/agent-root/src/agent/error-contract.ts +154 -0
  152. package/{dist/agent/prompts/system.js → vendor/agent-root/src/agent/prompts/system.ts} +47 -23
  153. package/vendor/agent-root/src/agent/prompts/system1.ts +208 -0
  154. package/vendor/agent-root/src/agent/storage/__test__/file-history-store.test.ts +98 -0
  155. package/vendor/agent-root/src/agent/storage/file-history-store.ts +313 -0
  156. package/vendor/agent-root/src/agent/storage/file-storage-config.ts +94 -0
  157. package/vendor/agent-root/src/agent/storage/file-system.ts +31 -0
  158. package/vendor/agent-root/src/agent/storage/file-write-service.ts +21 -0
  159. package/vendor/agent-root/src/agent/tool/__test__/base-tool.test.ts +413 -0
  160. package/vendor/agent-root/src/agent/tool/__test__/bash-policy.test.ts +356 -0
  161. package/vendor/agent-root/src/agent/tool/__test__/bash.mocked-coverage.test.ts +375 -0
  162. package/vendor/agent-root/src/agent/tool/__test__/bash.test.ts +372 -0
  163. package/vendor/agent-root/src/agent/tool/__test__/error.test.ts +108 -0
  164. package/vendor/agent-root/src/agent/tool/__test__/file-edit-tool.test.ts +258 -0
  165. package/vendor/agent-root/src/agent/tool/__test__/file-history-tools.test.ts +121 -0
  166. package/vendor/agent-root/src/agent/tool/__test__/file-read-tool.test.ts +210 -0
  167. package/vendor/agent-root/src/agent/tool/__test__/glob.test.ts +139 -0
  168. package/vendor/agent-root/src/agent/tool/__test__/grep.mocked-coverage.test.ts +456 -0
  169. package/vendor/agent-root/src/agent/tool/__test__/grep.test.ts +192 -0
  170. package/vendor/agent-root/src/agent/tool/__test__/lsp.test.ts +300 -0
  171. package/vendor/agent-root/src/agent/tool/__test__/outside-workspace-confirmation.test.ts +214 -0
  172. package/vendor/agent-root/src/agent/tool/__test__/path-security.test.ts +336 -0
  173. package/vendor/agent-root/src/agent/tool/__test__/skill-loader.test.ts +494 -0
  174. package/vendor/agent-root/src/agent/tool/__test__/skill-parser.test.ts +543 -0
  175. package/vendor/agent-root/src/agent/tool/__test__/skill-tool.test.ts +172 -0
  176. package/vendor/agent-root/src/agent/tool/__test__/task-concurrency-and-version.test.ts +116 -0
  177. package/vendor/agent-root/src/agent/tool/__test__/task-create-get-list-update.test.ts +267 -0
  178. package/vendor/agent-root/src/agent/tool/__test__/task-create.test.ts +519 -0
  179. package/vendor/agent-root/src/agent/tool/__test__/task-errors.test.ts +225 -0
  180. package/vendor/agent-root/src/agent/tool/__test__/task-output-blocking.test.ts +223 -0
  181. package/vendor/agent-root/src/agent/tool/__test__/task-output.test.ts +184 -0
  182. package/vendor/agent-root/src/agent/tool/__test__/task-parent-abort.test.ts +287 -0
  183. package/vendor/agent-root/src/agent/tool/__test__/task-real-runner-adapter.test.ts +190 -0
  184. package/vendor/agent-root/src/agent/tool/__test__/task-run-lifecycle.test.ts +352 -0
  185. package/vendor/agent-root/src/agent/tool/__test__/task-store-runner-branches.test.ts +395 -0
  186. package/vendor/agent-root/src/agent/tool/__test__/task-store.test.ts +391 -0
  187. package/vendor/agent-root/src/agent/tool/__test__/task-subagent-config-integration.test.ts +176 -0
  188. package/vendor/agent-root/src/agent/tool/__test__/task-subagent-config.test.ts +68 -0
  189. package/vendor/agent-root/src/agent/tool/__test__/task-tools-core-edges.test.ts +630 -0
  190. package/vendor/agent-root/src/agent/tool/__test__/task-tools-runtime-edges.test.ts +732 -0
  191. package/vendor/agent-root/src/agent/tool/__test__/task-types.test.ts +494 -0
  192. package/vendor/agent-root/src/agent/tool/__test__/task-utils-branches.test.ts +175 -0
  193. package/vendor/agent-root/src/agent/tool/__test__/tool-manager.test.ts +505 -0
  194. package/vendor/agent-root/src/agent/tool/__test__/types.test.ts +55 -0
  195. package/vendor/agent-root/src/agent/tool/__test__/web-fetch.test.ts +244 -0
  196. package/vendor/agent-root/src/agent/tool/__test__/web-search.test.ts +290 -0
  197. package/vendor/agent-root/src/agent/tool/__test__/write-file.test.ts +368 -0
  198. package/vendor/agent-root/src/agent/tool/base-tool.ts +345 -0
  199. package/vendor/agent-root/src/agent/tool/bash-policy.ts +636 -0
  200. package/vendor/agent-root/src/agent/tool/bash.ts +688 -0
  201. package/vendor/agent-root/src/agent/tool/error.ts +131 -0
  202. package/vendor/agent-root/src/agent/tool/file-edit-tool.ts +264 -0
  203. package/vendor/agent-root/src/agent/tool/file-history-list.ts +103 -0
  204. package/vendor/agent-root/src/agent/tool/file-history-restore.ts +149 -0
  205. package/vendor/agent-root/src/agent/tool/file-read-tool.ts +211 -0
  206. package/vendor/agent-root/src/agent/tool/glob.ts +171 -0
  207. package/vendor/agent-root/src/agent/tool/grep.ts +496 -0
  208. package/vendor/agent-root/src/agent/tool/lsp.ts +481 -0
  209. package/vendor/agent-root/src/agent/tool/path-security.ts +117 -0
  210. package/vendor/agent-root/src/agent/tool/search/common.ts +153 -0
  211. package/vendor/agent-root/src/agent/tool/skill/index.ts +13 -0
  212. package/vendor/agent-root/src/agent/tool/skill/loader.ts +229 -0
  213. package/vendor/agent-root/src/agent/tool/skill/parser.ts +124 -0
  214. package/vendor/agent-root/src/agent/tool/skill/types.ts +27 -0
  215. package/vendor/agent-root/src/agent/tool/skill-tool.ts +143 -0
  216. package/vendor/agent-root/src/agent/tool/task-create.ts +186 -0
  217. package/vendor/agent-root/src/agent/tool/task-errors.ts +42 -0
  218. package/vendor/agent-root/src/agent/tool/task-get.ts +116 -0
  219. package/vendor/agent-root/src/agent/tool/task-graph.ts +78 -0
  220. package/vendor/agent-root/src/agent/tool/task-list.ts +141 -0
  221. package/vendor/agent-root/src/agent/tool/task-mock-runner-adapter.ts +232 -0
  222. package/vendor/agent-root/src/agent/tool/task-output.ts +223 -0
  223. package/vendor/agent-root/src/agent/tool/task-parent-abort.ts +115 -0
  224. package/vendor/agent-root/src/agent/tool/task-real-runner-adapter.ts +336 -0
  225. package/vendor/agent-root/src/agent/tool/task-runner-adapter.ts +55 -0
  226. package/vendor/agent-root/src/agent/tool/task-stop.ts +187 -0
  227. package/vendor/agent-root/src/agent/tool/task-store.ts +217 -0
  228. package/vendor/agent-root/src/agent/tool/task-subagent-config.ts +149 -0
  229. package/vendor/agent-root/src/agent/tool/task-types.ts +264 -0
  230. package/vendor/agent-root/src/agent/tool/task-update.ts +315 -0
  231. package/vendor/agent-root/src/agent/tool/task.ts +209 -0
  232. package/vendor/agent-root/src/agent/tool/tool-manager.ts +362 -0
  233. package/vendor/agent-root/src/agent/tool/tool-prompts.ts +242 -0
  234. package/vendor/agent-root/src/agent/tool/types.ts +116 -0
  235. package/vendor/agent-root/src/agent/tool/web-fetch.ts +227 -0
  236. package/vendor/agent-root/src/agent/tool/web-search.ts +208 -0
  237. package/vendor/agent-root/src/agent/tool/write-file.ts +497 -0
  238. package/vendor/agent-root/src/agent/types.ts +232 -0
  239. package/vendor/agent-root/src/agent/utils/__tests__/index.test.ts +18 -0
  240. package/vendor/agent-root/src/agent/utils/__tests__/message-utils.test.ts +610 -0
  241. package/vendor/agent-root/src/agent/utils/__tests__/message.test.ts +223 -0
  242. package/vendor/agent-root/src/agent/utils/__tests__/token.test.ts +42 -0
  243. package/vendor/agent-root/src/agent/utils/index.ts +16 -0
  244. package/vendor/agent-root/src/agent/utils/message.ts +171 -0
  245. package/vendor/agent-root/src/agent/utils/token.ts +28 -0
  246. package/vendor/agent-root/src/config/__tests__/load-config-to-env.test.ts +129 -0
  247. package/vendor/agent-root/src/config/__tests__/loader.test.ts +247 -0
  248. package/vendor/agent-root/src/config/__tests__/runtime.test.ts +88 -0
  249. package/vendor/agent-root/src/config/index.ts +54 -0
  250. package/vendor/agent-root/src/config/loader.ts +431 -0
  251. package/vendor/agent-root/src/config/paths.ts +30 -0
  252. package/vendor/agent-root/src/config/runtime.ts +163 -0
  253. package/vendor/agent-root/src/config/types.ts +70 -0
  254. package/vendor/agent-root/src/logger/index.ts +57 -0
  255. package/vendor/agent-root/src/logger/logger.ts +819 -0
  256. package/vendor/agent-root/src/logger/types.ts +150 -0
  257. package/vendor/agent-root/src/providers/__tests__/errors.test.ts +441 -0
  258. package/vendor/agent-root/src/providers/__tests__/index.test.ts +16 -0
  259. package/vendor/agent-root/src/providers/__tests__/openai-compatible.options.test.ts +318 -0
  260. package/vendor/agent-root/src/providers/__tests__/openai-compatible.test.ts +600 -0
  261. package/vendor/agent-root/src/providers/__tests__/registry.test.ts +449 -0
  262. package/vendor/agent-root/src/providers/__tests__/responses-adapter.test.ts +298 -0
  263. package/vendor/agent-root/src/providers/adapters/__tests__/anthropic.test.ts +354 -0
  264. package/vendor/agent-root/src/providers/adapters/__tests__/kimi.test.ts +58 -0
  265. package/vendor/agent-root/src/providers/adapters/__tests__/standard.test.ts +261 -0
  266. package/vendor/agent-root/src/providers/adapters/anthropic.ts +572 -0
  267. package/vendor/agent-root/src/providers/adapters/base.ts +131 -0
  268. package/vendor/agent-root/src/providers/adapters/kimi.ts +48 -0
  269. package/vendor/agent-root/src/providers/adapters/responses.ts +732 -0
  270. package/vendor/agent-root/src/providers/adapters/standard.ts +120 -0
  271. package/vendor/agent-root/src/providers/http/__tests__/client.timeout.test.ts +313 -0
  272. package/vendor/agent-root/src/providers/http/client.ts +289 -0
  273. package/vendor/agent-root/src/providers/http/stream-parser.ts +109 -0
  274. package/vendor/agent-root/src/providers/index.ts +76 -0
  275. package/vendor/agent-root/src/providers/kimi-headers.ts +177 -0
  276. package/vendor/agent-root/src/providers/openai-compatible.ts +387 -0
  277. package/vendor/agent-root/src/providers/registry/model-config.ts +230 -0
  278. package/vendor/agent-root/src/providers/registry/provider-factory.ts +123 -0
  279. package/vendor/agent-root/src/providers/registry.ts +135 -0
  280. package/vendor/agent-root/src/providers/types/api.ts +284 -0
  281. package/vendor/agent-root/src/providers/types/config.ts +58 -0
  282. package/vendor/agent-root/src/providers/types/errors.ts +323 -0
  283. package/vendor/agent-root/src/providers/types/index.ts +72 -0
  284. package/vendor/agent-root/src/providers/types/provider.ts +45 -0
  285. package/vendor/agent-root/src/providers/types/registry.ts +88 -0
  286. package/LICENSE +0 -21
  287. package/dist/App.d.ts +0 -2
  288. package/dist/App.d.ts.map +0 -1
  289. package/dist/App.js +0 -170
  290. package/dist/App.js.map +0 -1
  291. package/dist/agent/prompts/system.d.ts +0 -24
  292. package/dist/agent/prompts/system.d.ts.map +0 -1
  293. package/dist/agent/prompts/system.js.map +0 -1
  294. package/dist/agent/runtime/event-format.d.ts +0 -17
  295. package/dist/agent/runtime/event-format.d.ts.map +0 -1
  296. package/dist/agent/runtime/event-format.js +0 -194
  297. package/dist/agent/runtime/event-format.js.map +0 -1
  298. package/dist/agent/runtime/model-types.d.ts +0 -13
  299. package/dist/agent/runtime/model-types.d.ts.map +0 -1
  300. package/dist/agent/runtime/model-types.js +0 -1
  301. package/dist/agent/runtime/model-types.js.map +0 -1
  302. package/dist/agent/runtime/runtime.d.ts +0 -16
  303. package/dist/agent/runtime/runtime.d.ts.map +0 -1
  304. package/dist/agent/runtime/runtime.js +0 -691
  305. package/dist/agent/runtime/runtime.js.map +0 -1
  306. package/dist/agent/runtime/source-modules.d.ts +0 -176
  307. package/dist/agent/runtime/source-modules.d.ts.map +0 -1
  308. package/dist/agent/runtime/source-modules.js +0 -110
  309. package/dist/agent/runtime/source-modules.js.map +0 -1
  310. package/dist/agent/runtime/tool-call-buffer.d.ts +0 -12
  311. package/dist/agent/runtime/tool-call-buffer.d.ts.map +0 -1
  312. package/dist/agent/runtime/tool-call-buffer.js +0 -48
  313. package/dist/agent/runtime/tool-call-buffer.js.map +0 -1
  314. package/dist/agent/runtime/tool-confirmation.d.ts +0 -3
  315. package/dist/agent/runtime/tool-confirmation.d.ts.map +0 -1
  316. package/dist/agent/runtime/tool-confirmation.js +0 -9
  317. package/dist/agent/runtime/tool-confirmation.js.map +0 -1
  318. package/dist/agent/runtime/types.d.ts +0 -86
  319. package/dist/agent/runtime/types.d.ts.map +0 -1
  320. package/dist/agent/runtime/types.js +0 -1
  321. package/dist/agent/runtime/types.js.map +0 -1
  322. package/dist/cli.d.ts +0 -3
  323. package/dist/cli.d.ts.map +0 -1
  324. package/dist/cli.js +0 -12
  325. package/dist/cli.js.map +0 -1
  326. package/dist/commands/slash-commands.d.ts +0 -11
  327. package/dist/commands/slash-commands.d.ts.map +0 -1
  328. package/dist/commands/slash-commands.js +0 -48
  329. package/dist/commands/slash-commands.js.map +0 -1
  330. package/dist/components/chat/assistant-reply.d.ts +0 -13
  331. package/dist/components/chat/assistant-reply.d.ts.map +0 -1
  332. package/dist/components/chat/assistant-reply.js +0 -78
  333. package/dist/components/chat/assistant-reply.js.map +0 -1
  334. package/dist/components/chat/assistant-segment.d.ts +0 -8
  335. package/dist/components/chat/assistant-segment.d.ts.map +0 -1
  336. package/dist/components/chat/assistant-segment.js +0 -54
  337. package/dist/components/chat/assistant-segment.js.map +0 -1
  338. package/dist/components/chat/assistant-tool-group.d.ts +0 -7
  339. package/dist/components/chat/assistant-tool-group.d.ts.map +0 -1
  340. package/dist/components/chat/assistant-tool-group.js +0 -695
  341. package/dist/components/chat/assistant-tool-group.js.map +0 -1
  342. package/dist/components/chat/code-block.d.ts +0 -16
  343. package/dist/components/chat/code-block.d.ts.map +0 -1
  344. package/dist/components/chat/code-block.js +0 -194
  345. package/dist/components/chat/code-block.js.map +0 -1
  346. package/dist/components/chat/prompt-card.d.ts +0 -9
  347. package/dist/components/chat/prompt-card.d.ts.map +0 -1
  348. package/dist/components/chat/prompt-card.js +0 -18
  349. package/dist/components/chat/prompt-card.js.map +0 -1
  350. package/dist/components/chat/segment-groups.d.ts +0 -24
  351. package/dist/components/chat/segment-groups.d.ts.map +0 -1
  352. package/dist/components/chat/segment-groups.js +0 -69
  353. package/dist/components/chat/segment-groups.js.map +0 -1
  354. package/dist/components/chat/turn-item.d.ts +0 -9
  355. package/dist/components/chat/turn-item.d.ts.map +0 -1
  356. package/dist/components/chat/turn-item.js +0 -11
  357. package/dist/components/chat/turn-item.js.map +0 -1
  358. package/dist/components/conversation-panel.d.ts +0 -8
  359. package/dist/components/conversation-panel.d.ts.map +0 -1
  360. package/dist/components/conversation-panel.js +0 -8
  361. package/dist/components/conversation-panel.js.map +0 -1
  362. package/dist/components/file-mention-menu.d.ts +0 -11
  363. package/dist/components/file-mention-menu.d.ts.map +0 -1
  364. package/dist/components/file-mention-menu.js +0 -15
  365. package/dist/components/file-mention-menu.js.map +0 -1
  366. package/dist/components/file-picker-dialog.d.ts +0 -21
  367. package/dist/components/file-picker-dialog.d.ts.map +0 -1
  368. package/dist/components/file-picker-dialog.js +0 -48
  369. package/dist/components/file-picker-dialog.js.map +0 -1
  370. package/dist/components/footer-hints.d.ts +0 -7
  371. package/dist/components/footer-hints.d.ts.map +0 -1
  372. package/dist/components/footer-hints.js +0 -29
  373. package/dist/components/footer-hints.js.map +0 -1
  374. package/dist/components/model-picker-dialog.d.ts +0 -20
  375. package/dist/components/model-picker-dialog.d.ts.map +0 -1
  376. package/dist/components/model-picker-dialog.js +0 -72
  377. package/dist/components/model-picker-dialog.js.map +0 -1
  378. package/dist/components/prompt.d.ts +0 -18
  379. package/dist/components/prompt.d.ts.map +0 -1
  380. package/dist/components/prompt.js +0 -96
  381. package/dist/components/prompt.js.map +0 -1
  382. package/dist/components/slash-command-menu.d.ts +0 -9
  383. package/dist/components/slash-command-menu.d.ts.map +0 -1
  384. package/dist/components/slash-command-menu.js +0 -20
  385. package/dist/components/slash-command-menu.js.map +0 -1
  386. package/dist/components/tool-confirm-dialog-content.d.ts +0 -15
  387. package/dist/components/tool-confirm-dialog-content.d.ts.map +0 -1
  388. package/dist/components/tool-confirm-dialog-content.js +0 -143
  389. package/dist/components/tool-confirm-dialog-content.js.map +0 -1
  390. package/dist/components/tool-confirm-dialog.d.ts +0 -12
  391. package/dist/components/tool-confirm-dialog.d.ts.map +0 -1
  392. package/dist/components/tool-confirm-dialog.js +0 -21
  393. package/dist/components/tool-confirm-dialog.js.map +0 -1
  394. package/dist/components/tool-display-config.d.ts +0 -11
  395. package/dist/components/tool-display-config.d.ts.map +0 -1
  396. package/dist/components/tool-display-config.js +0 -94
  397. package/dist/components/tool-display-config.js.map +0 -1
  398. package/dist/config/paths.d.ts +0 -7
  399. package/dist/config/paths.d.ts.map +0 -1
  400. package/dist/config/paths.js +0 -24
  401. package/dist/config/paths.js.map +0 -1
  402. package/dist/files/attachment-capabilities.d.ts +0 -19
  403. package/dist/files/attachment-capabilities.d.ts.map +0 -1
  404. package/dist/files/attachment-capabilities.js +0 -26
  405. package/dist/files/attachment-capabilities.js.map +0 -1
  406. package/dist/files/attachment-content.d.ts +0 -5
  407. package/dist/files/attachment-content.d.ts.map +0 -1
  408. package/dist/files/attachment-content.js +0 -117
  409. package/dist/files/attachment-content.js.map +0 -1
  410. package/dist/files/file-mention-query.d.ts +0 -9
  411. package/dist/files/file-mention-query.d.ts.map +0 -1
  412. package/dist/files/file-mention-query.js +0 -23
  413. package/dist/files/file-mention-query.js.map +0 -1
  414. package/dist/files/prompt-display.d.ts +0 -3
  415. package/dist/files/prompt-display.d.ts.map +0 -1
  416. package/dist/files/prompt-display.js +0 -11
  417. package/dist/files/prompt-display.js.map +0 -1
  418. package/dist/files/types.d.ts +0 -6
  419. package/dist/files/types.d.ts.map +0 -1
  420. package/dist/files/types.js +0 -1
  421. package/dist/files/types.js.map +0 -1
  422. package/dist/files/workspace-files.d.ts +0 -3
  423. package/dist/files/workspace-files.d.ts.map +0 -1
  424. package/dist/files/workspace-files.js +0 -48
  425. package/dist/files/workspace-files.js.map +0 -1
  426. package/dist/hooks/agent-event-handlers.d.ts +0 -11
  427. package/dist/hooks/agent-event-handlers.d.ts.map +0 -1
  428. package/dist/hooks/agent-event-handlers.js +0 -137
  429. package/dist/hooks/agent-event-handlers.js.map +0 -1
  430. package/dist/hooks/chat-local-replies.d.ts +0 -9
  431. package/dist/hooks/chat-local-replies.d.ts.map +0 -1
  432. package/dist/hooks/chat-local-replies.js +0 -54
  433. package/dist/hooks/chat-local-replies.js.map +0 -1
  434. package/dist/hooks/turn-updater.d.ts +0 -9
  435. package/dist/hooks/turn-updater.d.ts.map +0 -1
  436. package/dist/hooks/turn-updater.js +0 -103
  437. package/dist/hooks/turn-updater.js.map +0 -1
  438. package/dist/hooks/use-agent-chat.d.ts +0 -29
  439. package/dist/hooks/use-agent-chat.d.ts.map +0 -1
  440. package/dist/hooks/use-agent-chat.js +0 -455
  441. package/dist/hooks/use-agent-chat.js.map +0 -1
  442. package/dist/hooks/use-file-mention-menu.d.ts +0 -22
  443. package/dist/hooks/use-file-mention-menu.d.ts.map +0 -1
  444. package/dist/hooks/use-file-mention-menu.js +0 -137
  445. package/dist/hooks/use-file-mention-menu.js.map +0 -1
  446. package/dist/hooks/use-file-picker.d.ts +0 -21
  447. package/dist/hooks/use-file-picker.d.ts.map +0 -1
  448. package/dist/hooks/use-file-picker.js +0 -145
  449. package/dist/hooks/use-file-picker.js.map +0 -1
  450. package/dist/hooks/use-model-picker.d.ts +0 -23
  451. package/dist/hooks/use-model-picker.d.ts.map +0 -1
  452. package/dist/hooks/use-model-picker.js +0 -151
  453. package/dist/hooks/use-model-picker.js.map +0 -1
  454. package/dist/hooks/use-slash-command-menu.d.ts +0 -19
  455. package/dist/hooks/use-slash-command-menu.d.ts.map +0 -1
  456. package/dist/hooks/use-slash-command-menu.js +0 -101
  457. package/dist/hooks/use-slash-command-menu.js.map +0 -1
  458. package/dist/index.d.ts +0 -2
  459. package/dist/index.d.ts.map +0 -1
  460. package/dist/index.js +0 -6
  461. package/dist/index.js.map +0 -1
  462. package/dist/run-cli-app.d.ts +0 -2
  463. package/dist/run-cli-app.d.ts.map +0 -1
  464. package/dist/run-cli-app.js +0 -41
  465. package/dist/run-cli-app.js.map +0 -1
  466. package/dist/runtime/clipboard.d.ts +0 -10
  467. package/dist/runtime/clipboard.d.ts.map +0 -1
  468. package/dist/runtime/clipboard.js +0 -64
  469. package/dist/runtime/clipboard.js.map +0 -1
  470. package/dist/runtime/exit.d.ts +0 -7
  471. package/dist/runtime/exit.d.ts.map +0 -1
  472. package/dist/runtime/exit.js +0 -85
  473. package/dist/runtime/exit.js.map +0 -1
  474. package/dist/runtime/runtime-support.d.ts +0 -4
  475. package/dist/runtime/runtime-support.d.ts.map +0 -1
  476. package/dist/runtime/runtime-support.js +0 -19
  477. package/dist/runtime/runtime-support.js.map +0 -1
  478. package/dist/runtime/terminal-theme.d.ts +0 -25
  479. package/dist/runtime/terminal-theme.d.ts.map +0 -1
  480. package/dist/runtime/terminal-theme.js +0 -148
  481. package/dist/runtime/terminal-theme.js.map +0 -1
  482. package/dist/types/chat.d.ts +0 -29
  483. package/dist/types/chat.d.ts.map +0 -1
  484. package/dist/types/chat.js +0 -1
  485. package/dist/types/chat.js.map +0 -1
  486. package/dist/types/message-content.d.ts +0 -38
  487. package/dist/types/message-content.d.ts.map +0 -1
  488. package/dist/types/message-content.js +0 -1
  489. package/dist/types/message-content.js.map +0 -1
  490. package/dist/ui/open-code-theme.d.ts +0 -58
  491. package/dist/ui/open-code-theme.d.ts.map +0 -1
  492. package/dist/ui/open-code-theme.js +0 -113
  493. package/dist/ui/open-code-theme.js.map +0 -1
  494. package/dist/ui/opencode-markdown.d.ts +0 -7
  495. package/dist/ui/opencode-markdown.d.ts.map +0 -1
  496. package/dist/ui/opencode-markdown.js +0 -169
  497. package/dist/ui/opencode-markdown.js.map +0 -1
  498. package/dist/ui/theme.d.ts +0 -68
  499. package/dist/ui/theme.d.ts.map +0 -1
  500. package/dist/ui/theme.js +0 -80
  501. package/dist/ui/theme.js.map +0 -1
  502. package/dist/utils/time.d.ts +0 -2
  503. package/dist/utils/time.d.ts.map +0 -1
  504. package/dist/utils/time.js +0 -7
  505. package/dist/utils/time.js.map +0 -1
@@ -0,0 +1,1182 @@
1
+ import type { Message } from '../types';
2
+ import type {
3
+ CliEventEnvelope,
4
+ CompactionDroppedMessageRecord,
5
+ ListConversationEventsOptions,
6
+ ListRunLogsOptions,
7
+ ListRunsOptions,
8
+ ListRunsResult,
9
+ RunRecord,
10
+ RunLogRecord,
11
+ } from './contracts';
12
+ import type {
13
+ ContextProjectionStorePort,
14
+ EventStorePort,
15
+ ExecutionStorePort,
16
+ MessageProjectionStorePort,
17
+ RunLogStorePort,
18
+ } from './ports';
19
+ import { AgentAppSqliteClient } from './sqlite-client';
20
+
21
+ interface RunRow {
22
+ execution_id: string;
23
+ run_id: string;
24
+ conversation_id: string;
25
+ status: RunRecord['status'];
26
+ created_at_ms: number;
27
+ updated_at_ms: number;
28
+ step_index: number;
29
+ started_at_ms: number | null;
30
+ completed_at_ms: number | null;
31
+ last_checkpoint_seq: number | null;
32
+ terminal_reason: RunRecord['terminalReason'] | null;
33
+ error_code: string | null;
34
+ error_category: string | null;
35
+ error_message: string | null;
36
+ }
37
+
38
+ interface EventRow {
39
+ conversation_id: string;
40
+ execution_id: string;
41
+ seq: number;
42
+ event_type: CliEventEnvelope['eventType'];
43
+ payload_json: string;
44
+ created_at_ms: number;
45
+ }
46
+
47
+ interface MessageRow {
48
+ message_id: string;
49
+ execution_id?: string;
50
+ seq?: number;
51
+ role: Message['role'];
52
+ type: Message['type'];
53
+ content_json: string;
54
+ reasoning_content: string | null;
55
+ tool_call_id: string | null;
56
+ tool_calls_json: string | null;
57
+ usage_json: string | null;
58
+ metadata_json: string | null;
59
+ created_at_ms: number;
60
+ }
61
+
62
+ interface CursorToken {
63
+ updatedAt: number;
64
+ executionId: string;
65
+ }
66
+
67
+ interface MessageEventPayload {
68
+ message: Message;
69
+ stepIndex?: number;
70
+ }
71
+
72
+ interface CompactionDroppedMessageRow {
73
+ conversation_id: string;
74
+ execution_id: string;
75
+ step_index: number;
76
+ removed_message_id: string;
77
+ created_at_ms: number;
78
+ }
79
+
80
+ interface RunLogRow {
81
+ id: number;
82
+ execution_id: string;
83
+ conversation_id: string;
84
+ step_index: number | null;
85
+ level: 'debug' | 'info' | 'warn' | 'error';
86
+ code: string | null;
87
+ source: string;
88
+ message: string;
89
+ error_json: string | null;
90
+ context_json: string | null;
91
+ data_json: string | null;
92
+ created_at_ms: number;
93
+ }
94
+
95
+ const APP_MIGRATIONS = [
96
+ {
97
+ version: 1,
98
+ sql: `
99
+ CREATE TABLE IF NOT EXISTS agent_v4_schema_migrations (
100
+ version INTEGER PRIMARY KEY,
101
+ applied_at_ms INTEGER NOT NULL
102
+ );
103
+
104
+ CREATE TABLE IF NOT EXISTS runs (
105
+ execution_id TEXT PRIMARY KEY,
106
+ run_id TEXT NOT NULL,
107
+ conversation_id TEXT NOT NULL,
108
+ status TEXT NOT NULL,
109
+ created_at_ms INTEGER NOT NULL,
110
+ updated_at_ms INTEGER NOT NULL,
111
+ step_index INTEGER NOT NULL DEFAULT 0,
112
+ started_at_ms INTEGER,
113
+ completed_at_ms INTEGER,
114
+ last_checkpoint_seq INTEGER,
115
+ terminal_reason TEXT,
116
+ error_code TEXT,
117
+ error_category TEXT,
118
+ error_message TEXT
119
+ );
120
+ CREATE INDEX IF NOT EXISTS idx_runs_conversation_updated
121
+ ON runs(conversation_id, updated_at_ms DESC, execution_id DESC);
122
+
123
+ CREATE TABLE IF NOT EXISTS events (
124
+ event_id INTEGER PRIMARY KEY AUTOINCREMENT,
125
+ conversation_id TEXT NOT NULL,
126
+ execution_id TEXT NOT NULL,
127
+ seq INTEGER NOT NULL,
128
+ event_type TEXT NOT NULL,
129
+ payload_json TEXT NOT NULL,
130
+ created_at_ms INTEGER NOT NULL,
131
+ UNIQUE(conversation_id, seq)
132
+ );
133
+ CREATE INDEX IF NOT EXISTS idx_events_execution_seq
134
+ ON events(execution_id, seq ASC);
135
+ CREATE INDEX IF NOT EXISTS idx_events_conversation_seq
136
+ ON events(conversation_id, seq ASC);
137
+
138
+ CREATE TABLE IF NOT EXISTS messages (
139
+ message_id TEXT PRIMARY KEY,
140
+ conversation_id TEXT NOT NULL,
141
+ execution_id TEXT NOT NULL,
142
+ seq INTEGER NOT NULL,
143
+ step_index INTEGER,
144
+ role TEXT NOT NULL,
145
+ type TEXT NOT NULL,
146
+ content_json TEXT NOT NULL,
147
+ reasoning_content TEXT,
148
+ tool_call_id TEXT,
149
+ tool_calls_json TEXT,
150
+ usage_json TEXT,
151
+ metadata_json TEXT,
152
+ created_at_ms INTEGER NOT NULL
153
+ );
154
+ CREATE INDEX IF NOT EXISTS idx_messages_conversation_seq
155
+ ON messages(conversation_id, seq ASC);
156
+ CREATE INDEX IF NOT EXISTS idx_messages_execution_seq
157
+ ON messages(execution_id, seq ASC);
158
+ `,
159
+ },
160
+ {
161
+ version: 2,
162
+ sql: `
163
+ CREATE TABLE IF NOT EXISTS context_messages (
164
+ conversation_id TEXT NOT NULL,
165
+ execution_id TEXT NOT NULL,
166
+ message_id TEXT NOT NULL,
167
+ seq INTEGER NOT NULL,
168
+ step_index INTEGER,
169
+ role TEXT NOT NULL,
170
+ type TEXT NOT NULL,
171
+ content_json TEXT NOT NULL,
172
+ reasoning_content TEXT,
173
+ tool_call_id TEXT,
174
+ tool_calls_json TEXT,
175
+ usage_json TEXT,
176
+ metadata_json TEXT,
177
+ created_at_ms INTEGER NOT NULL,
178
+ PRIMARY KEY (conversation_id, message_id)
179
+ );
180
+ CREATE INDEX IF NOT EXISTS idx_context_messages_conversation_seq
181
+ ON context_messages(conversation_id, seq ASC);
182
+ CREATE INDEX IF NOT EXISTS idx_context_messages_execution_seq
183
+ ON context_messages(execution_id, seq ASC);
184
+
185
+ CREATE TABLE IF NOT EXISTS compaction_dropped_messages (
186
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
187
+ conversation_id TEXT NOT NULL,
188
+ execution_id TEXT NOT NULL,
189
+ step_index INTEGER NOT NULL,
190
+ removed_message_id TEXT NOT NULL,
191
+ created_at_ms INTEGER NOT NULL,
192
+ UNIQUE(execution_id, step_index, removed_message_id)
193
+ );
194
+ CREATE INDEX IF NOT EXISTS idx_compaction_dropped_execution_step
195
+ ON compaction_dropped_messages(execution_id, step_index ASC, id ASC);
196
+ CREATE INDEX IF NOT EXISTS idx_compaction_dropped_conversation
197
+ ON compaction_dropped_messages(conversation_id, id ASC);
198
+
199
+ INSERT OR IGNORE INTO context_messages (
200
+ conversation_id,
201
+ execution_id,
202
+ message_id,
203
+ seq,
204
+ step_index,
205
+ role,
206
+ type,
207
+ content_json,
208
+ reasoning_content,
209
+ tool_call_id,
210
+ tool_calls_json,
211
+ usage_json,
212
+ metadata_json,
213
+ created_at_ms
214
+ )
215
+ SELECT
216
+ conversation_id,
217
+ execution_id,
218
+ message_id,
219
+ seq,
220
+ step_index,
221
+ role,
222
+ type,
223
+ content_json,
224
+ reasoning_content,
225
+ tool_call_id,
226
+ tool_calls_json,
227
+ usage_json,
228
+ metadata_json,
229
+ created_at_ms
230
+ FROM messages;
231
+ `,
232
+ },
233
+ {
234
+ version: 3,
235
+ sql: `
236
+ CREATE TABLE IF NOT EXISTS run_logs (
237
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
238
+ execution_id TEXT NOT NULL,
239
+ conversation_id TEXT NOT NULL,
240
+ step_index INTEGER,
241
+ level TEXT NOT NULL CHECK(level IN ('debug', 'info', 'warn', 'error')),
242
+ code TEXT,
243
+ source TEXT NOT NULL,
244
+ message TEXT NOT NULL,
245
+ error_json TEXT,
246
+ context_json TEXT,
247
+ data_json TEXT,
248
+ created_at_ms INTEGER NOT NULL
249
+ );
250
+ CREATE INDEX IF NOT EXISTS idx_run_logs_execution_created
251
+ ON run_logs(execution_id, created_at_ms ASC, id ASC);
252
+ CREATE INDEX IF NOT EXISTS idx_run_logs_execution_level_created
253
+ ON run_logs(execution_id, level, created_at_ms ASC, id ASC);
254
+ `,
255
+ },
256
+ ];
257
+
258
+ export class SqliteAgentAppStore
259
+ implements
260
+ ExecutionStorePort,
261
+ EventStorePort,
262
+ MessageProjectionStorePort,
263
+ ContextProjectionStorePort,
264
+ RunLogStorePort
265
+ {
266
+ private readonly client: AgentAppSqliteClient;
267
+ private prepared = false;
268
+ private preparePromise: Promise<void> | null = null;
269
+ private mutationChain: Promise<void> = Promise.resolve();
270
+
271
+ constructor(private readonly dbPath: string) {
272
+ this.client = new AgentAppSqliteClient(dbPath);
273
+ }
274
+
275
+ async prepare(): Promise<void> {
276
+ if (this.prepared) {
277
+ return;
278
+ }
279
+ if (this.preparePromise) {
280
+ await this.preparePromise;
281
+ return;
282
+ }
283
+
284
+ this.preparePromise = (async () => {
285
+ await this.client.prepare();
286
+ await this.withMutationLock(async () => {
287
+ await runAppMigrations(this.client);
288
+ });
289
+ this.prepared = true;
290
+ })();
291
+
292
+ try {
293
+ await this.preparePromise;
294
+ } finally {
295
+ this.preparePromise = null;
296
+ }
297
+ }
298
+
299
+ async close(): Promise<void> {
300
+ await this.client.close();
301
+ this.prepared = false;
302
+ }
303
+
304
+ getDatabasePath(): string {
305
+ return this.dbPath;
306
+ }
307
+
308
+ async create(run: RunRecord): Promise<void> {
309
+ await this.prepare();
310
+ await this.withMutationLock(async () => {
311
+ await this.client.run(
312
+ `
313
+ INSERT INTO runs (
314
+ execution_id,
315
+ run_id,
316
+ conversation_id,
317
+ status,
318
+ created_at_ms,
319
+ updated_at_ms,
320
+ step_index,
321
+ started_at_ms,
322
+ completed_at_ms,
323
+ last_checkpoint_seq,
324
+ terminal_reason,
325
+ error_code,
326
+ error_category,
327
+ error_message
328
+ ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
329
+ `,
330
+ [
331
+ run.executionId,
332
+ run.runId,
333
+ run.conversationId,
334
+ run.status,
335
+ run.createdAt,
336
+ run.updatedAt,
337
+ run.stepIndex,
338
+ run.startedAt ?? null,
339
+ run.completedAt ?? null,
340
+ run.lastCheckpointSeq ?? null,
341
+ run.terminalReason ?? null,
342
+ run.errorCode ?? null,
343
+ run.errorCategory ?? null,
344
+ run.errorMessage ?? null,
345
+ ]
346
+ );
347
+ });
348
+ }
349
+
350
+ async patch(executionId: string, patch: Partial<RunRecord>): Promise<void> {
351
+ await this.prepare();
352
+ const updates: string[] = [];
353
+ const params: unknown[] = [];
354
+
355
+ if (typeof patch.runId === 'string') {
356
+ updates.push('run_id = ?');
357
+ params.push(patch.runId);
358
+ }
359
+ if (typeof patch.conversationId === 'string') {
360
+ updates.push('conversation_id = ?');
361
+ params.push(patch.conversationId);
362
+ }
363
+ if (typeof patch.status === 'string') {
364
+ updates.push('status = ?');
365
+ params.push(patch.status);
366
+ }
367
+ if (typeof patch.stepIndex === 'number') {
368
+ updates.push('step_index = ?');
369
+ params.push(patch.stepIndex);
370
+ }
371
+ if ('startedAt' in patch) {
372
+ updates.push('started_at_ms = ?');
373
+ params.push(patch.startedAt ?? null);
374
+ }
375
+ if ('completedAt' in patch) {
376
+ updates.push('completed_at_ms = ?');
377
+ params.push(patch.completedAt ?? null);
378
+ }
379
+ if ('lastCheckpointSeq' in patch) {
380
+ updates.push('last_checkpoint_seq = ?');
381
+ params.push(patch.lastCheckpointSeq ?? null);
382
+ }
383
+ if ('terminalReason' in patch) {
384
+ updates.push('terminal_reason = ?');
385
+ params.push(patch.terminalReason ?? null);
386
+ }
387
+ if ('errorCode' in patch) {
388
+ updates.push('error_code = ?');
389
+ params.push(patch.errorCode ?? null);
390
+ }
391
+ if ('errorCategory' in patch) {
392
+ updates.push('error_category = ?');
393
+ params.push(patch.errorCategory ?? null);
394
+ }
395
+ if ('errorMessage' in patch) {
396
+ updates.push('error_message = ?');
397
+ params.push(patch.errorMessage ?? null);
398
+ }
399
+
400
+ updates.push('updated_at_ms = ?');
401
+ params.push(typeof patch.updatedAt === 'number' ? patch.updatedAt : Date.now());
402
+ params.push(executionId);
403
+
404
+ await this.withMutationLock(async () => {
405
+ await this.client.run(`UPDATE runs SET ${updates.join(', ')} WHERE execution_id = ?`, params);
406
+ });
407
+ }
408
+
409
+ async get(executionId: string): Promise<RunRecord | null> {
410
+ await this.prepare();
411
+ const row = await this.client.get<RunRow>(
412
+ `
413
+ SELECT
414
+ execution_id,
415
+ run_id,
416
+ conversation_id,
417
+ status,
418
+ created_at_ms,
419
+ updated_at_ms,
420
+ step_index,
421
+ started_at_ms,
422
+ completed_at_ms,
423
+ last_checkpoint_seq,
424
+ terminal_reason,
425
+ error_code,
426
+ error_category,
427
+ error_message
428
+ FROM runs
429
+ WHERE execution_id = ?
430
+ `,
431
+ [executionId]
432
+ );
433
+
434
+ return row ? mapRunRow(row) : null;
435
+ }
436
+
437
+ async listByConversation(
438
+ conversationId: string,
439
+ opts: ListRunsOptions = {}
440
+ ): Promise<ListRunsResult> {
441
+ await this.prepare();
442
+ const limit = clampLimit(opts.limit);
443
+ const params: unknown[] = [conversationId];
444
+ const filters: string[] = ['conversation_id = ?'];
445
+
446
+ if (opts.statuses && opts.statuses.length > 0) {
447
+ const placeholders = opts.statuses.map(() => '?').join(', ');
448
+ filters.push(`status IN (${placeholders})`);
449
+ params.push(...opts.statuses);
450
+ }
451
+
452
+ const cursor = decodeCursor(opts.cursor);
453
+ if (cursor) {
454
+ filters.push('(updated_at_ms < ? OR (updated_at_ms = ? AND execution_id < ?))');
455
+ params.push(cursor.updatedAt, cursor.updatedAt, cursor.executionId);
456
+ }
457
+
458
+ params.push(limit + 1);
459
+
460
+ const rows = await this.client.all<RunRow>(
461
+ `
462
+ SELECT
463
+ execution_id,
464
+ run_id,
465
+ conversation_id,
466
+ status,
467
+ created_at_ms,
468
+ updated_at_ms,
469
+ step_index,
470
+ started_at_ms,
471
+ completed_at_ms,
472
+ last_checkpoint_seq,
473
+ terminal_reason,
474
+ error_code,
475
+ error_category,
476
+ error_message
477
+ FROM runs
478
+ WHERE ${filters.join(' AND ')}
479
+ ORDER BY updated_at_ms DESC, execution_id DESC
480
+ LIMIT ?
481
+ `,
482
+ params
483
+ );
484
+
485
+ const hasNext = rows.length > limit;
486
+ const selected = hasNext ? rows.slice(0, limit) : rows;
487
+ const items = selected.map(mapRunRow);
488
+ const tail = items[items.length - 1];
489
+
490
+ return {
491
+ items,
492
+ nextCursor: hasNext && tail ? encodeCursor(tail.updatedAt, tail.executionId) : undefined,
493
+ };
494
+ }
495
+
496
+ async appendAutoSeq(event: Omit<CliEventEnvelope, 'seq'>): Promise<CliEventEnvelope> {
497
+ await this.prepare();
498
+
499
+ return this.withMutationLock(async () => {
500
+ return this.client.transaction(async () => {
501
+ const row = await this.client.get<{ max_seq: number | null }>(
502
+ 'SELECT MAX(seq) AS max_seq FROM events WHERE conversation_id = ?',
503
+ [event.conversationId]
504
+ );
505
+ const seq = ((row?.max_seq ?? 0) as number) + 1;
506
+ const payloadJson = JSON.stringify(event.data ?? null);
507
+
508
+ await this.client.run(
509
+ `
510
+ INSERT INTO events (
511
+ conversation_id,
512
+ execution_id,
513
+ seq,
514
+ event_type,
515
+ payload_json,
516
+ created_at_ms
517
+ ) VALUES (?, ?, ?, ?, ?, ?)
518
+ `,
519
+ [
520
+ event.conversationId,
521
+ event.executionId,
522
+ seq,
523
+ event.eventType,
524
+ payloadJson,
525
+ event.createdAt,
526
+ ]
527
+ );
528
+
529
+ return {
530
+ ...event,
531
+ seq,
532
+ };
533
+ });
534
+ });
535
+ }
536
+
537
+ async append(event: CliEventEnvelope): Promise<void> {
538
+ await this.prepare();
539
+ await this.withMutationLock(async () => {
540
+ await this.client.run(
541
+ `
542
+ INSERT INTO events (
543
+ conversation_id,
544
+ execution_id,
545
+ seq,
546
+ event_type,
547
+ payload_json,
548
+ created_at_ms
549
+ ) VALUES (?, ?, ?, ?, ?, ?)
550
+ `,
551
+ [
552
+ event.conversationId,
553
+ event.executionId,
554
+ event.seq,
555
+ event.eventType,
556
+ JSON.stringify(event.data ?? null),
557
+ event.createdAt,
558
+ ]
559
+ );
560
+ });
561
+ }
562
+
563
+ async listByRun(executionId: string): Promise<CliEventEnvelope[]> {
564
+ await this.prepare();
565
+ const rows = await this.client.all<EventRow>(
566
+ `
567
+ SELECT
568
+ conversation_id,
569
+ execution_id,
570
+ seq,
571
+ event_type,
572
+ payload_json,
573
+ created_at_ms
574
+ FROM events
575
+ WHERE execution_id = ?
576
+ ORDER BY seq ASC
577
+ `,
578
+ [executionId]
579
+ );
580
+ return rows.map(mapEventRow);
581
+ }
582
+
583
+ async listEventsByConversation(
584
+ conversationId: string,
585
+ opts: ListConversationEventsOptions = {}
586
+ ): Promise<CliEventEnvelope[]> {
587
+ await this.prepare();
588
+ const filters = ['conversation_id = ?'];
589
+ const params: unknown[] = [conversationId];
590
+
591
+ if (typeof opts.fromSeq === 'number' && opts.fromSeq > 0) {
592
+ filters.push('seq >= ?');
593
+ params.push(opts.fromSeq);
594
+ }
595
+
596
+ if (typeof opts.limit === 'number' && opts.limit > 0) {
597
+ params.push(opts.limit);
598
+ const rows = await this.client.all<EventRow>(
599
+ `
600
+ SELECT
601
+ conversation_id,
602
+ execution_id,
603
+ seq,
604
+ event_type,
605
+ payload_json,
606
+ created_at_ms
607
+ FROM events
608
+ WHERE ${filters.join(' AND ')}
609
+ ORDER BY seq ASC
610
+ LIMIT ?
611
+ `,
612
+ params
613
+ );
614
+ return rows.map(mapEventRow);
615
+ }
616
+
617
+ const rows = await this.client.all<EventRow>(
618
+ `
619
+ SELECT
620
+ conversation_id,
621
+ execution_id,
622
+ seq,
623
+ event_type,
624
+ payload_json,
625
+ created_at_ms
626
+ FROM events
627
+ WHERE ${filters.join(' AND ')}
628
+ ORDER BY seq ASC
629
+ `,
630
+ params
631
+ );
632
+ return rows.map(mapEventRow);
633
+ }
634
+
635
+ async upsertFromEvent(event: CliEventEnvelope): Promise<void> {
636
+ await this.prepare();
637
+ const payload = extractMessagePayload(event);
638
+ if (!payload) {
639
+ return;
640
+ }
641
+
642
+ const { message, stepIndex } = payload;
643
+ await this.withMutationLock(async () => {
644
+ await this.client.transaction(async () => {
645
+ await upsertMessageIntoHistory(this.client, event, message, stepIndex);
646
+ await upsertMessageIntoContext(this.client, event, message, stepIndex);
647
+ });
648
+ });
649
+ }
650
+
651
+ async list(conversationId: string): Promise<Message[]> {
652
+ await this.prepare();
653
+ const rows = await this.client.all<MessageRow>(
654
+ `
655
+ SELECT
656
+ message_id,
657
+ role,
658
+ type,
659
+ content_json,
660
+ reasoning_content,
661
+ tool_call_id,
662
+ tool_calls_json,
663
+ usage_json,
664
+ metadata_json,
665
+ created_at_ms
666
+ FROM messages
667
+ WHERE conversation_id = ?
668
+ ORDER BY seq ASC
669
+ `,
670
+ [conversationId]
671
+ );
672
+
673
+ return rows.map((row) => mapMessageRow(row));
674
+ }
675
+
676
+ async listContext(conversationId: string): Promise<Message[]> {
677
+ await this.prepare();
678
+ const rows = await this.client.all<MessageRow>(
679
+ `
680
+ SELECT
681
+ message_id,
682
+ role,
683
+ type,
684
+ content_json,
685
+ reasoning_content,
686
+ tool_call_id,
687
+ tool_calls_json,
688
+ usage_json,
689
+ metadata_json,
690
+ created_at_ms
691
+ FROM context_messages
692
+ WHERE conversation_id = ?
693
+ ORDER BY seq ASC
694
+ `,
695
+ [conversationId]
696
+ );
697
+
698
+ return rows.map((row) => mapMessageRow(row));
699
+ }
700
+
701
+ async applyCompaction(input: {
702
+ conversationId: string;
703
+ executionId: string;
704
+ stepIndex: number;
705
+ removedMessageIds: string[];
706
+ createdAt: number;
707
+ }): Promise<void> {
708
+ await this.prepare();
709
+ const deduplicated = Array.from(
710
+ new Set(input.removedMessageIds.filter((messageId) => messageId.trim().length > 0))
711
+ );
712
+ if (deduplicated.length === 0) {
713
+ return;
714
+ }
715
+
716
+ await this.withMutationLock(async () => {
717
+ await this.client.transaction(async () => {
718
+ for (const removedMessageId of deduplicated) {
719
+ await this.client.run(
720
+ `
721
+ INSERT OR IGNORE INTO compaction_dropped_messages (
722
+ conversation_id,
723
+ execution_id,
724
+ step_index,
725
+ removed_message_id,
726
+ created_at_ms
727
+ ) VALUES (?, ?, ?, ?, ?)
728
+ `,
729
+ [
730
+ input.conversationId,
731
+ input.executionId,
732
+ input.stepIndex,
733
+ removedMessageId,
734
+ input.createdAt,
735
+ ]
736
+ );
737
+ }
738
+
739
+ for (const idsChunk of chunkStrings(deduplicated, 200)) {
740
+ const placeholders = idsChunk.map(() => '?').join(', ');
741
+ await this.client.run(
742
+ `
743
+ DELETE FROM context_messages
744
+ WHERE conversation_id = ?
745
+ AND message_id IN (${placeholders})
746
+ `,
747
+ [input.conversationId, ...idsChunk]
748
+ );
749
+ }
750
+ });
751
+ });
752
+ }
753
+
754
+ async listDroppedMessages(
755
+ executionId: string,
756
+ opts: { stepIndex?: number; limit?: number } = {}
757
+ ): Promise<CompactionDroppedMessageRecord[]> {
758
+ await this.prepare();
759
+ const filters = ['execution_id = ?'];
760
+ const params: unknown[] = [executionId];
761
+
762
+ if (typeof opts.stepIndex === 'number' && Number.isFinite(opts.stepIndex)) {
763
+ filters.push('step_index = ?');
764
+ params.push(Math.floor(opts.stepIndex));
765
+ }
766
+
767
+ const effectiveLimit =
768
+ typeof opts.limit === 'number' && Number.isFinite(opts.limit) && opts.limit > 0
769
+ ? Math.floor(opts.limit)
770
+ : 1000;
771
+ params.push(effectiveLimit);
772
+
773
+ const rows = await this.client.all<CompactionDroppedMessageRow>(
774
+ `
775
+ SELECT
776
+ conversation_id,
777
+ execution_id,
778
+ step_index,
779
+ removed_message_id,
780
+ created_at_ms
781
+ FROM compaction_dropped_messages
782
+ WHERE ${filters.join(' AND ')}
783
+ ORDER BY step_index ASC, id ASC
784
+ LIMIT ?
785
+ `,
786
+ params
787
+ );
788
+
789
+ return rows.map((row) => ({
790
+ conversationId: row.conversation_id,
791
+ executionId: row.execution_id,
792
+ stepIndex: row.step_index,
793
+ removedMessageId: row.removed_message_id,
794
+ createdAt: row.created_at_ms,
795
+ }));
796
+ }
797
+
798
+ async appendRunLog(record: RunLogRecord): Promise<void> {
799
+ await this.prepare();
800
+ await this.withMutationLock(async () => {
801
+ await this.client.run(
802
+ `
803
+ INSERT INTO run_logs (
804
+ execution_id,
805
+ conversation_id,
806
+ step_index,
807
+ level,
808
+ code,
809
+ source,
810
+ message,
811
+ error_json,
812
+ context_json,
813
+ data_json,
814
+ created_at_ms
815
+ ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
816
+ `,
817
+ [
818
+ record.executionId,
819
+ record.conversationId,
820
+ record.stepIndex ?? null,
821
+ record.level,
822
+ record.code ?? null,
823
+ record.source,
824
+ record.message,
825
+ record.error ? JSON.stringify(record.error) : null,
826
+ record.context ? JSON.stringify(record.context) : null,
827
+ record.data !== undefined ? JSON.stringify(record.data) : null,
828
+ record.createdAt,
829
+ ]
830
+ );
831
+ });
832
+ }
833
+
834
+ async listRunLogs(executionId: string, opts: ListRunLogsOptions = {}): Promise<RunLogRecord[]> {
835
+ await this.prepare();
836
+ const filters = ['execution_id = ?'];
837
+ const params: unknown[] = [executionId];
838
+
839
+ if (opts.level) {
840
+ filters.push('level = ?');
841
+ params.push(opts.level);
842
+ }
843
+
844
+ params.push(clampLimit(opts.limit));
845
+
846
+ const rows = await this.client.all<RunLogRow>(
847
+ `
848
+ SELECT
849
+ id,
850
+ execution_id,
851
+ conversation_id,
852
+ step_index,
853
+ level,
854
+ code,
855
+ source,
856
+ message,
857
+ error_json,
858
+ context_json,
859
+ data_json,
860
+ created_at_ms
861
+ FROM run_logs
862
+ WHERE ${filters.join(' AND ')}
863
+ ORDER BY created_at_ms ASC, id ASC
864
+ LIMIT ?
865
+ `,
866
+ params
867
+ );
868
+
869
+ return rows.map(mapRunLogRow);
870
+ }
871
+
872
+ private async withMutationLock<T>(operation: () => Promise<T>): Promise<T> {
873
+ const previous = this.mutationChain;
874
+ let release: () => void = () => undefined;
875
+ this.mutationChain = new Promise<void>((resolve) => {
876
+ release = resolve;
877
+ });
878
+ await previous;
879
+ try {
880
+ return await operation();
881
+ } finally {
882
+ release();
883
+ }
884
+ }
885
+ }
886
+
887
+ export function createSqliteAgentAppStore(dbPath: string): SqliteAgentAppStore {
888
+ return new SqliteAgentAppStore(dbPath);
889
+ }
890
+
891
+ async function upsertMessageIntoHistory(
892
+ client: AgentAppSqliteClient,
893
+ event: CliEventEnvelope,
894
+ message: Message,
895
+ stepIndex?: number
896
+ ): Promise<void> {
897
+ const serialized = serializeMessage(event, message, stepIndex);
898
+ await client.run(
899
+ `
900
+ INSERT INTO messages (
901
+ message_id,
902
+ conversation_id,
903
+ execution_id,
904
+ seq,
905
+ step_index,
906
+ role,
907
+ type,
908
+ content_json,
909
+ reasoning_content,
910
+ tool_call_id,
911
+ tool_calls_json,
912
+ usage_json,
913
+ metadata_json,
914
+ created_at_ms
915
+ ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
916
+ ON CONFLICT(message_id) DO UPDATE SET
917
+ conversation_id = excluded.conversation_id,
918
+ execution_id = excluded.execution_id,
919
+ seq = excluded.seq,
920
+ step_index = excluded.step_index,
921
+ role = excluded.role,
922
+ type = excluded.type,
923
+ content_json = excluded.content_json,
924
+ reasoning_content = excluded.reasoning_content,
925
+ tool_call_id = excluded.tool_call_id,
926
+ tool_calls_json = excluded.tool_calls_json,
927
+ usage_json = excluded.usage_json,
928
+ metadata_json = excluded.metadata_json,
929
+ created_at_ms = excluded.created_at_ms
930
+ `,
931
+ serialized
932
+ );
933
+ }
934
+
935
+ async function upsertMessageIntoContext(
936
+ client: AgentAppSqliteClient,
937
+ event: CliEventEnvelope,
938
+ message: Message,
939
+ stepIndex?: number
940
+ ): Promise<void> {
941
+ const serialized = serializeMessage(event, message, stepIndex);
942
+ await client.run(
943
+ `
944
+ INSERT INTO context_messages (
945
+ message_id,
946
+ conversation_id,
947
+ execution_id,
948
+ seq,
949
+ step_index,
950
+ role,
951
+ type,
952
+ content_json,
953
+ reasoning_content,
954
+ tool_call_id,
955
+ tool_calls_json,
956
+ usage_json,
957
+ metadata_json,
958
+ created_at_ms
959
+ ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
960
+ ON CONFLICT(conversation_id, message_id) DO UPDATE SET
961
+ execution_id = excluded.execution_id,
962
+ seq = excluded.seq,
963
+ step_index = excluded.step_index,
964
+ role = excluded.role,
965
+ type = excluded.type,
966
+ content_json = excluded.content_json,
967
+ reasoning_content = excluded.reasoning_content,
968
+ tool_call_id = excluded.tool_call_id,
969
+ tool_calls_json = excluded.tool_calls_json,
970
+ usage_json = excluded.usage_json,
971
+ metadata_json = excluded.metadata_json,
972
+ created_at_ms = excluded.created_at_ms
973
+ `,
974
+ serialized
975
+ );
976
+ }
977
+
978
+ function serializeMessage(
979
+ event: CliEventEnvelope,
980
+ message: Message,
981
+ stepIndex?: number
982
+ ): unknown[] {
983
+ return [
984
+ message.messageId,
985
+ event.conversationId,
986
+ event.executionId,
987
+ event.seq,
988
+ stepIndex ?? null,
989
+ message.role,
990
+ message.type,
991
+ JSON.stringify(message.content ?? null),
992
+ message.reasoning_content ?? null,
993
+ message.tool_call_id ?? null,
994
+ message.tool_calls ? JSON.stringify(message.tool_calls) : null,
995
+ message.usage ? JSON.stringify(message.usage) : null,
996
+ message.metadata ? JSON.stringify(message.metadata) : null,
997
+ message.timestamp,
998
+ ];
999
+ }
1000
+
1001
+ function mapMessageRow(row: MessageRow): Message {
1002
+ return {
1003
+ messageId: row.message_id,
1004
+ role: row.role,
1005
+ type: row.type,
1006
+ content: parseJsonOrDefault(row.content_json, ''),
1007
+ reasoning_content: row.reasoning_content ?? undefined,
1008
+ tool_call_id: row.tool_call_id ?? undefined,
1009
+ tool_calls: row.tool_calls_json
1010
+ ? (parseJsonOrDefault(row.tool_calls_json, undefined) as Message['tool_calls'])
1011
+ : undefined,
1012
+ usage: row.usage_json
1013
+ ? (parseJsonOrDefault(row.usage_json, undefined) as Message['usage'])
1014
+ : undefined,
1015
+ metadata: row.metadata_json
1016
+ ? (parseJsonOrDefault(row.metadata_json, undefined) as Message['metadata'])
1017
+ : undefined,
1018
+ timestamp: row.created_at_ms,
1019
+ };
1020
+ }
1021
+
1022
+ function chunkStrings(items: string[], chunkSize: number): string[][] {
1023
+ const chunks: string[][] = [];
1024
+ for (let index = 0; index < items.length; index += chunkSize) {
1025
+ chunks.push(items.slice(index, index + chunkSize));
1026
+ }
1027
+ return chunks;
1028
+ }
1029
+
1030
+ function mapRunRow(row: RunRow): RunRecord {
1031
+ return {
1032
+ executionId: row.execution_id,
1033
+ runId: row.run_id,
1034
+ conversationId: row.conversation_id,
1035
+ status: row.status,
1036
+ createdAt: row.created_at_ms,
1037
+ updatedAt: row.updated_at_ms,
1038
+ stepIndex: row.step_index,
1039
+ startedAt: row.started_at_ms ?? undefined,
1040
+ completedAt: row.completed_at_ms ?? undefined,
1041
+ lastCheckpointSeq: row.last_checkpoint_seq ?? undefined,
1042
+ terminalReason: row.terminal_reason ?? undefined,
1043
+ errorCode: row.error_code ?? undefined,
1044
+ errorCategory: row.error_category ?? undefined,
1045
+ errorMessage: row.error_message ?? undefined,
1046
+ };
1047
+ }
1048
+
1049
+ function mapEventRow(row: EventRow): CliEventEnvelope {
1050
+ return {
1051
+ conversationId: row.conversation_id,
1052
+ executionId: row.execution_id,
1053
+ seq: row.seq,
1054
+ eventType: row.event_type,
1055
+ data: parseJsonOrDefault(row.payload_json, null),
1056
+ createdAt: row.created_at_ms,
1057
+ };
1058
+ }
1059
+
1060
+ function mapRunLogRow(row: RunLogRow): RunLogRecord {
1061
+ return {
1062
+ id: row.id,
1063
+ executionId: row.execution_id,
1064
+ conversationId: row.conversation_id,
1065
+ stepIndex: row.step_index ?? undefined,
1066
+ level: row.level,
1067
+ code: row.code ?? undefined,
1068
+ source: row.source,
1069
+ message: row.message,
1070
+ error: row.error_json
1071
+ ? (parseJsonOrDefault(row.error_json, undefined) as RunLogRecord['error'])
1072
+ : undefined,
1073
+ context: row.context_json
1074
+ ? (parseJsonOrDefault(row.context_json, undefined) as RunLogRecord['context'])
1075
+ : undefined,
1076
+ data: row.data_json ? parseJsonOrDefault(row.data_json, undefined) : undefined,
1077
+ createdAt: row.created_at_ms,
1078
+ };
1079
+ }
1080
+
1081
+ function clampLimit(limit?: number): number {
1082
+ if (!Number.isFinite(limit)) {
1083
+ return 20;
1084
+ }
1085
+ return Math.min(100, Math.max(1, Math.floor(Number(limit))));
1086
+ }
1087
+
1088
+ function encodeCursor(updatedAt: number, executionId: string): string {
1089
+ return `${updatedAt}:${executionId}`;
1090
+ }
1091
+
1092
+ function decodeCursor(cursor?: string): CursorToken | null {
1093
+ if (!cursor) {
1094
+ return null;
1095
+ }
1096
+ const splitIndex = cursor.indexOf(':');
1097
+ if (splitIndex <= 0 || splitIndex >= cursor.length - 1) {
1098
+ return null;
1099
+ }
1100
+ const updatedAtRaw = cursor.slice(0, splitIndex);
1101
+ const executionId = cursor.slice(splitIndex + 1);
1102
+ const updatedAt = Number(updatedAtRaw);
1103
+ if (!Number.isFinite(updatedAt) || executionId.length === 0) {
1104
+ return null;
1105
+ }
1106
+ return {
1107
+ updatedAt,
1108
+ executionId,
1109
+ };
1110
+ }
1111
+
1112
+ function parseJsonOrDefault<T>(raw: string, defaultValue: T): T {
1113
+ try {
1114
+ return JSON.parse(raw) as T;
1115
+ } catch {
1116
+ return defaultValue;
1117
+ }
1118
+ }
1119
+
1120
+ function isRecord(value: unknown): value is Record<string, unknown> {
1121
+ return typeof value === 'object' && value !== null;
1122
+ }
1123
+
1124
+ function isMessage(value: unknown): value is Message {
1125
+ if (!isRecord(value)) {
1126
+ return false;
1127
+ }
1128
+ return (
1129
+ typeof value.messageId === 'string' &&
1130
+ typeof value.role === 'string' &&
1131
+ typeof value.type === 'string' &&
1132
+ typeof value.timestamp === 'number' &&
1133
+ 'content' in value
1134
+ );
1135
+ }
1136
+
1137
+ function extractMessagePayload(event: CliEventEnvelope): MessageEventPayload | null {
1138
+ if (event.eventType !== 'user_message' && event.eventType !== 'assistant_message') {
1139
+ return null;
1140
+ }
1141
+
1142
+ if (isMessage(event.data)) {
1143
+ return { message: event.data };
1144
+ }
1145
+
1146
+ if (!isRecord(event.data) || !isMessage(event.data.message)) {
1147
+ return null;
1148
+ }
1149
+
1150
+ const stepIndex = event.data.stepIndex;
1151
+ return {
1152
+ message: event.data.message,
1153
+ stepIndex: typeof stepIndex === 'number' ? stepIndex : undefined,
1154
+ };
1155
+ }
1156
+
1157
+ async function runAppMigrations(client: AgentAppSqliteClient): Promise<void> {
1158
+ await client.exec(`
1159
+ CREATE TABLE IF NOT EXISTS agent_v4_schema_migrations (
1160
+ version INTEGER PRIMARY KEY,
1161
+ applied_at_ms INTEGER NOT NULL
1162
+ );
1163
+ `);
1164
+
1165
+ const rows = await client.all<{ version: number }>(
1166
+ 'SELECT version FROM agent_v4_schema_migrations ORDER BY version ASC'
1167
+ );
1168
+ const applied = new Set(rows.map((row) => row.version));
1169
+
1170
+ for (const migration of APP_MIGRATIONS) {
1171
+ if (applied.has(migration.version)) {
1172
+ continue;
1173
+ }
1174
+ await client.transaction(async () => {
1175
+ await client.exec(migration.sql);
1176
+ await client.run(
1177
+ 'INSERT INTO agent_v4_schema_migrations(version, applied_at_ms) VALUES(?, ?)',
1178
+ [migration.version, Date.now()]
1179
+ );
1180
+ });
1181
+ }
1182
+ }