byterover-cli 0.3.5 → 0.4.1

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 (345) hide show
  1. package/README.md +119 -63
  2. package/bin/dev.js +8 -1
  3. package/bin/run.js +7 -0
  4. package/dist/commands/cipher-agent/run.d.ts +30 -0
  5. package/dist/commands/cipher-agent/run.js +123 -61
  6. package/dist/commands/cipher-agent/set-prompt.d.ts +2 -0
  7. package/dist/commands/cipher-agent/set-prompt.js +13 -8
  8. package/dist/commands/cipher-agent/show-prompt.d.ts +2 -0
  9. package/dist/commands/cipher-agent/show-prompt.js +17 -12
  10. package/dist/commands/curate.d.ts +3 -60
  11. package/dist/commands/curate.js +45 -341
  12. package/dist/commands/foo.d.ts +4 -2
  13. package/dist/commands/foo.js +21 -16
  14. package/dist/commands/main.d.ts +9 -0
  15. package/dist/commands/main.js +34 -0
  16. package/dist/commands/query.d.ts +2 -48
  17. package/dist/commands/query.js +19 -287
  18. package/dist/commands/status.d.ts +2 -13
  19. package/dist/commands/status.js +12 -91
  20. package/dist/commands/watch.d.ts +2 -0
  21. package/dist/commands/watch.js +23 -19
  22. package/dist/config/environment.d.ts +1 -1
  23. package/dist/config/environment.js +2 -2
  24. package/dist/constants.d.ts +4 -5
  25. package/dist/constants.js +5 -5
  26. package/dist/core/domain/cipher/errors/storage-error.d.ts +89 -0
  27. package/dist/core/domain/cipher/errors/storage-error.js +130 -0
  28. package/dist/core/domain/cipher/queue/types.d.ts +71 -0
  29. package/dist/core/domain/cipher/queue/types.js +9 -0
  30. package/dist/core/domain/cipher/storage/message-storage-types.d.ts +218 -0
  31. package/dist/core/domain/cipher/storage/message-storage-types.js +18 -0
  32. package/dist/core/domain/cipher/tools/constants.d.ts +1 -0
  33. package/dist/core/domain/cipher/tools/constants.js +1 -0
  34. package/dist/core/domain/entities/event.d.ts +1 -1
  35. package/dist/core/domain/entities/event.js +8 -1
  36. package/dist/core/domain/entities/global-config.d.ts +36 -0
  37. package/dist/core/domain/entities/global-config.js +66 -0
  38. package/dist/core/domain/knowledge/directory-manager.d.ts +10 -0
  39. package/dist/core/domain/knowledge/directory-manager.js +18 -0
  40. package/dist/core/domain/knowledge/markdown-writer.d.ts +9 -0
  41. package/dist/core/domain/knowledge/markdown-writer.js +51 -1
  42. package/dist/core/interfaces/cipher/i-agent-storage.d.ts +152 -0
  43. package/dist/core/interfaces/cipher/i-agent-storage.js +1 -0
  44. package/dist/core/interfaces/cipher/i-cipher-agent.d.ts +2 -0
  45. package/dist/core/interfaces/cipher/i-key-storage.d.ts +91 -0
  46. package/dist/core/interfaces/cipher/i-key-storage.js +1 -0
  47. package/dist/core/interfaces/i-global-config-store.d.ts +34 -0
  48. package/dist/core/interfaces/i-global-config-store.js +1 -0
  49. package/dist/core/interfaces/i-onboarding-preference-store.d.ts +20 -0
  50. package/dist/core/interfaces/i-onboarding-preference-store.js +1 -0
  51. package/dist/core/interfaces/i-terminal.d.ts +146 -0
  52. package/dist/core/interfaces/i-terminal.js +1 -0
  53. package/dist/core/interfaces/i-workspace-detector-service.d.ts +8 -0
  54. package/dist/core/interfaces/i-workspace-detector-service.js +1 -0
  55. package/dist/core/interfaces/usecase/i-clear-use-case.d.ts +6 -0
  56. package/dist/core/interfaces/usecase/i-clear-use-case.js +1 -0
  57. package/dist/core/interfaces/usecase/i-curate-use-case.d.ts +10 -0
  58. package/dist/core/interfaces/usecase/i-curate-use-case.js +1 -0
  59. package/dist/core/interfaces/usecase/i-generate-rules-use-case.d.ts +3 -0
  60. package/dist/core/interfaces/usecase/i-generate-rules-use-case.js +1 -0
  61. package/dist/core/interfaces/usecase/i-init-use-case.d.ts +5 -0
  62. package/dist/core/interfaces/usecase/i-init-use-case.js +1 -0
  63. package/dist/core/interfaces/usecase/i-login-use-case.d.ts +3 -0
  64. package/dist/core/interfaces/usecase/i-login-use-case.js +1 -0
  65. package/dist/core/interfaces/usecase/i-logout-use-case.d.ts +5 -0
  66. package/dist/core/interfaces/usecase/i-logout-use-case.js +1 -0
  67. package/dist/core/interfaces/usecase/i-pull-use-case.d.ts +5 -0
  68. package/dist/core/interfaces/usecase/i-pull-use-case.js +1 -0
  69. package/dist/core/interfaces/usecase/i-push-use-case.d.ts +6 -0
  70. package/dist/core/interfaces/usecase/i-push-use-case.js +1 -0
  71. package/dist/core/interfaces/usecase/i-query-use-case.d.ts +9 -0
  72. package/dist/core/interfaces/usecase/i-query-use-case.js +1 -0
  73. package/dist/core/interfaces/usecase/i-space-list-use-case.d.ts +3 -0
  74. package/dist/core/interfaces/usecase/i-space-list-use-case.js +1 -0
  75. package/dist/core/interfaces/usecase/i-space-switch-use-case.d.ts +3 -0
  76. package/dist/core/interfaces/usecase/i-space-switch-use-case.js +1 -0
  77. package/dist/core/interfaces/usecase/i-status-use-case.d.ts +5 -0
  78. package/dist/core/interfaces/usecase/i-status-use-case.js +1 -0
  79. package/dist/hooks/init/welcome.js +10 -26
  80. package/dist/infra/cipher/agent-service-factory.d.ts +13 -6
  81. package/dist/infra/cipher/agent-service-factory.js +40 -16
  82. package/dist/infra/cipher/cipher-agent.js +4 -4
  83. package/dist/infra/cipher/consumer/consumer-lock.d.ts +20 -0
  84. package/dist/infra/cipher/consumer/consumer-lock.js +40 -0
  85. package/dist/infra/cipher/consumer/consumer-service.d.ts +99 -0
  86. package/dist/infra/cipher/consumer/consumer-service.js +165 -0
  87. package/dist/infra/cipher/consumer/execution-consumer.d.ts +121 -0
  88. package/dist/infra/cipher/consumer/execution-consumer.js +523 -0
  89. package/dist/infra/cipher/consumer/index.d.ts +33 -0
  90. package/dist/infra/cipher/consumer/index.js +33 -0
  91. package/dist/infra/cipher/consumer/queue-polling-service.d.ts +120 -0
  92. package/dist/infra/cipher/consumer/queue-polling-service.js +248 -0
  93. package/dist/infra/cipher/http/internal-llm-http-service.d.ts +94 -0
  94. package/dist/infra/cipher/http/internal-llm-http-service.js +118 -0
  95. package/dist/infra/cipher/llm/context/compaction/compaction-service.d.ts +106 -0
  96. package/dist/infra/cipher/llm/context/compaction/compaction-service.js +132 -0
  97. package/dist/infra/cipher/llm/context/compaction/index.d.ts +9 -0
  98. package/dist/infra/cipher/llm/context/compaction/index.js +9 -0
  99. package/dist/infra/cipher/llm/context/context-manager.d.ts +46 -2
  100. package/dist/infra/cipher/llm/context/context-manager.js +68 -4
  101. package/dist/infra/cipher/llm/context/rw-lock.d.ts +72 -0
  102. package/dist/infra/cipher/llm/context/rw-lock.js +145 -0
  103. package/dist/infra/cipher/llm/generators/byterover-content-generator.d.ts +7 -7
  104. package/dist/infra/cipher/llm/generators/byterover-content-generator.js +8 -8
  105. package/dist/infra/cipher/llm/internal-llm-service.js +2 -0
  106. package/dist/infra/cipher/session/session-manager.d.ts +4 -4
  107. package/dist/infra/cipher/session/session-manager.js +5 -5
  108. package/dist/infra/cipher/storage/agent-storage.d.ts +246 -0
  109. package/dist/infra/cipher/storage/agent-storage.js +956 -0
  110. package/dist/infra/cipher/storage/dual-format-history-storage.d.ts +77 -0
  111. package/dist/infra/cipher/storage/dual-format-history-storage.js +149 -0
  112. package/dist/infra/cipher/storage/granular-history-storage.d.ts +65 -0
  113. package/dist/infra/cipher/storage/granular-history-storage.js +118 -0
  114. package/dist/infra/cipher/storage/message-storage-service.d.ts +108 -0
  115. package/dist/infra/cipher/storage/message-storage-service.js +529 -0
  116. package/dist/infra/cipher/storage/process-utils.d.ts +16 -0
  117. package/dist/infra/cipher/storage/process-utils.js +43 -0
  118. package/dist/infra/cipher/storage/sqlite-key-storage.d.ts +105 -0
  119. package/dist/infra/cipher/storage/sqlite-key-storage.js +404 -0
  120. package/dist/infra/cipher/system-prompt/simple-prompt-factory.d.ts +1 -0
  121. package/dist/infra/cipher/system-prompt/simple-prompt-factory.js +7 -0
  122. package/dist/infra/cipher/tools/default-policy-rules.js +1 -1
  123. package/dist/infra/cipher/tools/implementations/curate-tool.d.ts +10 -0
  124. package/dist/infra/cipher/tools/implementations/curate-tool.js +371 -0
  125. package/dist/infra/cipher/tools/implementations/find-knowledge-topics-tool.js +11 -8
  126. package/dist/infra/cipher/tools/tool-manager.d.ts +8 -2
  127. package/dist/infra/cipher/tools/tool-manager.js +29 -2
  128. package/dist/infra/cipher/tools/tool-registry.js +7 -0
  129. package/dist/infra/http/authenticated-http-client.d.ts +21 -0
  130. package/dist/infra/http/authenticated-http-client.js +38 -0
  131. package/dist/infra/repl/commands/arg-parser.d.ts +97 -0
  132. package/dist/infra/repl/commands/arg-parser.js +129 -0
  133. package/dist/infra/repl/commands/clear-command.d.ts +5 -0
  134. package/dist/infra/repl/commands/clear-command.js +61 -0
  135. package/dist/infra/repl/commands/curate-command.d.ts +9 -0
  136. package/dist/infra/repl/commands/curate-command.js +88 -0
  137. package/dist/infra/repl/commands/gen-rules-command.d.ts +7 -0
  138. package/dist/infra/repl/commands/gen-rules-command.js +38 -0
  139. package/dist/infra/repl/commands/index.d.ts +8 -0
  140. package/dist/infra/repl/commands/index.js +36 -0
  141. package/dist/infra/repl/commands/init-command.d.ts +7 -0
  142. package/dist/infra/repl/commands/init-command.js +83 -0
  143. package/dist/infra/repl/commands/login-command.d.ts +7 -0
  144. package/dist/infra/repl/commands/login-command.js +50 -0
  145. package/dist/infra/repl/commands/logout-command.d.ts +5 -0
  146. package/dist/infra/repl/commands/logout-command.js +48 -0
  147. package/dist/infra/repl/commands/pull-command.d.ts +5 -0
  148. package/dist/infra/repl/commands/pull-command.js +61 -0
  149. package/dist/infra/repl/commands/push-command.d.ts +5 -0
  150. package/dist/infra/repl/commands/push-command.js +66 -0
  151. package/dist/infra/repl/commands/query-command.d.ts +5 -0
  152. package/dist/infra/repl/commands/query-command.js +66 -0
  153. package/dist/infra/repl/commands/space/index.d.ts +5 -0
  154. package/dist/infra/repl/commands/space/index.js +14 -0
  155. package/dist/infra/repl/commands/space/list-command.d.ts +5 -0
  156. package/dist/infra/repl/commands/space/list-command.js +70 -0
  157. package/dist/infra/repl/commands/space/switch-command.d.ts +5 -0
  158. package/dist/infra/repl/commands/space/switch-command.js +37 -0
  159. package/dist/infra/repl/commands/status-command.d.ts +5 -0
  160. package/dist/infra/repl/commands/status-command.js +39 -0
  161. package/dist/infra/repl/repl-startup.d.ts +18 -0
  162. package/dist/infra/repl/repl-startup.js +28 -0
  163. package/dist/infra/storage/file-global-config-store.d.ts +22 -0
  164. package/dist/infra/storage/file-global-config-store.js +65 -0
  165. package/dist/infra/storage/file-onboarding-preference-store.d.ts +10 -0
  166. package/dist/infra/storage/file-onboarding-preference-store.js +46 -0
  167. package/dist/infra/terminal/oclif-terminal.d.ts +19 -0
  168. package/dist/infra/terminal/oclif-terminal.js +60 -0
  169. package/dist/infra/terminal/repl-terminal.d.ts +31 -0
  170. package/dist/infra/terminal/repl-terminal.js +116 -0
  171. package/dist/infra/tracking/mixpanel-tracking-service.d.ts +11 -1
  172. package/dist/infra/tracking/mixpanel-tracking-service.js +18 -13
  173. package/dist/infra/usecase/clear-use-case.d.ts +20 -0
  174. package/dist/infra/usecase/clear-use-case.js +58 -0
  175. package/dist/infra/usecase/curate-use-case.d.ts +66 -0
  176. package/dist/infra/usecase/curate-use-case.js +288 -0
  177. package/dist/{commands/gen-rules.d.ts → infra/usecase/generate-rules-use-case.d.ts} +14 -20
  178. package/dist/{commands/gen-rules.js → infra/usecase/generate-rules-use-case.js} +59 -78
  179. package/dist/infra/usecase/init-use-case.d.ts +139 -0
  180. package/dist/{commands/init.js → infra/usecase/init-use-case.js} +197 -233
  181. package/dist/infra/usecase/login-use-case.d.ts +28 -0
  182. package/dist/infra/usecase/login-use-case.js +94 -0
  183. package/dist/infra/usecase/logout-use-case.d.ts +22 -0
  184. package/dist/infra/usecase/logout-use-case.js +51 -0
  185. package/dist/infra/usecase/pull-use-case.d.ts +35 -0
  186. package/dist/infra/usecase/pull-use-case.js +89 -0
  187. package/dist/infra/usecase/push-use-case.d.ts +37 -0
  188. package/dist/infra/usecase/push-use-case.js +124 -0
  189. package/dist/infra/usecase/query-use-case.d.ts +78 -0
  190. package/dist/infra/usecase/query-use-case.js +402 -0
  191. package/dist/infra/usecase/space-list-use-case.d.ts +27 -0
  192. package/dist/infra/usecase/space-list-use-case.js +64 -0
  193. package/dist/infra/usecase/space-switch-use-case.d.ts +36 -0
  194. package/dist/infra/usecase/space-switch-use-case.js +140 -0
  195. package/dist/infra/usecase/status-use-case.d.ts +27 -0
  196. package/dist/infra/usecase/status-use-case.js +97 -0
  197. package/dist/infra/workspace/workspace-detector-service.d.ts +3 -6
  198. package/dist/resources/prompts/curate-context-tree-curation.yml +23 -11
  199. package/dist/resources/prompts/query-context-tree-retrieval.yml +3 -4
  200. package/dist/resources/prompts/system-prompt.yml +1 -1
  201. package/dist/resources/prompts/tool-outputs.yml +4 -3
  202. package/dist/templates/sections/command-reference.md +12 -0
  203. package/dist/templates/sections/workflow.md +10 -1
  204. package/dist/tui/app.d.ts +9 -0
  205. package/dist/tui/app.js +26 -0
  206. package/dist/tui/components/enter-prompt.d.ts +13 -0
  207. package/dist/tui/components/enter-prompt.js +15 -0
  208. package/dist/tui/components/execution/execution-changes.d.ts +14 -0
  209. package/dist/tui/components/execution/execution-changes.js +15 -0
  210. package/dist/tui/components/execution/execution-content.d.ts +25 -0
  211. package/dist/tui/components/execution/execution-content.js +67 -0
  212. package/dist/tui/components/execution/execution-input.d.ts +12 -0
  213. package/dist/tui/components/execution/execution-input.js +16 -0
  214. package/dist/tui/components/execution/execution-progress.d.ts +21 -0
  215. package/dist/tui/components/execution/execution-progress.js +21 -0
  216. package/dist/tui/components/execution/execution-status.d.ts +13 -0
  217. package/dist/tui/components/execution/execution-status.js +19 -0
  218. package/dist/tui/components/execution/index.d.ts +11 -0
  219. package/dist/tui/components/execution/index.js +11 -0
  220. package/dist/tui/components/execution/log-item.d.ts +17 -0
  221. package/dist/tui/components/execution/log-item.js +25 -0
  222. package/dist/tui/components/footer.d.ts +5 -0
  223. package/dist/tui/components/footer.js +12 -0
  224. package/dist/tui/components/header.d.ts +18 -0
  225. package/dist/tui/components/header.js +18 -0
  226. package/dist/tui/components/index.d.ts +17 -0
  227. package/dist/tui/components/index.js +14 -0
  228. package/dist/tui/components/inline-prompts/index.d.ts +15 -0
  229. package/dist/tui/components/inline-prompts/index.js +10 -0
  230. package/dist/tui/components/inline-prompts/inline-confirm.d.ts +17 -0
  231. package/dist/tui/components/inline-prompts/inline-confirm.js +32 -0
  232. package/dist/tui/components/inline-prompts/inline-file-selector.d.ts +43 -0
  233. package/dist/tui/components/inline-prompts/inline-file-selector.js +185 -0
  234. package/dist/tui/components/inline-prompts/inline-input.d.ts +19 -0
  235. package/dist/tui/components/inline-prompts/inline-input.js +32 -0
  236. package/dist/tui/components/inline-prompts/inline-search.d.ts +20 -0
  237. package/dist/tui/components/inline-prompts/inline-search.js +50 -0
  238. package/dist/tui/components/inline-prompts/inline-select.d.ts +20 -0
  239. package/dist/tui/components/inline-prompts/inline-select.js +34 -0
  240. package/dist/tui/components/logo.d.ts +43 -0
  241. package/dist/tui/components/logo.js +103 -0
  242. package/dist/tui/components/message-item.d.ts +12 -0
  243. package/dist/tui/components/message-item.js +12 -0
  244. package/dist/tui/components/onboarding/copyable-prompt.d.ts +15 -0
  245. package/dist/tui/components/onboarding/copyable-prompt.js +65 -0
  246. package/dist/tui/components/onboarding/index.d.ts +7 -0
  247. package/dist/tui/components/onboarding/index.js +6 -0
  248. package/dist/tui/components/onboarding/onboarding-flow.d.ts +13 -0
  249. package/dist/tui/components/onboarding/onboarding-flow.js +304 -0
  250. package/dist/tui/components/onboarding/onboarding-step.d.ts +23 -0
  251. package/dist/tui/components/onboarding/onboarding-step.js +12 -0
  252. package/dist/tui/components/output-log.d.ts +14 -0
  253. package/dist/tui/components/output-log.js +13 -0
  254. package/dist/tui/components/scrollable-list.d.ts +30 -0
  255. package/dist/tui/components/scrollable-list.js +121 -0
  256. package/dist/tui/components/suggestions.d.ts +16 -0
  257. package/dist/tui/components/suggestions.js +162 -0
  258. package/dist/tui/components/tab-bar.d.ts +10 -0
  259. package/dist/tui/components/tab-bar.js +12 -0
  260. package/dist/tui/constants.d.ts +11 -0
  261. package/dist/tui/constants.js +13 -0
  262. package/dist/tui/contexts/auth-context.d.ts +30 -0
  263. package/dist/tui/contexts/auth-context.js +153 -0
  264. package/dist/tui/contexts/consumer.d.ts +31 -0
  265. package/dist/tui/contexts/consumer.js +56 -0
  266. package/dist/tui/contexts/index.d.ts +6 -0
  267. package/dist/tui/contexts/index.js +6 -0
  268. package/dist/tui/contexts/onboarding-context.d.ts +43 -0
  269. package/dist/tui/contexts/onboarding-context.js +181 -0
  270. package/dist/tui/contexts/services-context.d.ts +29 -0
  271. package/dist/tui/contexts/services-context.js +20 -0
  272. package/dist/tui/contexts/use-commands.d.ts +29 -0
  273. package/dist/tui/contexts/use-commands.js +54 -0
  274. package/dist/tui/contexts/use-mode.d.ts +43 -0
  275. package/dist/tui/contexts/use-mode.js +76 -0
  276. package/dist/tui/contexts/use-theme.d.ts +53 -0
  277. package/dist/tui/contexts/use-theme.js +60 -0
  278. package/dist/tui/hooks/index.d.ts +17 -0
  279. package/dist/tui/hooks/index.js +14 -0
  280. package/dist/tui/hooks/use-activity-logs.d.ts +26 -0
  281. package/dist/tui/hooks/use-activity-logs.js +90 -0
  282. package/dist/tui/hooks/use-consumer.d.ts +12 -0
  283. package/dist/tui/hooks/use-consumer.js +50 -0
  284. package/dist/tui/hooks/use-onboarding.d.ts +7 -0
  285. package/dist/tui/hooks/use-onboarding.js +6 -0
  286. package/dist/tui/hooks/use-queue-polling.d.ts +31 -0
  287. package/dist/tui/hooks/use-queue-polling.js +90 -0
  288. package/dist/tui/hooks/use-slash-command-processor.d.ts +16 -0
  289. package/dist/tui/hooks/use-slash-command-processor.js +132 -0
  290. package/dist/tui/hooks/use-slash-completion.d.ts +30 -0
  291. package/dist/tui/hooks/use-slash-completion.js +230 -0
  292. package/dist/tui/hooks/use-tab-navigation.d.ts +10 -0
  293. package/dist/tui/hooks/use-tab-navigation.js +35 -0
  294. package/dist/tui/hooks/use-visible-window.d.ts +22 -0
  295. package/dist/tui/hooks/use-visible-window.js +37 -0
  296. package/dist/tui/index.d.ts +1 -0
  297. package/dist/tui/index.js +1 -0
  298. package/dist/tui/providers/app-providers.d.ts +25 -0
  299. package/dist/tui/providers/app-providers.js +9 -0
  300. package/dist/tui/types/commands.d.ts +252 -0
  301. package/dist/tui/types/commands.js +16 -0
  302. package/dist/tui/types/dialogs.d.ts +37 -0
  303. package/dist/tui/types/dialogs.js +4 -0
  304. package/dist/tui/types/index.d.ts +11 -0
  305. package/dist/tui/types/index.js +7 -0
  306. package/dist/tui/types/messages.d.ts +55 -0
  307. package/dist/tui/types/messages.js +4 -0
  308. package/dist/tui/types/prompts.d.ts +100 -0
  309. package/dist/tui/types/prompts.js +4 -0
  310. package/dist/tui/types/ui.d.ts +14 -0
  311. package/dist/tui/types/ui.js +4 -0
  312. package/dist/tui/types.d.ts +1 -0
  313. package/dist/tui/types.js +1 -0
  314. package/dist/tui/views/command-view.d.ts +12 -0
  315. package/dist/tui/views/command-view.js +451 -0
  316. package/dist/tui/views/index.d.ts +6 -0
  317. package/dist/tui/views/index.js +6 -0
  318. package/dist/tui/views/login-view.d.ts +10 -0
  319. package/dist/tui/views/login-view.js +30 -0
  320. package/dist/tui/views/logs-view.d.ts +11 -0
  321. package/dist/tui/views/logs-view.js +73 -0
  322. package/dist/utils/file-validator.d.ts +16 -0
  323. package/dist/utils/file-validator.js +81 -0
  324. package/dist/utils/global-config-path.d.ts +15 -0
  325. package/dist/utils/global-config-path.js +38 -0
  326. package/oclif.manifest.json +29 -315
  327. package/package.json +11 -4
  328. package/dist/commands/clear.d.ts +0 -19
  329. package/dist/commands/clear.js +0 -78
  330. package/dist/commands/init.d.ts +0 -130
  331. package/dist/commands/login.d.ts +0 -22
  332. package/dist/commands/login.js +0 -108
  333. package/dist/commands/logout.d.ts +0 -16
  334. package/dist/commands/logout.js +0 -61
  335. package/dist/commands/pull.d.ts +0 -33
  336. package/dist/commands/pull.js +0 -115
  337. package/dist/commands/push.d.ts +0 -35
  338. package/dist/commands/push.js +0 -160
  339. package/dist/commands/space/list.d.ts +0 -25
  340. package/dist/commands/space/list.js +0 -114
  341. package/dist/commands/space/switch.d.ts +0 -36
  342. package/dist/commands/space/switch.js +0 -160
  343. package/dist/infra/cipher/grpc/internal-llm-grpc-service.d.ts +0 -149
  344. package/dist/infra/cipher/grpc/internal-llm-grpc-service.js +0 -364
  345. package/dist/infra/cipher/grpc/internal-llm-grpc.proto +0 -94
