@greppleai/grip 0.0.0-stage → 0.1.3

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 (1119) hide show
  1. package/CHANGELOG.md +115 -0
  2. package/README.md +731 -2
  3. package/dist/bun/cli.d.ts +3 -0
  4. package/dist/bun/cli.d.ts.map +1 -0
  5. package/dist/bun/cli.js +13 -0
  6. package/dist/bun/cli.js.map +1 -0
  7. package/dist/bun/embedded-assets.d.ts +3 -0
  8. package/dist/bun/embedded-assets.d.ts.map +1 -0
  9. package/dist/bun/embedded-assets.js +52 -0
  10. package/dist/bun/embedded-assets.js.map +1 -0
  11. package/dist/bun/register-bedrock.d.ts +2 -0
  12. package/dist/bun/register-bedrock.d.ts.map +1 -0
  13. package/dist/bun/register-bedrock.js +4 -0
  14. package/dist/bun/register-bedrock.js.map +1 -0
  15. package/dist/bun/restore-sandbox-env.d.ts +13 -0
  16. package/dist/bun/restore-sandbox-env.d.ts.map +1 -0
  17. package/dist/bun/restore-sandbox-env.js +32 -0
  18. package/dist/bun/restore-sandbox-env.js.map +1 -0
  19. package/dist/cli/args.d.ts +70 -0
  20. package/dist/cli/args.d.ts.map +1 -0
  21. package/dist/cli/args.js +442 -0
  22. package/dist/cli/args.js.map +1 -0
  23. package/dist/cli/config-selector.d.ts +14 -0
  24. package/dist/cli/config-selector.d.ts.map +1 -0
  25. package/dist/cli/config-selector.js +31 -0
  26. package/dist/cli/config-selector.js.map +1 -0
  27. package/dist/cli/file-processor.d.ts +15 -0
  28. package/dist/cli/file-processor.d.ts.map +1 -0
  29. package/dist/cli/file-processor.js +60 -0
  30. package/dist/cli/file-processor.js.map +1 -0
  31. package/dist/cli/initial-message.d.ts +18 -0
  32. package/dist/cli/initial-message.d.ts.map +1 -0
  33. package/dist/cli/initial-message.js +22 -0
  34. package/dist/cli/initial-message.js.map +1 -0
  35. package/dist/cli/list-models.d.ts +9 -0
  36. package/dist/cli/list-models.d.ts.map +1 -0
  37. package/dist/cli/list-models.js +98 -0
  38. package/dist/cli/list-models.js.map +1 -0
  39. package/dist/cli/session-picker.d.ts +9 -0
  40. package/dist/cli/session-picker.d.ts.map +1 -0
  41. package/dist/cli/session-picker.js +35 -0
  42. package/dist/cli/session-picker.js.map +1 -0
  43. package/dist/cli.d.ts +3 -0
  44. package/dist/cli.d.ts.map +1 -0
  45. package/dist/cli.js +14 -0
  46. package/dist/cli.js.map +1 -0
  47. package/dist/config.d.ts +82 -0
  48. package/dist/config.d.ts.map +1 -0
  49. package/dist/config.js +406 -0
  50. package/dist/config.js.map +1 -0
  51. package/dist/core/agent-session.d.ts +970 -0
  52. package/dist/core/agent-session.d.ts.map +1 -0
  53. package/dist/core/agent-session.js +5191 -0
  54. package/dist/core/agent-session.js.map +1 -0
  55. package/dist/core/auth-guidance.d.ts +5 -0
  56. package/dist/core/auth-guidance.d.ts.map +1 -0
  57. package/dist/core/auth-guidance.js +21 -0
  58. package/dist/core/auth-guidance.js.map +1 -0
  59. package/dist/core/auth-storage.d.ts +150 -0
  60. package/dist/core/auth-storage.d.ts.map +1 -0
  61. package/dist/core/auth-storage.js +557 -0
  62. package/dist/core/auth-storage.js.map +1 -0
  63. package/dist/core/bash-executor.d.ts +26 -0
  64. package/dist/core/bash-executor.d.ts.map +1 -0
  65. package/dist/core/bash-executor.js +99 -0
  66. package/dist/core/bash-executor.js.map +1 -0
  67. package/dist/core/compaction/branch-summarization.d.ts +83 -0
  68. package/dist/core/compaction/branch-summarization.d.ts.map +1 -0
  69. package/dist/core/compaction/branch-summarization.js +220 -0
  70. package/dist/core/compaction/branch-summarization.js.map +1 -0
  71. package/dist/core/compaction/compaction.d.ts +65 -0
  72. package/dist/core/compaction/compaction.d.ts.map +1 -0
  73. package/dist/core/compaction/compaction.js +550 -0
  74. package/dist/core/compaction/compaction.js.map +1 -0
  75. package/dist/core/compaction/compression-detection-ledger.d.ts +34 -0
  76. package/dist/core/compaction/compression-detection-ledger.d.ts.map +1 -0
  77. package/dist/core/compaction/compression-detection-ledger.js +52 -0
  78. package/dist/core/compaction/compression-detection-ledger.js.map +1 -0
  79. package/dist/core/compaction/compression-detector.d.ts +71 -0
  80. package/dist/core/compaction/compression-detector.d.ts.map +1 -0
  81. package/dist/core/compaction/compression-detector.js +407 -0
  82. package/dist/core/compaction/compression-detector.js.map +1 -0
  83. package/dist/core/compaction/compression-economics.d.ts +55 -0
  84. package/dist/core/compaction/compression-economics.d.ts.map +1 -0
  85. package/dist/core/compaction/compression-economics.js +151 -0
  86. package/dist/core/compaction/compression-economics.js.map +1 -0
  87. package/dist/core/compaction/utils.d.ts +28 -0
  88. package/dist/core/compaction/utils.d.ts.map +1 -0
  89. package/dist/core/compaction/utils.js +165 -0
  90. package/dist/core/compaction/utils.js.map +1 -0
  91. package/dist/core/defaults.d.ts +3 -0
  92. package/dist/core/defaults.d.ts.map +1 -0
  93. package/dist/core/defaults.js +2 -0
  94. package/dist/core/defaults.js.map +1 -0
  95. package/dist/core/diagnostics.d.ts +18 -0
  96. package/dist/core/diagnostics.d.ts.map +1 -0
  97. package/dist/core/diagnostics.js +2 -0
  98. package/dist/core/diagnostics.js.map +1 -0
  99. package/dist/core/event-bus.d.ts +9 -0
  100. package/dist/core/event-bus.d.ts.map +1 -0
  101. package/dist/core/event-bus.js +25 -0
  102. package/dist/core/event-bus.js.map +1 -0
  103. package/dist/core/exec.d.ts +29 -0
  104. package/dist/core/exec.d.ts.map +1 -0
  105. package/dist/core/exec.js +75 -0
  106. package/dist/core/exec.js.map +1 -0
  107. package/dist/core/export-html/ansi-to-html.d.ts +22 -0
  108. package/dist/core/export-html/ansi-to-html.d.ts.map +1 -0
  109. package/dist/core/export-html/ansi-to-html.js +245 -0
  110. package/dist/core/export-html/ansi-to-html.js.map +1 -0
  111. package/dist/core/export-html/index.d.ts +21 -0
  112. package/dist/core/export-html/index.d.ts.map +1 -0
  113. package/dist/core/export-html/index.js +230 -0
  114. package/dist/core/export-html/index.js.map +1 -0
  115. package/dist/core/export-html/template.css +1066 -0
  116. package/dist/core/export-html/template.html +55 -0
  117. package/dist/core/export-html/template.js +1864 -0
  118. package/dist/core/export-html/tool-renderer.d.ts +32 -0
  119. package/dist/core/export-html/tool-renderer.d.ts.map +1 -0
  120. package/dist/core/export-html/tool-renderer.js +108 -0
  121. package/dist/core/export-html/tool-renderer.js.map +1 -0
  122. package/dist/core/export-html/vendor/highlight.min.js +1213 -0
  123. package/dist/core/export-html/vendor/marked.min.js +78 -0
  124. package/dist/core/extensions/loader.d.ts +24 -0
  125. package/dist/core/extensions/loader.d.ts.map +1 -0
  126. package/dist/core/extensions/loader.js +613 -0
  127. package/dist/core/extensions/loader.js.map +1 -0
  128. package/dist/core/extensions/runner.d.ts +160 -0
  129. package/dist/core/extensions/runner.d.ts.map +1 -0
  130. package/dist/core/extensions/runner.js +962 -0
  131. package/dist/core/extensions/runner.js.map +1 -0
  132. package/dist/core/extensions/types.d.ts +1311 -0
  133. package/dist/core/extensions/types.d.ts.map +1 -0
  134. package/dist/core/extensions/types.js +51 -0
  135. package/dist/core/extensions/types.js.map +1 -0
  136. package/dist/core/extensions/wrapper.d.ts +20 -0
  137. package/dist/core/extensions/wrapper.d.ts.map +1 -0
  138. package/dist/core/extensions/wrapper.js +22 -0
  139. package/dist/core/extensions/wrapper.js.map +1 -0
  140. package/dist/core/footer-data-provider.d.ts +52 -0
  141. package/dist/core/footer-data-provider.d.ts.map +1 -0
  142. package/dist/core/footer-data-provider.js +318 -0
  143. package/dist/core/footer-data-provider.js.map +1 -0
  144. package/dist/core/grip-agent.d.ts +240 -0
  145. package/dist/core/grip-agent.d.ts.map +1 -0
  146. package/dist/core/grip-agent.js +1243 -0
  147. package/dist/core/grip-agent.js.map +1 -0
  148. package/dist/core/grip-manifest.d.ts +9 -0
  149. package/dist/core/grip-manifest.d.ts.map +1 -0
  150. package/dist/core/grip-manifest.js +25 -0
  151. package/dist/core/grip-manifest.js.map +1 -0
  152. package/dist/core/hooks/aggregate.d.ts +5 -0
  153. package/dist/core/hooks/aggregate.d.ts.map +1 -0
  154. package/dist/core/hooks/aggregate.js +226 -0
  155. package/dist/core/hooks/aggregate.js.map +1 -0
  156. package/dist/core/hooks/config.d.ts +14 -0
  157. package/dist/core/hooks/config.d.ts.map +1 -0
  158. package/dist/core/hooks/config.js +372 -0
  159. package/dist/core/hooks/config.js.map +1 -0
  160. package/dist/core/hooks/executor.d.ts +12 -0
  161. package/dist/core/hooks/executor.d.ts.map +1 -0
  162. package/dist/core/hooks/executor.js +708 -0
  163. package/dist/core/hooks/executor.js.map +1 -0
  164. package/dist/core/hooks/index.d.ts +9 -0
  165. package/dist/core/hooks/index.d.ts.map +1 -0
  166. package/dist/core/hooks/index.js +14 -0
  167. package/dist/core/hooks/index.js.map +1 -0
  168. package/dist/core/hooks/matcher.d.ts +10 -0
  169. package/dist/core/hooks/matcher.d.ts.map +1 -0
  170. package/dist/core/hooks/matcher.js +70 -0
  171. package/dist/core/hooks/matcher.js.map +1 -0
  172. package/dist/core/hooks/trust-store.d.ts +38 -0
  173. package/dist/core/hooks/trust-store.d.ts.map +1 -0
  174. package/dist/core/hooks/trust-store.js +167 -0
  175. package/dist/core/hooks/trust-store.js.map +1 -0
  176. package/dist/core/hooks/types.d.ts +234 -0
  177. package/dist/core/hooks/types.d.ts.map +1 -0
  178. package/dist/core/hooks/types.js +52 -0
  179. package/dist/core/hooks/types.js.map +1 -0
  180. package/dist/core/http-dispatcher.d.ts +21 -0
  181. package/dist/core/http-dispatcher.d.ts.map +1 -0
  182. package/dist/core/http-dispatcher.js +82 -0
  183. package/dist/core/http-dispatcher.js.map +1 -0
  184. package/dist/core/instruction-resource-loader.d.ts +81 -0
  185. package/dist/core/instruction-resource-loader.d.ts.map +1 -0
  186. package/dist/core/instruction-resource-loader.js +574 -0
  187. package/dist/core/instruction-resource-loader.js.map +1 -0
  188. package/dist/core/keybindings.d.ts +399 -0
  189. package/dist/core/keybindings.d.ts.map +1 -0
  190. package/dist/core/keybindings.js +299 -0
  191. package/dist/core/keybindings.js.map +1 -0
  192. package/dist/core/lsp/abort.d.ts +3 -0
  193. package/dist/core/lsp/abort.d.ts.map +1 -0
  194. package/dist/core/lsp/abort.js +28 -0
  195. package/dist/core/lsp/abort.js.map +1 -0
  196. package/dist/core/lsp/client.d.ts +108 -0
  197. package/dist/core/lsp/client.d.ts.map +1 -0
  198. package/dist/core/lsp/client.js +586 -0
  199. package/dist/core/lsp/client.js.map +1 -0
  200. package/dist/core/lsp/config-loader.d.ts +44 -0
  201. package/dist/core/lsp/config-loader.d.ts.map +1 -0
  202. package/dist/core/lsp/config-loader.js +223 -0
  203. package/dist/core/lsp/config-loader.js.map +1 -0
  204. package/dist/core/lsp/config.d.ts +134 -0
  205. package/dist/core/lsp/config.d.ts.map +1 -0
  206. package/dist/core/lsp/config.js +682 -0
  207. package/dist/core/lsp/config.js.map +1 -0
  208. package/dist/core/lsp/diagnostics.d.ts +18 -0
  209. package/dist/core/lsp/diagnostics.d.ts.map +1 -0
  210. package/dist/core/lsp/diagnostics.js +311 -0
  211. package/dist/core/lsp/diagnostics.js.map +1 -0
  212. package/dist/core/lsp/file-sync.d.ts +58 -0
  213. package/dist/core/lsp/file-sync.d.ts.map +1 -0
  214. package/dist/core/lsp/file-sync.js +432 -0
  215. package/dist/core/lsp/file-sync.js.map +1 -0
  216. package/dist/core/lsp/integration.d.ts +62 -0
  217. package/dist/core/lsp/integration.d.ts.map +1 -0
  218. package/dist/core/lsp/integration.js +145 -0
  219. package/dist/core/lsp/integration.js.map +1 -0
  220. package/dist/core/lsp/language-map.d.ts +54 -0
  221. package/dist/core/lsp/language-map.d.ts.map +1 -0
  222. package/dist/core/lsp/language-map.js +300 -0
  223. package/dist/core/lsp/language-map.js.map +1 -0
  224. package/dist/core/lsp/manager.d.ts +120 -0
  225. package/dist/core/lsp/manager.d.ts.map +1 -0
  226. package/dist/core/lsp/manager.js +636 -0
  227. package/dist/core/lsp/manager.js.map +1 -0
  228. package/dist/core/lsp/navigation.d.ts +32 -0
  229. package/dist/core/lsp/navigation.d.ts.map +1 -0
  230. package/dist/core/lsp/navigation.js +327 -0
  231. package/dist/core/lsp/navigation.js.map +1 -0
  232. package/dist/core/lsp/portable-path.d.ts +18 -0
  233. package/dist/core/lsp/portable-path.d.ts.map +1 -0
  234. package/dist/core/lsp/portable-path.js +83 -0
  235. package/dist/core/lsp/portable-path.js.map +1 -0
  236. package/dist/core/lsp/refactor.d.ts +32 -0
  237. package/dist/core/lsp/refactor.d.ts.map +1 -0
  238. package/dist/core/lsp/refactor.js +519 -0
  239. package/dist/core/lsp/refactor.js.map +1 -0
  240. package/dist/core/lsp/transport.d.ts +39 -0
  241. package/dist/core/lsp/transport.d.ts.map +1 -0
  242. package/dist/core/lsp/transport.js +261 -0
  243. package/dist/core/lsp/transport.js.map +1 -0
  244. package/dist/core/messages.d.ts +34 -0
  245. package/dist/core/messages.d.ts.map +1 -0
  246. package/dist/core/messages.js +140 -0
  247. package/dist/core/messages.js.map +1 -0
  248. package/dist/core/model-registry.d.ts +148 -0
  249. package/dist/core/model-registry.d.ts.map +1 -0
  250. package/dist/core/model-registry.js +812 -0
  251. package/dist/core/model-registry.js.map +1 -0
  252. package/dist/core/model-resolver.d.ts +115 -0
  253. package/dist/core/model-resolver.d.ts.map +1 -0
  254. package/dist/core/model-resolver.js +498 -0
  255. package/dist/core/model-resolver.js.map +1 -0
  256. package/dist/core/output-guard.d.ts +7 -0
  257. package/dist/core/output-guard.d.ts.map +1 -0
  258. package/dist/core/output-guard.js +89 -0
  259. package/dist/core/output-guard.js.map +1 -0
  260. package/dist/core/package-manager.d.ts +209 -0
  261. package/dist/core/package-manager.d.ts.map +1 -0
  262. package/dist/core/package-manager.js +2341 -0
  263. package/dist/core/package-manager.js.map +1 -0
  264. package/dist/core/prompt-templates.d.ts +57 -0
  265. package/dist/core/prompt-templates.d.ts.map +1 -0
  266. package/dist/core/prompt-templates.js +353 -0
  267. package/dist/core/prompt-templates.js.map +1 -0
  268. package/dist/core/provider-display-names.d.ts +2 -0
  269. package/dist/core/provider-display-names.d.ts.map +1 -0
  270. package/dist/core/provider-display-names.js +33 -0
  271. package/dist/core/provider-display-names.js.map +1 -0
  272. package/dist/core/remote-workspace-protocol/contract.d.ts +465 -0
  273. package/dist/core/remote-workspace-protocol/contract.d.ts.map +1 -0
  274. package/dist/core/remote-workspace-protocol/contract.js +825 -0
  275. package/dist/core/remote-workspace-protocol/contract.js.map +1 -0
  276. package/dist/core/remote-workspace-protocol/guest-shared-client.d.ts +16 -0
  277. package/dist/core/remote-workspace-protocol/guest-shared-client.d.ts.map +1 -0
  278. package/dist/core/remote-workspace-protocol/guest-shared-client.js +54 -0
  279. package/dist/core/remote-workspace-protocol/guest-shared-client.js.map +1 -0
  280. package/dist/core/remote-workspace-protocol/guest-shared-outbound-scheduler.d.ts +23 -0
  281. package/dist/core/remote-workspace-protocol/guest-shared-outbound-scheduler.d.ts.map +1 -0
  282. package/dist/core/remote-workspace-protocol/guest-shared-outbound-scheduler.js +112 -0
  283. package/dist/core/remote-workspace-protocol/guest-shared-outbound-scheduler.js.map +1 -0
  284. package/dist/core/remote-workspace-protocol/guest-shared-uplink.d.ts +30 -0
  285. package/dist/core/remote-workspace-protocol/guest-shared-uplink.d.ts.map +1 -0
  286. package/dist/core/remote-workspace-protocol/guest-shared-uplink.js +243 -0
  287. package/dist/core/remote-workspace-protocol/guest-shared-uplink.js.map +1 -0
  288. package/dist/core/remote-workspace-protocol/lima-owner-directory.d.ts +3 -0
  289. package/dist/core/remote-workspace-protocol/lima-owner-directory.d.ts.map +1 -0
  290. package/dist/core/remote-workspace-protocol/lima-owner-directory.js +31 -0
  291. package/dist/core/remote-workspace-protocol/lima-owner-directory.js.map +1 -0
  292. package/dist/core/remote-workspace-protocol/lima-owner-lock.d.ts +9 -0
  293. package/dist/core/remote-workspace-protocol/lima-owner-lock.d.ts.map +1 -0
  294. package/dist/core/remote-workspace-protocol/lima-owner-lock.js +89 -0
  295. package/dist/core/remote-workspace-protocol/lima-owner-lock.js.map +1 -0
  296. package/dist/core/remote-workspace-protocol/session.d.ts +249 -0
  297. package/dist/core/remote-workspace-protocol/session.d.ts.map +1 -0
  298. package/dist/core/remote-workspace-protocol/session.js +1842 -0
  299. package/dist/core/remote-workspace-protocol/session.js.map +1 -0
  300. package/dist/core/remote-workspace-protocol/shared-transport.d.ts +71 -0
  301. package/dist/core/remote-workspace-protocol/shared-transport.d.ts.map +1 -0
  302. package/dist/core/remote-workspace-protocol/shared-transport.js +68 -0
  303. package/dist/core/remote-workspace-protocol/shared-transport.js.map +1 -0
  304. package/dist/core/resolve-config-value.d.ts +32 -0
  305. package/dist/core/resolve-config-value.d.ts.map +1 -0
  306. package/dist/core/resolve-config-value.js +257 -0
  307. package/dist/core/resolve-config-value.js.map +1 -0
  308. package/dist/core/resource-loader.d.ts +200 -0
  309. package/dist/core/resource-loader.d.ts.map +1 -0
  310. package/dist/core/resource-loader.js +1209 -0
  311. package/dist/core/resource-loader.js.map +1 -0
  312. package/dist/core/rules.d.ts +40 -0
  313. package/dist/core/rules.d.ts.map +1 -0
  314. package/dist/core/rules.js +57 -0
  315. package/dist/core/rules.js.map +1 -0
  316. package/dist/core/sandbox/command.d.ts +25 -0
  317. package/dist/core/sandbox/command.d.ts.map +1 -0
  318. package/dist/core/sandbox/command.js +102 -0
  319. package/dist/core/sandbox/command.js.map +1 -0
  320. package/dist/core/sandbox/config.d.ts +91 -0
  321. package/dist/core/sandbox/config.d.ts.map +1 -0
  322. package/dist/core/sandbox/config.js +88 -0
  323. package/dist/core/sandbox/config.js.map +1 -0
  324. package/dist/core/sandbox/lima-guest-binary.d.ts +11 -0
  325. package/dist/core/sandbox/lima-guest-binary.d.ts.map +1 -0
  326. package/dist/core/sandbox/lima-guest-binary.js +140 -0
  327. package/dist/core/sandbox/lima-guest-binary.js.map +1 -0
  328. package/dist/core/sandbox/lima.d.ts +57 -0
  329. package/dist/core/sandbox/lima.d.ts.map +1 -0
  330. package/dist/core/sandbox/lima.js +716 -0
  331. package/dist/core/sandbox/lima.js.map +1 -0
  332. package/dist/core/sandbox/shared-lima-roots.d.ts +11 -0
  333. package/dist/core/sandbox/shared-lima-roots.d.ts.map +1 -0
  334. package/dist/core/sandbox/shared-lima-roots.js +25 -0
  335. package/dist/core/sandbox/shared-lima-roots.js.map +1 -0
  336. package/dist/core/sandbox/update-shared-guest-binary.d.ts +8 -0
  337. package/dist/core/sandbox/update-shared-guest-binary.d.ts.map +1 -0
  338. package/dist/core/sandbox/update-shared-guest-binary.js +100 -0
  339. package/dist/core/sandbox/update-shared-guest-binary.js.map +1 -0
  340. package/dist/core/session/constants.d.ts +2 -0
  341. package/dist/core/session/constants.d.ts.map +1 -0
  342. package/dist/core/session/constants.js +2 -0
  343. package/dist/core/session/constants.js.map +1 -0
  344. package/dist/core/session/context-metadata.d.ts +5 -0
  345. package/dist/core/session/context-metadata.d.ts.map +1 -0
  346. package/dist/core/session/context-metadata.js +55 -0
  347. package/dist/core/session/context-metadata.js.map +1 -0
  348. package/dist/core/session/context.d.ts +14 -0
  349. package/dist/core/session/context.d.ts.map +1 -0
  350. package/dist/core/session/context.js +117 -0
  351. package/dist/core/session/context.js.map +1 -0
  352. package/dist/core/session/ids.d.ts +9 -0
  353. package/dist/core/session/ids.d.ts.map +1 -0
  354. package/dist/core/session/ids.js +21 -0
  355. package/dist/core/session/ids.js.map +1 -0
  356. package/dist/core/session/in-memory-session-manager.d.ts +17 -0
  357. package/dist/core/session/in-memory-session-manager.d.ts.map +1 -0
  358. package/dist/core/session/in-memory-session-manager.js +40 -0
  359. package/dist/core/session/in-memory-session-manager.js.map +1 -0
  360. package/dist/core/session/in-memory-session.d.ts +7 -0
  361. package/dist/core/session/in-memory-session.d.ts.map +1 -0
  362. package/dist/core/session/in-memory-session.js +11 -0
  363. package/dist/core/session/in-memory-session.js.map +1 -0
  364. package/dist/core/session/jsonl-errors.d.ts +36 -0
  365. package/dist/core/session/jsonl-errors.d.ts.map +1 -0
  366. package/dist/core/session/jsonl-errors.js +49 -0
  367. package/dist/core/session/jsonl-errors.js.map +1 -0
  368. package/dist/core/session/jsonl-helpers.d.ts +20 -0
  369. package/dist/core/session/jsonl-helpers.d.ts.map +1 -0
  370. package/dist/core/session/jsonl-helpers.js +21 -0
  371. package/dist/core/session/jsonl-helpers.js.map +1 -0
  372. package/dist/core/session/local-session-manager.d.ts +30 -0
  373. package/dist/core/session/local-session-manager.d.ts.map +1 -0
  374. package/dist/core/session/local-session-manager.js +205 -0
  375. package/dist/core/session/local-session-manager.js.map +1 -0
  376. package/dist/core/session/local-session.d.ts +9 -0
  377. package/dist/core/session/local-session.d.ts.map +1 -0
  378. package/dist/core/session/local-session.js +15 -0
  379. package/dist/core/session/local-session.js.map +1 -0
  380. package/dist/core/session/migrations.d.ts +11 -0
  381. package/dist/core/session/migrations.d.ts.map +1 -0
  382. package/dist/core/session/migrations.js +78 -0
  383. package/dist/core/session/migrations.js.map +1 -0
  384. package/dist/core/session/remote-session-client.d.ts +83 -0
  385. package/dist/core/session/remote-session-client.d.ts.map +1 -0
  386. package/dist/core/session/remote-session-client.js +224 -0
  387. package/dist/core/session/remote-session-client.js.map +1 -0
  388. package/dist/core/session/remote-session-manager.d.ts +32 -0
  389. package/dist/core/session/remote-session-manager.d.ts.map +1 -0
  390. package/dist/core/session/remote-session-manager.js +124 -0
  391. package/dist/core/session/remote-session-manager.js.map +1 -0
  392. package/dist/core/session/remote-session.d.ts +20 -0
  393. package/dist/core/session/remote-session.d.ts.map +1 -0
  394. package/dist/core/session/remote-session.js +33 -0
  395. package/dist/core/session/remote-session.js.map +1 -0
  396. package/dist/core/session/session-manager.d.ts +18 -0
  397. package/dist/core/session/session-manager.d.ts.map +1 -0
  398. package/dist/core/session/session-manager.js +2 -0
  399. package/dist/core/session/session-manager.js.map +1 -0
  400. package/dist/core/session/session.d.ts +140 -0
  401. package/dist/core/session/session.d.ts.map +1 -0
  402. package/dist/core/session/session.js +461 -0
  403. package/dist/core/session/session.js.map +1 -0
  404. package/dist/core/session/stores/in-memory-session-store.d.ts +39 -0
  405. package/dist/core/session/stores/in-memory-session-store.d.ts.map +1 -0
  406. package/dist/core/session/stores/in-memory-session-store.js +168 -0
  407. package/dist/core/session/stores/in-memory-session-store.js.map +1 -0
  408. package/dist/core/session/stores/jsonl-session-store.d.ts +97 -0
  409. package/dist/core/session/stores/jsonl-session-store.d.ts.map +1 -0
  410. package/dist/core/session/stores/jsonl-session-store.js +1140 -0
  411. package/dist/core/session/stores/jsonl-session-store.js.map +1 -0
  412. package/dist/core/session/stores/remote-session-store.d.ts +44 -0
  413. package/dist/core/session/stores/remote-session-store.d.ts.map +1 -0
  414. package/dist/core/session/stores/remote-session-store.js +159 -0
  415. package/dist/core/session/stores/remote-session-store.js.map +1 -0
  416. package/dist/core/session/stores/session-store.d.ts +42 -0
  417. package/dist/core/session/stores/session-store.d.ts.map +1 -0
  418. package/dist/core/session/stores/session-store.js +2 -0
  419. package/dist/core/session/stores/session-store.js.map +1 -0
  420. package/dist/core/session/types.d.ts +141 -0
  421. package/dist/core/session/types.d.ts.map +1 -0
  422. package/dist/core/session/types.js +2 -0
  423. package/dist/core/session/types.js.map +1 -0
  424. package/dist/core/session/usage-ledger.d.ts +18 -0
  425. package/dist/core/session/usage-ledger.d.ts.map +1 -0
  426. package/dist/core/session/usage-ledger.js +68 -0
  427. package/dist/core/session/usage-ledger.js.map +1 -0
  428. package/dist/core/session-cwd.d.ts +19 -0
  429. package/dist/core/session-cwd.d.ts.map +1 -0
  430. package/dist/core/session-cwd.js +38 -0
  431. package/dist/core/session-cwd.js.map +1 -0
  432. package/dist/core/settings-manager.d.ts +314 -0
  433. package/dist/core/settings-manager.d.ts.map +1 -0
  434. package/dist/core/settings-manager.js +991 -0
  435. package/dist/core/settings-manager.js.map +1 -0
  436. package/dist/core/skills.d.ts +40 -0
  437. package/dist/core/skills.d.ts.map +1 -0
  438. package/dist/core/skills.js +57 -0
  439. package/dist/core/skills.js.map +1 -0
  440. package/dist/core/slash-commands.d.ts +15 -0
  441. package/dist/core/slash-commands.d.ts.map +1 -0
  442. package/dist/core/slash-commands.js +36 -0
  443. package/dist/core/slash-commands.js.map +1 -0
  444. package/dist/core/source-info.d.ts +26 -0
  445. package/dist/core/source-info.d.ts.map +1 -0
  446. package/dist/core/source-info.js +27 -0
  447. package/dist/core/source-info.js.map +1 -0
  448. package/dist/core/system-prompt.d.ts +32 -0
  449. package/dist/core/system-prompt.d.ts.map +1 -0
  450. package/dist/core/system-prompt.js +131 -0
  451. package/dist/core/system-prompt.js.map +1 -0
  452. package/dist/core/telemetry.d.ts +3 -0
  453. package/dist/core/telemetry.d.ts.map +1 -0
  454. package/dist/core/telemetry.js +9 -0
  455. package/dist/core/telemetry.js.map +1 -0
  456. package/dist/core/timings.d.ts +10 -0
  457. package/dist/core/timings.d.ts.map +1 -0
  458. package/dist/core/timings.js +41 -0
  459. package/dist/core/timings.js.map +1 -0
  460. package/dist/core/tools/bash.d.ts +51 -0
  461. package/dist/core/tools/bash.d.ts.map +1 -0
  462. package/dist/core/tools/bash.js +321 -0
  463. package/dist/core/tools/bash.js.map +1 -0
  464. package/dist/core/tools/compress-context.d.ts +27 -0
  465. package/dist/core/tools/compress-context.d.ts.map +1 -0
  466. package/dist/core/tools/compress-context.js +142 -0
  467. package/dist/core/tools/compress-context.js.map +1 -0
  468. package/dist/core/tools/edit-diff.d.ts +82 -0
  469. package/dist/core/tools/edit-diff.d.ts.map +1 -0
  470. package/dist/core/tools/edit-diff.js +327 -0
  471. package/dist/core/tools/edit-diff.js.map +1 -0
  472. package/dist/core/tools/edit.d.ts +50 -0
  473. package/dist/core/tools/edit.d.ts.map +1 -0
  474. package/dist/core/tools/edit.js +324 -0
  475. package/dist/core/tools/edit.js.map +1 -0
  476. package/dist/core/tools/file-mutation-queue.d.ts +8 -0
  477. package/dist/core/tools/file-mutation-queue.d.ts.map +1 -0
  478. package/dist/core/tools/file-mutation-queue.js +69 -0
  479. package/dist/core/tools/file-mutation-queue.js.map +1 -0
  480. package/dist/core/tools/find.d.ts +22 -0
  481. package/dist/core/tools/find.d.ts.map +1 -0
  482. package/dist/core/tools/find.js +268 -0
  483. package/dist/core/tools/find.js.map +1 -0
  484. package/dist/core/tools/grep.d.ts +27 -0
  485. package/dist/core/tools/grep.d.ts.map +1 -0
  486. package/dist/core/tools/grep.js +332 -0
  487. package/dist/core/tools/grep.js.map +1 -0
  488. package/dist/core/tools/hash-store.d.ts +12 -0
  489. package/dist/core/tools/hash-store.d.ts.map +1 -0
  490. package/dist/core/tools/hash-store.js +48 -0
  491. package/dist/core/tools/hash-store.js.map +1 -0
  492. package/dist/core/tools/hashline/apply.d.ts +40 -0
  493. package/dist/core/tools/hashline/apply.d.ts.map +1 -0
  494. package/dist/core/tools/hashline/apply.js +261 -0
  495. package/dist/core/tools/hashline/apply.js.map +1 -0
  496. package/dist/core/tools/hashline/hash.d.ts +56 -0
  497. package/dist/core/tools/hashline/hash.d.ts.map +1 -0
  498. package/dist/core/tools/hashline/hash.js +196 -0
  499. package/dist/core/tools/hashline/hash.js.map +1 -0
  500. package/dist/core/tools/hashline/parse.d.ts +8 -0
  501. package/dist/core/tools/hashline/parse.d.ts.map +1 -0
  502. package/dist/core/tools/hashline/parse.js +41 -0
  503. package/dist/core/tools/hashline/parse.js.map +1 -0
  504. package/dist/core/tools/hashline/resolve.d.ts +51 -0
  505. package/dist/core/tools/hashline/resolve.d.ts.map +1 -0
  506. package/dist/core/tools/hashline/resolve.js +187 -0
  507. package/dist/core/tools/hashline/resolve.js.map +1 -0
  508. package/dist/core/tools/hashline-utils.d.ts +6 -0
  509. package/dist/core/tools/hashline-utils.d.ts.map +1 -0
  510. package/dist/core/tools/hashline-utils.js +23 -0
  511. package/dist/core/tools/hashline-utils.js.map +1 -0
  512. package/dist/core/tools/index.d.ts +36 -0
  513. package/dist/core/tools/index.d.ts.map +1 -0
  514. package/dist/core/tools/index.js +141 -0
  515. package/dist/core/tools/index.js.map +1 -0
  516. package/dist/core/tools/ls.d.ts +21 -0
  517. package/dist/core/tools/ls.d.ts.map +1 -0
  518. package/dist/core/tools/ls.js +156 -0
  519. package/dist/core/tools/ls.js.map +1 -0
  520. package/dist/core/tools/operations.d.ts +212 -0
  521. package/dist/core/tools/operations.d.ts.map +1 -0
  522. package/dist/core/tools/operations.js +793 -0
  523. package/dist/core/tools/operations.js.map +1 -0
  524. package/dist/core/tools/output-accumulator.d.ts +54 -0
  525. package/dist/core/tools/output-accumulator.d.ts.map +1 -0
  526. package/dist/core/tools/output-accumulator.js +184 -0
  527. package/dist/core/tools/output-accumulator.js.map +1 -0
  528. package/dist/core/tools/path-utils.d.ts +9 -0
  529. package/dist/core/tools/path-utils.d.ts.map +1 -0
  530. package/dist/core/tools/path-utils.js +99 -0
  531. package/dist/core/tools/path-utils.js.map +1 -0
  532. package/dist/core/tools/read.d.ts +32 -0
  533. package/dist/core/tools/read.d.ts.map +1 -0
  534. package/dist/core/tools/read.js +318 -0
  535. package/dist/core/tools/read.js.map +1 -0
  536. package/dist/core/tools/render-utils.d.ts +33 -0
  537. package/dist/core/tools/render-utils.d.ts.map +1 -0
  538. package/dist/core/tools/render-utils.js +61 -0
  539. package/dist/core/tools/render-utils.js.map +1 -0
  540. package/dist/core/tools/replace-diff.d.ts +16 -0
  541. package/dist/core/tools/replace-diff.d.ts.map +1 -0
  542. package/dist/core/tools/replace-diff.js +117 -0
  543. package/dist/core/tools/replace-diff.js.map +1 -0
  544. package/dist/core/tools/replace-normalize.d.ts +2 -0
  545. package/dist/core/tools/replace-normalize.d.ts.map +1 -0
  546. package/dist/core/tools/replace-normalize.js +73 -0
  547. package/dist/core/tools/replace-normalize.js.map +1 -0
  548. package/dist/core/tools/replace-render.d.ts +51 -0
  549. package/dist/core/tools/replace-render.d.ts.map +1 -0
  550. package/dist/core/tools/replace-render.js +162 -0
  551. package/dist/core/tools/replace-render.js.map +1 -0
  552. package/dist/core/tools/runtime.d.ts +2 -0
  553. package/dist/core/tools/runtime.d.ts.map +1 -0
  554. package/dist/core/tools/runtime.js +6 -0
  555. package/dist/core/tools/runtime.js.map +1 -0
  556. package/dist/core/tools/session-history.d.ts +55 -0
  557. package/dist/core/tools/session-history.d.ts.map +1 -0
  558. package/dist/core/tools/session-history.js +649 -0
  559. package/dist/core/tools/session-history.js.map +1 -0
  560. package/dist/core/tools/subagent-agents.d.ts +29 -0
  561. package/dist/core/tools/subagent-agents.d.ts.map +1 -0
  562. package/dist/core/tools/subagent-agents.js +223 -0
  563. package/dist/core/tools/subagent-agents.js.map +1 -0
  564. package/dist/core/tools/subagent.d.ts +185 -0
  565. package/dist/core/tools/subagent.d.ts.map +1 -0
  566. package/dist/core/tools/subagent.js +1309 -0
  567. package/dist/core/tools/subagent.js.map +1 -0
  568. package/dist/core/tools/tool-definition-wrapper.d.ts +14 -0
  569. package/dist/core/tools/tool-definition-wrapper.d.ts.map +1 -0
  570. package/dist/core/tools/tool-definition-wrapper.js +34 -0
  571. package/dist/core/tools/tool-definition-wrapper.js.map +1 -0
  572. package/dist/core/tools/truncate.d.ts +39 -0
  573. package/dist/core/tools/truncate.d.ts.map +1 -0
  574. package/dist/core/tools/truncate.js +215 -0
  575. package/dist/core/tools/truncate.js.map +1 -0
  576. package/dist/core/tools/websearch.d.ts +33 -0
  577. package/dist/core/tools/websearch.d.ts.map +1 -0
  578. package/dist/core/tools/websearch.js +341 -0
  579. package/dist/core/tools/websearch.js.map +1 -0
  580. package/dist/core/tools/workspace-tool-host.d.ts +102 -0
  581. package/dist/core/tools/workspace-tool-host.d.ts.map +1 -0
  582. package/dist/core/tools/workspace-tool-host.js +348 -0
  583. package/dist/core/tools/workspace-tool-host.js.map +1 -0
  584. package/dist/core/tools/write.d.ts +16 -0
  585. package/dist/core/tools/write.d.ts.map +1 -0
  586. package/dist/core/tools/write.js +204 -0
  587. package/dist/core/tools/write.js.map +1 -0
  588. package/dist/core/workspace-identity.d.ts +7 -0
  589. package/dist/core/workspace-identity.d.ts.map +1 -0
  590. package/dist/core/workspace-identity.js +2 -0
  591. package/dist/core/workspace-identity.js.map +1 -0
  592. package/dist/daemon/activity-budget.d.ts +10 -0
  593. package/dist/daemon/activity-budget.d.ts.map +1 -0
  594. package/dist/daemon/activity-budget.js +34 -0
  595. package/dist/daemon/activity-budget.js.map +1 -0
  596. package/dist/daemon/command.d.ts +6 -0
  597. package/dist/daemon/command.d.ts.map +1 -0
  598. package/dist/daemon/command.js +58 -0
  599. package/dist/daemon/command.js.map +1 -0
  600. package/dist/daemon/config.d.ts +45 -0
  601. package/dist/daemon/config.d.ts.map +1 -0
  602. package/dist/daemon/config.js +319 -0
  603. package/dist/daemon/config.js.map +1 -0
  604. package/dist/daemon/help.d.ts +2 -0
  605. package/dist/daemon/help.d.ts.map +1 -0
  606. package/dist/daemon/help.js +42 -0
  607. package/dist/daemon/help.js.map +1 -0
  608. package/dist/daemon/lsp-config.d.ts +4 -0
  609. package/dist/daemon/lsp-config.d.ts.map +1 -0
  610. package/dist/daemon/lsp-config.js +155 -0
  611. package/dist/daemon/lsp-config.js.map +1 -0
  612. package/dist/daemon/outbound-budget.d.ts +10 -0
  613. package/dist/daemon/outbound-budget.d.ts.map +1 -0
  614. package/dist/daemon/outbound-budget.js +30 -0
  615. package/dist/daemon/outbound-budget.js.map +1 -0
  616. package/dist/daemon/security.d.ts +19 -0
  617. package/dist/daemon/security.d.ts.map +1 -0
  618. package/dist/daemon/security.js +177 -0
  619. package/dist/daemon/security.js.map +1 -0
  620. package/dist/daemon/server.d.ts +20 -0
  621. package/dist/daemon/server.d.ts.map +1 -0
  622. package/dist/daemon/server.js +480 -0
  623. package/dist/daemon/server.js.map +1 -0
  624. package/dist/daemon/shared-connection.d.ts +33 -0
  625. package/dist/daemon/shared-connection.d.ts.map +1 -0
  626. package/dist/daemon/shared-connection.js +271 -0
  627. package/dist/daemon/shared-connection.js.map +1 -0
  628. package/dist/daemon/shared-revision.d.ts +5 -0
  629. package/dist/daemon/shared-revision.d.ts.map +1 -0
  630. package/dist/daemon/shared-revision.js +61 -0
  631. package/dist/daemon/shared-revision.js.map +1 -0
  632. package/dist/daemon/shared-roots.d.ts +9 -0
  633. package/dist/daemon/shared-roots.d.ts.map +1 -0
  634. package/dist/daemon/shared-roots.js +33 -0
  635. package/dist/daemon/shared-roots.js.map +1 -0
  636. package/dist/daemon/workspace-runtime.d.ts +46 -0
  637. package/dist/daemon/workspace-runtime.d.ts.map +1 -0
  638. package/dist/daemon/workspace-runtime.js +705 -0
  639. package/dist/daemon/workspace-runtime.js.map +1 -0
  640. package/dist/index.d.ts +109 -0
  641. package/dist/index.d.ts.map +1 -0
  642. package/dist/index.js +107 -0
  643. package/dist/index.js.map +1 -0
  644. package/dist/main.d.ts +39 -0
  645. package/dist/main.d.ts.map +1 -0
  646. package/dist/main.js +765 -0
  647. package/dist/main.js.map +1 -0
  648. package/dist/migrations.d.ts +35 -0
  649. package/dist/migrations.d.ts.map +1 -0
  650. package/dist/migrations.js +412 -0
  651. package/dist/migrations.js.map +1 -0
  652. package/dist/modes/interactive/components/assistant-message.d.ts +30 -0
  653. package/dist/modes/interactive/components/assistant-message.d.ts.map +1 -0
  654. package/dist/modes/interactive/components/assistant-message.js +159 -0
  655. package/dist/modes/interactive/components/assistant-message.js.map +1 -0
  656. package/dist/modes/interactive/components/bash-execution.d.ts +36 -0
  657. package/dist/modes/interactive/components/bash-execution.d.ts.map +1 -0
  658. package/dist/modes/interactive/components/bash-execution.js +173 -0
  659. package/dist/modes/interactive/components/bash-execution.js.map +1 -0
  660. package/dist/modes/interactive/components/bordered-loader.d.ts +18 -0
  661. package/dist/modes/interactive/components/bordered-loader.d.ts.map +1 -0
  662. package/dist/modes/interactive/components/bordered-loader.js +54 -0
  663. package/dist/modes/interactive/components/bordered-loader.js.map +1 -0
  664. package/dist/modes/interactive/components/branch-summary-message.d.ts +17 -0
  665. package/dist/modes/interactive/components/branch-summary-message.d.ts.map +1 -0
  666. package/dist/modes/interactive/components/branch-summary-message.js +45 -0
  667. package/dist/modes/interactive/components/branch-summary-message.js.map +1 -0
  668. package/dist/modes/interactive/components/compaction-summary-message.d.ts +17 -0
  669. package/dist/modes/interactive/components/compaction-summary-message.d.ts.map +1 -0
  670. package/dist/modes/interactive/components/compaction-summary-message.js +46 -0
  671. package/dist/modes/interactive/components/compaction-summary-message.js.map +1 -0
  672. package/dist/modes/interactive/components/config-selector.d.ts +74 -0
  673. package/dist/modes/interactive/components/config-selector.d.ts.map +1 -0
  674. package/dist/modes/interactive/components/config-selector.js +514 -0
  675. package/dist/modes/interactive/components/config-selector.js.map +1 -0
  676. package/dist/modes/interactive/components/countdown-timer.d.ts +14 -0
  677. package/dist/modes/interactive/components/countdown-timer.d.ts.map +1 -0
  678. package/dist/modes/interactive/components/countdown-timer.js +33 -0
  679. package/dist/modes/interactive/components/countdown-timer.js.map +1 -0
  680. package/dist/modes/interactive/components/custom-editor.d.ts +25 -0
  681. package/dist/modes/interactive/components/custom-editor.d.ts.map +1 -0
  682. package/dist/modes/interactive/components/custom-editor.js +85 -0
  683. package/dist/modes/interactive/components/custom-editor.js.map +1 -0
  684. package/dist/modes/interactive/components/custom-message.d.ts +20 -0
  685. package/dist/modes/interactive/components/custom-message.d.ts.map +1 -0
  686. package/dist/modes/interactive/components/custom-message.js +81 -0
  687. package/dist/modes/interactive/components/custom-message.js.map +1 -0
  688. package/dist/modes/interactive/components/diff.d.ts +12 -0
  689. package/dist/modes/interactive/components/diff.d.ts.map +1 -0
  690. package/dist/modes/interactive/components/diff.js +118 -0
  691. package/dist/modes/interactive/components/diff.js.map +1 -0
  692. package/dist/modes/interactive/components/dynamic-border.d.ts +15 -0
  693. package/dist/modes/interactive/components/dynamic-border.d.ts.map +1 -0
  694. package/dist/modes/interactive/components/dynamic-border.js +21 -0
  695. package/dist/modes/interactive/components/dynamic-border.js.map +1 -0
  696. package/dist/modes/interactive/components/extension-editor.d.ts +22 -0
  697. package/dist/modes/interactive/components/extension-editor.d.ts.map +1 -0
  698. package/dist/modes/interactive/components/extension-editor.js +128 -0
  699. package/dist/modes/interactive/components/extension-editor.js.map +1 -0
  700. package/dist/modes/interactive/components/extension-input.d.ts +23 -0
  701. package/dist/modes/interactive/components/extension-input.d.ts.map +1 -0
  702. package/dist/modes/interactive/components/extension-input.js +61 -0
  703. package/dist/modes/interactive/components/extension-input.js.map +1 -0
  704. package/dist/modes/interactive/components/extension-selector.d.ts +26 -0
  705. package/dist/modes/interactive/components/extension-selector.d.ts.map +1 -0
  706. package/dist/modes/interactive/components/extension-selector.js +83 -0
  707. package/dist/modes/interactive/components/extension-selector.js.map +1 -0
  708. package/dist/modes/interactive/components/footer.d.ts +36 -0
  709. package/dist/modes/interactive/components/footer.d.ts.map +1 -0
  710. package/dist/modes/interactive/components/footer.js +227 -0
  711. package/dist/modes/interactive/components/footer.js.map +1 -0
  712. package/dist/modes/interactive/components/hook-execution.d.ts +19 -0
  713. package/dist/modes/interactive/components/hook-execution.d.ts.map +1 -0
  714. package/dist/modes/interactive/components/hook-execution.js +185 -0
  715. package/dist/modes/interactive/components/hook-execution.js.map +1 -0
  716. package/dist/modes/interactive/components/keybinding-hints.d.ts +13 -0
  717. package/dist/modes/interactive/components/keybinding-hints.d.ts.map +1 -0
  718. package/dist/modes/interactive/components/keybinding-hints.js +36 -0
  719. package/dist/modes/interactive/components/keybinding-hints.js.map +1 -0
  720. package/dist/modes/interactive/components/login-dialog.d.ts +55 -0
  721. package/dist/modes/interactive/components/login-dialog.d.ts.map +1 -0
  722. package/dist/modes/interactive/components/login-dialog.js +176 -0
  723. package/dist/modes/interactive/components/login-dialog.js.map +1 -0
  724. package/dist/modes/interactive/components/markdown-transform.d.ts +4 -0
  725. package/dist/modes/interactive/components/markdown-transform.d.ts.map +1 -0
  726. package/dist/modes/interactive/components/markdown-transform.js +19 -0
  727. package/dist/modes/interactive/components/markdown-transform.js.map +1 -0
  728. package/dist/modes/interactive/components/mermaid.d.ts +14 -0
  729. package/dist/modes/interactive/components/mermaid.d.ts.map +1 -0
  730. package/dist/modes/interactive/components/mermaid.js +228 -0
  731. package/dist/modes/interactive/components/mermaid.js.map +1 -0
  732. package/dist/modes/interactive/components/message-card.d.ts +9 -0
  733. package/dist/modes/interactive/components/message-card.d.ts.map +1 -0
  734. package/dist/modes/interactive/components/message-card.js +24 -0
  735. package/dist/modes/interactive/components/message-card.js.map +1 -0
  736. package/dist/modes/interactive/components/model-selector.d.ts +52 -0
  737. package/dist/modes/interactive/components/model-selector.d.ts.map +1 -0
  738. package/dist/modes/interactive/components/model-selector.js +296 -0
  739. package/dist/modes/interactive/components/model-selector.js.map +1 -0
  740. package/dist/modes/interactive/components/oauth-selector.d.ts +33 -0
  741. package/dist/modes/interactive/components/oauth-selector.d.ts.map +1 -0
  742. package/dist/modes/interactive/components/oauth-selector.js +165 -0
  743. package/dist/modes/interactive/components/oauth-selector.js.map +1 -0
  744. package/dist/modes/interactive/components/scoped-models-selector.d.ts +50 -0
  745. package/dist/modes/interactive/components/scoped-models-selector.d.ts.map +1 -0
  746. package/dist/modes/interactive/components/scoped-models-selector.js +300 -0
  747. package/dist/modes/interactive/components/scoped-models-selector.js.map +1 -0
  748. package/dist/modes/interactive/components/session-selector-search.d.ts +22 -0
  749. package/dist/modes/interactive/components/session-selector-search.d.ts.map +1 -0
  750. package/dist/modes/interactive/components/session-selector-search.js +144 -0
  751. package/dist/modes/interactive/components/session-selector-search.js.map +1 -0
  752. package/dist/modes/interactive/components/session-selector.d.ts +108 -0
  753. package/dist/modes/interactive/components/session-selector.d.ts.map +1 -0
  754. package/dist/modes/interactive/components/session-selector.js +835 -0
  755. package/dist/modes/interactive/components/session-selector.js.map +1 -0
  756. package/dist/modes/interactive/components/settings-selector.d.ts +81 -0
  757. package/dist/modes/interactive/components/settings-selector.d.ts.map +1 -0
  758. package/dist/modes/interactive/components/settings-selector.js +455 -0
  759. package/dist/modes/interactive/components/settings-selector.js.map +1 -0
  760. package/dist/modes/interactive/components/show-images-selector.d.ts +10 -0
  761. package/dist/modes/interactive/components/show-images-selector.d.ts.map +1 -0
  762. package/dist/modes/interactive/components/show-images-selector.js +39 -0
  763. package/dist/modes/interactive/components/show-images-selector.js.map +1 -0
  764. package/dist/modes/interactive/components/skill-invocation-message.d.ts +18 -0
  765. package/dist/modes/interactive/components/skill-invocation-message.d.ts.map +1 -0
  766. package/dist/modes/interactive/components/skill-invocation-message.js +48 -0
  767. package/dist/modes/interactive/components/skill-invocation-message.js.map +1 -0
  768. package/dist/modes/interactive/components/theme-selector.d.ts +11 -0
  769. package/dist/modes/interactive/components/theme-selector.d.ts.map +1 -0
  770. package/dist/modes/interactive/components/theme-selector.js +50 -0
  771. package/dist/modes/interactive/components/theme-selector.js.map +1 -0
  772. package/dist/modes/interactive/components/thinking-selector.d.ts +11 -0
  773. package/dist/modes/interactive/components/thinking-selector.d.ts.map +1 -0
  774. package/dist/modes/interactive/components/thinking-selector.js +51 -0
  775. package/dist/modes/interactive/components/thinking-selector.js.map +1 -0
  776. package/dist/modes/interactive/components/tool-execution.d.ts +67 -0
  777. package/dist/modes/interactive/components/tool-execution.d.ts.map +1 -0
  778. package/dist/modes/interactive/components/tool-execution.js +312 -0
  779. package/dist/modes/interactive/components/tool-execution.js.map +1 -0
  780. package/dist/modes/interactive/components/tree-selector.d.ts +127 -0
  781. package/dist/modes/interactive/components/tree-selector.d.ts.map +1 -0
  782. package/dist/modes/interactive/components/tree-selector.js +1098 -0
  783. package/dist/modes/interactive/components/tree-selector.js.map +1 -0
  784. package/dist/modes/interactive/components/user-message-selector.d.ts +30 -0
  785. package/dist/modes/interactive/components/user-message-selector.d.ts.map +1 -0
  786. package/dist/modes/interactive/components/user-message-selector.js +114 -0
  787. package/dist/modes/interactive/components/user-message-selector.js.map +1 -0
  788. package/dist/modes/interactive/components/user-message.d.ts +16 -0
  789. package/dist/modes/interactive/components/user-message.d.ts.map +1 -0
  790. package/dist/modes/interactive/components/user-message.js +50 -0
  791. package/dist/modes/interactive/components/user-message.js.map +1 -0
  792. package/dist/modes/interactive/components/visual-truncate.d.ts +24 -0
  793. package/dist/modes/interactive/components/visual-truncate.d.ts.map +1 -0
  794. package/dist/modes/interactive/components/visual-truncate.js +33 -0
  795. package/dist/modes/interactive/components/visual-truncate.js.map +1 -0
  796. package/dist/modes/interactive/interactive-mode.d.ts +554 -0
  797. package/dist/modes/interactive/interactive-mode.d.ts.map +1 -0
  798. package/dist/modes/interactive/interactive-mode.js +5870 -0
  799. package/dist/modes/interactive/interactive-mode.js.map +1 -0
  800. package/dist/modes/interactive/theme/dark.json +86 -0
  801. package/dist/modes/interactive/theme/light.json +85 -0
  802. package/dist/modes/interactive/theme/theme-schema.json +335 -0
  803. package/dist/modes/interactive/theme/theme.d.ts +109 -0
  804. package/dist/modes/interactive/theme/theme.d.ts.map +1 -0
  805. package/dist/modes/interactive/theme/theme.js +1040 -0
  806. package/dist/modes/interactive/theme/theme.js.map +1 -0
  807. package/dist/modes/json-event.d.ts +28 -0
  808. package/dist/modes/json-event.d.ts.map +1 -0
  809. package/dist/modes/json-event.js +12 -0
  810. package/dist/modes/json-event.js.map +1 -0
  811. package/dist/modes/print-mode.d.ts +29 -0
  812. package/dist/modes/print-mode.d.ts.map +1 -0
  813. package/dist/modes/print-mode.js +142 -0
  814. package/dist/modes/print-mode.js.map +1 -0
  815. package/dist/modes/rpc/jsonl.d.ts +17 -0
  816. package/dist/modes/rpc/jsonl.d.ts.map +1 -0
  817. package/dist/modes/rpc/jsonl.js +49 -0
  818. package/dist/modes/rpc/jsonl.js.map +1 -0
  819. package/dist/modes/rpc/rpc-client.d.ts +321 -0
  820. package/dist/modes/rpc/rpc-client.d.ts.map +1 -0
  821. package/dist/modes/rpc/rpc-client.js +755 -0
  822. package/dist/modes/rpc/rpc-client.js.map +1 -0
  823. package/dist/modes/rpc/rpc-mode.d.ts +20 -0
  824. package/dist/modes/rpc/rpc-mode.d.ts.map +1 -0
  825. package/dist/modes/rpc/rpc-mode.js +963 -0
  826. package/dist/modes/rpc/rpc-mode.js.map +1 -0
  827. package/dist/modes/rpc/rpc-types.d.ts +652 -0
  828. package/dist/modes/rpc/rpc-types.d.ts.map +1 -0
  829. package/dist/modes/rpc/rpc-types.js +8 -0
  830. package/dist/modes/rpc/rpc-types.js.map +1 -0
  831. package/dist/package-manager-cli.d.ts +4 -0
  832. package/dist/package-manager-cli.d.ts.map +1 -0
  833. package/dist/package-manager-cli.js +488 -0
  834. package/dist/package-manager-cli.js.map +1 -0
  835. package/dist/utils/ansi.d.ts +2 -0
  836. package/dist/utils/ansi.d.ts.map +1 -0
  837. package/dist/utils/ansi.js +25 -0
  838. package/dist/utils/ansi.js.map +1 -0
  839. package/dist/utils/changelog.d.ts +23 -0
  840. package/dist/utils/changelog.d.ts.map +1 -0
  841. package/dist/utils/changelog.js +74 -0
  842. package/dist/utils/changelog.js.map +1 -0
  843. package/dist/utils/child-process.d.ts +15 -0
  844. package/dist/utils/child-process.d.ts.map +1 -0
  845. package/dist/utils/child-process.js +88 -0
  846. package/dist/utils/child-process.js.map +1 -0
  847. package/dist/utils/clipboard-image.d.ts +13 -0
  848. package/dist/utils/clipboard-image.d.ts.map +1 -0
  849. package/dist/utils/clipboard-image.js +248 -0
  850. package/dist/utils/clipboard-image.js.map +1 -0
  851. package/dist/utils/clipboard-native.d.ts +11 -0
  852. package/dist/utils/clipboard-native.d.ts.map +1 -0
  853. package/dist/utils/clipboard-native.js +20 -0
  854. package/dist/utils/clipboard-native.js.map +1 -0
  855. package/dist/utils/clipboard.d.ts +4 -0
  856. package/dist/utils/clipboard.d.ts.map +1 -0
  857. package/dist/utils/clipboard.js +171 -0
  858. package/dist/utils/clipboard.js.map +1 -0
  859. package/dist/utils/deprecation.d.ts +4 -0
  860. package/dist/utils/deprecation.d.ts.map +1 -0
  861. package/dist/utils/deprecation.js +13 -0
  862. package/dist/utils/deprecation.js.map +1 -0
  863. package/dist/utils/directory-completions.d.ts +5 -0
  864. package/dist/utils/directory-completions.d.ts.map +1 -0
  865. package/dist/utils/directory-completions.js +64 -0
  866. package/dist/utils/directory-completions.js.map +1 -0
  867. package/dist/utils/exif-orientation.d.ts +6 -0
  868. package/dist/utils/exif-orientation.d.ts.map +1 -0
  869. package/dist/utils/exif-orientation.js +166 -0
  870. package/dist/utils/exif-orientation.js.map +1 -0
  871. package/dist/utils/frontmatter.d.ts +8 -0
  872. package/dist/utils/frontmatter.d.ts.map +1 -0
  873. package/dist/utils/frontmatter.js +26 -0
  874. package/dist/utils/frontmatter.js.map +1 -0
  875. package/dist/utils/fs-watch.d.ts +5 -0
  876. package/dist/utils/fs-watch.d.ts.map +1 -0
  877. package/dist/utils/fs-watch.js +25 -0
  878. package/dist/utils/fs-watch.js.map +1 -0
  879. package/dist/utils/git.d.ts +27 -0
  880. package/dist/utils/git.d.ts.map +1 -0
  881. package/dist/utils/git.js +237 -0
  882. package/dist/utils/git.js.map +1 -0
  883. package/dist/utils/grip-user-agent.d.ts +2 -0
  884. package/dist/utils/grip-user-agent.d.ts.map +1 -0
  885. package/dist/utils/grip-user-agent.js +5 -0
  886. package/dist/utils/grip-user-agent.js.map +1 -0
  887. package/dist/utils/html.d.ts +7 -0
  888. package/dist/utils/html.d.ts.map +1 -0
  889. package/dist/utils/html.js +40 -0
  890. package/dist/utils/html.js.map +1 -0
  891. package/dist/utils/image-convert.d.ts +12 -0
  892. package/dist/utils/image-convert.d.ts.map +1 -0
  893. package/dist/utils/image-convert.js +43 -0
  894. package/dist/utils/image-convert.js.map +1 -0
  895. package/dist/utils/image-process.d.ts +18 -0
  896. package/dist/utils/image-process.d.ts.map +1 -0
  897. package/dist/utils/image-process.js +83 -0
  898. package/dist/utils/image-process.js.map +1 -0
  899. package/dist/utils/image-resize-core.d.ts +30 -0
  900. package/dist/utils/image-resize-core.d.ts.map +1 -0
  901. package/dist/utils/image-resize-core.js +133 -0
  902. package/dist/utils/image-resize-core.js.map +1 -0
  903. package/dist/utils/image-resize-worker.d.ts +2 -0
  904. package/dist/utils/image-resize-worker.d.ts.map +1 -0
  905. package/dist/utils/image-resize-worker.js +31 -0
  906. package/dist/utils/image-resize-worker.js.map +1 -0
  907. package/dist/utils/image-resize.d.ts +19 -0
  908. package/dist/utils/image-resize.d.ts.map +1 -0
  909. package/dist/utils/image-resize.js +86 -0
  910. package/dist/utils/image-resize.js.map +1 -0
  911. package/dist/utils/json.d.ts +3 -0
  912. package/dist/utils/json.d.ts.map +1 -0
  913. package/dist/utils/json.js +7 -0
  914. package/dist/utils/json.js.map +1 -0
  915. package/dist/utils/mime.d.ts +3 -0
  916. package/dist/utils/mime.d.ts.map +1 -0
  917. package/dist/utils/mime.js +110 -0
  918. package/dist/utils/mime.js.map +1 -0
  919. package/dist/utils/open-browser.d.ts +9 -0
  920. package/dist/utils/open-browser.d.ts.map +1 -0
  921. package/dist/utils/open-browser.js +22 -0
  922. package/dist/utils/open-browser.js.map +1 -0
  923. package/dist/utils/paths.d.ts +31 -0
  924. package/dist/utils/paths.d.ts.map +1 -0
  925. package/dist/utils/paths.js +87 -0
  926. package/dist/utils/paths.js.map +1 -0
  927. package/dist/utils/photon.d.ts +22 -0
  928. package/dist/utils/photon.d.ts.map +1 -0
  929. package/dist/utils/photon.js +126 -0
  930. package/dist/utils/photon.js.map +1 -0
  931. package/dist/utils/shell.d.ts +28 -0
  932. package/dist/utils/shell.d.ts.map +1 -0
  933. package/dist/utils/shell.js +188 -0
  934. package/dist/utils/shell.js.map +1 -0
  935. package/dist/utils/sleep.d.ts +5 -0
  936. package/dist/utils/sleep.d.ts.map +1 -0
  937. package/dist/utils/sleep.js +17 -0
  938. package/dist/utils/sleep.js.map +1 -0
  939. package/dist/utils/syntax-highlight.d.ts +12 -0
  940. package/dist/utils/syntax-highlight.d.ts.map +1 -0
  941. package/dist/utils/syntax-highlight.js +125 -0
  942. package/dist/utils/syntax-highlight.js.map +1 -0
  943. package/dist/utils/tools-manager.d.ts +5 -0
  944. package/dist/utils/tools-manager.d.ts.map +1 -0
  945. package/dist/utils/tools-manager.js +329 -0
  946. package/dist/utils/tools-manager.js.map +1 -0
  947. package/dist/utils/version-check.d.ts +14 -0
  948. package/dist/utils/version-check.d.ts.map +1 -0
  949. package/dist/utils/version-check.js +91 -0
  950. package/dist/utils/version-check.js.map +1 -0
  951. package/dist/utils/windows-self-update.d.ts +3 -0
  952. package/dist/utils/windows-self-update.d.ts.map +1 -0
  953. package/dist/utils/windows-self-update.js +77 -0
  954. package/dist/utils/windows-self-update.js.map +1 -0
  955. package/docs/compaction.md +408 -0
  956. package/docs/custom-provider.md +714 -0
  957. package/docs/daemon-architecture.md +399 -0
  958. package/docs/daemon.md +112 -0
  959. package/docs/development.md +72 -0
  960. package/docs/docs.json +164 -0
  961. package/docs/extensions.md +2745 -0
  962. package/docs/hooks.md +85 -0
  963. package/docs/images/doom-extension.png +0 -0
  964. package/docs/images/exy.png +0 -0
  965. package/docs/images/interactive-mode.png +0 -0
  966. package/docs/images/tree-view.png +0 -0
  967. package/docs/index.md +77 -0
  968. package/docs/json.md +89 -0
  969. package/docs/keybindings.md +230 -0
  970. package/docs/lsp.md +499 -0
  971. package/docs/migrating-to-grip.md +18 -0
  972. package/docs/models.md +496 -0
  973. package/docs/packages.md +228 -0
  974. package/docs/prompt-templates.md +88 -0
  975. package/docs/providers.md +251 -0
  976. package/docs/quickstart.md +159 -0
  977. package/docs/rpc.md +1492 -0
  978. package/docs/rules.md +117 -0
  979. package/docs/sandbox.md +104 -0
  980. package/docs/sdk.md +360 -0
  981. package/docs/session-format.md +414 -0
  982. package/docs/sessions.md +137 -0
  983. package/docs/settings.md +372 -0
  984. package/docs/shell-aliases.md +13 -0
  985. package/docs/skills.md +246 -0
  986. package/docs/terminal-setup.md +112 -0
  987. package/docs/termux.md +112 -0
  988. package/docs/themes.md +295 -0
  989. package/docs/tmux.md +61 -0
  990. package/docs/tui.md +918 -0
  991. package/docs/usage.md +304 -0
  992. package/docs/windows.md +17 -0
  993. package/examples/README.md +29 -0
  994. package/examples/daemon-docker/Dockerfile +43 -0
  995. package/examples/daemon-docker/README.md +45 -0
  996. package/examples/extensions/README.md +208 -0
  997. package/examples/extensions/auto-commit-on-exit.ts +46 -0
  998. package/examples/extensions/bash-spawn-hook.ts +30 -0
  999. package/examples/extensions/bookmark.ts +50 -0
  1000. package/examples/extensions/border-status-editor.ts +145 -0
  1001. package/examples/extensions/built-in-tool-renderer.ts +259 -0
  1002. package/examples/extensions/claude-rules.ts +86 -0
  1003. package/examples/extensions/commands.ts +82 -0
  1004. package/examples/extensions/confirm-destructive.ts +59 -0
  1005. package/examples/extensions/custom-compaction.ts +131 -0
  1006. package/examples/extensions/custom-footer.ts +79 -0
  1007. package/examples/extensions/custom-header.ts +73 -0
  1008. package/examples/extensions/custom-provider-anthropic/index.ts +707 -0
  1009. package/examples/extensions/custom-provider-anthropic/package-lock.json +24 -0
  1010. package/examples/extensions/custom-provider-anthropic/package.json +19 -0
  1011. package/examples/extensions/custom-provider-gitlab-duo/index.ts +402 -0
  1012. package/examples/extensions/custom-provider-gitlab-duo/package.json +16 -0
  1013. package/examples/extensions/custom-provider-gitlab-duo/test.ts +104 -0
  1014. package/examples/extensions/dirty-repo-guard.ts +59 -0
  1015. package/examples/extensions/doom-overlay/README.md +46 -0
  1016. package/examples/extensions/doom-overlay/doom/build/doom.js +21 -0
  1017. package/examples/extensions/doom-overlay/doom/build/doom.wasm +0 -0
  1018. package/examples/extensions/doom-overlay/doom/build.sh +152 -0
  1019. package/examples/extensions/doom-overlay/doom/doomgeneric_pi.c +72 -0
  1020. package/examples/extensions/doom-overlay/doom-component.ts +133 -0
  1021. package/examples/extensions/doom-overlay/doom-engine.ts +173 -0
  1022. package/examples/extensions/doom-overlay/doom-keys.ts +104 -0
  1023. package/examples/extensions/doom-overlay/index.ts +74 -0
  1024. package/examples/extensions/doom-overlay/wad-finder.ts +51 -0
  1025. package/examples/extensions/dynamic-resources/RULES.md +8 -0
  1026. package/examples/extensions/dynamic-resources/SKILL.md +8 -0
  1027. package/examples/extensions/dynamic-resources/dynamic.json +79 -0
  1028. package/examples/extensions/dynamic-resources/dynamic.md +5 -0
  1029. package/examples/extensions/dynamic-resources/index.ts +16 -0
  1030. package/examples/extensions/dynamic-tools.ts +74 -0
  1031. package/examples/extensions/event-bus.ts +43 -0
  1032. package/examples/extensions/file-trigger.ts +41 -0
  1033. package/examples/extensions/git-checkpoint.ts +53 -0
  1034. package/examples/extensions/git-merge-and-resolve.ts +125 -0
  1035. package/examples/extensions/github-issue-autocomplete.ts +191 -0
  1036. package/examples/extensions/handoff.ts +191 -0
  1037. package/examples/extensions/hello.ts +26 -0
  1038. package/examples/extensions/hidden-thinking-label.ts +53 -0
  1039. package/examples/extensions/inline-bash.ts +104 -0
  1040. package/examples/extensions/input-transform.ts +43 -0
  1041. package/examples/extensions/interactive-shell.ts +194 -0
  1042. package/examples/extensions/mac-system-theme.ts +47 -0
  1043. package/examples/extensions/message-renderer.ts +59 -0
  1044. package/examples/extensions/minimal-mode.ts +428 -0
  1045. package/examples/extensions/modal-editor.ts +86 -0
  1046. package/examples/extensions/model-status.ts +31 -0
  1047. package/examples/extensions/notify.ts +55 -0
  1048. package/examples/extensions/overlay-qa-tests.ts +1374 -0
  1049. package/examples/extensions/overlay-test.ts +171 -0
  1050. package/examples/extensions/permission-gate.ts +34 -0
  1051. package/examples/extensions/pirate.ts +47 -0
  1052. package/examples/extensions/plan-mode/README.md +65 -0
  1053. package/examples/extensions/plan-mode/index.ts +346 -0
  1054. package/examples/extensions/plan-mode/utils.ts +172 -0
  1055. package/examples/extensions/preset.ts +426 -0
  1056. package/examples/extensions/prompt-customizer.ts +97 -0
  1057. package/examples/extensions/protected-paths.ts +29 -0
  1058. package/examples/extensions/provider-payload.ts +18 -0
  1059. package/examples/extensions/qna.ts +125 -0
  1060. package/examples/extensions/question.ts +294 -0
  1061. package/examples/extensions/questionnaire.ts +459 -0
  1062. package/examples/extensions/rainbow-editor.ts +88 -0
  1063. package/examples/extensions/reload-runtime.ts +37 -0
  1064. package/examples/extensions/rpc-demo.ts +118 -0
  1065. package/examples/extensions/sandbox/index.ts +320 -0
  1066. package/examples/extensions/sandbox/package-lock.json +92 -0
  1067. package/examples/extensions/sandbox/package.json +19 -0
  1068. package/examples/extensions/send-user-message.ts +97 -0
  1069. package/examples/extensions/session-name.ts +27 -0
  1070. package/examples/extensions/shutdown-command.ts +63 -0
  1071. package/examples/extensions/snake.ts +381 -0
  1072. package/examples/extensions/space-invaders.ts +597 -0
  1073. package/examples/extensions/status-line.ts +32 -0
  1074. package/examples/extensions/structured-output.ts +65 -0
  1075. package/examples/extensions/subagent/README.md +175 -0
  1076. package/examples/extensions/subagent/agents/planner.md +37 -0
  1077. package/examples/extensions/subagent/agents/reviewer.md +35 -0
  1078. package/examples/extensions/subagent/agents/scout.md +50 -0
  1079. package/examples/extensions/subagent/agents/worker.md +24 -0
  1080. package/examples/extensions/subagent/agents.ts +126 -0
  1081. package/examples/extensions/subagent/index.ts +1083 -0
  1082. package/examples/extensions/subagent/prompts/implement-and-review.md +10 -0
  1083. package/examples/extensions/subagent/prompts/implement.md +10 -0
  1084. package/examples/extensions/subagent/prompts/scout-and-plan.md +9 -0
  1085. package/examples/extensions/summarize.ts +186 -0
  1086. package/examples/extensions/system-prompt-header.ts +17 -0
  1087. package/examples/extensions/tic-tac-toe.ts +1091 -0
  1088. package/examples/extensions/timed-confirm.ts +70 -0
  1089. package/examples/extensions/titlebar-spinner.ts +58 -0
  1090. package/examples/extensions/todo.ts +306 -0
  1091. package/examples/extensions/tool-override.ts +144 -0
  1092. package/examples/extensions/tools.ts +141 -0
  1093. package/examples/extensions/trigger-compact.ts +50 -0
  1094. package/examples/extensions/truncated-tool.ts +200 -0
  1095. package/examples/extensions/widget-placement.ts +9 -0
  1096. package/examples/extensions/with-deps/index.ts +32 -0
  1097. package/examples/extensions/with-deps/package-lock.json +31 -0
  1098. package/examples/extensions/with-deps/package.json +22 -0
  1099. package/examples/extensions/working-indicator.ts +123 -0
  1100. package/examples/extensions/working-message-test.ts +25 -0
  1101. package/examples/remote-session-server/README.md +71 -0
  1102. package/examples/remote-session-server/server.ts +353 -0
  1103. package/examples/rpc-extension-ui.ts +642 -0
  1104. package/examples/sdk/01-minimal.ts +27 -0
  1105. package/examples/sdk/02-custom-model.ts +54 -0
  1106. package/examples/sdk/03-custom-prompt.ts +76 -0
  1107. package/examples/sdk/04-skills.ts +60 -0
  1108. package/examples/sdk/05-tools.ts +55 -0
  1109. package/examples/sdk/06-extensions.ts +94 -0
  1110. package/examples/sdk/07-context-files.ts +47 -0
  1111. package/examples/sdk/08-prompt-templates.ts +56 -0
  1112. package/examples/sdk/09-api-keys-and-oauth.ts +50 -0
  1113. package/examples/sdk/10-settings.ts +58 -0
  1114. package/examples/sdk/11-sessions.ts +54 -0
  1115. package/examples/sdk/12-full-control.ts +79 -0
  1116. package/examples/sdk/13-session-runtime.ts +49 -0
  1117. package/examples/sdk/README.md +94 -0
  1118. package/npm-shrinkwrap.json +1878 -0
  1119. package/package.json +101 -5