@@ -0,0 +1,529 @@
1
+ import { randomUUID } from 'node:crypto';
2
+ import { COMPACTED_TOOL_OUTPUT_PLACEHOLDER } from '../../../core/domain/cipher/storage/message-storage-types.js';
3
+ /**
4
+ * Service for granular message and part storage.
5
+ *
6
+ * Handles the conversion between InternalMessage format and the granular
7
+ * StoredMessage/StoredPart format, enabling:
8
+ * - Streaming message loading (newest to oldest)
9
+ * - Selective tool output pruning
10
+ * - Compaction boundary markers
11
+ *
12
+ * Key structure:
13
+ * - ["session", sessionId] → SessionRecord
14
+ * - ["message", sessionId, messageId] → StoredMessage
15
+ * - ["part", messageId, partId] → StoredPart
16
+ */
17
+ export class MessageStorageService {
18
+ keyStorage;
19
+ constructor(keyStorage) {
20
+ this.keyStorage = keyStorage;
21
+ }
22
+ /**
23
+ * Delete a session and all its messages and parts.
24
+ */
25
+ async deleteSession(sessionId) {
26
+ const session = await this.getSession(sessionId);
27
+ if (!session) {
28
+ return false;
29
+ }
30
+ // Delete all messages and their parts
31
+ const messageKeys = await this.keyStorage.list(this.messagePrefix(sessionId));
32
+ for (const messageKey of messageKeys) {
33
+ const messageId = messageKey[2];
34
+ // Delete all parts for this message
35
+ // eslint-disable-next-line no-await-in-loop
36
+ const partKeys = await this.keyStorage.list(this.partPrefix(messageId));
37
+ for (const partKey of partKeys) {
38
+ // eslint-disable-next-line no-await-in-loop
39
+ await this.keyStorage.delete(partKey);
40
+ }
41
+ // Delete the message
42
+ // eslint-disable-next-line no-await-in-loop
43
+ await this.keyStorage.delete(messageKey);
44
+ }
45
+ // Delete the session record
46
+ return this.keyStorage.delete(this.sessionKey(sessionId));
47
+ }
48
+ /**
49
+ * Get the session record, if it exists.
50
+ */
51
+ async getSession(sessionId) {
52
+ return this.keyStorage.get(this.sessionKey(sessionId));
53
+ }
54
+ /**
55
+ * Check if a session exists in granular format.
56
+ */
57
+ async hasSession(sessionId) {
58
+ return this.keyStorage.exists(this.sessionKey(sessionId));
59
+ }
60
+ /**
61
+ * Insert a compaction boundary marker.
62
+ * Creates a special message that signals where to stop loading history.
63
+ */
64
+ async insertCompactionBoundary(sessionId, summary) {
65
+ const now = Date.now();
66
+ const messageId = randomUUID();
67
+ // Get session
68
+ const session = await this.getSession(sessionId);
69
+ if (!session) {
70
+ throw new Error(`Session ${sessionId} not found`);
71
+ }
72
+ // Create compaction boundary message
73
+ const boundaryMessage = {
74
+ compactionBoundary: true,
75
+ compactionSummary: summary,
76
+ content: summary,
77
+ createdAt: now,
78
+ id: messageId,
79
+ partIds: [],
80
+ prevMessageId: session.newestMessageId,
81
+ role: 'user', // Compaction boundaries are modeled as user messages
82
+ sessionId,
83
+ updatedAt: now,
84
+ };
85
+ // Update the previous newest message
86
+ if (session.newestMessageId) {
87
+ await this.keyStorage.update(this.messageKey(sessionId, session.newestMessageId), (prev) => {
88
+ if (!prev)
89
+ throw new Error(`Previous message ${session.newestMessageId} not found`);
90
+ return { ...prev, nextMessageId: messageId, updatedAt: now };
91
+ });
92
+ }
93
+ // Save boundary message
94
+ await this.keyStorage.set(this.messageKey(sessionId, messageId), boundaryMessage);
95
+ // Update session
96
+ session.newestMessageId = messageId;
97
+ session.lastCompactionMessageId = messageId;
98
+ session.messageCount += 1;
99
+ session.updatedAt = now;
100
+ await this.saveSession(session);
101
+ return boundaryMessage;
102
+ }
103
+ /**
104
+ * List all session IDs in granular format.
105
+ */
106
+ async listSessions() {
107
+ const sessionKeys = await this.keyStorage.list(['session']);
108
+ return sessionKeys.map((key) => key[1]); // ["session", sessionId] -> sessionId
109
+ }
110
+ /**
111
+ * Load messages from a session, stopping at compaction boundary.
112
+ * Returns messages in chronological order (oldest first).
113
+ */
114
+ async loadMessages(sessionId, options) {
115
+ const session = await this.getSession(sessionId);
116
+ if (!session || !session.newestMessageId) {
117
+ return { hitCompactionBoundary: false, messages: [] };
118
+ }
119
+ const stopAtCompaction = options?.stopAtCompaction ?? true;
120
+ const messages = [];
121
+ let hitCompactionBoundary = false;
122
+ // Traverse from newest to oldest
123
+ let currentMessageId = session.newestMessageId;
124
+ while (currentMessageId) {
125
+ // eslint-disable-next-line no-await-in-loop
126
+ const storedMsg = await this.keyStorage.get(this.messageKey(sessionId, currentMessageId));
127
+ if (!storedMsg)
128
+ break;
129
+ // Load parts for this message
130
+ // eslint-disable-next-line no-await-in-loop
131
+ const parts = await this.loadParts(storedMsg);
132
+ const messageWithParts = { ...storedMsg, parts };
133
+ // Check for compaction boundary
134
+ if (stopAtCompaction && storedMsg.compactionBoundary) {
135
+ // Include the compaction boundary message itself
136
+ messages.unshift(messageWithParts);
137
+ hitCompactionBoundary = true;
138
+ break;
139
+ }
140
+ messages.unshift(messageWithParts);
141
+ currentMessageId = storedMsg.prevMessageId;
142
+ }
143
+ return { hitCompactionBoundary, messages };
144
+ }
145
+ /**
146
+ * Prune old tool outputs by marking them as compacted.
147
+ * Keeps the most recent tool outputs up to the specified token limit.
148
+ */
149
+ async pruneToolOutputs(options) {
150
+ const { keepTokens = 40_000, sessionId } = options;
151
+ const session = await this.getSession(sessionId);
152
+ if (!session || !session.newestMessageId) {
153
+ return { compactedCount: 0, tokensSaved: 0 };
154
+ }
155
+ // Collect all tool output parts, newest first
156
+ const toolOutputParts = [];
157
+ // Traverse messages from newest to oldest
158
+ let currentMessageId = session.newestMessageId;
159
+ while (currentMessageId) {
160
+ // eslint-disable-next-line no-await-in-loop
161
+ const storedMsg = await this.keyStorage.get(this.messageKey(sessionId, currentMessageId));
162
+ if (!storedMsg)
163
+ break;
164
+ // Collect tool output parts from this message
165
+ for (const partId of storedMsg.partIds) {
166
+ // eslint-disable-next-line no-await-in-loop
167
+ const part = await this.keyStorage.get(this.partKey(storedMsg.id, partId));
168
+ if (part && part.type === 'tool_output' && !part.compactedAt) {
169
+ toolOutputParts.push({
170
+ key: this.partKey(storedMsg.id, partId),
171
+ part,
172
+ });
173
+ }
174
+ }
175
+ currentMessageId = storedMsg.prevMessageId;
176
+ }
177
+ // Estimate tokens (rough: 1 token ≈ 4 chars)
178
+ let keptTokens = 0;
179
+ let compactedCount = 0;
180
+ let tokensSaved = 0;
181
+ const now = Date.now();
182
+ for (const { key, part } of toolOutputParts) {
183
+ const estimatedTokens = Math.ceil(part.content.length / 4);
184
+ if (keptTokens < keepTokens) {
185
+ keptTokens += estimatedTokens;
186
+ }
187
+ else {
188
+ // Mark this part as compacted
189
+ // eslint-disable-next-line no-await-in-loop
190
+ await this.keyStorage.set(key, {
191
+ ...part,
192
+ compactedAt: now,
193
+ content: '', // Clear the content to save space
194
+ });
195
+ compactedCount++;
196
+ tokensSaved += estimatedTokens;
197
+ }
198
+ }
199
+ return { compactedCount, tokensSaved };
200
+ }
201
+ /**
202
+ * Save a single message with its parts.
203
+ * Updates the session record to maintain linked list pointers.
204
+ */
205
+ async saveMessage(sessionId, message) {
206
+ const now = Date.now();
207
+ const messageId = randomUUID();
208
+ // Convert InternalMessage content to parts
209
+ const { content, parts } = this.extractParts(message, messageId, now);
210
+ // Get or create session
211
+ let session = await this.getSession(sessionId);
212
+ const isNewSession = !session;
213
+ if (isNewSession) {
214
+ session = {
215
+ createdAt: now,
216
+ messageCount: 0,
217
+ sessionId,
218
+ updatedAt: now,
219
+ };
220
+ }
221
+ // Create stored message
222
+ const storedMessage = {
223
+ content,
224
+ createdAt: now,
225
+ id: messageId,
226
+ name: message.name,
227
+ partIds: parts.map((p) => p.id),
228
+ prevMessageId: session.newestMessageId,
229
+ reasoning: message.reasoning,
230
+ role: message.role,
231
+ sessionId,
232
+ thought: message.thought,
233
+ thoughtSummary: message.thoughtSummary,
234
+ toolCallId: message.toolCallId,
235
+ toolCalls: message.toolCalls,
236
+ updatedAt: now,
237
+ };
238
+ // Update the previous newest message to point to this one
239
+ if (session.newestMessageId) {
240
+ await this.keyStorage.update(this.messageKey(sessionId, session.newestMessageId), (prev) => {
241
+ if (!prev)
242
+ throw new Error(`Previous message ${session.newestMessageId} not found`);
243
+ return { ...prev, nextMessageId: messageId, updatedAt: now };
244
+ });
245
+ }
246
+ // Save parts
247
+ for (const part of parts) {
248
+ // eslint-disable-next-line no-await-in-loop
249
+ await this.keyStorage.set(this.partKey(part.messageId, part.id), part);
250
+ }
251
+ // Save message
252
+ await this.keyStorage.set(this.messageKey(sessionId, messageId), storedMessage);
253
+ // Update session
254
+ session.newestMessageId = messageId;
255
+ if (!session.oldestMessageId) {
256
+ session.oldestMessageId = messageId;
257
+ }
258
+ session.messageCount += 1;
259
+ session.updatedAt = now;
260
+ await this.saveSession(session);
261
+ return storedMessage;
262
+ }
263
+ /**
264
+ * Save multiple messages in order.
265
+ * More efficient than calling saveMessage multiple times.
266
+ */
267
+ async saveMessages(sessionId, messages) {
268
+ const results = [];
269
+ for (const message of messages) {
270
+ // eslint-disable-next-line no-await-in-loop
271
+ const stored = await this.saveMessage(sessionId, message);
272
+ results.push(stored);
273
+ }
274
+ return results;
275
+ }
276
+ /**
277
+ * Create or update a session record.
278
+ */
279
+ async saveSession(session) {
280
+ await this.keyStorage.set(this.sessionKey(session.sessionId), session);
281
+ }
282
+ /**
283
+ * Stream messages from newest to oldest using an async generator.
284
+ * More memory efficient for large histories.
285
+ *
286
+ * @yields StoredMessageWithParts - Messages from the session history
287
+ */
288
+ async *streamMessages(options) {
289
+ const { limit, sessionId, stopAtCompaction = true } = options;
290
+ const session = await this.getSession(sessionId);
291
+ if (!session || !session.newestMessageId) {
292
+ return;
293
+ }
294
+ let count = 0;
295
+ let currentMessageId = session.newestMessageId;
296
+ while (currentMessageId) {
297
+ if (limit && count >= limit)
298
+ break;
299
+ // eslint-disable-next-line no-await-in-loop
300
+ const storedMsg = await this.keyStorage.get(this.messageKey(sessionId, currentMessageId));
301
+ if (!storedMsg)
302
+ break;
303
+ // Load parts for this message
304
+ // eslint-disable-next-line no-await-in-loop
305
+ const parts = await this.loadParts(storedMsg);
306
+ const messageWithParts = { ...storedMsg, parts };
307
+ yield messageWithParts;
308
+ count++;
309
+ // Stop at compaction boundary (but yield it first)
310
+ if (stopAtCompaction && storedMsg.compactionBoundary) {
311
+ break;
312
+ }
313
+ currentMessageId = storedMsg.prevMessageId;
314
+ }
315
+ }
316
+ /**
317
+ * Convert a single stored message with parts back to InternalMessage format.
318
+ */
319
+ toInternalMessage(message) {
320
+ // Reconstruct content from parts or use stored content
321
+ const { content: messageContent, parts } = message;
322
+ let content = messageContent;
323
+ // If we have parts, reconstruct the content array
324
+ if (parts.length > 0) {
325
+ const contentParts = [];
326
+ for (const part of parts) {
327
+ if (part.compactedAt) {
328
+ // Show placeholder for compacted parts
329
+ contentParts.push({
330
+ text: part.type === 'tool_output' ? COMPACTED_TOOL_OUTPUT_PLACEHOLDER : '[Content cleared]',
331
+ type: 'text',
332
+ });
333
+ }
334
+ else {
335
+ switch (part.type) {
336
+ case 'file': {
337
+ contentParts.push({
338
+ data: part.content,
339
+ filename: part.filename,
340
+ mimeType: part.mimeType || 'application/octet-stream',
341
+ type: 'file',
342
+ });
343
+ break;
344
+ }
345
+ case 'image': {
346
+ contentParts.push({
347
+ image: part.content,
348
+ mimeType: part.mimeType,
349
+ type: 'image',
350
+ });
351
+ break;
352
+ }
353
+ case 'text': {
354
+ contentParts.push({ text: part.content, type: 'text' });
355
+ break;
356
+ }
357
+ case 'tool_output': {
358
+ // Tool output becomes text content for tool messages
359
+ content = part.content;
360
+ break;
361
+ }
362
+ }
363
+ }
364
+ }
365
+ // Only use content parts array if we have non-tool parts
366
+ if (contentParts.length > 0 && message.role === 'user') {
367
+ content = contentParts;
368
+ }
369
+ }
370
+ const { name, reasoning, role, thought, thoughtSummary, toolCallId, toolCalls } = message;
371
+ return {
372
+ content,
373
+ name,
374
+ reasoning,
375
+ role,
376
+ thought,
377
+ thoughtSummary,
378
+ toolCallId,
379
+ toolCalls,
380
+ };
381
+ }
382
+ /**
383
+ * Convert loaded messages back to InternalMessage format.
384
+ */
385
+ toInternalMessages(messages) {
386
+ return messages.map((msg) => this.toInternalMessage(msg));
387
+ }
388
+ /**
389
+ * Extract parts from an InternalMessage.
390
+ */
391
+ extractParts(message, messageId, now) {
392
+ const parts = [];
393
+ let content = null;
394
+ if (message.content === null) {
395
+ // Assistant message with only tool calls
396
+ content = null;
397
+ }
398
+ else if (typeof message.content === 'string') {
399
+ // Tool result or simple text message
400
+ if (message.role === 'tool') {
401
+ // Store tool output as a part for selective pruning
402
+ const partId = randomUUID();
403
+ parts.push({
404
+ content: message.content,
405
+ createdAt: now,
406
+ id: partId,
407
+ messageId,
408
+ toolName: message.name,
409
+ type: 'tool_output',
410
+ });
411
+ content = message.content; // Also keep in content for quick access
412
+ }
413
+ else {
414
+ // System or simple assistant message
415
+ content = message.content;
416
+ }
417
+ }
418
+ else if (Array.isArray(message.content)) {
419
+ // User message with multiple parts
420
+ for (const part of message.content) {
421
+ const partId = randomUUID();
422
+ switch (part.type) {
423
+ case 'file': {
424
+ parts.push({
425
+ content: this.serializeFileContent(part.data),
426
+ createdAt: now,
427
+ filename: part.filename,
428
+ id: partId,
429
+ messageId,
430
+ mimeType: part.mimeType,
431
+ type: 'file',
432
+ });
433
+ break;
434
+ }
435
+ case 'image': {
436
+ parts.push({
437
+ content: this.serializeImageContent(part.image),
438
+ createdAt: now,
439
+ id: partId,
440
+ messageId,
441
+ mimeType: part.mimeType,
442
+ type: 'image',
443
+ });
444
+ break;
445
+ }
446
+ case 'text': {
447
+ parts.push({
448
+ content: part.text,
449
+ createdAt: now,
450
+ id: partId,
451
+ messageId,
452
+ type: 'text',
453
+ });
454
+ break;
455
+ }
456
+ }
457
+ }
458
+ // For user messages, content is reconstructed from parts
459
+ // but we can store a text preview
460
+ const textParts = message.content.filter((p) => p.type === 'text');
461
+ if (textParts.length > 0) {
462
+ content = textParts.map((p) => p.text).join('\n');
463
+ }
464
+ }
465
+ return { content, parts };
466
+ }
467
+ /**
468
+ * Load parts for a message.
469
+ */
470
+ async loadParts(message) {
471
+ const parts = [];
472
+ for (const partId of message.partIds) {
473
+ // eslint-disable-next-line no-await-in-loop
474
+ const part = await this.keyStorage.get(this.partKey(message.id, partId));
475
+ if (part) {
476
+ parts.push(part);
477
+ }
478
+ }
479
+ return parts;
480
+ }
481
+ // Key builders
482
+ messageKey(sessionId, messageId) {
483
+ return ['message', sessionId, messageId];
484
+ }
485
+ messagePrefix(sessionId) {
486
+ return ['message', sessionId];
487
+ }
488
+ partKey(messageId, partId) {
489
+ return ['part', messageId, partId];
490
+ }
491
+ partPrefix(messageId) {
492
+ return ['part', messageId];
493
+ }
494
+ /**
495
+ * Serialize file content for storage.
496
+ */
497
+ serializeFileContent(data) {
498
+ return this.serializeImageContent(data);
499
+ }
500
+ /**
501
+ * Serialize image content for storage.
502
+ */
503
+ serializeImageContent(image) {
504
+ if (typeof image === 'string') {
505
+ return image;
506
+ }
507
+ if (image instanceof URL) {
508
+ return image.toString();
509
+ }
510
+ if (image instanceof ArrayBuffer) {
511
+ return Buffer.from(image).toString('base64');
512
+ }
513
+ if (image instanceof Uint8Array) {
514
+ return Buffer.from(image).toString('base64');
515
+ }
516
+ // Buffer.isBuffer check is redundant since Buffer extends Uint8Array,
517
+ // but we keep it explicit for clarity
518
+ return image.toString('base64');
519
+ }
520
+ sessionKey(sessionId) {
521
+ return ['session', sessionId];
522
+ }
523
+ }
524
+ /**
525
+ * Factory function to create MessageStorageService.
526
+ */
527
+ export function createMessageStorageService(keyStorage) {
528
+ return new MessageStorageService(keyStorage);
529
+ }
@@ -0,0 +1,16 @@
1
+ /**
2
+ * Process detection utilities for orphan cleanup
3
+ *
4
+ * Used by cleanupStaleConsumers() to detect dead query processes.
5
+ * Provides cross-platform process existence checks.
6
+ */
7
+ /**
8
+ * Check if a process is still running
9
+ *
10
+ * Uses signal 0 to check process existence without actually sending a signal.
11
+ * This is a POSIX standard way to check if a process exists.
12
+ *
13
+ * @param pid - Process ID to check
14
+ * @returns true if running, false if dead, null if can't determine
15
+ */
16
+ export declare function isProcessRunning(pid: number): boolean | null;
@@ -0,0 +1,43 @@
1
+ /**
2
+ * Process detection utilities for orphan cleanup
3
+ *
4
+ * Used by cleanupStaleConsumers() to detect dead query processes.
5
+ * Provides cross-platform process existence checks.
6
+ */
7
+ /**
8
+ * Check if a process is still running
9
+ *
10
+ * Uses signal 0 to check process existence without actually sending a signal.
11
+ * This is a POSIX standard way to check if a process exists.
12
+ *
13
+ * @param pid - Process ID to check
14
+ * @returns true if running, false if dead, null if can't determine
15
+ */
16
+ export function isProcessRunning(pid) {
17
+ // Guard against invalid PIDs
18
+ // - Must be positive integer (PIDs are always > 0)
19
+ // - Negative PIDs are dangerous: kill(-1, 0) signals ALL processes!
20
+ // - PID 0 refers to current process group - not what we want
21
+ if (!Number.isInteger(pid) || pid <= 0) {
22
+ return null; // Can't determine → fallback to activity check
23
+ }
24
+ try {
25
+ // Signal 0 = check existence without killing
26
+ // If process exists and we have permission, this succeeds silently
27
+ process.kill(pid, 0);
28
+ return true;
29
+ }
30
+ catch (error) {
31
+ const { code } = error;
32
+ if (code === 'ESRCH') {
33
+ // ESRCH = No such process - definitely dead
34
+ return false;
35
+ }
36
+ if (code === 'EPERM') {
37
+ // EPERM = No permission to signal, but process exists
38
+ return true;
39
+ }
40
+ // Unknown error - can't determine (return null for fallback to activity check)
41
+ return null;
42
+ }
43
+ }
@@ -0,0 +1,105 @@
1
+ import type { BatchOperation, IKeyStorage, StorageKey } from '../../../core/interfaces/cipher/i-key-storage.js';
2
+ /**
3
+ * Configuration for SQLite key storage
4
+ */
5
+ export interface SqliteKeyStorageConfig {
6
+ /**
7
+ * Database file path (relative or absolute).
8
+ * Defaults to '.brv/context.db'
9
+ */
10
+ dbPath?: string;
11
+ /**
12
+ * Enable in-memory mode for testing.
13
+ * Defaults to false.
14
+ */
15
+ inMemory?: boolean;
16
+ /**
17
+ * Storage directory for the database file.
18
+ * Defaults to process.cwd()/.brv
19
+ */
20
+ storageDir?: string;
21
+ }
22
+ /**
23
+ * SQLite-based key storage implementation.
24
+ *
25
+ * Stores key-value pairs where keys are hierarchical (StorageKey = string[])
26
+ * and values are JSON-serializable objects.
27
+ *
28
+ * Key path structure:
29
+ * - ["session", sessionId] → Session metadata
30
+ * - ["message", sessionId, messageId] → Individual message
31
+ * - ["part", messageId, partId] → Message part (tool output, file, etc.)
32
+ *
33
+ * Schema:
34
+ * - key_store: key_path (primary), value (JSON blob), created_at, updated_at
35
+ *
36
+ * Features:
37
+ * - Hierarchical key organization with prefix-based listing
38
+ * - Reader-writer locks for concurrent access
39
+ * - Atomic batch operations
40
+ * - ACID transactions via SQLite
41
+ */
42
+ export declare class SqliteKeyStorage implements IKeyStorage {
43
+ private db;
44
+ private readonly dbPath;
45
+ private initialized;
46
+ private readonly inMemory;
47
+ private readonly storageDir;
48
+ constructor(config?: SqliteKeyStorageConfig);
49
+ /**
50
+ * Execute batch operations atomically.
51
+ * All operations succeed or fail together.
52
+ */
53
+ batch(operations: BatchOperation[]): Promise<void>;
54
+ /**
55
+ * Close the database connection.
56
+ */
57
+ close(): void;
58
+ /**
59
+ * Delete a value by its composite key.
60
+ */
61
+ delete(key: StorageKey): Promise<boolean>;
62
+ /**
63
+ * Check if a key exists.
64
+ */
65
+ exists(key: StorageKey): Promise<boolean>;
66
+ /**
67
+ * Get a value by its composite key.
68
+ */
69
+ get<T>(key: StorageKey): Promise<T | undefined>;
70
+ /**
71
+ * Initialize the storage backend.
72
+ * Creates the database and runs migrations.
73
+ */
74
+ initialize(): Promise<void>;
75
+ /**
76
+ * List all keys matching a prefix.
77
+ */
78
+ list(prefix: StorageKey): Promise<StorageKey[]>;
79
+ /**
80
+ * Set a value at a composite key.
81
+ */
82
+ set<T>(key: StorageKey, value: T): Promise<void>;
83
+ /**
84
+ * Atomic update with optimistic locking.
85
+ */
86
+ update<T>(key: StorageKey, updater: (current: T | undefined) => T): Promise<T>;
87
+ /**
88
+ * Deserialize a key path string back to StorageKey.
89
+ * Converts "message:session123:msg456" to ["message", "session123", "msg456"]
90
+ */
91
+ private deserializeKey;
92
+ /**
93
+ * Ensure storage has been initialized.
94
+ */
95
+ private ensureInitialized;
96
+ /**
97
+ * Serialize a StorageKey to a string path.
98
+ * Converts ["message", "session123", "msg456"] to "message:session123:msg456"
99
+ */
100
+ private serializeKey;
101
+ }
102
+ /**
103
+ * Factory function to create SqliteKeyStorage with common defaults.
104
+ */
105
+ export declare function createKeyStorage(config?: SqliteKeyStorageConfig): SqliteKeyStorage;