@@ -0,0 +1 @@
1
+ {"version":3,"file":"session.js","sourceRoot":"","sources":["../../../src/core/session/session.ts"],"names":[],"mappings":"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","sourcesContent":["import { statSync } from \"node:fs\";\nimport type { ImageContent, Message, TextContent } from \"@greppleai/grip-ai\";\nimport type { BashExecutionMessage, CustomMessage } from \"../messages.ts\";\nimport { CURRENT_SESSION_VERSION } from \"./constants.ts\";\nimport { buildSessionContext } from \"./context.ts\";\nimport { createSessionId, generateId, validateSessionId } from \"./ids.ts\";\nimport { migrateToCurrentVersion } from \"./migrations.ts\";\nimport type { SessionManager, SessionResult } from \"./session-manager.ts\";\nimport { getJsonlEntryLocations, validateCurrentSessionEntries } from \"./stores/jsonl-session-store.ts\";\nimport type { SessionStore } from \"./stores/session-store.ts\";\nimport type {\n\tBranchSummaryEntry,\n\tCompactionEntry,\n\tCustomEntry,\n\tCustomMessageEntry,\n\tLabelEntry,\n\tModelChangeEntry,\n\tNewSessionOptions,\n\tSessionContext,\n\tSessionEntry,\n\tSessionHeader,\n\tSessionInfoEntry,\n\tSessionMessageEntry,\n\tSessionTreeNode,\n\tThinkingLevelChangeEntry,\n} from \"./types.ts\";\n\nexport type ReadonlySession = Pick<\n\tSession,\n\t| \"getCwd\"\n\t| \"getSessionDir\"\n\t| \"getSessionId\"\n\t| \"getSessionReference\"\n\t| \"getLeafId\"\n\t| \"getLeafEntry\"\n\t| \"getEntry\"\n\t| \"getLabel\"\n\t| \"getBranch\"\n\t| \"getHeader\"\n\t| \"getEntries\"\n\t| \"getTree\"\n\t| \"getSessionName\"\n>;\n\n/**\n * Represents one active conversation session as an append-only tree.\n *\n * Each session entry has an id and parentId forming a tree structure. The \"leaf\"\n * pointer tracks the current position. Appending creates a child of the current leaf.\n * Branching moves the leaf to an earlier entry, allowing new branches without\n * modifying history.\n *\n * Use buildSessionContext() to get the resolved message list for the LLM, which\n * handles compaction summaries and follows the path from root to current leaf.\n */\nexport abstract class Session {\n\tprivate sessionId: string = \"\";\n\tprivate sessionDir: string;\n\tprivate cwd: string;\n\tprivate store: SessionStore;\n\tprivate sessionManager: SessionManager | undefined;\n\n\tprotected constructor(\n\t\tcwd: string,\n\t\tsessionDir: string,\n\t\tsessionReference: string | undefined,\n\t\tstore: SessionStore,\n\t\tsessionManager?: SessionManager,\n\t) {\n\t\tthis.cwd = cwd;\n\t\tthis.sessionDir = sessionDir;\n\t\tthis.store = store;\n\t\tthis.sessionManager = sessionManager;\n\t\tif (sessionDir) {\n\t\t\tthis.store.ensureDir(sessionDir);\n\t\t}\n\n\t\tif (sessionReference) {\n\t\t\tthis.setSessionReference(sessionReference);\n\t\t} else {\n\t\t\tthis.newSession();\n\t\t}\n\t}\n\n\tprotected abstract prepareNewSessionReference(\n\t\tsessionDir: string,\n\t\tsessionId: string,\n\t\ttimestamp: string,\n\t): string | undefined;\n\n\t/** Switch to a different session reference (used for resume and branching). */\n\tsetSessionReference(sessionReference: string): void {\n\t\tthis.store.setSessionReference(sessionReference);\n\t\tif (this.store.exists(sessionReference)) {\n\t\t\tthis.store.setEntries(this.store.load(sessionReference));\n\n\t\t\t// If the file is empty, initialize it with a valid session header. If it was\n\t\t\t// non-empty but did not parse as a grip session, fail without modifying it.\n\t\t\tif (this.store.getFileEntries().length === 0) {\n\t\t\t\tif (statSync(sessionReference).size > 0) {\n\t\t\t\t\tthrow new Error(`Session file is not a valid grip session: ${sessionReference}`);\n\t\t\t\t}\n\t\t\t\tthis.newSession();\n\t\t\t\tthis.store.setSessionReference(sessionReference, { allowExistingEmptyFile: true });\n\t\t\t\tthis.store.saveSnapshot();\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tconst header = this.store.getHeader();\n\t\t\tthis.sessionId = header?.id ?? createSessionId();\n\n\t\t\tconst entries = this.store.getFileEntries();\n\t\t\tif (migrateToCurrentVersion(entries)) {\n\t\t\t\tvalidateCurrentSessionEntries(entries, sessionReference, {\n\t\t\t\t\tphase: \"migrate\",\n\t\t\t\t\tlocations: getJsonlEntryLocations(entries),\n\t\t\t\t});\n\t\t\t\tthis.store.setEntries(entries);\n\t\t\t\tthis.store.saveSnapshot({ phase: \"migrate\" });\n\t\t\t}\n\t\t} else {\n\t\t\tthis.newSession();\n\t\t\tthis.store.setSessionReference(sessionReference); // preserve explicit reference from --session flag\n\t\t}\n\t}\n\n\tnewSession(options?: NewSessionOptions): string | undefined {\n\t\tthis.sessionId = options?.id ?? createSessionId();\n\t\tvalidateSessionId(this.sessionId);\n\t\tconst timestamp = new Date().toISOString();\n\t\tconst header: SessionHeader = {\n\t\t\ttype: \"session\",\n\t\t\tversion: CURRENT_SESSION_VERSION,\n\t\t\tid: this.sessionId,\n\t\t\ttimestamp,\n\t\t\tcwd: this.cwd,\n\t\t\tparentSession: options?.parentSession,\n\t\t};\n\t\tconst sessionReference = this.prepareNewSessionReference(this.getSessionDir(), this.sessionId, timestamp);\n\t\tif (sessionReference) {\n\t\t\tthis.store.setSessionReference(sessionReference);\n\t\t}\n\t\tthis.store.setEntries([header]);\n\t\treturn sessionReference;\n\t}\n\n\tisPersisted(): boolean {\n\t\treturn this.store.isPersisted();\n\t}\n\n\tgetCwd(): string {\n\t\treturn this.cwd;\n\t}\n\n\t/** Update the active runtime cwd without rewriting the session's original header. */\n\tsetCwd(cwd: string): void {\n\t\tthis.cwd = cwd;\n\t}\n\n\tgetSessionDir(): string {\n\t\treturn this.sessionDir;\n\t}\n\n\tgetSessionId(): string {\n\t\treturn this.sessionId;\n\t}\n\n\tgetSessionReference(): string | undefined {\n\t\treturn this.store.getSessionReference();\n\t}\n\n\tprivate _appendEntry(entry: SessionEntry): void {\n\t\tthis.store.appendEntry(entry);\n\t}\n\n\t/** Copy a preserved suffix onto a new branch without mutating the archived entries. */\n\tappendReplayedEntry(entry: SessionEntry, ids: ReadonlyMap<string, string>): string {\n\t\tif (entry.type === \"compaction\") throw new Error(\"Cannot replay a compaction boundary\");\n\t\tconst id = generateId(this.store);\n\t\tconst base = { id, parentId: this.store.getLeafId(), timestamp: new Date().toISOString() };\n\t\tconst replayed: SessionEntry =\n\t\t\tentry.type === \"label\"\n\t\t\t\t? { ...entry, ...base, targetId: ids.get(entry.targetId) ?? entry.targetId }\n\t\t\t\t: entry.type === \"branch_summary\"\n\t\t\t\t\t? { ...entry, ...base, fromId: ids.get(entry.fromId) ?? entry.fromId }\n\t\t\t\t\t: entry.type === \"message\"\n\t\t\t\t\t\t? { ...entry, ...base, replayedFromId: entry.replayedFromId ?? entry.id }\n\t\t\t\t\t\t: { ...entry, ...base };\n\t\tthis._appendEntry(replayed);\n\t\treturn id;\n\t}\n\n\t/** Append a message as child of current leaf, then advance leaf. Returns entry id.\n\t * Does not allow writing CompactionSummaryMessage and BranchSummaryMessage directly.\n\t * Reason: we want these to be top-level entries in the session, not message session entries,\n\t * so it is easier to find them.\n\t * These need to be appended via appendCompaction() and appendBranchSummary() methods.\n\t */\n\tappendMessage(message: Message | CustomMessage | BashExecutionMessage): string {\n\t\tconst entry: SessionMessageEntry = {\n\t\t\ttype: \"message\",\n\t\t\tid: generateId(this.store),\n\t\t\tparentId: this.store.getLeafId(),\n\t\t\ttimestamp: new Date().toISOString(),\n\t\t\tmessage,\n\t\t};\n\t\tthis._appendEntry(entry);\n\t\treturn entry.id;\n\t}\n\n\t/** Append a thinking level change as child of current leaf, then advance leaf. Returns entry id. */\n\tappendThinkingLevelChange(thinkingLevel: string): string {\n\t\tconst entry: ThinkingLevelChangeEntry = {\n\t\t\ttype: \"thinking_level_change\",\n\t\t\tid: generateId(this.store),\n\t\t\tparentId: this.store.getLeafId(),\n\t\t\ttimestamp: new Date().toISOString(),\n\t\t\tthinkingLevel,\n\t\t};\n\t\tthis._appendEntry(entry);\n\t\treturn entry.id;\n\t}\n\n\t/** Append a model change as child of current leaf, then advance leaf. Returns entry id. */\n\tappendModelChange(provider: string, modelId: string): string {\n\t\tconst entry: ModelChangeEntry = {\n\t\t\ttype: \"model_change\",\n\t\t\tid: generateId(this.store),\n\t\t\tparentId: this.store.getLeafId(),\n\t\t\ttimestamp: new Date().toISOString(),\n\t\t\tprovider,\n\t\t\tmodelId,\n\t\t};\n\t\tthis._appendEntry(entry);\n\t\treturn entry.id;\n\t}\n\n\t/** Append a compaction summary as child of current leaf, then advance leaf. Returns entry id. */\n\tappendCompaction<T = unknown>(\n\t\tsummary: string,\n\t\tfirstKeptEntryId: string,\n\t\ttokensBefore: number,\n\t\tdetails?: T,\n\t\tfromHook?: boolean,\n\t): string {\n\t\tconst entry: CompactionEntry<T> = {\n\t\t\ttype: \"compaction\",\n\t\t\tid: generateId(this.store),\n\t\t\tparentId: this.store.getLeafId(),\n\t\t\ttimestamp: new Date().toISOString(),\n\t\t\tsummary,\n\t\t\tfirstKeptEntryId,\n\t\t\ttokensBefore,\n\t\t\tdetails,\n\t\t\tfromHook,\n\t\t};\n\t\tthis._appendEntry(entry);\n\t\treturn entry.id;\n\t}\n\n\t/** Append a custom entry (for extensions) as child of current leaf, then advance leaf. Returns entry id. */\n\tappendCustomEntry(customType: string, data?: unknown): string {\n\t\tconst entry: CustomEntry = {\n\t\t\ttype: \"custom\",\n\t\t\tcustomType,\n\t\t\tdata,\n\t\t\tid: generateId(this.store),\n\t\t\tparentId: this.store.getLeafId(),\n\t\t\ttimestamp: new Date().toISOString(),\n\t\t};\n\t\tthis._appendEntry(entry);\n\t\treturn entry.id;\n\t}\n\n\t/** Append a session info entry (e.g., display name). Returns entry id. */\n\tappendSessionInfo(name: string): string {\n\t\tconst entry: SessionInfoEntry = {\n\t\t\ttype: \"session_info\",\n\t\t\tid: generateId(this.store),\n\t\t\tparentId: this.store.getLeafId(),\n\t\t\ttimestamp: new Date().toISOString(),\n\t\t\tname: name.trim(),\n\t\t};\n\t\tthis._appendEntry(entry);\n\t\treturn entry.id;\n\t}\n\n\t/** Get the current session name from the latest session_info entry, if any. */\n\tgetSessionName(): string | undefined {\n\t\treturn this.store.getSessionName();\n\t}\n\n\t/**\n\t * Append a custom message entry (for extensions) that participates in LLM context.\n\t * @param customType Extension identifier for filtering on reload\n\t * @param content Message content (string or TextContent/ImageContent array)\n\t * @param display Whether to show in TUI (true = styled display, false = hidden)\n\t * @param details Optional extension-specific metadata (not sent to LLM)\n\t * @returns Entry id\n\t */\n\tappendCustomMessageEntry<T = unknown>(\n\t\tcustomType: string,\n\t\tcontent: string | (TextContent | ImageContent)[],\n\t\tdisplay: boolean,\n\t\tdetails?: T,\n\t): string {\n\t\tconst entry: CustomMessageEntry<T> = {\n\t\t\ttype: \"custom_message\",\n\t\t\tcustomType,\n\t\t\tcontent,\n\t\t\tdisplay,\n\t\t\tdetails,\n\t\t\tid: generateId(this.store),\n\t\t\tparentId: this.store.getLeafId(),\n\t\t\ttimestamp: new Date().toISOString(),\n\t\t};\n\t\tthis._appendEntry(entry);\n\t\treturn entry.id;\n\t}\n\n\t// =========================================================================\n\t// Tree Traversal\n\t// =========================================================================\n\n\tgetLeafId(): string | null {\n\t\treturn this.store.getLeafId();\n\t}\n\n\tgetLeafEntry(): SessionEntry | undefined {\n\t\treturn this.store.getLeafEntry();\n\t}\n\n\tgetEntry(id: string): SessionEntry | undefined {\n\t\treturn this.store.getEntry(id);\n\t}\n\n\t/**\n\t * Get all direct children of an entry.\n\t */\n\tgetChildren(parentId: string): SessionEntry[] {\n\t\treturn this.store.getChildren(parentId);\n\t}\n\n\t/**\n\t * Get the label for an entry, if any.\n\t */\n\tgetLabel(id: string): string | undefined {\n\t\treturn this.store.getLabel(id);\n\t}\n\n\t/**\n\t * Set or clear a label on an entry.\n\t * Labels are user-defined markers for bookmarking/navigation.\n\t * Pass undefined or empty string to clear the label.\n\t */\n\tappendLabelChange(targetId: string, label: string | undefined): string {\n\t\tif (!this.store.has(targetId)) {\n\t\t\tthrow new Error(`Entry ${targetId} not found`);\n\t\t}\n\t\tconst entry: LabelEntry = {\n\t\t\ttype: \"label\",\n\t\t\tid: generateId(this.store),\n\t\t\tparentId: this.store.getLeafId(),\n\t\t\ttimestamp: new Date().toISOString(),\n\t\t\ttargetId,\n\t\t\tlabel,\n\t\t};\n\t\tthis._appendEntry(entry);\n\t\treturn entry.id;\n\t}\n\n\t/**\n\t * Walk from entry to root, returning all entries in path order.\n\t * Includes all entry types (messages, compaction, model changes, etc.).\n\t * Use buildSessionContext() to get the resolved messages for the LLM.\n\t */\n\tgetBranch(fromId?: string): SessionEntry[] {\n\t\treturn this.store.getBranch(fromId);\n\t}\n\n\t/**\n\t * Build the session context (what gets sent to the LLM).\n\t * Uses tree traversal from current leaf.\n\t */\n\tbuildSessionContext(): SessionContext {\n\t\treturn buildSessionContext(this.getEntries(), this.store.getLeafId(), this.store.getEntryIndex());\n\t}\n\n\t/**\n\t * Get session header.\n\t */\n\tgetHeader(): SessionHeader | null {\n\t\treturn this.store.getHeader();\n\t}\n\n\t/**\n\t * Get all session entries (excludes header). Returns a shallow copy.\n\t * The session is append-only: use appendXXX() to add entries, branch() to\n\t * change the leaf pointer. Entries cannot be modified or deleted.\n\t */\n\tgetEntries(): SessionEntry[] {\n\t\treturn this.store.getEntries();\n\t}\n\n\t/**\n\t * Get the session as a tree structure. Returns a shallow defensive copy of all entries.\n\t * A well-formed session has exactly one root (first entry with parentId === null).\n\t * Orphaned entries (broken parent chain) are also returned as roots.\n\t */\n\tgetTree(): SessionTreeNode[] {\n\t\treturn this.store.getTree();\n\t}\n\n\t// =========================================================================\n\t// Branching\n\t// =========================================================================\n\n\t/**\n\t * Start a new branch from an earlier entry.\n\t * Moves the leaf pointer to the specified entry. The next appendXXX() call\n\t * will create a child of that entry, forming a new branch. Existing entries\n\t * are not modified or deleted.\n\t */\n\tbranch(branchFromId: string): void {\n\t\tif (!this.store.has(branchFromId)) {\n\t\t\tthrow new Error(`Entry ${branchFromId} not found`);\n\t\t}\n\t\tthis.store.setLeafId(branchFromId);\n\t}\n\n\t/**\n\t * Reset the leaf pointer to null (before any entries).\n\t * The next appendXXX() call will create a new root entry (parentId = null).\n\t * Use this when navigating to re-edit the first user message.\n\t */\n\tresetLeaf(): void {\n\t\tthis.store.setLeafId(null);\n\t}\n\n\t/**\n\t * Start a new branch with a summary of the abandoned path.\n\t * Same as branch(), but also appends a branch_summary entry that captures\n\t * context from the abandoned conversation path.\n\t */\n\tbranchWithSummary(branchFromId: string | null, summary: string, details?: unknown, fromHook?: boolean): string {\n\t\tif (branchFromId !== null && !this.store.has(branchFromId)) {\n\t\t\tthrow new Error(`Entry ${branchFromId} not found`);\n\t\t}\n\t\tthis.store.setLeafId(branchFromId);\n\t\tconst entry: BranchSummaryEntry = {\n\t\t\ttype: \"branch_summary\",\n\t\t\tid: generateId(this.store),\n\t\t\tparentId: branchFromId,\n\t\t\ttimestamp: new Date().toISOString(),\n\t\t\tfromId: branchFromId ?? \"root\",\n\t\t\tsummary,\n\t\t\tdetails,\n\t\t\tfromHook,\n\t\t};\n\t\tthis._appendEntry(entry);\n\t\treturn entry.id;\n\t}\n\n\t/**\n\t * Create a new session reference containing only the path from root to the specified leaf.\n\t * Useful for extracting a single conversation path from a branched session.\n\t * Returns the new session reference, or undefined if the store does not expose one.\n\t */\n\tcreateBranchedSession(leafId: string): string | undefined {\n\t\tconst parentSession = this.getSessionReference();\n\t\tconst path = this.getBranch(leafId);\n\t\tif (path.length === 0) {\n\t\t\tthrow new Error(`Entry ${leafId} not found`);\n\t\t}\n\n\t\t// Filter out LabelEntry from path - we'll recreate them from the resolved map\n\t\tconst pathWithoutLabels = path.filter((e) => e.type !== \"label\");\n\n\t\tconst newSessionId = createSessionId();\n\t\tconst timestamp = new Date().toISOString();\n\t\tconst newSessionReference = this.prepareNewSessionReference(this.getSessionDir(), newSessionId, timestamp);\n\t\tif (newSessionReference) {\n\t\t\tthis.store.setSessionReference(newSessionReference);\n\t\t}\n\n\t\tconst header: SessionHeader = {\n\t\t\ttype: \"session\",\n\t\t\tversion: CURRENT_SESSION_VERSION,\n\t\t\tid: newSessionId,\n\t\t\ttimestamp,\n\t\t\tcwd: this.cwd,\n\t\t\tparentSession,\n\t\t};\n\n\t\t// Collect labels for entries in the path\n\t\tconst pathEntryIds = new Set(pathWithoutLabels.map((e) => e.id));\n\t\tconst labelsToWrite = this.store.getLabelsForEntryIds(pathEntryIds);\n\n\t\tconst labelEntries: LabelEntry[] = [];\n\t\tlet parentId = pathWithoutLabels[pathWithoutLabels.length - 1]?.id || null;\n\t\tfor (const { targetId, label, timestamp: labelTimestamp } of labelsToWrite) {\n\t\t\tconst labelEntry: LabelEntry = {\n\t\t\t\ttype: \"label\",\n\t\t\t\tid: generateId(pathEntryIds),\n\t\t\t\tparentId,\n\t\t\t\ttimestamp: labelTimestamp,\n\t\t\t\ttargetId,\n\t\t\t\tlabel,\n\t\t\t};\n\t\t\tpathEntryIds.add(labelEntry.id);\n\t\t\tlabelEntries.push(labelEntry);\n\t\t\tparentId = labelEntry.id;\n\t\t}\n\t\tthis.store.setEntries([header, ...pathWithoutLabels, ...labelEntries]);\n\t\tthis.sessionId = newSessionId;\n\t\tthis.store.commitSnapshot();\n\t\treturn newSessionReference;\n\t}\n\n\tcopyBranchFrom(source: Session, leafId: string, parentSession?: string): void {\n\t\tconst path = source.getBranch(leafId);\n\t\tif (path.length === 0) {\n\t\t\tthrow new Error(`Entry ${leafId} not found`);\n\t\t}\n\n\t\tconst header = this.getHeader();\n\t\tif (!header) {\n\t\t\tthrow new Error(\"Target session has no header\");\n\t\t}\n\n\t\tconst pathWithoutLabels = structuredClone(path.filter((entry) => entry.type !== \"label\"));\n\t\tconst pathEntryIds = new Set(pathWithoutLabels.map((entry) => entry.id));\n\t\tconst labelsToWrite = source.store.getLabelsForEntryIds(pathEntryIds);\n\t\tconst labelEntries: LabelEntry[] = [];\n\t\tlet nextParentId = pathWithoutLabels[pathWithoutLabels.length - 1]?.id ?? null;\n\t\tfor (const { targetId, label, timestamp } of labelsToWrite) {\n\t\t\tconst labelEntry: LabelEntry = {\n\t\t\t\ttype: \"label\",\n\t\t\t\tid: generateId(pathEntryIds),\n\t\t\t\tparentId: nextParentId,\n\t\t\t\ttimestamp,\n\t\t\t\ttargetId,\n\t\t\t\tlabel,\n\t\t\t};\n\t\t\tpathEntryIds.add(labelEntry.id);\n\t\t\tlabelEntries.push(labelEntry);\n\t\t\tnextParentId = labelEntry.id;\n\t\t}\n\n\t\tthis.store.setEntries([{ ...header, parentSession }, ...pathWithoutLabels, ...labelEntries]);\n\t\tthis.store.commitSnapshot();\n\t}\n\n\tcreateSubSession(options?: NewSessionOptions): SessionResult {\n\t\tif (!this.sessionManager) {\n\t\t\tthrow new Error(\"Session manager unavailable\");\n\t\t}\n\t\treturn this.sessionManager.create({\n\t\t\t...options,\n\t\t\tparentSession: options?.parentSession ?? this.getSessionReference(),\n\t\t});\n\t}\n\n\tforkSubSession(targetLeafId: string | null): SessionResult {\n\t\tif (!this.sessionManager) {\n\t\t\tthrow new Error(\"Session manager unavailable\");\n\t\t}\n\t\treturn this.sessionManager.forkSession(this, targetLeafId);\n\t}\n}\n"]}
@@ -0,0 +1,39 @@
1
+ import type { FileEntry, SessionEntry, SessionHeader, SessionTreeNode } from "../types.ts";
2
+ import type { SessionLabelSnapshot, SessionStore } from "./session-store.ts";
3
+ export declare class InMemorySessionStore implements SessionStore {
4
+ protected fileEntries: FileEntry[];
5
+ protected byId: Map<string, SessionEntry>;
6
+ protected labelsById: Map<string, string>;
7
+ protected labelTimestampsById: Map<string, string>;
8
+ protected leafId: string | null;
9
+ private sessionReference;
10
+ isPersisted(): boolean;
11
+ getSessionReference(): string | undefined;
12
+ setSessionReference(reference: string): void;
13
+ exists(reference: string): boolean;
14
+ ensureDir(_path: string): void;
15
+ load(reference: string): FileEntry[];
16
+ setEntries(entries: FileEntry[]): void;
17
+ getFileEntries(): FileEntry[];
18
+ getHeader(): SessionHeader | null;
19
+ getEntries(): SessionEntry[];
20
+ getEntryIndex(): Map<string, SessionEntry>;
21
+ has(id: string): boolean;
22
+ appendEntry(entry: SessionEntry): void;
23
+ saveSnapshot(): void;
24
+ commitSnapshot(): void;
25
+ getLeafId(): string | null;
26
+ setLeafId(leafId: string | null): void;
27
+ getLeafEntry(): SessionEntry | undefined;
28
+ getEntry(id: string): SessionEntry | undefined;
29
+ getChildren(parentId: string): SessionEntry[];
30
+ getLabel(id: string): string | undefined;
31
+ getBranch(fromId?: string): SessionEntry[];
32
+ getTree(): SessionTreeNode[];
33
+ getSessionName(): string | undefined;
34
+ getLabelsForEntryIds(entryIds: Set<string>): SessionLabelSnapshot[];
35
+ hasAssistantMessage(): boolean;
36
+ private rebuildIndex;
37
+ private applyLabelEntry;
38
+ }
39
+ //# sourceMappingURL=in-memory-session-store.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"in-memory-session-store.d.ts","sourceRoot":"","sources":["../../../../src/core/session/stores/in-memory-session-store.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAc,YAAY,EAAE,aAAa,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AACvG,OAAO,KAAK,EAAE,oBAAoB,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAE7E,qBAAa,oBAAqB,YAAW,YAAY;IACxD,SAAS,CAAC,WAAW,EAAE,SAAS,EAAE,CAAM;IACxC,SAAS,CAAC,IAAI,EAAE,GAAG,CAAC,MAAM,EAAE,YAAY,CAAC,CAAa;IACtD,SAAS,CAAC,UAAU,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAa;IACtD,SAAS,CAAC,mBAAmB,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAa;IAC/D,SAAS,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAQ;IACvC,OAAO,CAAC,gBAAgB,CAAqB;IAE7C,WAAW,IAAI,OAAO,CAErB;IAED,mBAAmB,IAAI,MAAM,GAAG,SAAS,CAExC;IAED,mBAAmB,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,CAE3C;IAED,MAAM,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAEjC;IAED,SAAS,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAE7B;IAED,IAAI,CAAC,SAAS,EAAE,MAAM,GAAG,SAAS,EAAE,CAEnC;IAED,UAAU,CAAC,OAAO,EAAE,SAAS,EAAE,GAAG,IAAI,CAGrC;IAED,cAAc,IAAI,SAAS,EAAE,CAE5B;IAED,SAAS,IAAI,aAAa,GAAG,IAAI,CAGhC;IAED,UAAU,IAAI,YAAY,EAAE,CAE3B;IAED,aAAa,IAAI,GAAG,CAAC,MAAM,EAAE,YAAY,CAAC,CAEzC;IAED,GAAG,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAEvB;IAED,WAAW,CAAC,KAAK,EAAE,YAAY,GAAG,IAAI,CAKrC;IAED,YAAY,IAAI,IAAI,CAEnB;IAED,cAAc,IAAI,IAAI,CAErB;IAED,SAAS,IAAI,MAAM,GAAG,IAAI,CAEzB;IAED,SAAS,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,GAAG,IAAI,CAErC;IAED,YAAY,IAAI,YAAY,GAAG,SAAS,CAEvC;IAED,QAAQ,CAAC,EAAE,EAAE,MAAM,GAAG,YAAY,GAAG,SAAS,CAE7C;IAED,WAAW,CAAC,QAAQ,EAAE,MAAM,GAAG,YAAY,EAAE,CAQ5C;IAED,QAAQ,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAEvC;IAED,SAAS,CAAC,MAAM,CAAC,EAAE,MAAM,GAAG,YAAY,EAAE,CASzC;IAED,OAAO,IAAI,eAAe,EAAE,CA4B3B;IAED,cAAc,IAAI,MAAM,GAAG,SAAS,CASnC;IAED,oBAAoB,CAAC,QAAQ,EAAE,GAAG,CAAC,MAAM,CAAC,GAAG,oBAAoB,EAAE,CAQlE;IAED,mBAAmB,IAAI,OAAO,CAE7B;IAED,OAAO,CAAC,YAAY;IAapB,OAAO,CAAC,eAAe;CAWvB","sourcesContent":["import type { FileEntry, LabelEntry, SessionEntry, SessionHeader, SessionTreeNode } from \"../types.ts\";\nimport type { SessionLabelSnapshot, SessionStore } from \"./session-store.ts\";\n\nexport class InMemorySessionStore implements SessionStore {\n\tprotected fileEntries: FileEntry[] = [];\n\tprotected byId: Map<string, SessionEntry> = new Map();\n\tprotected labelsById: Map<string, string> = new Map();\n\tprotected labelTimestampsById: Map<string, string> = new Map();\n\tprotected leafId: string | null = null;\n\tprivate sessionReference: string | undefined;\n\n\tisPersisted(): boolean {\n\t\treturn false;\n\t}\n\n\tgetSessionReference(): string | undefined {\n\t\treturn this.sessionReference;\n\t}\n\n\tsetSessionReference(reference: string): void {\n\t\tthis.sessionReference = reference;\n\t}\n\n\texists(reference: string): boolean {\n\t\treturn reference === this.sessionReference && this.fileEntries.length > 0;\n\t}\n\n\tensureDir(_path: string): void {\n\t\t// No-op for in-memory sessions.\n\t}\n\n\tload(reference: string): FileEntry[] {\n\t\treturn reference === this.sessionReference ? [...this.fileEntries] : [];\n\t}\n\n\tsetEntries(entries: FileEntry[]): void {\n\t\tthis.fileEntries = entries;\n\t\tthis.rebuildIndex();\n\t}\n\n\tgetFileEntries(): FileEntry[] {\n\t\treturn this.fileEntries;\n\t}\n\n\tgetHeader(): SessionHeader | null {\n\t\tconst header = this.fileEntries.find((entry) => entry.type === \"session\");\n\t\treturn header ? (header as SessionHeader) : null;\n\t}\n\n\tgetEntries(): SessionEntry[] {\n\t\treturn this.fileEntries.filter((entry): entry is SessionEntry => entry.type !== \"session\");\n\t}\n\n\tgetEntryIndex(): Map<string, SessionEntry> {\n\t\treturn this.byId;\n\t}\n\n\thas(id: string): boolean {\n\t\treturn this.byId.has(id);\n\t}\n\n\tappendEntry(entry: SessionEntry): void {\n\t\tthis.fileEntries.push(entry);\n\t\tthis.byId.set(entry.id, entry);\n\t\tthis.leafId = entry.id;\n\t\tthis.applyLabelEntry(entry);\n\t}\n\n\tsaveSnapshot(): void {\n\t\t// No-op for in-memory sessions.\n\t}\n\n\tcommitSnapshot(): void {\n\t\t// No-op for in-memory sessions.\n\t}\n\n\tgetLeafId(): string | null {\n\t\treturn this.leafId;\n\t}\n\n\tsetLeafId(leafId: string | null): void {\n\t\tthis.leafId = leafId;\n\t}\n\n\tgetLeafEntry(): SessionEntry | undefined {\n\t\treturn this.leafId ? this.byId.get(this.leafId) : undefined;\n\t}\n\n\tgetEntry(id: string): SessionEntry | undefined {\n\t\treturn this.byId.get(id);\n\t}\n\n\tgetChildren(parentId: string): SessionEntry[] {\n\t\tconst children: SessionEntry[] = [];\n\t\tfor (const entry of this.byId.values()) {\n\t\t\tif (entry.parentId === parentId) {\n\t\t\t\tchildren.push(entry);\n\t\t\t}\n\t\t}\n\t\treturn children;\n\t}\n\n\tgetLabel(id: string): string | undefined {\n\t\treturn this.labelsById.get(id);\n\t}\n\n\tgetBranch(fromId?: string): SessionEntry[] {\n\t\tconst path: SessionEntry[] = [];\n\t\tconst startId = fromId ?? this.leafId;\n\t\tlet current = startId ? this.byId.get(startId) : undefined;\n\t\twhile (current) {\n\t\t\tpath.unshift(current);\n\t\t\tcurrent = current.parentId ? this.byId.get(current.parentId) : undefined;\n\t\t}\n\t\treturn path;\n\t}\n\n\tgetTree(): SessionTreeNode[] {\n\t\tconst entries = this.getEntries();\n\t\tconst nodeMap = new Map<string, SessionTreeNode>();\n\t\tconst roots: SessionTreeNode[] = [];\n\n\t\tfor (const entry of entries) {\n\t\t\tconst label = this.labelsById.get(entry.id);\n\t\t\tconst labelTimestamp = this.labelTimestampsById.get(entry.id);\n\t\t\tnodeMap.set(entry.id, { entry, children: [], label, labelTimestamp });\n\t\t}\n\n\t\tconst childNodes: Array<[parent: SessionTreeNode, child: SessionTreeNode]> = [];\n\t\tfor (const entry of entries) {\n\t\t\tconst node = nodeMap.get(entry.id)!;\n\t\t\tif (entry.parentId === null || entry.parentId === entry.id) {\n\t\t\t\troots.push(node);\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tconst parent = nodeMap.get(entry.parentId);\n\t\t\tif (parent) childNodes.push([parent, node]);\n\t\t\telse roots.push(node);\n\t\t}\n\t\tchildNodes.sort(\n\t\t\t([, left], [, right]) => new Date(left.entry.timestamp).getTime() - new Date(right.entry.timestamp).getTime(),\n\t\t);\n\t\tfor (const [parent, child] of childNodes) parent.children.push(child);\n\n\t\treturn roots;\n\t}\n\n\tgetSessionName(): string | undefined {\n\t\tconst entries = this.getEntries();\n\t\tfor (let i = entries.length - 1; i >= 0; i--) {\n\t\t\tconst entry = entries[i];\n\t\t\tif (entry.type === \"session_info\") {\n\t\t\t\treturn entry.name?.trim() || undefined;\n\t\t\t}\n\t\t}\n\t\treturn undefined;\n\t}\n\n\tgetLabelsForEntryIds(entryIds: Set<string>): SessionLabelSnapshot[] {\n\t\tconst labels: SessionLabelSnapshot[] = [];\n\t\tfor (const [targetId, label] of this.labelsById) {\n\t\t\tif (entryIds.has(targetId)) {\n\t\t\t\tlabels.push({ targetId, label, timestamp: this.labelTimestampsById.get(targetId)! });\n\t\t\t}\n\t\t}\n\t\treturn labels;\n\t}\n\n\thasAssistantMessage(): boolean {\n\t\treturn this.fileEntries.some((entry) => entry.type === \"message\" && entry.message.role === \"assistant\");\n\t}\n\n\tprivate rebuildIndex(): void {\n\t\tthis.byId.clear();\n\t\tthis.labelsById.clear();\n\t\tthis.labelTimestampsById.clear();\n\t\tthis.leafId = null;\n\t\tfor (const entry of this.fileEntries) {\n\t\t\tif (entry.type === \"session\") continue;\n\t\t\tthis.byId.set(entry.id, entry);\n\t\t\tthis.leafId = entry.id;\n\t\t\tthis.applyLabelEntry(entry);\n\t\t}\n\t}\n\n\tprivate applyLabelEntry(entry: SessionEntry): void {\n\t\tif (entry.type !== \"label\") return;\n\t\tconst labelEntry = entry as LabelEntry;\n\t\tif (labelEntry.label) {\n\t\t\tthis.labelsById.set(labelEntry.targetId, labelEntry.label);\n\t\t\tthis.labelTimestampsById.set(labelEntry.targetId, labelEntry.timestamp);\n\t\t} else {\n\t\t\tthis.labelsById.delete(labelEntry.targetId);\n\t\t\tthis.labelTimestampsById.delete(labelEntry.targetId);\n\t\t}\n\t}\n}\n"]}
@@ -0,0 +1,168 @@
1
+ export class InMemorySessionStore {
2
+ fileEntries = [];
3
+ byId = new Map();
4
+ labelsById = new Map();
5
+ labelTimestampsById = new Map();
6
+ leafId = null;
7
+ sessionReference;
8
+ isPersisted() {
9
+ return false;
10
+ }
11
+ getSessionReference() {
12
+ return this.sessionReference;
13
+ }
14
+ setSessionReference(reference) {
15
+ this.sessionReference = reference;
16
+ }
17
+ exists(reference) {
18
+ return reference === this.sessionReference && this.fileEntries.length > 0;
19
+ }
20
+ ensureDir(_path) {
21
+ // No-op for in-memory sessions.
22
+ }
23
+ load(reference) {
24
+ return reference === this.sessionReference ? [...this.fileEntries] : [];
25
+ }
26
+ setEntries(entries) {
27
+ this.fileEntries = entries;
28
+ this.rebuildIndex();
29
+ }
30
+ getFileEntries() {
31
+ return this.fileEntries;
32
+ }
33
+ getHeader() {
34
+ const header = this.fileEntries.find((entry) => entry.type === "session");
35
+ return header ? header : null;
36
+ }
37
+ getEntries() {
38
+ return this.fileEntries.filter((entry) => entry.type !== "session");
39
+ }
40
+ getEntryIndex() {
41
+ return this.byId;
42
+ }
43
+ has(id) {
44
+ return this.byId.has(id);
45
+ }
46
+ appendEntry(entry) {
47
+ this.fileEntries.push(entry);
48
+ this.byId.set(entry.id, entry);
49
+ this.leafId = entry.id;
50
+ this.applyLabelEntry(entry);
51
+ }
52
+ saveSnapshot() {
53
+ // No-op for in-memory sessions.
54
+ }
55
+ commitSnapshot() {
56
+ // No-op for in-memory sessions.
57
+ }
58
+ getLeafId() {
59
+ return this.leafId;
60
+ }
61
+ setLeafId(leafId) {
62
+ this.leafId = leafId;
63
+ }
64
+ getLeafEntry() {
65
+ return this.leafId ? this.byId.get(this.leafId) : undefined;
66
+ }
67
+ getEntry(id) {
68
+ return this.byId.get(id);
69
+ }
70
+ getChildren(parentId) {
71
+ const children = [];
72
+ for (const entry of this.byId.values()) {
73
+ if (entry.parentId === parentId) {
74
+ children.push(entry);
75
+ }
76
+ }
77
+ return children;
78
+ }
79
+ getLabel(id) {
80
+ return this.labelsById.get(id);
81
+ }
82
+ getBranch(fromId) {
83
+ const path = [];
84
+ const startId = fromId ?? this.leafId;
85
+ let current = startId ? this.byId.get(startId) : undefined;
86
+ while (current) {
87
+ path.unshift(current);
88
+ current = current.parentId ? this.byId.get(current.parentId) : undefined;
89
+ }
90
+ return path;
91
+ }
92
+ getTree() {
93
+ const entries = this.getEntries();
94
+ const nodeMap = new Map();
95
+ const roots = [];
96
+ for (const entry of entries) {
97
+ const label = this.labelsById.get(entry.id);
98
+ const labelTimestamp = this.labelTimestampsById.get(entry.id);
99
+ nodeMap.set(entry.id, { entry, children: [], label, labelTimestamp });
100
+ }
101
+ const childNodes = [];
102
+ for (const entry of entries) {
103
+ const node = nodeMap.get(entry.id);
104
+ if (entry.parentId === null || entry.parentId === entry.id) {
105
+ roots.push(node);
106
+ continue;
107
+ }
108
+ const parent = nodeMap.get(entry.parentId);
109
+ if (parent)
110
+ childNodes.push([parent, node]);
111
+ else
112
+ roots.push(node);
113
+ }
114
+ childNodes.sort(([, left], [, right]) => new Date(left.entry.timestamp).getTime() - new Date(right.entry.timestamp).getTime());
115
+ for (const [parent, child] of childNodes)
116
+ parent.children.push(child);
117
+ return roots;
118
+ }
119
+ getSessionName() {
120
+ const entries = this.getEntries();
121
+ for (let i = entries.length - 1; i >= 0; i--) {
122
+ const entry = entries[i];
123
+ if (entry.type === "session_info") {
124
+ return entry.name?.trim() || undefined;
125
+ }
126
+ }
127
+ return undefined;
128
+ }
129
+ getLabelsForEntryIds(entryIds) {
130
+ const labels = [];
131
+ for (const [targetId, label] of this.labelsById) {
132
+ if (entryIds.has(targetId)) {
133
+ labels.push({ targetId, label, timestamp: this.labelTimestampsById.get(targetId) });
134
+ }
135
+ }
136
+ return labels;
137
+ }
138
+ hasAssistantMessage() {
139
+ return this.fileEntries.some((entry) => entry.type === "message" && entry.message.role === "assistant");
140
+ }
141
+ rebuildIndex() {
142
+ this.byId.clear();
143
+ this.labelsById.clear();
144
+ this.labelTimestampsById.clear();
145
+ this.leafId = null;
146
+ for (const entry of this.fileEntries) {
147
+ if (entry.type === "session")
148
+ continue;
149
+ this.byId.set(entry.id, entry);
150
+ this.leafId = entry.id;
151
+ this.applyLabelEntry(entry);
152
+ }
153
+ }
154
+ applyLabelEntry(entry) {
155
+ if (entry.type !== "label")
156
+ return;
157
+ const labelEntry = entry;
158
+ if (labelEntry.label) {
159
+ this.labelsById.set(labelEntry.targetId, labelEntry.label);
160
+ this.labelTimestampsById.set(labelEntry.targetId, labelEntry.timestamp);
161
+ }
162
+ else {
163
+ this.labelsById.delete(labelEntry.targetId);
164
+ this.labelTimestampsById.delete(labelEntry.targetId);
165
+ }
166
+ }
167
+ }
168
+ //# sourceMappingURL=in-memory-session-store.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"in-memory-session-store.js","sourceRoot":"","sources":["../../../../src/core/session/stores/in-memory-session-store.ts"],"names":[],"mappings":"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","sourcesContent":["import type { FileEntry, LabelEntry, SessionEntry, SessionHeader, SessionTreeNode } from \"../types.ts\";\nimport type { SessionLabelSnapshot, SessionStore } from \"./session-store.ts\";\n\nexport class InMemorySessionStore implements SessionStore {\n\tprotected fileEntries: FileEntry[] = [];\n\tprotected byId: Map<string, SessionEntry> = new Map();\n\tprotected labelsById: Map<string, string> = new Map();\n\tprotected labelTimestampsById: Map<string, string> = new Map();\n\tprotected leafId: string | null = null;\n\tprivate sessionReference: string | undefined;\n\n\tisPersisted(): boolean {\n\t\treturn false;\n\t}\n\n\tgetSessionReference(): string | undefined {\n\t\treturn this.sessionReference;\n\t}\n\n\tsetSessionReference(reference: string): void {\n\t\tthis.sessionReference = reference;\n\t}\n\n\texists(reference: string): boolean {\n\t\treturn reference === this.sessionReference && this.fileEntries.length > 0;\n\t}\n\n\tensureDir(_path: string): void {\n\t\t// No-op for in-memory sessions.\n\t}\n\n\tload(reference: string): FileEntry[] {\n\t\treturn reference === this.sessionReference ? [...this.fileEntries] : [];\n\t}\n\n\tsetEntries(entries: FileEntry[]): void {\n\t\tthis.fileEntries = entries;\n\t\tthis.rebuildIndex();\n\t}\n\n\tgetFileEntries(): FileEntry[] {\n\t\treturn this.fileEntries;\n\t}\n\n\tgetHeader(): SessionHeader | null {\n\t\tconst header = this.fileEntries.find((entry) => entry.type === \"session\");\n\t\treturn header ? (header as SessionHeader) : null;\n\t}\n\n\tgetEntries(): SessionEntry[] {\n\t\treturn this.fileEntries.filter((entry): entry is SessionEntry => entry.type !== \"session\");\n\t}\n\n\tgetEntryIndex(): Map<string, SessionEntry> {\n\t\treturn this.byId;\n\t}\n\n\thas(id: string): boolean {\n\t\treturn this.byId.has(id);\n\t}\n\n\tappendEntry(entry: SessionEntry): void {\n\t\tthis.fileEntries.push(entry);\n\t\tthis.byId.set(entry.id, entry);\n\t\tthis.leafId = entry.id;\n\t\tthis.applyLabelEntry(entry);\n\t}\n\n\tsaveSnapshot(): void {\n\t\t// No-op for in-memory sessions.\n\t}\n\n\tcommitSnapshot(): void {\n\t\t// No-op for in-memory sessions.\n\t}\n\n\tgetLeafId(): string | null {\n\t\treturn this.leafId;\n\t}\n\n\tsetLeafId(leafId: string | null): void {\n\t\tthis.leafId = leafId;\n\t}\n\n\tgetLeafEntry(): SessionEntry | undefined {\n\t\treturn this.leafId ? this.byId.get(this.leafId) : undefined;\n\t}\n\n\tgetEntry(id: string): SessionEntry | undefined {\n\t\treturn this.byId.get(id);\n\t}\n\n\tgetChildren(parentId: string): SessionEntry[] {\n\t\tconst children: SessionEntry[] = [];\n\t\tfor (const entry of this.byId.values()) {\n\t\t\tif (entry.parentId === parentId) {\n\t\t\t\tchildren.push(entry);\n\t\t\t}\n\t\t}\n\t\treturn children;\n\t}\n\n\tgetLabel(id: string): string | undefined {\n\t\treturn this.labelsById.get(id);\n\t}\n\n\tgetBranch(fromId?: string): SessionEntry[] {\n\t\tconst path: SessionEntry[] = [];\n\t\tconst startId = fromId ?? this.leafId;\n\t\tlet current = startId ? this.byId.get(startId) : undefined;\n\t\twhile (current) {\n\t\t\tpath.unshift(current);\n\t\t\tcurrent = current.parentId ? this.byId.get(current.parentId) : undefined;\n\t\t}\n\t\treturn path;\n\t}\n\n\tgetTree(): SessionTreeNode[] {\n\t\tconst entries = this.getEntries();\n\t\tconst nodeMap = new Map<string, SessionTreeNode>();\n\t\tconst roots: SessionTreeNode[] = [];\n\n\t\tfor (const entry of entries) {\n\t\t\tconst label = this.labelsById.get(entry.id);\n\t\t\tconst labelTimestamp = this.labelTimestampsById.get(entry.id);\n\t\t\tnodeMap.set(entry.id, { entry, children: [], label, labelTimestamp });\n\t\t}\n\n\t\tconst childNodes: Array<[parent: SessionTreeNode, child: SessionTreeNode]> = [];\n\t\tfor (const entry of entries) {\n\t\t\tconst node = nodeMap.get(entry.id)!;\n\t\t\tif (entry.parentId === null || entry.parentId === entry.id) {\n\t\t\t\troots.push(node);\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tconst parent = nodeMap.get(entry.parentId);\n\t\t\tif (parent) childNodes.push([parent, node]);\n\t\t\telse roots.push(node);\n\t\t}\n\t\tchildNodes.sort(\n\t\t\t([, left], [, right]) => new Date(left.entry.timestamp).getTime() - new Date(right.entry.timestamp).getTime(),\n\t\t);\n\t\tfor (const [parent, child] of childNodes) parent.children.push(child);\n\n\t\treturn roots;\n\t}\n\n\tgetSessionName(): string | undefined {\n\t\tconst entries = this.getEntries();\n\t\tfor (let i = entries.length - 1; i >= 0; i--) {\n\t\t\tconst entry = entries[i];\n\t\t\tif (entry.type === \"session_info\") {\n\t\t\t\treturn entry.name?.trim() || undefined;\n\t\t\t}\n\t\t}\n\t\treturn undefined;\n\t}\n\n\tgetLabelsForEntryIds(entryIds: Set<string>): SessionLabelSnapshot[] {\n\t\tconst labels: SessionLabelSnapshot[] = [];\n\t\tfor (const [targetId, label] of this.labelsById) {\n\t\t\tif (entryIds.has(targetId)) {\n\t\t\t\tlabels.push({ targetId, label, timestamp: this.labelTimestampsById.get(targetId)! });\n\t\t\t}\n\t\t}\n\t\treturn labels;\n\t}\n\n\thasAssistantMessage(): boolean {\n\t\treturn this.fileEntries.some((entry) => entry.type === \"message\" && entry.message.role === \"assistant\");\n\t}\n\n\tprivate rebuildIndex(): void {\n\t\tthis.byId.clear();\n\t\tthis.labelsById.clear();\n\t\tthis.labelTimestampsById.clear();\n\t\tthis.leafId = null;\n\t\tfor (const entry of this.fileEntries) {\n\t\t\tif (entry.type === \"session\") continue;\n\t\t\tthis.byId.set(entry.id, entry);\n\t\t\tthis.leafId = entry.id;\n\t\t\tthis.applyLabelEntry(entry);\n\t\t}\n\t}\n\n\tprivate applyLabelEntry(entry: SessionEntry): void {\n\t\tif (entry.type !== \"label\") return;\n\t\tconst labelEntry = entry as LabelEntry;\n\t\tif (labelEntry.label) {\n\t\t\tthis.labelsById.set(labelEntry.targetId, labelEntry.label);\n\t\t\tthis.labelTimestampsById.set(labelEntry.targetId, labelEntry.timestamp);\n\t\t} else {\n\t\t\tthis.labelsById.delete(labelEntry.targetId);\n\t\t\tthis.labelTimestampsById.delete(labelEntry.targetId);\n\t\t}\n\t}\n}\n"]}
@@ -0,0 +1,97 @@
1
+ import { type JsonlErrorPhase } from "../jsonl-errors.ts";
2
+ import type { FileEntry, SessionEntry, SessionHeader, SessionInfo, SessionListProgress } from "../types.ts";
3
+ import { InMemorySessionStore } from "./in-memory-session-store.ts";
4
+ interface JsonlRecordLocation {
5
+ line: number;
6
+ byteOffset: number;
7
+ }
8
+ export declare function getJsonlEntryLocations(entries: FileEntry[]): ReadonlyArray<JsonlRecordLocation | undefined> | undefined;
9
+ export declare class SessionHeaderScanLimitError extends Error {
10
+ constructor(filePath: string);
11
+ }
12
+ export declare function readSessionHeader(filePath: string): SessionHeader | null;
13
+ export declare function getSessionDirForReference(reference: string): string;
14
+ export declare function getDefaultSessionDirPath(cwd: string, agentDir?: string): string;
15
+ export declare function getDefaultSessionDir(cwd: string, agentDir?: string): string;
16
+ export declare function getSessionsRoot(): string;
17
+ export declare function prepareSessionReference(sessionDir: string, sessionId: string, timestamp: string): string;
18
+ export declare function exists(path: string): boolean;
19
+ export declare function ensureDir(path: string): void;
20
+ export interface JsonlValidationContext {
21
+ phase?: JsonlErrorPhase;
22
+ locations?: ReadonlyArray<JsonlRecordLocation | undefined>;
23
+ }
24
+ export declare function validateCurrentSessionEntries(entries: FileEntry[], filePath?: string, context?: JsonlValidationContext): void;
25
+ export declare function load(filePath: string, publicationOptions?: JsonlAtomicPublicationOptions, repair?: boolean, phase?: JsonlErrorPhase): FileEntry[];
26
+ export declare function append(filePath: string, entry: FileEntry): void;
27
+ export interface JsonlAtomicPublicationOptions {
28
+ rename?: (source: string, destination: string) => void;
29
+ remove?: (path: string) => void;
30
+ platform?: NodeJS.Platform;
31
+ phase?: JsonlErrorPhase;
32
+ }
33
+ export declare function publishJsonlAtomically(filePath: string, entries: FileEntry[], options?: JsonlAtomicPublicationOptions): void;
34
+ export declare function rewrite(filePath: string, entries: FileEntry[]): void;
35
+ export declare function forkSession(sessionDir: string, header: SessionHeader, sourceEntries: FileEntry[]): string;
36
+ export declare function findMostRecent(sessionDir: string, cwd?: string): string | null;
37
+ export declare function list(dir: string, onProgress?: SessionListProgress): Promise<SessionInfo[]>;
38
+ export declare function listAll(sessionsDir: string, onProgress?: SessionListProgress): Promise<SessionInfo[]>;
39
+ interface PreloadedSessionEntries {
40
+ reference: string;
41
+ entries: FileEntry[];
42
+ }
43
+ type JsonlNewSessionPublicationPhase = "create" | "fork";
44
+ export type JsonlFirstPublicationPhase = JsonlNewSessionPublicationPhase | "import";
45
+ interface JsonlFirstPublicationOptions {
46
+ allowExistingEmptyFile: boolean;
47
+ phase: JsonlFirstPublicationPhase;
48
+ }
49
+ interface JsonlSessionReferenceOptions {
50
+ allowExistingEmptyFile?: boolean;
51
+ }
52
+ interface JsonlSnapshotOptions {
53
+ phase?: JsonlErrorPhase;
54
+ }
55
+ export interface JsonlStoreWriteOperations {
56
+ append(filePath: string, serializedEntry: string): void;
57
+ publish(filePath: string, entries: FileEntry[], options?: JsonlAtomicPublicationOptions): void;
58
+ }
59
+ export interface JsonlFirstPublicationCoordinator {
60
+ publish(filePath: string, entries: FileEntry[], operation: () => void, options: JsonlFirstPublicationOptions): void;
61
+ }
62
+ export declare class SessionAlreadyExistsError extends Error {
63
+ readonly code = "already_exists";
64
+ readonly reference: string;
65
+ readonly path: string;
66
+ readonly phase: JsonlFirstPublicationPhase;
67
+ readonly outcome = "not_written";
68
+ constructor(reference: string, sessionId: string, phase?: JsonlFirstPublicationPhase);
69
+ }
70
+ export declare class JsonlSessionStore extends InMemorySessionStore {
71
+ private reference;
72
+ private flushed;
73
+ private preloaded;
74
+ private allowExistingEmptyFile;
75
+ private readonly writeOperations;
76
+ private readonly firstPublicationCoordinator;
77
+ private writeFence;
78
+ private nextAppendLine;
79
+ private nextAppendOffset;
80
+ constructor(preloaded?: PreloadedSessionEntries, writeOperations?: JsonlStoreWriteOperations, firstPublicationCoordinator?: JsonlFirstPublicationCoordinator);
81
+ isPersisted(): boolean;
82
+ getSessionReference(): string | undefined;
83
+ setSessionReference(reference: string, options?: JsonlSessionReferenceOptions): void;
84
+ exists(path: string): boolean;
85
+ ensureDir(path: string): void;
86
+ load(filePath: string): FileEntry[];
87
+ private updateNextAppendPosition;
88
+ private persistAppendedEntry;
89
+ private recordAppendedEntryPosition;
90
+ appendEntry(entry: SessionEntry): void;
91
+ private assertWritable;
92
+ private publishFirstSnapshot;
93
+ saveSnapshot(options?: JsonlSnapshotOptions): void;
94
+ commitSnapshot(): void;
95
+ }
96
+ export {};
97
+ //# sourceMappingURL=jsonl-session-store.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"jsonl-session-store.d.ts","sourceRoot":"","sources":["../../../../src/core/session/stores/jsonl-session-store.ts"],"names":[],"mappings":"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","sourcesContent":["import { randomUUID } from \"node:crypto\";\nimport type { AgentMessage, JsonlPhysicalRecord } from \"@greppleai/grip-agent-core\";\nimport type { Message, TextContent } from \"@greppleai/grip-ai\";\nimport {\n\tappendFileSync,\n\tcloseSync,\n\tcreateReadStream,\n\texistsSync,\n\tlstatSync,\n\tmkdirSync,\n\topenSync,\n\treaddirSync,\n\treadFileSync,\n\treadSync,\n\trenameSync,\n\trmSync,\n\tstatSync,\n\twriteFileSync,\n} from \"fs\";\nimport { readdir, stat } from \"fs/promises\";\nimport { basename, dirname, join, resolve } from \"path\";\nimport { createInterface } from \"readline\";\nimport { getAgentDir as getDefaultAgentDir, getSessionsDir } from \"../../../config.ts\";\nimport {\n\tJsonlDecodeError as JsonlDecodeFailure,\n\ttype JsonlErrorPhase,\n\tJsonlSessionError,\n\ttype JsonlWriteOutcome,\n} from \"../jsonl-errors.ts\";\nimport type {\n\tFileEntry,\n\tSessionEntry,\n\tSessionHeader,\n\tSessionInfo,\n\tSessionListProgress,\n\tSessionMessageEntry,\n} from \"../types.ts\";\nimport { InMemorySessionStore } from \"./in-memory-session-store.ts\";\n\nfunction isMessageWithContent(message: AgentMessage): message is Message {\n\treturn typeof (message as Message).role === \"string\" && \"content\" in message;\n}\n\nfunction extractTextContent(message: Message): string {\n\tconst content = message.content;\n\tif (content == null) {\n\t\treturn \"\";\n\t}\n\tif (typeof content === \"string\") {\n\t\treturn content;\n\t}\n\treturn content\n\t\t.filter((block): block is TextContent => block.type === \"text\")\n\t\t.map((block) => block.text)\n\t\t.join(\" \");\n}\n\nfunction getMessageActivityTime(entry: SessionMessageEntry): number | undefined {\n\tconst message = entry.message;\n\tif (!isMessageWithContent(message)) return undefined;\n\tif (message.role !== \"user\" && message.role !== \"assistant\") return undefined;\n\n\tconst msgTimestamp = message.timestamp;\n\tif (typeof msgTimestamp === \"number\") {\n\t\treturn msgTimestamp;\n\t}\n\n\tconst t = new Date(entry.timestamp).getTime();\n\treturn Number.isNaN(t) ? undefined : t;\n}\n\nconst SESSION_READ_BUFFER_SIZE = 1024 * 1024;\nconst SESSION_HEADER_READ_BUFFER_SIZE = 4096;\n/** Bound synchronous header discovery while allowing large cwd and custom metadata fields. */\nconst MAX_SESSION_HEADER_SCAN_BYTES = 1024 * 1024;\nconst SAFE_ID_PATTERN = /^[A-Za-z0-9](?:[A-Za-z0-9._-]*[A-Za-z0-9])?$/;\n\ninterface JsonlRecordLocation {\n\tline: number;\n\tbyteOffset: number;\n}\n\nfunction parseSessionEntryLine(line: string): FileEntry | null {\n\tif (!line.trim()) return null;\n\ttry {\n\t\treturn JSON.parse(line) as FileEntry;\n\t} catch {\n\t\treturn null;\n\t}\n}\n\nfunction* readPhysicalRecords(filePath: string): Generator<JsonlPhysicalRecord> {\n\tconst fd = openSync(filePath, \"r\");\n\tconst buffer = Buffer.allocUnsafe(SESSION_READ_BUFFER_SIZE);\n\tlet pending = Buffer.alloc(0);\n\tlet consumedBytes = 0;\n\tlet recordStart = 0;\n\tlet line = 1;\n\ttry {\n\t\twhile (true) {\n\t\t\tconst bytesRead = readSync(fd, buffer, 0, buffer.length, null);\n\t\t\tif (bytesRead === 0) break;\n\t\t\tconst chunk = buffer.subarray(0, bytesRead);\n\t\t\tconst data = pending.length === 0 ? chunk : Buffer.concat([pending, chunk]);\n\t\t\tlet start = 0;\n\t\t\tlet newline = data.indexOf(0x0a, start);\n\t\t\twhile (newline !== -1) {\n\t\t\t\tyield { bytes: data.subarray(start, newline), line, start: recordStart, terminated: true };\n\t\t\t\tline++;\n\t\t\t\tstart = newline + 1;\n\t\t\t\trecordStart = consumedBytes + bytesRead - (data.length - start);\n\t\t\t\tnewline = data.indexOf(0x0a, start);\n\t\t\t}\n\t\t\tpending = Buffer.from(data.subarray(start));\n\t\t\tconsumedBytes += bytesRead;\n\t\t}\n\t\tif (pending.length > 0) yield { bytes: pending, line, start: recordStart, terminated: false };\n\t} finally {\n\t\tcloseSync(fd);\n\t}\n}\n\nconst jsonlEntryLocations = new WeakMap<FileEntry[], ReadonlyArray<JsonlRecordLocation | undefined>>();\n\nexport function getJsonlEntryLocations(\n\tentries: FileEntry[],\n): ReadonlyArray<JsonlRecordLocation | undefined> | undefined {\n\treturn jsonlEntryLocations.get(entries);\n}\n\nfunction decodePhysicalRecord(record: JsonlPhysicalRecord): string {\n\tlet bytes = record.bytes;\n\tif (bytes.at(-1) === 0x0d) bytes = bytes.subarray(0, bytes.length - 1);\n\ttry {\n\t\treturn new TextDecoder(\"utf-8\", { fatal: true }).decode(bytes);\n\t} catch (error) {\n\t\tthrow new JsonlDecodeFailure(\n\t\t\t\"utf8\",\n\t\t\t\"contains invalid UTF-8\",\n\t\t\terror instanceof Error ? error : new Error(String(error)),\n\t\t);\n\t}\n}\n\nfunction parseJsonObject(record: JsonlPhysicalRecord): Record<string, unknown> {\n\tlet parsed: unknown;\n\ttry {\n\t\tparsed = JSON.parse(decodePhysicalRecord(record));\n\t} catch (error) {\n\t\tif (error instanceof JsonlDecodeFailure) throw error;\n\t\tthrow new JsonlDecodeFailure(\n\t\t\t\"syntax\",\n\t\t\t\"is not valid JSON\",\n\t\t\terror instanceof Error ? error : new Error(String(error)),\n\t\t);\n\t}\n\tif (typeof parsed !== \"object\" || parsed === null || Array.isArray(parsed)) {\n\t\tthrow new JsonlDecodeFailure(\"schema\", \"is not a JSON object\");\n\t}\n\treturn parsed as Record<string, unknown>;\n}\n\nfunction requireString(value: unknown, field: string): string {\n\tif (typeof value !== \"string\" || value.length === 0) {\n\t\tthrow new JsonlDecodeFailure(\"schema\", `has invalid ${field}`);\n\t}\n\treturn value;\n}\n\nfunction requireId(value: unknown, field: string): string {\n\tconst id = requireString(value, field);\n\tif (!SAFE_ID_PATTERN.test(id)) throw new JsonlDecodeFailure(\"schema\", `has invalid ${field}`);\n\treturn id;\n}\n\nfunction requireTimestamp(value: unknown): string {\n\tconst timestamp = requireString(value, \"timestamp\");\n\tif (Number.isNaN(Date.parse(timestamp))) throw new JsonlDecodeFailure(\"schema\", \"has invalid timestamp\");\n\treturn timestamp;\n}\n\nconst MESSAGE_ROLES = new Set([\n\t\"user\",\n\t\"assistant\",\n\t\"toolResult\",\n\t\"bashExecution\",\n\t\"custom\",\n\t\"branchSummary\",\n\t\"compactionSummary\",\n\t\"hookMessage\",\n]);\n\nfunction validatePersistedMessageRole(message: Record<string, unknown>, role: string): void {\n\tswitch (role) {\n\t\tcase \"toolResult\":\n\t\t\trequireString(message.toolCallId, \"toolCallId\");\n\t\t\trequireString(message.toolName, \"toolName\");\n\t\t\tif (typeof message.isError !== \"boolean\") throw new JsonlDecodeFailure(\"schema\", \"has invalid isError\");\n\t\t\tbreak;\n\t\tcase \"custom\":\n\t\tcase \"hookMessage\":\n\t\t\trequireString(message.customType, \"customType\");\n\t\t\tif (typeof message.display !== \"boolean\") throw new JsonlDecodeFailure(\"schema\", \"has invalid display\");\n\t\t\tbreak;\n\t\tcase \"bashExecution\":\n\t\t\trequireString(message.command, \"command\");\n\t\t\tif (typeof message.output !== \"string\") throw new JsonlDecodeFailure(\"schema\", \"has invalid output\");\n\t\t\tif (typeof message.cancelled !== \"boolean\" || typeof message.truncated !== \"boolean\") {\n\t\t\t\tthrow new JsonlDecodeFailure(\"schema\", \"has invalid bash state\");\n\t\t\t}\n\t\t\tbreak;\n\t\tcase \"branchSummary\":\n\t\tcase \"compactionSummary\":\n\t\t\trequireString(message.summary, \"summary\");\n\t}\n}\n\nfunction validatePersistedMessage(value: unknown): void {\n\tif (typeof value !== \"object\" || value === null) throw new JsonlDecodeFailure(\"schema\", \"has invalid message\");\n\tconst message = value as Record<string, unknown>;\n\tconst role = requireString(message.role, \"message role\");\n\tif (!MESSAGE_ROLES.has(role)) throw new JsonlDecodeFailure(\"schema\", `has unknown message role ${role}`);\n\tif (typeof message.timestamp !== \"number\" || !Number.isFinite(message.timestamp)) {\n\t\tthrow new JsonlDecodeFailure(\"schema\", \"has invalid message timestamp\");\n\t}\n\tif (message.content != null && typeof message.content !== \"string\" && !Array.isArray(message.content)) {\n\t\tthrow new JsonlDecodeFailure(\"schema\", \"has invalid message content\");\n\t}\n\tvalidatePersistedMessageRole(message, role);\n}\n\nconst SESSION_ENTRY_TYPES = new Set<SessionEntry[\"type\"]>([\n\t\"message\",\n\t\"thinking_level_change\",\n\t\"model_change\",\n\t\"compaction\",\n\t\"branch_summary\",\n\t\"custom\",\n\t\"custom_message\",\n\t\"label\",\n\t\"session_info\",\n]);\n\nfunction parseStrictHeader(record: JsonlPhysicalRecord): SessionHeader {\n\tconst value = parseJsonObject(record);\n\tif (value.type !== \"session\") throw new JsonlDecodeFailure(\"schema\", \"is not a session header\");\n\tconst version = value.version ?? 1;\n\tif (version !== 1 && version !== 2 && version !== 3) {\n\t\tthrow new JsonlDecodeFailure(\"schema\", \"has unsupported session version\");\n\t}\n\trequireId(value.id, \"session id\");\n\trequireTimestamp(value.timestamp);\n\trequireString(value.cwd, \"cwd\");\n\tif (value.parentSession !== undefined && typeof value.parentSession !== \"string\") {\n\t\tthrow new JsonlDecodeFailure(\"schema\", \"has invalid parentSession\");\n\t}\n\treturn value as unknown as SessionHeader;\n}\nfunction validateVersionedEntryLinks(value: Record<string, unknown>, version: number): void {\n\tif (version < 2) return;\n\trequireId(value.id, \"entry id\");\n\tif (value.parentId !== null && (typeof value.parentId !== \"string\" || !SAFE_ID_PATTERN.test(value.parentId))) {\n\t\tthrow new JsonlDecodeFailure(\"schema\", \"has invalid parentId\");\n\t}\n}\n\nfunction validateCompactionEntry(value: Record<string, unknown>, version: number): void {\n\trequireString(value.summary, \"summary\");\n\tif (version === 1) {\n\t\tif (value.firstKeptEntryId === undefined && !Number.isInteger(value.firstKeptEntryIndex)) {\n\t\t\tthrow new JsonlDecodeFailure(\"schema\", \"has invalid compaction target\");\n\t\t}\n\t} else requireId(value.firstKeptEntryId, \"firstKeptEntryId\");\n\tif (typeof value.tokensBefore !== \"number\" || !Number.isFinite(value.tokensBefore)) {\n\t\tthrow new JsonlDecodeFailure(\"schema\", \"has invalid tokensBefore\");\n\t}\n}\n\nfunction validateCustomMessageEntry(value: Record<string, unknown>): void {\n\trequireString(value.customType, \"customType\");\n\tif (value.content != null && typeof value.content !== \"string\" && !Array.isArray(value.content)) {\n\t\tthrow new JsonlDecodeFailure(\"schema\", \"has invalid content\");\n\t}\n\tif (typeof value.display !== \"boolean\") throw new JsonlDecodeFailure(\"schema\", \"has invalid display\");\n}\n\nfunction parseStrictEntry(record: JsonlPhysicalRecord, version: number): SessionEntry {\n\tconst value = parseJsonObject(record);\n\tconst type = requireString(value.type, \"entry type\");\n\tif (!SESSION_ENTRY_TYPES.has(type as SessionEntry[\"type\"])) {\n\t\tthrow new JsonlDecodeFailure(\"schema\", `has unknown entry type ${type}`);\n\t}\n\trequireTimestamp(value.timestamp);\n\tvalidateVersionedEntryLinks(value, version);\n\tswitch (type) {\n\t\tcase \"message\":\n\t\t\tvalidatePersistedMessage(value.message);\n\t\t\tbreak;\n\t\tcase \"thinking_level_change\":\n\t\t\trequireString(value.thinkingLevel, \"thinkingLevel\");\n\t\t\tbreak;\n\t\tcase \"model_change\":\n\t\t\trequireString(value.provider, \"provider\");\n\t\t\trequireString(value.modelId, \"modelId\");\n\t\t\tbreak;\n\t\tcase \"compaction\":\n\t\t\tvalidateCompactionEntry(value, version);\n\t\t\tbreak;\n\t\tcase \"branch_summary\":\n\t\t\trequireId(value.fromId, \"fromId\");\n\t\t\trequireString(value.summary, \"summary\");\n\t\t\tbreak;\n\t\tcase \"custom\":\n\t\t\trequireString(value.customType, \"customType\");\n\t\t\tbreak;\n\t\tcase \"custom_message\":\n\t\t\tvalidateCustomMessageEntry(value);\n\t\t\tif (typeof value.display !== \"boolean\") throw new JsonlDecodeFailure(\"schema\", \"has invalid display\");\n\t\t\tbreak;\n\t\tcase \"label\":\n\t\t\trequireId(value.targetId, \"targetId\");\n\t\t\tif (value.label !== undefined && typeof value.label !== \"string\") {\n\t\t\t\tthrow new JsonlDecodeFailure(\"schema\", \"has invalid label\");\n\t\t\t}\n\t\t\tbreak;\n\t\tcase \"session_info\":\n\t\t\tif (value.name !== undefined && typeof value.name !== \"string\") {\n\t\t\t\tthrow new JsonlDecodeFailure(\"schema\", \"has invalid name\");\n\t\t\t}\n\t\t\tbreak;\n\t}\n\treturn value as unknown as SessionEntry;\n}\n\nfunction invalidJsonl(\n\tfilePath: string,\n\trecord: JsonlPhysicalRecord,\n\tfailure: Error,\n\tphase: JsonlErrorPhase,\n): JsonlSessionError {\n\tconst decodeFailure =\n\t\tfailure instanceof JsonlDecodeFailure ? failure : new JsonlDecodeFailure(\"state\", failure.message, failure);\n\treturn new JsonlSessionError({\n\t\tcode: \"invalid_jsonl\",\n\t\treference: filePath,\n\t\tphase,\n\t\tline: record.line,\n\t\tbyteOffset: record.start,\n\t\tdecodeKind: decodeFailure.decodeKind,\n\t\tmessage: `Invalid JSONL session file ${filePath}: line ${record.line} ${failure.message}`,\n\t\tcause: decodeFailure,\n\t});\n}\n\nfunction jsonlStorageError(\n\treference: string,\n\tphase: JsonlErrorPhase,\n\tmessage: string,\n\tcause: Error,\n\toutcome?: JsonlWriteOutcome,\n): JsonlSessionError {\n\tif (cause instanceof JsonlSessionError && cause.phase === phase) return cause;\n\treturn new JsonlSessionError({\n\t\tcode: cause instanceof JsonlSessionError ? cause.code : \"storage\",\n\t\treference,\n\t\tphase,\n\t\tline: cause instanceof JsonlSessionError ? cause.line : undefined,\n\t\tbyteOffset: cause instanceof JsonlSessionError ? cause.byteOffset : undefined,\n\t\tdecodeKind: cause instanceof JsonlSessionError ? cause.decodeKind : undefined,\n\t\tmessage,\n\t\toutcome: outcome ?? (cause instanceof JsonlSessionError ? cause.outcome : undefined),\n\t\tcause,\n\t});\n}\n\nexport class SessionHeaderScanLimitError extends Error {\n\tconstructor(filePath: string) {\n\t\tsuper(`Session header exceeds ${MAX_SESSION_HEADER_SCAN_BYTES}-byte scan limit: ${filePath}`);\n\t\tthis.name = \"SessionHeaderScanLimitError\";\n\t}\n}\n\n/**\n * Inspect a physical line while searching for the first parsed session entry.\n * Blank lines are skipped; a malformed non-blank candidate quarantines the file.\n */\nfunction parseSessionHeaderCandidate(line: string): SessionHeader | null | undefined {\n\tif (!line.trim()) return undefined;\n\ttry {\n\t\tconst bytes = new TextEncoder().encode(line);\n\t\treturn parseStrictHeader({ bytes, line: 1, start: 0, terminated: true });\n\t} catch {\n\t\treturn null;\n\t}\n}\n\nfunction parseSessionHeaderBytes(bytes: Uint8Array): SessionHeader | null | undefined {\n\ttry {\n\t\treturn parseSessionHeaderCandidate(new TextDecoder(\"utf-8\", { fatal: true }).decode(bytes));\n\t} catch {\n\t\treturn null;\n\t}\n}\n\nexport function readSessionHeader(filePath: string): SessionHeader | null {\n\tconst fd = openSync(filePath, \"r\");\n\ttry {\n\t\tconst buffer = Buffer.allocUnsafe(SESSION_HEADER_READ_BUFFER_SIZE);\n\t\tlet pending = Buffer.alloc(0);\n\t\tlet scannedBytes = 0;\n\t\twhile (scannedBytes < MAX_SESSION_HEADER_SCAN_BYTES) {\n\t\t\tconst readLength = Math.min(buffer.length, MAX_SESSION_HEADER_SCAN_BYTES - scannedBytes);\n\t\t\tconst bytesRead = readSync(fd, buffer, 0, readLength, null);\n\t\t\tif (bytesRead === 0) return parseSessionHeaderBytes(pending) ?? null;\n\t\t\tscannedBytes += bytesRead;\n\t\t\tconst data =\n\t\t\t\tpending.length === 0\n\t\t\t\t\t? buffer.subarray(0, bytesRead)\n\t\t\t\t\t: Buffer.concat([pending, buffer.subarray(0, bytesRead)]);\n\t\t\tlet lineStart = 0;\n\t\t\tlet newlineIndex = data.indexOf(0x0a, lineStart);\n\t\t\twhile (newlineIndex !== -1) {\n\t\t\t\tconst header = parseSessionHeaderBytes(data.subarray(lineStart, newlineIndex));\n\t\t\t\tif (header !== undefined) return header;\n\t\t\t\tlineStart = newlineIndex + 1;\n\t\t\t\tnewlineIndex = data.indexOf(0x0a, lineStart);\n\t\t\t}\n\t\t\tpending = Buffer.from(data.subarray(lineStart));\n\t\t}\n\t\tconst probe = Buffer.allocUnsafe(1);\n\t\tif (readSync(fd, probe, 0, probe.length, null) === 0) return parseSessionHeaderBytes(pending) ?? null;\n\t\tthrow new SessionHeaderScanLimitError(filePath);\n\t} finally {\n\t\tcloseSync(fd);\n\t}\n}\n\nfunction readSessionHeaderForDiscovery(filePath: string): SessionHeader | null {\n\ttry {\n\t\treturn readSessionHeader(filePath);\n\t} catch (error) {\n\t\tif (error instanceof SessionHeaderScanLimitError) return null;\n\t\tthrow error;\n\t}\n}\n\nfunction getSessionHeaderCwd(header: SessionHeader): string | undefined {\n\tconst cwd = (header as { cwd?: unknown }).cwd;\n\treturn typeof cwd === \"string\" ? cwd : undefined;\n}\n\nfunction sessionCwdMatches(cwd: string | undefined, resolvedCwd: string): boolean {\n\treturn cwd !== undefined && cwd !== \"\" && resolve(cwd) === resolvedCwd;\n}\ninterface SessionInfoScanResult {\n\tmessageCount: number;\n\tfirstMessage: string;\n\tallMessages: string[];\n\tname: string | undefined;\n\tlastActivityTime: number | undefined;\n}\n\nfunction recordSessionInfoEntry(result: SessionInfoScanResult, entry: FileEntry): void {\n\tif (entry.type === \"session_info\") result.name = entry.name?.trim() || undefined;\n\tif (entry.type !== \"message\") return;\n\n\tresult.messageCount++;\n\tconst activityTime = getMessageActivityTime(entry);\n\tif (typeof activityTime === \"number\") {\n\t\tresult.lastActivityTime = Math.max(result.lastActivityTime ?? 0, activityTime);\n\t}\n\n\tconst message = entry.message;\n\tif (!isMessageWithContent(message)) return;\n\tif (message.role !== \"user\" && message.role !== \"assistant\") return;\n\tconst textContent = extractTextContent(message);\n\tif (!textContent) return;\n\n\tresult.allMessages.push(textContent);\n\tif (!result.firstMessage && message.role === \"user\") result.firstMessage = textContent;\n}\n\nasync function scanSessionInfo(filePath: string): Promise<SessionInfoScanResult> {\n\tconst result: SessionInfoScanResult = {\n\t\tmessageCount: 0,\n\t\tfirstMessage: \"\",\n\t\tallMessages: [],\n\t\tname: undefined,\n\t\tlastActivityTime: undefined,\n\t};\n\tconst lines = createInterface({\n\t\tinput: createReadStream(filePath, { encoding: \"utf8\" }),\n\t\tcrlfDelay: Infinity,\n\t});\n\tfor await (const line of lines) {\n\t\tconst entry = parseSessionEntryLine(line);\n\t\tif (entry && entry.type !== \"session\") recordSessionInfoEntry(result, entry);\n\t}\n\treturn result;\n}\n\nfunction resolveSessionModifiedDate(header: SessionHeader, lastActivityTime: number | undefined, fallback: Date): Date {\n\tif (typeof lastActivityTime === \"number\" && lastActivityTime > 0) return new Date(lastActivityTime);\n\tconst headerTime = typeof header.timestamp === \"string\" ? new Date(header.timestamp).getTime() : NaN;\n\treturn Number.isNaN(headerTime) ? fallback : new Date(headerTime);\n}\n\nasync function buildSessionInfo(filePath: string): Promise<SessionInfo | null> {\n\ttry {\n\t\tconst stats = await stat(filePath);\n\t\tconst header = readSessionHeaderForDiscovery(filePath);\n\t\tif (!header) return null;\n\t\tconst scan = await scanSessionInfo(filePath);\n\t\tconst cwd = typeof header.cwd === \"string\" ? header.cwd : \"\";\n\n\t\treturn {\n\t\t\treference: filePath,\n\t\t\tpath: filePath,\n\t\t\tid: header.id,\n\t\t\tcwd,\n\t\t\tname: scan.name,\n\t\t\tparentSessionPath: header.parentSession,\n\t\t\tcreated: new Date(header.timestamp),\n\t\t\tmodified: resolveSessionModifiedDate(header, scan.lastActivityTime, stats.mtime),\n\t\t\tmessageCount: scan.messageCount,\n\t\t\tfirstMessage: scan.firstMessage || \"(no messages)\",\n\t\t\tallMessagesText: scan.allMessages.join(\" \"),\n\t\t};\n\t} catch {\n\t\treturn null;\n\t}\n}\n\nconst MAX_CONCURRENT_SESSION_INFO_LOADS = 10;\n\nexport function getSessionDirForReference(reference: string): string {\n\treturn resolve(reference, \"..\");\n}\n\nexport function getDefaultSessionDirPath(cwd: string, agentDir: string = getDefaultAgentDir()): string {\n\tconst resolvedCwd = resolve(cwd);\n\tconst safePath = `--${resolvedCwd.replace(/^[/\\\\]/, \"\").replace(/[/\\\\:]/g, \"-\")}--`;\n\treturn join(resolve(agentDir), \"sessions\", safePath);\n}\n\nexport function getDefaultSessionDir(cwd: string, agentDir: string = getDefaultAgentDir()): string {\n\tconst sessionDir = getDefaultSessionDirPath(cwd, agentDir);\n\tensureDir(sessionDir);\n\treturn sessionDir;\n}\n\nexport function getSessionsRoot(): string {\n\treturn getSessionsDir();\n}\n\nexport function prepareSessionReference(sessionDir: string, sessionId: string, timestamp: string): string {\n\tconst fileTimestamp = timestamp.replace(/[:.]/g, \"-\");\n\treturn join(sessionDir, `${fileTimestamp}_${sessionId}.jsonl`);\n}\n\nexport function exists(path: string): boolean {\n\treturn existsSync(path);\n}\n\nexport function ensureDir(path: string): void {\n\tif (!existsSync(path)) {\n\t\tmkdirSync(path, { recursive: true });\n\t}\n}\nexport interface JsonlValidationContext {\n\tphase?: JsonlErrorPhase;\n\tlocations?: ReadonlyArray<JsonlRecordLocation | undefined>;\n}\ninterface CurrentSessionValidationState {\n\tfilePath: string;\n\tphase: JsonlErrorPhase;\n\tlocations: ReadonlyArray<JsonlRecordLocation | undefined> | undefined;\n\tentriesById: Map<string, SessionEntry>;\n}\n\nfunction failCurrentSessionValidation(\n\tstate: CurrentSessionValidationState,\n\tindex: number,\n\tfailure: JsonlDecodeFailure,\n): never {\n\tconst location = state.locations?.[index];\n\tthrow new JsonlSessionError({\n\t\tcode: \"invalid_jsonl\",\n\t\treference: state.filePath,\n\t\tphase: state.phase,\n\t\tline: location?.line ?? index + 1,\n\t\tbyteOffset: location?.byteOffset,\n\t\tdecodeKind: failure.decodeKind,\n\t\tmessage: `Invalid JSONL session file ${state.filePath}: line ${location?.line ?? index + 1} ${failure.message}`,\n\t\tcause: failure,\n\t});\n}\n\nfunction validateCurrentSessionHeader(header: FileEntry | undefined, state: CurrentSessionValidationState): void {\n\tif (header?.type !== \"session\" || header.version !== 3) {\n\t\tfailCurrentSessionValidation(\n\t\t\tstate,\n\t\t\t0,\n\t\t\tnew JsonlDecodeFailure(\"state\", \"does not have a current version-3 header\"),\n\t\t);\n\t}\n\ttry {\n\t\tconst encodedHeader = new TextEncoder().encode(JSON.stringify(header));\n\t\tparseStrictHeader({ bytes: encodedHeader, line: 1, start: 0, terminated: true });\n\t} catch (error) {\n\t\tif (error instanceof JsonlDecodeFailure) failCurrentSessionValidation(state, 0, error);\n\t\tthrow error;\n\t}\n}\n\nfunction validateCurrentSessionEntrySchema(\n\tentry: FileEntry | undefined,\n\tindex: number,\n\tstate: CurrentSessionValidationState,\n): asserts entry is SessionEntry {\n\tif (!entry || entry.type === \"session\") {\n\t\tfailCurrentSessionValidation(\n\t\t\tstate,\n\t\t\tindex,\n\t\t\tnew JsonlDecodeFailure(\"state\", `has an unexpected session header at logical entry ${index + 1}`),\n\t\t);\n\t}\n\ttry {\n\t\tconst encodedEntry = new TextEncoder().encode(JSON.stringify(entry));\n\t\tparseStrictEntry({ bytes: encodedEntry, line: index + 1, start: 0, terminated: true }, 3);\n\t} catch (error) {\n\t\tif (error instanceof JsonlDecodeFailure) failCurrentSessionValidation(state, index, error);\n\t\tthrow error;\n\t}\n}\n\nfunction getCurrentSessionEntryTarget(entry: SessionEntry): string | undefined {\n\tswitch (entry.type) {\n\t\tcase \"label\":\n\t\t\treturn entry.targetId;\n\t\tcase \"compaction\":\n\t\t\treturn entry.firstKeptEntryId;\n\t\tcase \"branch_summary\":\n\t\t\treturn entry.fromId;\n\t\tdefault:\n\t\t\treturn undefined;\n\t}\n}\n\nfunction validateCurrentSessionEntryLinks(\n\tentry: SessionEntry,\n\tindex: number,\n\tstate: CurrentSessionValidationState,\n): void {\n\tif (state.entriesById.has(entry.id)) {\n\t\tfailCurrentSessionValidation(state, index, new JsonlDecodeFailure(\"state\", `duplicates entry id ${entry.id}`));\n\t}\n\tif (entry.parentId !== null && !state.entriesById.has(entry.parentId)) {\n\t\tfailCurrentSessionValidation(\n\t\t\tstate,\n\t\t\tindex,\n\t\t\tnew JsonlDecodeFailure(\"state\", `references missing parent ${entry.parentId}`),\n\t\t);\n\t}\n\tconst targetId = getCurrentSessionEntryTarget(entry);\n\tif (targetId !== undefined && !state.entriesById.has(targetId)) {\n\t\tfailCurrentSessionValidation(\n\t\t\tstate,\n\t\t\tindex,\n\t\t\tnew JsonlDecodeFailure(\"state\", `references missing target ${targetId}`),\n\t\t);\n\t}\n\tstate.entriesById.set(entry.id, entry);\n}\n\nexport function validateCurrentSessionEntries(\n\tentries: FileEntry[],\n\tfilePath = \"session\",\n\tcontext: JsonlValidationContext = {},\n): void {\n\tconst state: CurrentSessionValidationState = {\n\t\tfilePath,\n\t\tphase: context.phase ?? \"open\",\n\t\tlocations: context.locations,\n\t\tentriesById: new Map(),\n\t};\n\tvalidateCurrentSessionHeader(entries[0], state);\n\tfor (let index = 1; index < entries.length; index++) {\n\t\tconst entry = entries[index];\n\t\tvalidateCurrentSessionEntrySchema(entry, index, state);\n\t\tvalidateCurrentSessionEntryLinks(entry, index, state);\n\t}\n}\n\ninterface JsonlLoadContext {\n\tfilePath: string;\n\tpublicationOptions: JsonlAtomicPublicationOptions;\n\trepair: boolean;\n\tphase: JsonlErrorPhase;\n}\n\ninterface JsonlLoadState {\n\tentries: FileEntry[];\n\tlocations: JsonlRecordLocation[];\n\theader: SessionHeader | undefined;\n\theaderRecord: JsonlPhysicalRecord | undefined;\n\tfinalRecord: JsonlPhysicalRecord | undefined;\n}\n\ntype JsonlRecordScanAction = \"continue\" | \"stop\";\n\nfunction repairTornJsonlRecord(context: JsonlLoadContext, record: JsonlPhysicalRecord): void {\n\tpublishJsonlContentAtomically(context.filePath, readFileSync(context.filePath).subarray(0, record.start), {\n\t\t...context.publicationOptions,\n\t\tphase: \"repair\",\n\t});\n}\n\nfunction isRepairableDecodeFailure(\n\tcontext: JsonlLoadContext,\n\tstate: JsonlLoadState,\n\trecord: JsonlPhysicalRecord,\n\tfailure: Error,\n): boolean {\n\treturn context.repair && state.header !== undefined && !record.terminated && failure instanceof JsonlDecodeFailure;\n}\n\nfunction isRepairableSyntaxFailure(\n\tcontext: JsonlLoadContext,\n\tstate: JsonlLoadState,\n\trecord: JsonlPhysicalRecord,\n\tfailure: Error,\n): boolean {\n\treturn (\n\t\tcontext.repair &&\n\t\tstate.header !== undefined &&\n\t\t!record.terminated &&\n\t\tfailure instanceof JsonlDecodeFailure &&\n\t\tfailure.kind === \"syntax\"\n\t);\n}\n\nfunction scanJsonlRecord(\n\tcontext: JsonlLoadContext,\n\tstate: JsonlLoadState,\n\trecord: JsonlPhysicalRecord,\n): JsonlRecordScanAction {\n\tstate.finalRecord = record;\n\tlet line: string;\n\ttry {\n\t\tline = decodePhysicalRecord(record);\n\t} catch (error) {\n\t\tconst failure = error instanceof Error ? error : new Error(String(error));\n\t\tif (isRepairableDecodeFailure(context, state, record, failure)) {\n\t\t\trepairTornJsonlRecord(context, record);\n\t\t\treturn \"stop\";\n\t\t}\n\t\tthrow invalidJsonl(context.filePath, record, failure, context.phase);\n\t}\n\tif (!line.trim()) return \"continue\";\n\n\ttry {\n\t\tif (!state.header) {\n\t\t\tstate.header = parseStrictHeader(record);\n\t\t\tstate.headerRecord = record;\n\t\t\tstate.entries.push(state.header);\n\t\t} else {\n\t\t\tstate.entries.push(parseStrictEntry(record, state.header.version ?? 1));\n\t\t}\n\t\tstate.locations.push({ line: record.line, byteOffset: record.start });\n\t\treturn \"continue\";\n\t} catch (error) {\n\t\tconst failure = error instanceof Error ? error : new Error(String(error));\n\t\tif (isRepairableSyntaxFailure(context, state, record, failure)) {\n\t\t\trepairTornJsonlRecord(context, record);\n\t\t\treturn \"stop\";\n\t\t}\n\t\tthrow invalidJsonl(context.filePath, record, failure, context.phase);\n\t}\n}\n\nfunction requireLoadedSessionHeader(context: JsonlLoadContext, state: JsonlLoadState): SessionHeader {\n\tif (state.header && state.headerRecord) return state.header;\n\tconst failure = new JsonlDecodeFailure(\"schema\", \"does not contain a session header\");\n\tthrow new JsonlSessionError({\n\t\tcode: \"invalid_jsonl\",\n\t\treference: context.filePath,\n\t\tphase: context.phase,\n\t\tline: state.finalRecord?.line ?? 1,\n\t\tbyteOffset: state.finalRecord?.start ?? 0,\n\t\tdecodeKind: failure.decodeKind,\n\t\tmessage: `Session file is not a valid grip session: ${context.filePath}`,\n\t\tcause: failure,\n\t});\n}\n\nfunction repairMissingFinalNewline(context: JsonlLoadContext, state: JsonlLoadState): void {\n\tif (!context.repair || state.finalRecord?.terminated !== false || state.entries.at(-1) === undefined) return;\n\tconst original = readFileSync(context.filePath);\n\tif (original.length === 0 || original.at(-1) === 0x0a) return;\n\tconst repaired = Buffer.allocUnsafe(original.length + 1);\n\toriginal.copy(repaired);\n\trepaired[original.length] = 0x0a;\n\tpublishJsonlContentAtomically(context.filePath, repaired, {\n\t\t...context.publicationOptions,\n\t\tphase: \"repair\",\n\t});\n}\n\nfunction validateLoadedSessionEntries(context: JsonlLoadContext, state: JsonlLoadState, header: SessionHeader): void {\n\tif ((header.version ?? 1) < 2) return;\n\tconst validationContext: JsonlValidationContext = { phase: context.phase, locations: state.locations };\n\tif (header.version === 2) {\n\t\t// Version 2 has current tree fields; validate via a non-mutating header projection.\n\t\tvalidateCurrentSessionEntries(\n\t\t\t[{ ...header, version: 3 }, ...state.entries.slice(1)],\n\t\t\tcontext.filePath,\n\t\t\tvalidationContext,\n\t\t);\n\t\treturn;\n\t}\n\tvalidateCurrentSessionEntries(state.entries, context.filePath, validationContext);\n}\n\nfunction loadJsonlSession(\n\tfilePath: string,\n\tpublicationOptions: JsonlAtomicPublicationOptions = {},\n\trepair = true,\n\tphase: JsonlErrorPhase = \"open\",\n): FileEntry[] {\n\tif (!existsSync(filePath)) return [];\n\tif (lstatSync(filePath).size === 0) return [];\n\tconst context: JsonlLoadContext = { filePath, publicationOptions, repair, phase };\n\tconst state: JsonlLoadState = {\n\t\tentries: [],\n\t\tlocations: [],\n\t\theader: undefined,\n\t\theaderRecord: undefined,\n\t\tfinalRecord: undefined,\n\t};\n\n\tfor (const record of readPhysicalRecords(filePath)) {\n\t\tif (scanJsonlRecord(context, state, record) === \"stop\") break;\n\t}\n\tconst header = requireLoadedSessionHeader(context, state);\n\trepairMissingFinalNewline(context, state);\n\tvalidateLoadedSessionEntries(context, state, header);\n\tjsonlEntryLocations.set(state.entries, state.locations);\n\treturn state.entries;\n}\n\nexport function load(\n\tfilePath: string,\n\tpublicationOptions: JsonlAtomicPublicationOptions = {},\n\trepair = true,\n\tphase: JsonlErrorPhase = \"open\",\n): FileEntry[] {\n\ttry {\n\t\treturn loadJsonlSession(filePath, publicationOptions, repair, phase);\n\t} catch (error) {\n\t\tif (error instanceof JsonlSessionError) throw error;\n\t\tconst cause = error instanceof Error ? error : new Error(String(error));\n\t\tthrow jsonlStorageError(filePath, phase, `Failed to ${phase} JSONL session ${filePath}: ${cause.message}`, cause);\n\t}\n}\n\nfunction getNextAppendPosition(bytes: Uint8Array): JsonlRecordLocation {\n\tlet line = 1;\n\tfor (const byte of bytes) {\n\t\tif (byte === 0x0a) line++;\n\t}\n\treturn { line, byteOffset: bytes.length };\n}\n\nfunction serializeJsonlEntries(entries: FileEntry[]): string {\n\treturn `${entries.map((entry) => JSON.stringify(entry)).join(\"\\n\")}\\n`;\n}\n\nexport function append(filePath: string, entry: FileEntry): void {\n\tappendFileSync(filePath, `${JSON.stringify(entry)}\\n`);\n}\n\nexport interface JsonlAtomicPublicationOptions {\n\trename?: (source: string, destination: string) => void;\n\tremove?: (path: string) => void;\n\tplatform?: NodeJS.Platform;\n\tphase?: JsonlErrorPhase;\n}\n\nfunction isWindowsRenameSharingError(error: unknown): boolean {\n\tif (!(error instanceof Error) || !(\"code\" in error)) return false;\n\tconst code = (error as NodeJS.ErrnoException).code;\n\treturn code === \"EPERM\" || code === \"EACCES\" || code === \"EBUSY\";\n}\n\nfunction renameWithRetry(\n\tsource: string,\n\tdestination: string,\n\trename: (source: string, destination: string) => void,\n\tplatform: NodeJS.Platform,\n): void {\n\tfor (let attempt = 0; attempt < 5; attempt++) {\n\t\ttry {\n\t\t\trename(source, destination);\n\t\t\treturn;\n\t\t} catch (error) {\n\t\t\tif (platform !== \"win32\" || !isWindowsRenameSharingError(error) || attempt === 4) throw error;\n\t\t\tAtomics.wait(new Int32Array(new SharedArrayBuffer(4)), 0, 0, 10 * 2 ** attempt);\n\t\t}\n\t}\n}\n\nfunction assertJsonlDestinationReplaceable(filePath: string): void {\n\ttry {\n\t\tconst destinationInfo = lstatSync(filePath);\n\t\tif (!destinationInfo.isFile()) throw new Error(`Refusing to replace non-file session path: ${filePath}`);\n\t} catch (error) {\n\t\tif (!(error instanceof Error) || !(\"code\" in error) || (error as NodeJS.ErrnoException).code !== \"ENOENT\") {\n\t\t\tthrow error;\n\t\t}\n\t}\n}\n\nfunction allocateJsonlStagingPath(filePath: string): string {\n\tconst parentDir = dirname(filePath);\n\tensureDir(parentDir);\n\tfor (let attempt = 0; attempt < 100; attempt++) {\n\t\tconst candidate = join(parentDir, `.${basename(filePath)}.tmp-${randomUUID()}`);\n\t\tif (!existsSync(candidate)) return candidate;\n\t}\n\tthrow new Error(`Failed to allocate staging path for session: ${filePath}`);\n}\n\nfunction stageJsonlContent(\n\ttempPath: string,\n\tfilePath: string,\n\tcontent: string | Uint8Array,\n\toptions: JsonlAtomicPublicationOptions,\n): void {\n\ttry {\n\t\twriteFileSync(tempPath, content);\n\t} catch (error) {\n\t\tconst cause = error instanceof Error ? error : new Error(String(error));\n\t\tthrow jsonlStorageError(\n\t\t\tfilePath,\n\t\t\toptions.phase ?? \"replace\",\n\t\t\t`Failed to stage JSONL session ${filePath}: ${cause.message}`,\n\t\t\tcause,\n\t\t\t\"not_written\",\n\t\t);\n\t}\n}\n\nfunction publishJsonlStagingPath(tempPath: string, filePath: string, options: JsonlAtomicPublicationOptions): void {\n\ttry {\n\t\trenameWithRetry(tempPath, filePath, options.rename ?? renameSync, options.platform ?? process.platform);\n\t} catch (error) {\n\t\tconst cause = error instanceof Error ? error : new Error(String(error));\n\t\tthrow jsonlStorageError(\n\t\t\tfilePath,\n\t\t\toptions.phase ?? \"replace\",\n\t\t\t`Failed to publish JSONL session ${filePath}: ${cause.message}`,\n\t\t\tcause,\n\t\t\t\"unknown\",\n\t\t);\n\t}\n}\n\nfunction removeUnpublishedJsonlStagingPath(tempPath: string, options: JsonlAtomicPublicationOptions): void {\n\ttry {\n\t\t(options.remove ?? ((path) => rmSync(path, { force: true })))(tempPath);\n\t} catch {\n\t\t// Preserve the staging or rename failure; stale temps are undiscoverable.\n\t}\n}\n\nfunction publishJsonlContentAtomicallyUnsafe(\n\tfilePath: string,\n\tcontent: string | Uint8Array,\n\toptions: JsonlAtomicPublicationOptions = {},\n): void {\n\tassertJsonlDestinationReplaceable(filePath);\n\tconst tempPath = allocateJsonlStagingPath(filePath);\n\tlet published = false;\n\ttry {\n\t\tstageJsonlContent(tempPath, filePath, content, options);\n\t\tpublishJsonlStagingPath(tempPath, filePath, options);\n\t\tpublished = true;\n\t} finally {\n\t\tif (!published) removeUnpublishedJsonlStagingPath(tempPath, options);\n\t}\n}\n\nfunction publishJsonlContentAtomically(\n\tfilePath: string,\n\tcontent: string | Uint8Array,\n\toptions: JsonlAtomicPublicationOptions = {},\n): void {\n\ttry {\n\t\tpublishJsonlContentAtomicallyUnsafe(filePath, content, options);\n\t} catch (error) {\n\t\tif (error instanceof JsonlSessionError) throw error;\n\t\tconst cause = error instanceof Error ? error : new Error(String(error));\n\t\tthrow jsonlStorageError(\n\t\t\tfilePath,\n\t\t\toptions.phase ?? \"replace\",\n\t\t\t`Failed to publish JSONL session ${filePath}: ${cause.message}`,\n\t\t\tcause,\n\t\t\t\"not_written\",\n\t\t);\n\t}\n}\n\nexport function publishJsonlAtomically(\n\tfilePath: string,\n\tentries: FileEntry[],\n\toptions: JsonlAtomicPublicationOptions = {},\n): void {\n\tpublishJsonlContentAtomically(filePath, serializeJsonlEntries(entries), options);\n}\n\nexport function rewrite(filePath: string, entries: FileEntry[]): void {\n\tpublishJsonlAtomically(filePath, entries);\n}\n\nexport function forkSession(sessionDir: string, header: SessionHeader, sourceEntries: FileEntry[]): string {\n\tconst reference = prepareSessionReference(sessionDir, header.id, header.timestamp);\n\tpublishJsonlAtomically(reference, [header, ...sourceEntries.filter((entry) => entry.type !== \"session\")], {\n\t\tphase: \"fork\",\n\t});\n\treturn reference;\n}\n\nexport function findMostRecent(sessionDir: string, cwd?: string): string | null {\n\tconst resolvedCwd = cwd ? resolve(cwd) : undefined;\n\tlet names: string[];\n\ttry {\n\t\tnames = readdirSync(sessionDir).filter((file) => file.endsWith(\".jsonl\"));\n\t} catch (error) {\n\t\tif (error instanceof Error && \"code\" in error && (error as NodeJS.ErrnoException).code === \"ENOENT\") return null;\n\t\tthrow error;\n\t}\n\tconst files: Array<{ path: string; mtime: Date }> = [];\n\tfor (const name of names) {\n\t\tconst path = join(sessionDir, name);\n\t\ttry {\n\t\t\tconst header = readSessionHeaderForDiscovery(path);\n\t\t\tif (!header) continue;\n\t\t\tif (resolvedCwd && !sessionCwdMatches(getSessionHeaderCwd(header), resolvedCwd)) continue;\n\t\t\tfiles.push({ path, mtime: statSync(path).mtime });\n\t\t} catch {\n\t\t\t// Quarantine a candidate that disappeared or became unreadable without hiding valid siblings.\n\t\t}\n\t}\n\tfiles.sort((a, b) => b.mtime.getTime() - a.mtime.getTime());\n\treturn files[0]?.path ?? null;\n}\n\nexport async function list(dir: string, onProgress?: SessionListProgress): Promise<SessionInfo[]> {\n\tconst sessions: SessionInfo[] = [];\n\tif (!existsSync(dir)) {\n\t\treturn sessions;\n\t}\n\n\tconst dirEntries = await readdir(dir);\n\tconst files = dirEntries.filter((file) => file.endsWith(\".jsonl\")).map((file) => join(dir, file));\n\tlet loaded = 0;\n\tconst results = await buildSessionInfosWithConcurrency(files, () => {\n\t\tloaded++;\n\t\tonProgress?.(loaded, files.length);\n\t});\n\tfor (const info of results) {\n\t\tif (info) sessions.push(info);\n\t}\n\n\treturn sessions;\n}\n\nexport async function listAll(sessionsDir: string, onProgress?: SessionListProgress): Promise<SessionInfo[]> {\n\tif (!existsSync(sessionsDir)) return [];\n\tconst entries = await readdir(sessionsDir, { withFileTypes: true });\n\tconst dirs = entries.filter((entry) => entry.isDirectory()).map((entry) => join(sessionsDir, entry.name));\n\tlet totalFiles = 0;\n\tconst dirFiles: string[][] = [];\n\tfor (const dir of dirs) {\n\t\tconst files = (await readdir(dir)).filter((file) => file.endsWith(\".jsonl\"));\n\t\tdirFiles.push(files.map((file) => join(dir, file)));\n\t\ttotalFiles += files.length;\n\t}\n\tlet loaded = 0;\n\tconst sessions: SessionInfo[] = [];\n\tconst results = await buildSessionInfosWithConcurrency(dirFiles.flat(), () => {\n\t\tloaded++;\n\t\tonProgress?.(loaded, totalFiles);\n\t});\n\tfor (const info of results) {\n\t\tif (info) sessions.push(info);\n\t}\n\treturn sessions;\n}\n\nasync function buildSessionInfosWithConcurrency(\n\tfiles: string[],\n\tonLoaded: () => void,\n): Promise<(SessionInfo | null)[]> {\n\tconst results: (SessionInfo | null)[] = new Array(files.length).fill(null);\n\tconst inFlight = new Set<Promise<void>>();\n\tlet nextIndex = 0;\n\n\tconst startNext = (): void => {\n\t\tconst index = nextIndex++;\n\t\tconst file = files[index];\n\t\tif (!file) return;\n\n\t\tlet task: Promise<void>;\n\t\ttask = buildSessionInfo(file)\n\t\t\t.then((info) => {\n\t\t\t\tresults[index] = info;\n\t\t\t})\n\t\t\t.catch(() => {\n\t\t\t\tresults[index] = null;\n\t\t\t})\n\t\t\t.finally(() => {\n\t\t\t\tinFlight.delete(task);\n\t\t\t\tonLoaded();\n\t\t\t});\n\t\tinFlight.add(task);\n\t};\n\n\twhile (nextIndex < files.length || inFlight.size > 0) {\n\t\twhile (nextIndex < files.length && inFlight.size < MAX_CONCURRENT_SESSION_INFO_LOADS) {\n\t\t\tstartNext();\n\t\t}\n\t\tif (inFlight.size > 0) {\n\t\t\tawait Promise.race(inFlight);\n\t\t}\n\t}\n\n\treturn results;\n}\n\ninterface PreloadedSessionEntries {\n\treference: string;\n\tentries: FileEntry[];\n}\n\ntype JsonlNewSessionPublicationPhase = \"create\" | \"fork\";\nexport type JsonlFirstPublicationPhase = JsonlNewSessionPublicationPhase | \"import\";\n\ninterface JsonlFirstPublicationOptions {\n\tallowExistingEmptyFile: boolean;\n\tphase: JsonlFirstPublicationPhase;\n}\n\ninterface JsonlSessionReferenceOptions {\n\tallowExistingEmptyFile?: boolean;\n}\n\ninterface JsonlSnapshotOptions {\n\tphase?: JsonlErrorPhase;\n}\n\nexport interface JsonlStoreWriteOperations {\n\tappend(filePath: string, serializedEntry: string): void;\n\tpublish(filePath: string, entries: FileEntry[], options?: JsonlAtomicPublicationOptions): void;\n}\n\nexport interface JsonlFirstPublicationCoordinator {\n\tpublish(filePath: string, entries: FileEntry[], operation: () => void, options: JsonlFirstPublicationOptions): void;\n}\n\nexport class SessionAlreadyExistsError extends Error {\n\treadonly code = \"already_exists\";\n\treadonly reference: string;\n\treadonly path: string;\n\treadonly phase: JsonlFirstPublicationPhase;\n\treadonly outcome = \"not_written\";\n\n\tconstructor(reference: string, sessionId: string, phase: JsonlFirstPublicationPhase = \"create\") {\n\t\tsuper(`Session already exists: ${sessionId}`);\n\t\tthis.name = \"SessionAlreadyExistsError\";\n\t\tthis.reference = reference;\n\t\tthis.path = reference;\n\t\tthis.phase = phase;\n\t}\n}\n\nfunction isDefinitelyNotWritten(error: unknown): boolean {\n\tif (!(error instanceof Error) || !(\"code\" in error)) return false;\n\treturn new Set([\"ENOENT\", \"EACCES\", \"EPERM\", \"EISDIR\", \"ENOTDIR\", \"EINVAL\", \"EROFS\"]).has(\n\t\tString((error as NodeJS.ErrnoException).code),\n\t);\n}\n\nfunction getFirstPublicationPhase(entries: FileEntry[]): JsonlNewSessionPublicationPhase {\n\tconst header = entries[0];\n\treturn header?.type === \"session\" && header.parentSession ? \"fork\" : \"create\";\n}\n\nconst defaultWriteOperations: JsonlStoreWriteOperations = {\n\tappend: appendFileSync,\n\tpublish: publishJsonlAtomically,\n};\n\nexport class JsonlSessionStore extends InMemorySessionStore {\n\tprivate reference: string | undefined;\n\tprivate flushed = false;\n\tprivate preloaded: PreloadedSessionEntries | undefined;\n\tprivate allowExistingEmptyFile = false;\n\tprivate readonly writeOperations: JsonlStoreWriteOperations;\n\tprivate readonly firstPublicationCoordinator: JsonlFirstPublicationCoordinator | undefined;\n\tprivate writeFence: Error | undefined;\n\tprivate nextAppendLine = 1;\n\tprivate nextAppendOffset = 0;\n\n\tconstructor(\n\t\tpreloaded?: PreloadedSessionEntries,\n\t\twriteOperations: JsonlStoreWriteOperations = defaultWriteOperations,\n\t\tfirstPublicationCoordinator?: JsonlFirstPublicationCoordinator,\n\t) {\n\t\tsuper();\n\t\tthis.preloaded = preloaded ? { ...preloaded, reference: resolve(preloaded.reference) } : undefined;\n\t\tthis.writeOperations = writeOperations;\n\t\tthis.firstPublicationCoordinator = firstPublicationCoordinator;\n\t}\n\tisPersisted(): boolean {\n\t\treturn true;\n\t}\n\n\tgetSessionReference(): string | undefined {\n\t\treturn this.reference;\n\t}\n\n\tsetSessionReference(reference: string, options: JsonlSessionReferenceOptions = {}): void {\n\t\tconst resolvedReference = resolve(reference);\n\t\tif (this.reference !== resolvedReference) {\n\t\t\tthis.writeFence = undefined;\n\t\t\tthis.allowExistingEmptyFile = false;\n\t\t}\n\t\tthis.reference = resolvedReference;\n\t\tif (options.allowExistingEmptyFile) this.allowExistingEmptyFile = true;\n\t\tthis.flushed = false;\n\t}\n\n\texists(path: string): boolean {\n\t\treturn exists(path);\n\t}\n\n\tensureDir(path: string): void {\n\t\tensureDir(path);\n\t}\n\n\tload(filePath: string): FileEntry[] {\n\t\tif (!exists(filePath)) return [];\n\t\tconst info = lstatSync(filePath);\n\t\tthis.allowExistingEmptyFile = info.isFile() && info.size === 0;\n\t\tthis.flushed = true;\n\t\tconst resolvedFilePath = resolve(filePath);\n\t\tif (!this.writeFence && this.preloaded?.reference === resolvedFilePath) {\n\t\t\tconst entries = this.preloaded.entries;\n\t\t\tthis.preloaded = undefined;\n\t\t\tthis.updateNextAppendPosition(resolvedFilePath);\n\t\t\treturn entries;\n\t\t}\n\t\tconst entries = load(resolvedFilePath);\n\t\tthis.updateNextAppendPosition(resolvedFilePath);\n\t\tthis.writeFence = undefined;\n\t\tthis.preloaded = undefined;\n\t\treturn entries;\n\t}\n\n\tprivate updateNextAppendPosition(filePath: string): void {\n\t\tconst position = getNextAppendPosition(readFileSync(filePath));\n\t\tthis.nextAppendLine = position.line;\n\t\tthis.nextAppendOffset = position.byteOffset;\n\t}\n\n\tprivate persistAppendedEntry(\n\t\treference: string,\n\t\tprospectiveEntries: FileEntry[],\n\t\tserializedEntry: string | undefined,\n\t): void {\n\t\ttry {\n\t\t\tif (this.flushed) this.writeOperations.append(reference, serializedEntry!);\n\t\t\telse this.publishFirstSnapshot(prospectiveEntries);\n\t\t} catch (error) {\n\t\t\tif (error instanceof SessionAlreadyExistsError) throw error;\n\t\t\tconst cause = error instanceof Error ? error : new Error(String(error));\n\t\t\tif (this.flushed && isDefinitelyNotWritten(error)) {\n\t\t\t\tthrow jsonlStorageError(reference, \"append\", cause.message, cause, \"not_written\");\n\t\t\t}\n\t\t\tthis.writeFence = jsonlStorageError(\n\t\t\t\treference,\n\t\t\t\tthis.flushed ? \"append\" : getFirstPublicationPhase(prospectiveEntries),\n\t\t\t\tcause.message,\n\t\t\t\tcause,\n\t\t\t\tcause instanceof JsonlSessionError ? undefined : \"unknown\",\n\t\t\t);\n\t\t\tthrow this.writeFence;\n\t\t}\n\t}\n\n\tprivate recordAppendedEntryPosition(\n\t\twasFlushed: boolean,\n\t\tserializedEntry: string | undefined,\n\t\tprospectiveEntries: FileEntry[],\n\t): void {\n\t\tif (wasFlushed) {\n\t\t\tthis.nextAppendLine++;\n\t\t\tthis.nextAppendOffset += Buffer.byteLength(serializedEntry!);\n\t\t\treturn;\n\t\t}\n\t\tconst position = getNextAppendPosition(new TextEncoder().encode(serializeJsonlEntries(prospectiveEntries)));\n\t\tthis.nextAppendLine = position.line;\n\t\tthis.nextAppendOffset = position.byteOffset;\n\t}\n\n\tappendEntry(entry: SessionEntry): void {\n\t\tif (!this.reference) {\n\t\t\tsuper.appendEntry(entry);\n\t\t\treturn;\n\t\t}\n\t\tthis.assertWritable();\n\t\tconst prospectiveEntries = [...this.getFileEntries(), entry];\n\t\tconst wasFlushed = this.flushed;\n\t\tconst appendPosition = wasFlushed\n\t\t\t? { line: this.nextAppendLine, byteOffset: this.nextAppendOffset }\n\t\t\t: getNextAppendPosition(new TextEncoder().encode(serializeJsonlEntries(this.getFileEntries())));\n\t\tconst locations: Array<JsonlRecordLocation | undefined> = [];\n\t\tlocations[prospectiveEntries.length - 1] = appendPosition;\n\t\tvalidateCurrentSessionEntries(prospectiveEntries, this.reference, { phase: \"append\", locations });\n\t\tconst hasAssistantMessage = prospectiveEntries.some(\n\t\t\t(fileEntry) => fileEntry.type === \"message\" && fileEntry.message.role === \"assistant\",\n\t\t);\n\t\tif (!hasAssistantMessage) {\n\t\t\tsuper.appendEntry(entry);\n\t\t\tthis.flushed = false;\n\t\t\treturn;\n\t\t}\n\n\t\tif (!this.flushed) serializeJsonlEntries(prospectiveEntries);\n\t\tconst serializedEntry = this.flushed ? `${JSON.stringify(entry)}\\n` : undefined;\n\t\tthis.persistAppendedEntry(this.reference, prospectiveEntries, serializedEntry);\n\t\tsuper.appendEntry(entry);\n\t\tthis.recordAppendedEntryPosition(wasFlushed, serializedEntry, prospectiveEntries);\n\t\tthis.flushed = true;\n\t\tthis.allowExistingEmptyFile = false;\n\t}\n\n\tprivate assertWritable(): void {\n\t\tif (this.writeFence) {\n\t\t\tthrow new JsonlSessionError({\n\t\t\t\tcode: \"fenced\",\n\t\t\t\treference: this.reference ?? \"\",\n\t\t\t\tphase: \"append\",\n\t\t\t\tmessage: `Session writes are fenced after a persistence failure: ${this.reference}`,\n\t\t\t\toutcome: \"unknown\",\n\t\t\t\tcause: this.writeFence,\n\t\t\t});\n\t\t}\n\t}\n\tprivate publishFirstSnapshot(entries: FileEntry[]): void {\n\t\tif (!this.reference) return;\n\t\tconst phase = getFirstPublicationPhase(entries);\n\t\tconst operation = () => this.writeOperations.publish(this.reference!, entries, { phase });\n\t\tif (this.firstPublicationCoordinator) {\n\t\t\tthis.firstPublicationCoordinator.publish(this.reference, entries, operation, {\n\t\t\t\tallowExistingEmptyFile: this.allowExistingEmptyFile,\n\t\t\t\tphase,\n\t\t\t});\n\t\t} else {\n\t\t\toperation();\n\t\t}\n\t}\n\n\tsaveSnapshot(options: JsonlSnapshotOptions = {}): void {\n\t\tif (!this.reference) return;\n\t\tthis.assertWritable();\n\t\tserializeJsonlEntries(this.getFileEntries());\n\t\ttry {\n\t\t\tif (this.flushed) {\n\t\t\t\tthis.writeOperations.publish(this.reference, this.getFileEntries(), {\n\t\t\t\t\tphase: options.phase ?? \"replace\",\n\t\t\t\t});\n\t\t\t} else this.publishFirstSnapshot(this.getFileEntries());\n\t\t} catch (error) {\n\t\t\tif (error instanceof SessionAlreadyExistsError) throw error;\n\t\t\tconst cause = error instanceof Error ? error : new Error(String(error));\n\t\t\tthis.writeFence = jsonlStorageError(\n\t\t\t\tthis.reference,\n\t\t\t\toptions.phase ?? (this.flushed ? \"replace\" : getFirstPublicationPhase(this.getFileEntries())),\n\t\t\t\tcause.message,\n\t\t\t\tcause,\n\t\t\t\tcause instanceof JsonlSessionError ? undefined : \"unknown\",\n\t\t\t);\n\t\t\tthrow this.writeFence;\n\t\t}\n\t\tconst position = getNextAppendPosition(new TextEncoder().encode(serializeJsonlEntries(this.getFileEntries())));\n\t\tthis.nextAppendLine = position.line;\n\t\tthis.nextAppendOffset = position.byteOffset;\n\t\tthis.flushed = true;\n\t\tthis.allowExistingEmptyFile = false;\n\t}\n\n\tcommitSnapshot(): void {\n\t\tif (!this.hasAssistantMessage()) {\n\t\t\tthis.flushed = false;\n\t\t\treturn;\n\t\t}\n\t\tthis.saveSnapshot();\n\t}\n}\n"]}