@code-yeongyu/senpi-agent-core 2026.9.12 → 2026.9.13

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 (344) hide show
  1. package/README.md +4 -0
  2. package/dist/harness/agent-harness.d.ts +639 -384
  3. package/dist/harness/agent-harness.d.ts.map +1 -1
  4. package/dist/harness/agent-harness.js +5 -250
  5. package/dist/harness/agent-harness.js.map +1 -1
  6. package/dist/harness/compaction/branch-summarization.d.ts +12 -6
  7. package/dist/harness/compaction/branch-summarization.d.ts.map +1 -1
  8. package/dist/harness/compaction/branch-summarization.js +33 -27
  9. package/dist/harness/compaction/branch-summarization.js.map +1 -1
  10. package/dist/harness/compaction/compaction.d.ts +30 -8
  11. package/dist/harness/compaction/compaction.d.ts.map +1 -1
  12. package/dist/harness/compaction/compaction.js +53 -64
  13. package/dist/harness/compaction/compaction.js.map +1 -1
  14. package/dist/harness/config.d.ts +9 -0
  15. package/dist/harness/config.d.ts.map +1 -0
  16. package/dist/harness/config.js +35 -0
  17. package/dist/harness/config.js.map +1 -0
  18. package/dist/harness/context.d.ts +9 -0
  19. package/dist/harness/context.d.ts.map +1 -0
  20. package/dist/harness/context.js +13 -0
  21. package/dist/harness/context.js.map +1 -0
  22. package/dist/harness/env/nodejs.d.ts +25 -28
  23. package/dist/harness/env/nodejs.d.ts.map +1 -1
  24. package/dist/harness/env/nodejs.js +368 -125
  25. package/dist/harness/env/nodejs.js.map +1 -1
  26. package/dist/harness/events.d.ts +20 -38
  27. package/dist/harness/events.d.ts.map +1 -1
  28. package/dist/harness/events.js +233 -55
  29. package/dist/harness/events.js.map +1 -1
  30. package/dist/harness/execution/assistant.d.ts +42 -0
  31. package/dist/harness/execution/assistant.d.ts.map +1 -0
  32. package/dist/harness/execution/assistant.js +82 -0
  33. package/dist/harness/execution/assistant.js.map +1 -0
  34. package/dist/harness/execution/effect-gate.d.ts +22 -0
  35. package/dist/harness/execution/effect-gate.d.ts.map +1 -0
  36. package/dist/harness/execution/effect-gate.js +48 -0
  37. package/dist/harness/execution/effect-gate.js.map +1 -0
  38. package/dist/harness/execution/tools.d.ts +67 -0
  39. package/dist/harness/execution/tools.d.ts.map +1 -0
  40. package/dist/harness/execution/tools.js +121 -0
  41. package/dist/harness/execution/tools.js.map +1 -0
  42. package/dist/harness/hooks.d.ts +38 -0
  43. package/dist/harness/hooks.d.ts.map +1 -0
  44. package/dist/harness/hooks.js +404 -0
  45. package/dist/harness/hooks.js.map +1 -0
  46. package/dist/harness/messages.d.ts +2 -2
  47. package/dist/harness/messages.d.ts.map +1 -1
  48. package/dist/harness/messages.js.map +1 -1
  49. package/dist/harness/prompt-templates.d.ts +3 -2
  50. package/dist/harness/prompt-templates.d.ts.map +1 -1
  51. package/dist/harness/prompt-templates.js +17 -17
  52. package/dist/harness/prompt-templates.js.map +1 -1
  53. package/dist/harness/result.d.ts +93 -0
  54. package/dist/harness/result.d.ts.map +1 -1
  55. package/dist/harness/result.js +39 -0
  56. package/dist/harness/result.js.map +1 -1
  57. package/dist/harness/runtime/drive/boundary.d.ts +28 -0
  58. package/dist/harness/runtime/drive/boundary.d.ts.map +1 -0
  59. package/dist/harness/runtime/drive/boundary.js +173 -0
  60. package/dist/harness/runtime/drive/boundary.js.map +1 -0
  61. package/dist/harness/runtime/drive/checkpoint.d.ts +8 -0
  62. package/dist/harness/runtime/drive/checkpoint.d.ts.map +1 -0
  63. package/dist/harness/runtime/drive/checkpoint.js +133 -0
  64. package/dist/harness/runtime/drive/checkpoint.js.map +1 -0
  65. package/dist/harness/runtime/drive/deferred.d.ts +15 -0
  66. package/dist/harness/runtime/drive/deferred.d.ts.map +1 -0
  67. package/dist/harness/runtime/drive/deferred.js +179 -0
  68. package/dist/harness/runtime/drive/deferred.js.map +1 -0
  69. package/dist/harness/runtime/drive/generation.d.ts +8 -0
  70. package/dist/harness/runtime/drive/generation.d.ts.map +1 -0
  71. package/dist/harness/runtime/drive/generation.js +205 -0
  72. package/dist/harness/runtime/drive/generation.js.map +1 -0
  73. package/dist/harness/runtime/drive/reconcile.d.ts +5 -0
  74. package/dist/harness/runtime/drive/reconcile.d.ts.map +1 -0
  75. package/dist/harness/runtime/drive/reconcile.js +140 -0
  76. package/dist/harness/runtime/drive/reconcile.js.map +1 -0
  77. package/dist/harness/runtime/drive/recovery.d.ts +8 -0
  78. package/dist/harness/runtime/drive/recovery.d.ts.map +1 -0
  79. package/dist/harness/runtime/drive/recovery.js +85 -0
  80. package/dist/harness/runtime/drive/recovery.js.map +1 -0
  81. package/dist/harness/runtime/drive/response.d.ts +23 -0
  82. package/dist/harness/runtime/drive/response.d.ts.map +1 -0
  83. package/dist/harness/runtime/drive/response.js +394 -0
  84. package/dist/harness/runtime/drive/response.js.map +1 -0
  85. package/dist/harness/runtime/drive/retry.d.ts +4 -0
  86. package/dist/harness/runtime/drive/retry.d.ts.map +1 -0
  87. package/dist/harness/runtime/drive/retry.js +34 -0
  88. package/dist/harness/runtime/drive/retry.js.map +1 -0
  89. package/dist/harness/runtime/drive/structural.d.ts +32 -0
  90. package/dist/harness/runtime/drive/structural.d.ts.map +1 -0
  91. package/dist/harness/runtime/drive/structural.js +929 -0
  92. package/dist/harness/runtime/drive/structural.js.map +1 -0
  93. package/dist/harness/runtime/drive/terminal.d.ts +7 -0
  94. package/dist/harness/runtime/drive/terminal.d.ts.map +1 -0
  95. package/dist/harness/runtime/drive/terminal.js +49 -0
  96. package/dist/harness/runtime/drive/terminal.js.map +1 -0
  97. package/dist/harness/runtime/drive/tool-placement.d.ts +14 -0
  98. package/dist/harness/runtime/drive/tool-placement.d.ts.map +1 -0
  99. package/dist/harness/runtime/drive/tool-placement.js +244 -0
  100. package/dist/harness/runtime/drive/tool-placement.js.map +1 -0
  101. package/dist/harness/runtime/drive/tools.d.ts +6 -0
  102. package/dist/harness/runtime/drive/tools.d.ts.map +1 -0
  103. package/dist/harness/runtime/drive/tools.js +449 -0
  104. package/dist/harness/runtime/drive/tools.js.map +1 -0
  105. package/dist/harness/runtime/drive.d.ts +6 -0
  106. package/dist/harness/runtime/drive.d.ts.map +1 -0
  107. package/dist/harness/runtime/drive.js +93 -0
  108. package/dist/harness/runtime/drive.js.map +1 -0
  109. package/dist/harness/runtime/harness.d.ts +59 -0
  110. package/dist/harness/runtime/harness.d.ts.map +1 -0
  111. package/dist/harness/runtime/harness.js +302 -0
  112. package/dist/harness/runtime/harness.js.map +1 -0
  113. package/dist/harness/runtime/index.d.ts +2 -0
  114. package/dist/harness/runtime/index.d.ts.map +1 -0
  115. package/dist/harness/runtime/index.js +2 -0
  116. package/dist/harness/runtime/index.js.map +1 -0
  117. package/dist/harness/runtime/lane.d.ts +118 -0
  118. package/dist/harness/runtime/lane.d.ts.map +1 -0
  119. package/dist/harness/runtime/lane.js +1559 -0
  120. package/dist/harness/runtime/lane.js.map +1 -0
  121. package/dist/harness/runtime/progress.d.ts +15 -0
  122. package/dist/harness/runtime/progress.d.ts.map +1 -0
  123. package/dist/harness/runtime/progress.js +66 -0
  124. package/dist/harness/runtime/progress.js.map +1 -0
  125. package/dist/harness/runtime/reducer.d.ts +5 -0
  126. package/dist/harness/runtime/reducer.d.ts.map +1 -0
  127. package/dist/harness/runtime/reducer.js +240 -0
  128. package/dist/harness/runtime/reducer.js.map +1 -0
  129. package/dist/harness/runtime/restore.d.ts +24 -0
  130. package/dist/harness/runtime/restore.d.ts.map +1 -0
  131. package/dist/harness/runtime/restore.js +117 -0
  132. package/dist/harness/runtime/restore.js.map +1 -0
  133. package/dist/harness/runtime/transcript.d.ts +21 -0
  134. package/dist/harness/runtime/transcript.d.ts.map +1 -0
  135. package/dist/harness/runtime/transcript.js +72 -0
  136. package/dist/harness/runtime/transcript.js.map +1 -0
  137. package/dist/harness/runtime/types.d.ts +105 -0
  138. package/dist/harness/runtime/types.d.ts.map +1 -0
  139. package/dist/harness/runtime/types.js +50 -0
  140. package/dist/harness/runtime/types.js.map +1 -0
  141. package/dist/harness/session/commit.d.ts +53 -0
  142. package/dist/harness/session/commit.d.ts.map +1 -0
  143. package/dist/harness/session/commit.js +57 -0
  144. package/dist/harness/session/commit.js.map +1 -0
  145. package/dist/harness/session/context.d.ts +6 -19
  146. package/dist/harness/session/context.d.ts.map +1 -1
  147. package/dist/harness/session/context.js +31 -53
  148. package/dist/harness/session/context.js.map +1 -1
  149. package/dist/harness/session/fork-policy.d.ts +21 -0
  150. package/dist/harness/session/fork-policy.d.ts.map +1 -0
  151. package/dist/harness/session/fork-policy.js +55 -0
  152. package/dist/harness/session/fork-policy.js.map +1 -0
  153. package/dist/harness/session/fork.d.ts +16 -0
  154. package/dist/harness/session/fork.d.ts.map +1 -0
  155. package/dist/harness/session/fork.js +79 -0
  156. package/dist/harness/session/fork.js.map +1 -0
  157. package/dist/harness/session/in-memory-storage-state.d.ts +39 -0
  158. package/dist/harness/session/in-memory-storage-state.d.ts.map +1 -0
  159. package/dist/harness/session/in-memory-storage-state.js +269 -0
  160. package/dist/harness/session/in-memory-storage-state.js.map +1 -0
  161. package/dist/harness/session/index.d.ts +9 -5
  162. package/dist/harness/session/index.d.ts.map +1 -1
  163. package/dist/harness/session/index.js +7 -4
  164. package/dist/harness/session/index.js.map +1 -1
  165. package/dist/harness/session/jsonl/codec.d.ts +19 -8
  166. package/dist/harness/session/jsonl/codec.d.ts.map +1 -1
  167. package/dist/harness/session/jsonl/codec.js +34 -219
  168. package/dist/harness/session/jsonl/codec.js.map +1 -1
  169. package/dist/harness/session/jsonl/fork.d.ts +38 -0
  170. package/dist/harness/session/jsonl/fork.d.ts.map +1 -0
  171. package/dist/harness/session/jsonl/fork.js +266 -0
  172. package/dist/harness/session/jsonl/fork.js.map +1 -0
  173. package/dist/harness/session/jsonl/index.d.ts +4 -0
  174. package/dist/harness/session/jsonl/index.d.ts.map +1 -0
  175. package/dist/harness/session/jsonl/index.js +4 -0
  176. package/dist/harness/session/jsonl/index.js.map +1 -0
  177. package/dist/harness/session/jsonl/io.d.ts +14 -0
  178. package/dist/harness/session/jsonl/io.d.ts.map +1 -0
  179. package/dist/harness/session/jsonl/io.js +86 -0
  180. package/dist/harness/session/jsonl/io.js.map +1 -0
  181. package/dist/harness/session/jsonl/legacy-v3.d.ts +44 -0
  182. package/dist/harness/session/jsonl/legacy-v3.d.ts.map +1 -0
  183. package/dist/harness/session/jsonl/legacy-v3.js +454 -0
  184. package/dist/harness/session/jsonl/legacy-v3.js.map +1 -0
  185. package/dist/harness/session/jsonl/repo.d.ts +27 -24
  186. package/dist/harness/session/jsonl/repo.d.ts.map +1 -1
  187. package/dist/harness/session/jsonl/repo.js +276 -151
  188. package/dist/harness/session/jsonl/repo.js.map +1 -1
  189. package/dist/harness/session/jsonl/storage.d.ts +39 -41
  190. package/dist/harness/session/jsonl/storage.d.ts.map +1 -1
  191. package/dist/harness/session/jsonl/storage.js +175 -196
  192. package/dist/harness/session/jsonl/storage.js.map +1 -1
  193. package/dist/harness/session/jsonl/types.d.ts +23 -22
  194. package/dist/harness/session/jsonl/types.d.ts.map +1 -1
  195. package/dist/harness/session/jsonl/types.js +2 -1
  196. package/dist/harness/session/jsonl/types.js.map +1 -1
  197. package/dist/harness/session/memory.d.ts +44 -40
  198. package/dist/harness/session/memory.d.ts.map +1 -1
  199. package/dist/harness/session/memory.js +333 -115
  200. package/dist/harness/session/memory.js.map +1 -1
  201. package/dist/harness/session/mutation-line.d.ts +8 -0
  202. package/dist/harness/session/mutation-line.d.ts.map +1 -0
  203. package/dist/harness/session/mutation-line.js +22 -0
  204. package/dist/harness/session/mutation-line.js.map +1 -0
  205. package/dist/harness/session/session.d.ts +78 -51
  206. package/dist/harness/session/session.d.ts.map +1 -1
  207. package/dist/harness/session/session.js +327 -207
  208. package/dist/harness/session/session.js.map +1 -1
  209. package/dist/harness/session/testing/benchmark/datasets.d.ts +12 -0
  210. package/dist/harness/session/testing/benchmark/datasets.d.ts.map +1 -0
  211. package/dist/harness/session/testing/benchmark/datasets.js +24 -0
  212. package/dist/harness/session/testing/benchmark/datasets.js.map +1 -0
  213. package/dist/harness/session/testing/benchmark/session-repo.d.ts +42 -0
  214. package/dist/harness/session/testing/benchmark/session-repo.d.ts.map +1 -0
  215. package/dist/harness/session/testing/benchmark/session-repo.js +127 -0
  216. package/dist/harness/session/testing/benchmark/session-repo.js.map +1 -0
  217. package/dist/harness/session/testing/benchmark/storage.d.ts +25 -0
  218. package/dist/harness/session/testing/benchmark/storage.d.ts.map +1 -0
  219. package/dist/harness/session/testing/benchmark/storage.js +114 -0
  220. package/dist/harness/session/testing/benchmark/storage.js.map +1 -0
  221. package/dist/harness/session/testing/conformance/session-repo.d.ts +23 -0
  222. package/dist/harness/session/testing/conformance/session-repo.d.ts.map +1 -0
  223. package/dist/harness/session/testing/conformance/session-repo.js +809 -0
  224. package/dist/harness/session/testing/conformance/session-repo.js.map +1 -0
  225. package/dist/harness/session/testing/conformance/storage.d.ts +4 -0
  226. package/dist/harness/session/testing/conformance/storage.d.ts.map +1 -0
  227. package/dist/harness/session/testing/conformance/storage.js +600 -0
  228. package/dist/harness/session/testing/conformance/storage.js.map +1 -0
  229. package/dist/harness/session/testing/gating-storage.d.ts +26 -0
  230. package/dist/harness/session/testing/gating-storage.d.ts.map +1 -0
  231. package/dist/harness/session/testing/gating-storage.js +103 -0
  232. package/dist/harness/session/testing/gating-storage.js.map +1 -0
  233. package/dist/harness/session/testing/index.d.ts +9 -2
  234. package/dist/harness/session/testing/index.d.ts.map +1 -1
  235. package/dist/harness/session/testing/index.js +8 -1
  236. package/dist/harness/session/testing/index.js.map +1 -1
  237. package/dist/harness/session/testing/instrumented-storage.d.ts +11 -0
  238. package/dist/harness/session/testing/instrumented-storage.d.ts.map +1 -0
  239. package/dist/harness/session/testing/instrumented-storage.js +19 -0
  240. package/dist/harness/session/testing/instrumented-storage.js.map +1 -0
  241. package/dist/harness/session/testing/storage-decorator.d.ts +20 -0
  242. package/dist/harness/session/testing/storage-decorator.d.ts.map +1 -0
  243. package/dist/harness/session/testing/storage-decorator.js +40 -0
  244. package/dist/harness/session/testing/storage-decorator.js.map +1 -0
  245. package/dist/harness/session/testing/types.d.ts +5 -7
  246. package/dist/harness/session/testing/types.d.ts.map +1 -1
  247. package/dist/harness/session/testing/types.js.map +1 -1
  248. package/dist/harness/session/types.d.ts +425 -265
  249. package/dist/harness/session/types.d.ts.map +1 -1
  250. package/dist/harness/session/types.js +7 -7
  251. package/dist/harness/session/types.js.map +1 -1
  252. package/dist/harness/session/values.d.ts +95 -0
  253. package/dist/harness/session/values.d.ts.map +1 -0
  254. package/dist/harness/session/values.js +81 -0
  255. package/dist/harness/session/values.js.map +1 -0
  256. package/dist/harness/skills.d.ts +3 -2
  257. package/dist/harness/skills.d.ts.map +1 -1
  258. package/dist/harness/skills.js +29 -26
  259. package/dist/harness/skills.js.map +1 -1
  260. package/dist/harness/telemetry.d.ts +64 -43
  261. package/dist/harness/telemetry.d.ts.map +1 -1
  262. package/dist/harness/telemetry.js +45 -26
  263. package/dist/harness/telemetry.js.map +1 -1
  264. package/dist/harness/tools/bash.d.ts +4 -4
  265. package/dist/harness/tools/bash.d.ts.map +1 -1
  266. package/dist/harness/tools/bash.js +66 -93
  267. package/dist/harness/tools/bash.js.map +1 -1
  268. package/dist/harness/tools/edit.d.ts.map +1 -1
  269. package/dist/harness/tools/edit.js +17 -13
  270. package/dist/harness/tools/edit.js.map +1 -1
  271. package/dist/harness/tools/file-mutation-queue.d.ts +2 -1
  272. package/dist/harness/tools/file-mutation-queue.d.ts.map +1 -1
  273. package/dist/harness/tools/file-mutation-queue.js +5 -5
  274. package/dist/harness/tools/file-mutation-queue.js.map +1 -1
  275. package/dist/harness/tools/path-utils.d.ts +3 -2
  276. package/dist/harness/tools/path-utils.d.ts.map +1 -1
  277. package/dist/harness/tools/path-utils.js +5 -5
  278. package/dist/harness/tools/path-utils.js.map +1 -1
  279. package/dist/harness/tools/read.d.ts +2 -1
  280. package/dist/harness/tools/read.d.ts.map +1 -1
  281. package/dist/harness/tools/read.js +4 -6
  282. package/dist/harness/tools/read.js.map +1 -1
  283. package/dist/harness/tools/write.d.ts.map +1 -1
  284. package/dist/harness/tools/write.js +12 -8
  285. package/dist/harness/tools/write.js.map +1 -1
  286. package/dist/harness/types.d.ts +128 -45
  287. package/dist/harness/types.d.ts.map +1 -1
  288. package/dist/harness/types.js.map +1 -1
  289. package/dist/harness/utils/adaptive-publisher.d.ts +24 -0
  290. package/dist/harness/utils/adaptive-publisher.d.ts.map +1 -0
  291. package/dist/harness/utils/adaptive-publisher.js +79 -0
  292. package/dist/harness/utils/adaptive-publisher.js.map +1 -0
  293. package/dist/harness/utils/output-capture.d.ts +31 -0
  294. package/dist/harness/utils/output-capture.d.ts.map +1 -0
  295. package/dist/harness/utils/output-capture.js +217 -0
  296. package/dist/harness/utils/output-capture.js.map +1 -0
  297. package/dist/harness/utils/shell-output.d.ts +19 -5
  298. package/dist/harness/utils/shell-output.d.ts.map +1 -1
  299. package/dist/harness/utils/shell-output.js +65 -192
  300. package/dist/harness/utils/shell-output.js.map +1 -1
  301. package/dist/harness/utils/truncate.d.ts +1 -0
  302. package/dist/harness/utils/truncate.d.ts.map +1 -1
  303. package/dist/harness/utils/truncate.js +1 -1
  304. package/dist/harness/utils/truncate.js.map +1 -1
  305. package/dist/harness/utils/usage.d.ts +4 -0
  306. package/dist/harness/utils/usage.d.ts.map +1 -0
  307. package/dist/harness/utils/usage.js +33 -0
  308. package/dist/harness/utils/usage.js.map +1 -0
  309. package/dist/index.d.ts +4 -1
  310. package/dist/index.d.ts.map +1 -1
  311. package/dist/index.js +3 -6
  312. package/dist/index.js.map +1 -1
  313. package/dist/search/index.d.ts +24 -16
  314. package/dist/search/index.d.ts.map +1 -1
  315. package/dist/search/index.js +1 -1
  316. package/dist/search/index.js.map +1 -1
  317. package/dist/types.d.ts +2 -0
  318. package/dist/types.d.ts.map +1 -1
  319. package/dist/types.js.map +1 -1
  320. package/package.json +27 -6
  321. package/dist/harness/reducer.d.ts +0 -100
  322. package/dist/harness/reducer.d.ts.map +0 -1
  323. package/dist/harness/reducer.js +0 -420
  324. package/dist/harness/reducer.js.map +0 -1
  325. package/dist/harness/session/jsonl/errors.d.ts +0 -9
  326. package/dist/harness/session/jsonl/errors.d.ts.map +0 -1
  327. package/dist/harness/session/jsonl/errors.js +0 -18
  328. package/dist/harness/session/jsonl/errors.js.map +0 -1
  329. package/dist/harness/session/jsonl.d.ts +0 -3
  330. package/dist/harness/session/jsonl.d.ts.map +0 -1
  331. package/dist/harness/session/jsonl.js +0 -2
  332. package/dist/harness/session/jsonl.js.map +0 -1
  333. package/dist/harness/session/state.d.ts +0 -65
  334. package/dist/harness/session/state.d.ts.map +0 -1
  335. package/dist/harness/session/state.js +0 -320
  336. package/dist/harness/session/state.js.map +0 -1
  337. package/dist/harness/session/testing/conformance.d.ts +0 -4
  338. package/dist/harness/session/testing/conformance.d.ts.map +0 -1
  339. package/dist/harness/session/testing/conformance.js +0 -762
  340. package/dist/harness/session/testing/conformance.js.map +0 -1
  341. package/dist/search/scanning.d.ts +0 -29
  342. package/dist/search/scanning.d.ts.map +0 -1
  343. package/dist/search/scanning.js +0 -103
  344. package/dist/search/scanning.js.map +0 -1
@@ -0,0 +1,79 @@
1
+ import { projectForkCurrentStateWrite, selectBranchFork } from "./fork-policy.js";
2
+ import { branchTip, laneConfig, laneState, value } from "./values.js";
3
+ function storedValuesInNamespace(values, address) {
4
+ return values.filter((stored) => stored.address.namespace === address.namespace);
5
+ }
6
+ function findStoredValue(values, address) {
7
+ return values.find((stored) => stored.address.namespace === address.namespace && stored.address.key === address.key);
8
+ }
9
+ /** Build the complete logical state for a forked destination session. */
10
+ export function createForkSnapshot(source, options) {
11
+ const sourceEntries = new Map(source.entries.map((entry) => [entry.id, entry]));
12
+ const sourceTips = storedValuesInNamespace(source.scalarValues, branchTip(""));
13
+ validateForkSourceSnapshot(source, sourceEntries, sourceTips, options);
14
+ const { entryIds, plan } = selectForkContents(sourceEntries, sourceTips, options);
15
+ const entries = new Map();
16
+ for (const id of entryIds)
17
+ entries.set(id, sourceEntries.get(id));
18
+ const scalarValues = [];
19
+ let nextSeq = Math.max(0, ...[...entries.values()].map((entry) => entry.seq)) + 1;
20
+ for (const stored of source.scalarValues) {
21
+ const projected = projectForkCurrentStateWrite({
22
+ kind: "value",
23
+ op: "set",
24
+ seq: stored.seq,
25
+ namespace: stored.address.namespace,
26
+ key: stored.address.key,
27
+ value: stored.value,
28
+ }, plan, (entryId) => entryIds.has(entryId));
29
+ if (projected !== undefined) {
30
+ scalarValues.push({
31
+ address: value(projected.namespace, projected.key),
32
+ value: projected.value,
33
+ seq: nextSeq++,
34
+ });
35
+ }
36
+ }
37
+ return { entries, scalarValues, nextSeq };
38
+ }
39
+ function selectForkContents(sourceEntries, sourceTips, options) {
40
+ const entryIds = new Set();
41
+ if (options.scope === "tree") {
42
+ for (const id of sourceEntries.keys())
43
+ entryIds.add(id);
44
+ return { entryIds, plan: { scope: "tree" } };
45
+ }
46
+ const sourceTip = sourceTips.find((stored) => stored.address.key === options.branch);
47
+ const plan = selectBranchFork(options, {
48
+ tip: sourceTip?.value,
49
+ getParent: (entryId) => sourceEntries.get(entryId)?.parentId,
50
+ selectEntry: (entryId) => entryIds.add(entryId),
51
+ });
52
+ return { entryIds, plan };
53
+ }
54
+ function validateForkSourceSnapshot(source, sourceEntries, sourceTips, options) {
55
+ const sourceTipKeys = new Set(sourceTips.map((stored) => stored.address.key));
56
+ for (const stored of source.scalarValues) {
57
+ if ((stored.address.namespace === laneConfig("").namespace ||
58
+ stored.address.namespace === laneState("").namespace) &&
59
+ !sourceTipKeys.has(stored.address.key)) {
60
+ throw new Error(`Source session branch ${JSON.stringify(stored.address.key)} is missing branch.tip`);
61
+ }
62
+ }
63
+ for (const tip of sourceTips) {
64
+ const configuration = findStoredValue(source.scalarValues, laneConfig(tip.address.key));
65
+ const state = findStoredValue(source.scalarValues, laneState(tip.address.key));
66
+ if ((configuration === undefined) !== (state === undefined)) {
67
+ throw new Error(`Source session branch ${JSON.stringify(tip.address.key)} has incomplete lane state`);
68
+ }
69
+ if (options.scope === "branch" && tip.address.key === options.branch && configuration === undefined) {
70
+ throw new Error(`Source branch ${JSON.stringify(options.branch)} is not a configured AgentLane`);
71
+ }
72
+ if ((source.entriesComplete !== false || options.scope === "tree") &&
73
+ tip.value !== null &&
74
+ !sourceEntries.has(tip.value)) {
75
+ throw new Error(`Source session branch ${JSON.stringify(tip.address.key)} has an unknown tip`);
76
+ }
77
+ }
78
+ }
79
+ //# sourceMappingURL=fork.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fork.js","sourceRoot":"","sources":["../../../src/harness/session/fork.ts"],"names":[],"mappings":"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","sourcesContent":["import { type ForkCurrentStatePlan, projectForkCurrentStateWrite, selectBranchFork } from \"./fork-policy.ts\";\nimport type { Entry, ForkOptions } from \"./types.ts\";\nimport { branchTip, laneConfig, laneState, type StoredValue, type Value, value } from \"./values.ts\";\n\nexport interface ForkSourceSnapshot {\n\tentries: Entry[];\n\tscalarValues: StoredValue<unknown>[];\n\t/** False when a backend supplied only the requested branch rather than the full tree. */\n\tentriesComplete?: boolean;\n}\n\nexport interface ForkDestinationSnapshot {\n\tentries: Map<string, Entry>;\n\tscalarValues: StoredValue<unknown>[];\n\tnextSeq: number;\n}\n\nfunction storedValuesInNamespace<T>(values: readonly StoredValue<unknown>[], address: Value<T>): StoredValue<T>[] {\n\treturn values.filter((stored) => stored.address.namespace === address.namespace) as StoredValue<T>[];\n}\n\nfunction findStoredValue<T>(values: readonly StoredValue<unknown>[], address: Value<T>): StoredValue<T> | undefined {\n\treturn values.find(\n\t\t(stored) => stored.address.namespace === address.namespace && stored.address.key === address.key,\n\t) as StoredValue<T> | undefined;\n}\n\n/** Build the complete logical state for a forked destination session. */\nexport function createForkSnapshot(source: ForkSourceSnapshot, options: ForkOptions): ForkDestinationSnapshot {\n\tconst sourceEntries = new Map(source.entries.map((entry) => [entry.id, entry]));\n\tconst sourceTips = storedValuesInNamespace(source.scalarValues, branchTip(\"\"));\n\tvalidateForkSourceSnapshot(source, sourceEntries, sourceTips, options);\n\n\tconst { entryIds, plan } = selectForkContents(sourceEntries, sourceTips, options);\n\tconst entries = new Map<string, Entry>();\n\tfor (const id of entryIds) entries.set(id, sourceEntries.get(id)!);\n\n\tconst scalarValues: StoredValue<unknown>[] = [];\n\tlet nextSeq = Math.max(0, ...[...entries.values()].map((entry) => entry.seq)) + 1;\n\tfor (const stored of source.scalarValues) {\n\t\tconst projected = projectForkCurrentStateWrite(\n\t\t\t{\n\t\t\t\tkind: \"value\",\n\t\t\t\top: \"set\",\n\t\t\t\tseq: stored.seq,\n\t\t\t\tnamespace: stored.address.namespace,\n\t\t\t\tkey: stored.address.key,\n\t\t\t\tvalue: stored.value,\n\t\t\t},\n\t\t\tplan,\n\t\t\t(entryId) => entryIds.has(entryId),\n\t\t);\n\t\tif (projected !== undefined) {\n\t\t\tscalarValues.push({\n\t\t\t\taddress: value<unknown>(projected.namespace, projected.key),\n\t\t\t\tvalue: projected.value,\n\t\t\t\tseq: nextSeq++,\n\t\t\t});\n\t\t}\n\t}\n\n\treturn { entries, scalarValues, nextSeq };\n}\n\nfunction selectForkContents(\n\tsourceEntries: Map<string, Entry>,\n\tsourceTips: StoredValue<string | null>[],\n\toptions: ForkOptions,\n): { entryIds: Set<string>; plan: ForkCurrentStatePlan } {\n\tconst entryIds = new Set<string>();\n\tif (options.scope === \"tree\") {\n\t\tfor (const id of sourceEntries.keys()) entryIds.add(id);\n\t\treturn { entryIds, plan: { scope: \"tree\" } };\n\t}\n\n\tconst sourceTip = sourceTips.find((stored) => stored.address.key === options.branch);\n\tconst plan = selectBranchFork(options, {\n\t\ttip: sourceTip?.value,\n\t\tgetParent: (entryId) => sourceEntries.get(entryId)?.parentId,\n\t\tselectEntry: (entryId) => entryIds.add(entryId),\n\t});\n\treturn { entryIds, plan };\n}\n\nfunction validateForkSourceSnapshot(\n\tsource: ForkSourceSnapshot,\n\tsourceEntries: Map<string, Entry>,\n\tsourceTips: StoredValue<string | null>[],\n\toptions: ForkOptions,\n): void {\n\tconst sourceTipKeys = new Set(sourceTips.map((stored) => stored.address.key));\n\n\tfor (const stored of source.scalarValues) {\n\t\tif (\n\t\t\t(stored.address.namespace === laneConfig(\"\").namespace ||\n\t\t\t\tstored.address.namespace === laneState(\"\").namespace) &&\n\t\t\t!sourceTipKeys.has(stored.address.key)\n\t\t) {\n\t\t\tthrow new Error(`Source session branch ${JSON.stringify(stored.address.key)} is missing branch.tip`);\n\t\t}\n\t}\n\tfor (const tip of sourceTips) {\n\t\tconst configuration = findStoredValue(source.scalarValues, laneConfig(tip.address.key));\n\t\tconst state = findStoredValue(source.scalarValues, laneState(tip.address.key));\n\t\tif ((configuration === undefined) !== (state === undefined)) {\n\t\t\tthrow new Error(`Source session branch ${JSON.stringify(tip.address.key)} has incomplete lane state`);\n\t\t}\n\t\tif (options.scope === \"branch\" && tip.address.key === options.branch && configuration === undefined) {\n\t\t\tthrow new Error(`Source branch ${JSON.stringify(options.branch)} is not a configured AgentLane`);\n\t\t}\n\t\tif (\n\t\t\t(source.entriesComplete !== false || options.scope === \"tree\") &&\n\t\t\ttip.value !== null &&\n\t\t\t!sourceEntries.has(tip.value)\n\t\t) {\n\t\t\tthrow new Error(`Source session branch ${JSON.stringify(tip.address.key)} has an unknown tip`);\n\t\t}\n\t}\n}\n"]}
@@ -0,0 +1,39 @@
1
+ import { type CommittedWrite, type PreparedCommit } from "./commit.ts";
2
+ export type { CommittedEntryWrite, CommittedListAppendWrite, CommittedListDeleteWrite, CommittedUsageWrite, CommittedValueDeleteWrite, CommittedValueSetWrite, CommittedWrite, PreparedCommit, } from "./commit.ts";
3
+ import type { Entry, EntryScan, EntryStructure, ForkOptions, SessionStats, StorageBranchScan, UsageRow, UsageScan, Write } from "./types.ts";
4
+ import { type ListElement, type ListReadOptions, type StoredValue, type Value, type ValueList } from "./values.ts";
5
+ /**
6
+ * Complete materialized session state for MemoryStorage and JsonlStorage.
7
+ *
8
+ * This is intentionally unsuitable for database backends and long-running sessions that may not fit in memory.
9
+ * Those backends should query indexed durable state and update durable aggregates within each commit transaction.
10
+ */
11
+ export declare class InMemoryStorageState {
12
+ private readonly entries;
13
+ private readonly entriesBySeq;
14
+ private readonly scalarValues;
15
+ private readonly listValues;
16
+ private readonly usage;
17
+ private stats;
18
+ private nextSeq;
19
+ constructor();
20
+ prepareCommit(writes: Write[], timestamp: number): PreparedCommit;
21
+ validateCommitted(writes: readonly CommittedWrite[]): void;
22
+ /** Apply writes already accepted by validateCommitted() and return the post-apply totals. */
23
+ applyValidated(writes: readonly CommittedWrite[]): SessionStats;
24
+ createFork(options: ForkOptions): InMemoryStorageState;
25
+ private selectForkPlan;
26
+ private applyValueSetOrListAppend;
27
+ advanceNextSeq(nextSeq: number): void;
28
+ getEntries(ids: readonly string[]): Map<string, Entry>;
29
+ getValue<T>(address: Value<T>): StoredValue<T> | undefined;
30
+ scanValues<T>(prefix: Value<T>): StoredValue<T>[];
31
+ readList<T>(address: ValueList<T>, options?: ListReadOptions): ListElement<T>[];
32
+ scanBranch(query: StorageBranchScan): Entry[];
33
+ scanBranchStructure(query: StorageBranchScan): EntryStructure[];
34
+ scanEntries(query: EntryScan): Entry[];
35
+ scanUsage(query: UsageScan): UsageRow[];
36
+ getStats(): SessionStats;
37
+ getNextSeq(): number;
38
+ }
39
+ //# sourceMappingURL=in-memory-storage-state.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"in-memory-storage-state.d.ts","sourceRoot":"","sources":["../../../src/harness/session/in-memory-storage-state.ts"],"names":[],"mappings":"AACA,OAAO,EAGN,KAAK,cAAc,EACnB,KAAK,cAAc,EAGnB,MAAM,aAAa,CAAC;AAGrB,YAAY,EACX,mBAAmB,EACnB,wBAAwB,EACxB,wBAAwB,EACxB,mBAAmB,EACnB,yBAAyB,EACzB,sBAAsB,EACtB,cAAc,EACd,cAAc,GACd,MAAM,aAAa,CAAC;AAErB,OAAO,KAAK,EACX,KAAK,EACL,SAAS,EACT,cAAc,EACd,WAAW,EACX,YAAY,EACZ,iBAAiB,EACjB,QAAQ,EACR,SAAS,EACT,KAAK,EACL,MAAM,YAAY,CAAC;AACpB,OAAO,EAEN,KAAK,WAAW,EAChB,KAAK,eAAe,EAKpB,KAAK,WAAW,EAChB,KAAK,KAAK,EACV,KAAK,SAAS,EAEd,MAAM,aAAa,CAAC;AA0BrB;;;;;GAKG;AACH,qBAAa,oBAAoB;IAChC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAqB;IAC7C,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAU;IACvC,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAoC;IACjE,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAkC;IAC7D,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAwB;IAC9C,OAAO,CAAC,KAAK,CAAe;IAC5B,OAAO,CAAC,OAAO,CAAS;IAExB,cAQC;IAED,aAAa,CAAC,MAAM,EAAE,KAAK,EAAE,EAAE,SAAS,EAAE,MAAM,GAAG,cAAc,CAIhE;IAED,iBAAiB,CAAC,MAAM,EAAE,SAAS,cAAc,EAAE,GAAG,IAAI,CAKzD;IAED,6FAA6F;IAC7F,cAAc,CAAC,MAAM,EAAE,SAAS,cAAc,EAAE,GAAG,YAAY,CA4B9D;IAED,UAAU,CAAC,OAAO,EAAE,WAAW,GAAG,oBAAoB,CAoDrD;IAED,OAAO,CAAC,cAAc;IAkBtB,OAAO,CAAC,yBAAyB;IAuBjC,cAAc,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAKpC;IAED,UAAU,CAAC,GAAG,EAAE,SAAS,MAAM,EAAE,GAAG,GAAG,CAAC,MAAM,EAAE,KAAK,CAAC,CAOrD;IAED,QAAQ,CAAC,CAAC,EAAE,OAAO,EAAE,KAAK,CAAC,CAAC,CAAC,GAAG,WAAW,CAAC,CAAC,CAAC,GAAG,SAAS,CAEzD;IAED,UAAU,CAAC,CAAC,EAAE,MAAM,EAAE,KAAK,CAAC,CAAC,CAAC,GAAG,WAAW,CAAC,CAAC,CAAC,EAAE,CAIhD;IAED,QAAQ,CAAC,CAAC,EAAE,OAAO,EAAE,SAAS,CAAC,CAAC,CAAC,EAAE,OAAO,CAAC,EAAE,eAAe,GAAG,WAAW,CAAC,CAAC,CAAC,EAAE,CAS9E;IAED,UAAU,CAAC,KAAK,EAAE,iBAAiB,GAAG,KAAK,EAAE,CA4B5C;IAED,mBAAmB,CAAC,KAAK,EAAE,iBAAiB,GAAG,cAAc,EAAE,CAS9D;IAED,WAAW,CAAC,KAAK,EAAE,SAAS,GAAG,KAAK,EAAE,CAkBrC;IAED,SAAS,CAAC,KAAK,EAAE,SAAS,GAAG,QAAQ,EAAE,CAMtC;IAED,QAAQ,IAAI,YAAY,CAEvB;IAED,UAAU,IAAI,MAAM,CAEnB;CACD"}
@@ -0,0 +1,269 @@
1
+ import { addUsage, emptyUsage } from "../utils/usage.js";
2
+ import { prepareStorageCommit, validateCommittedWrites, } from "./commit.js";
3
+ import { projectForkCurrentStateWrite, selectBranchFork } from "./fork-policy.js";
4
+ import { branchTip, laneConfig, laneState, list, resolveListReadOptions, value, } from "./values.js";
5
+ function physicalKey(namespace, key) {
6
+ return `${namespace}\u0000${key}`;
7
+ }
8
+ function compareKeys(left, right) {
9
+ const leftCodePoints = Array.from(left, (character) => character.codePointAt(0));
10
+ const rightCodePoints = Array.from(right, (character) => character.codePointAt(0));
11
+ const length = Math.min(leftCodePoints.length, rightCodePoints.length);
12
+ for (let index = 0; index < length; index++) {
13
+ const difference = leftCodePoints[index] - rightCodePoints[index];
14
+ if (difference !== 0)
15
+ return difference;
16
+ }
17
+ return leftCodePoints.length - rightCodePoints.length;
18
+ }
19
+ /**
20
+ * Complete materialized session state for MemoryStorage and JsonlStorage.
21
+ *
22
+ * This is intentionally unsuitable for database backends and long-running sessions that may not fit in memory.
23
+ * Those backends should query indexed durable state and update durable aggregates within each commit transaction.
24
+ */
25
+ export class InMemoryStorageState {
26
+ constructor() {
27
+ this.entries = new Map();
28
+ this.entriesBySeq = [];
29
+ this.scalarValues = new Map();
30
+ this.listValues = new Map();
31
+ this.usage = new Map();
32
+ this.stats = { messageCount: 0, usage: emptyUsage() };
33
+ this.nextSeq = 1;
34
+ }
35
+ prepareCommit(writes, timestamp) {
36
+ const prepared = prepareStorageCommit(writes, this.nextSeq, timestamp);
37
+ this.validateCommitted(prepared.writes);
38
+ return prepared;
39
+ }
40
+ validateCommitted(writes) {
41
+ validateCommittedWrites(writes, this.nextSeq, {
42
+ hasEntryOrUsageId: (id) => this.entries.has(id) || this.usage.has(id),
43
+ hasEntryId: (id) => this.entries.has(id),
44
+ });
45
+ }
46
+ /** Apply writes already accepted by validateCommitted() and return the post-apply totals. */
47
+ applyValidated(writes) {
48
+ for (const write of writes) {
49
+ switch (write.kind) {
50
+ case "entry": {
51
+ const { kind: _kind, ...entry } = write;
52
+ this.entries.set(entry.id, entry);
53
+ this.entriesBySeq.push(entry);
54
+ if (entry.type === "message")
55
+ this.stats = { ...this.stats, messageCount: this.stats.messageCount + 1 };
56
+ break;
57
+ }
58
+ case "usage": {
59
+ const { kind: _kind, ...row } = write;
60
+ this.usage.set(row.id, row);
61
+ this.stats = { ...this.stats, usage: addUsage(this.stats.usage, row.usage) };
62
+ break;
63
+ }
64
+ case "value":
65
+ if (write.op === "delete")
66
+ this.scalarValues.delete(physicalKey(write.namespace, write.key));
67
+ else
68
+ this.applyValueSetOrListAppend(write);
69
+ break;
70
+ case "list":
71
+ if (write.op === "delete")
72
+ this.listValues.delete(physicalKey(write.namespace, write.key));
73
+ else
74
+ this.applyValueSetOrListAppend(write);
75
+ break;
76
+ }
77
+ this.nextSeq = write.seq + 1;
78
+ }
79
+ return this.stats;
80
+ }
81
+ createFork(options) {
82
+ const plan = this.selectForkPlan(options);
83
+ const isEntryCopied = (entryId) => {
84
+ if (plan.scope === "tree")
85
+ return true;
86
+ return plan.entryIds.has(entryId);
87
+ };
88
+ const destination = new InMemoryStorageState();
89
+ let messageCount = 0;
90
+ for (const entry of this.entriesBySeq) {
91
+ if (!isEntryCopied(entry.id))
92
+ continue;
93
+ destination.entries.set(entry.id, entry);
94
+ destination.entriesBySeq.push(entry);
95
+ if (entry.type === "message")
96
+ messageCount++;
97
+ }
98
+ destination.stats = { ...destination.stats, messageCount };
99
+ for (const stored of this.scalarValues.values()) {
100
+ const projected = projectForkCurrentStateWrite({
101
+ kind: "value",
102
+ op: "set",
103
+ seq: stored.seq,
104
+ namespace: stored.address.namespace,
105
+ key: stored.address.key,
106
+ value: stored.value,
107
+ }, plan, isEntryCopied);
108
+ if (projected !== undefined)
109
+ destination.applyValueSetOrListAppend(projected);
110
+ }
111
+ for (const stored of this.listValues.values()) {
112
+ for (const element of stored.elements) {
113
+ const projected = projectForkCurrentStateWrite({
114
+ kind: "list",
115
+ op: "append",
116
+ seq: element.seq,
117
+ namespace: stored.address.namespace,
118
+ key: stored.address.key,
119
+ value: element.value,
120
+ }, plan, isEntryCopied);
121
+ if (projected !== undefined)
122
+ destination.applyValueSetOrListAppend(projected);
123
+ }
124
+ }
125
+ destination.nextSeq = this.nextSeq;
126
+ return destination;
127
+ }
128
+ selectForkPlan(options) {
129
+ if (options.scope === "tree")
130
+ return { scope: "tree" };
131
+ const entryIds = new Set();
132
+ const plan = selectBranchFork(options, {
133
+ tip: this.getValue(branchTip(options.branch))?.value,
134
+ getParent: (entryId) => this.entries.get(entryId)?.parentId,
135
+ selectEntry: (entryId) => entryIds.add(entryId),
136
+ });
137
+ if (this.getValue(laneConfig(options.branch)) === undefined ||
138
+ this.getValue(laneState(options.branch)) === undefined) {
139
+ throw new Error(`Source branch ${JSON.stringify(options.branch)} is not a configured AgentLane`);
140
+ }
141
+ return { ...plan, entryIds };
142
+ }
143
+ applyValueSetOrListAppend(write) {
144
+ const key = physicalKey(write.namespace, write.key);
145
+ if (write.kind === "value") {
146
+ this.scalarValues.set(key, {
147
+ address: value(write.namespace, write.key),
148
+ value: write.value,
149
+ seq: write.seq,
150
+ });
151
+ return;
152
+ }
153
+ const element = { seq: write.seq, value: write.value };
154
+ const stored = this.listValues.get(key);
155
+ if (stored === undefined) {
156
+ this.listValues.set(key, {
157
+ address: list(write.namespace, write.key),
158
+ elements: [element],
159
+ });
160
+ }
161
+ else {
162
+ stored.elements.push(element);
163
+ }
164
+ }
165
+ advanceNextSeq(nextSeq) {
166
+ if (!Number.isSafeInteger(nextSeq) || nextSeq < 1) {
167
+ throw new Error(`Invalid storage sequence high-water mark: ${nextSeq}`);
168
+ }
169
+ this.nextSeq = Math.max(this.nextSeq, nextSeq);
170
+ }
171
+ getEntries(ids) {
172
+ const found = new Map();
173
+ for (const id of ids) {
174
+ const entry = this.entries.get(id);
175
+ if (entry !== undefined)
176
+ found.set(id, entry);
177
+ }
178
+ return found;
179
+ }
180
+ getValue(address) {
181
+ return this.scalarValues.get(physicalKey(address.namespace, address.key));
182
+ }
183
+ scanValues(prefix) {
184
+ return [...this.scalarValues.values()]
185
+ .filter((stored) => stored.address.namespace === prefix.namespace && stored.address.key.startsWith(prefix.key))
186
+ .sort((left, right) => compareKeys(left.address.key, right.address.key));
187
+ }
188
+ readList(address, options) {
189
+ const resolved = resolveListReadOptions(options);
190
+ const elements = this.listValues.get(physicalKey(address.namespace, address.key))?.elements ?? [];
191
+ const filtered = elements.filter((element) => {
192
+ if (resolved.cursor === undefined)
193
+ return true;
194
+ return resolved.order === "asc" ? element.seq > resolved.cursor.seq : element.seq < resolved.cursor.seq;
195
+ });
196
+ const ordered = resolved.order === "asc" ? filtered : [...filtered].reverse();
197
+ return ordered.slice(0, resolved.limit);
198
+ }
199
+ scanBranch(query) {
200
+ const start = this.entries.get(query.start);
201
+ if (start === undefined)
202
+ throw new Error(`Unknown branch start: ${query.start}`);
203
+ const path = [];
204
+ let entry = start;
205
+ while (entry !== undefined) {
206
+ path.push(entry);
207
+ if (entry.parentId === null)
208
+ break;
209
+ entry = this.entries.get(entry.parentId);
210
+ if (entry === undefined)
211
+ throw new Error("Corrupt branch: missing parent");
212
+ }
213
+ if (query.order === "oldestFirst")
214
+ path.reverse();
215
+ const stopped = [];
216
+ for (const candidate of path) {
217
+ stopped.push(candidate);
218
+ if (candidate.id === query.stopAtId || candidate.type === query.stopAtType)
219
+ break;
220
+ }
221
+ const filtered = stopped
222
+ .filter((candidate) => query.type === undefined || candidate.type === query.type)
223
+ .filter((candidate) => query.customType === undefined || candidate.customType === query.customType)
224
+ .filter((candidate) => query.cursor === undefined ||
225
+ (query.order === "oldestFirst" ? candidate.seq > query.cursor.seq : candidate.seq < query.cursor.seq));
226
+ return query.limit === undefined ? filtered : filtered.slice(0, Math.max(0, query.limit));
227
+ }
228
+ scanBranchStructure(query) {
229
+ return this.scanBranch(query).map((entry) => ({
230
+ id: entry.id,
231
+ parentId: entry.parentId,
232
+ seq: entry.seq,
233
+ timestamp: entry.timestamp,
234
+ type: entry.type,
235
+ ...(entry.customType === undefined ? {} : { customType: entry.customType }),
236
+ }));
237
+ }
238
+ scanEntries(query) {
239
+ const limit = query.limit === undefined ? Number.POSITIVE_INFINITY : Math.max(0, Math.trunc(query.limit));
240
+ const entries = [];
241
+ const descending = query.order === "desc";
242
+ let index = descending ? this.entriesBySeq.length - 1 : 0;
243
+ while (index >= 0 && index < this.entriesBySeq.length && entries.length < limit) {
244
+ const entry = this.entriesBySeq[index];
245
+ if ((query.type === undefined || entry.type === query.type) &&
246
+ (query.customType === undefined || entry.customType === query.customType) &&
247
+ (query.fromSeq === undefined || entry.seq >= query.fromSeq) &&
248
+ (query.toSeq === undefined || entry.seq <= query.toSeq)) {
249
+ entries.push(entry);
250
+ }
251
+ index += descending ? -1 : 1;
252
+ }
253
+ return entries;
254
+ }
255
+ scanUsage(query) {
256
+ const rows = [...this.usage.values()]
257
+ .filter((row) => query.fromSeq === undefined || row.seq >= query.fromSeq)
258
+ .filter((row) => query.toSeq === undefined || row.seq <= query.toSeq)
259
+ .sort((left, right) => (query.order === "desc" ? right.seq - left.seq : left.seq - right.seq));
260
+ return query.limit === undefined ? rows : rows.slice(0, Math.max(0, query.limit));
261
+ }
262
+ getStats() {
263
+ return this.stats;
264
+ }
265
+ getNextSeq() {
266
+ return this.nextSeq;
267
+ }
268
+ }
269
+ //# sourceMappingURL=in-memory-storage-state.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"in-memory-storage-state.js","sourceRoot":"","sources":["../../../src/harness/session/in-memory-storage-state.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AACzD,OAAO,EAKN,oBAAoB,EACpB,uBAAuB,GACvB,MAAM,aAAa,CAAC;AACrB,OAAO,EAAE,4BAA4B,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AAwBlF,OAAO,EACN,SAAS,EAGT,UAAU,EACV,SAAS,EACT,IAAI,EACJ,sBAAsB,EAItB,KAAK,GACL,MAAM,aAAa,CAAC;AAWrB,SAAS,WAAW,CAAC,SAAiB,EAAE,GAAW;IAClD,OAAO,GAAG,SAAS,SAAS,GAAG,EAAE,CAAC;AACnC,CAAC;AAED,SAAS,WAAW,CAAC,IAAY,EAAE,KAAa;IAC/C,MAAM,cAAc,GAAG,KAAK,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,SAAS,EAAE,EAAE,CAAC,SAAS,CAAC,WAAW,CAAC,CAAC,CAAE,CAAC,CAAC;IAClF,MAAM,eAAe,GAAG,KAAK,CAAC,IAAI,CAAC,KAAK,EAAE,CAAC,SAAS,EAAE,EAAE,CAAC,SAAS,CAAC,WAAW,CAAC,CAAC,CAAE,CAAC,CAAC;IACpF,MAAM,MAAM,GAAG,IAAI,CAAC,GAAG,CAAC,cAAc,CAAC,MAAM,EAAE,eAAe,CAAC,MAAM,CAAC,CAAC;IACvE,KAAK,IAAI,KAAK,GAAG,CAAC,EAAE,KAAK,GAAG,MAAM,EAAE,KAAK,EAAE,EAAE,CAAC;QAC7C,MAAM,UAAU,GAAG,cAAc,CAAC,KAAK,CAAE,GAAG,eAAe,CAAC,KAAK,CAAE,CAAC;QACpE,IAAI,UAAU,KAAK,CAAC;YAAE,OAAO,UAAU,CAAC;IACzC,CAAC;IACD,OAAO,cAAc,CAAC,MAAM,GAAG,eAAe,CAAC,MAAM,CAAC;AACvD,CAAC;AAED;;;;;GAKG;AACH,MAAM,OAAO,oBAAoB;IAShC;QACC,IAAI,CAAC,OAAO,GAAG,IAAI,GAAG,EAAE,CAAC;QACzB,IAAI,CAAC,YAAY,GAAG,EAAE,CAAC;QACvB,IAAI,CAAC,YAAY,GAAG,IAAI,GAAG,EAAE,CAAC;QAC9B,IAAI,CAAC,UAAU,GAAG,IAAI,GAAG,EAAE,CAAC;QAC5B,IAAI,CAAC,KAAK,GAAG,IAAI,GAAG,EAAE,CAAC;QACvB,IAAI,CAAC,KAAK,GAAG,EAAE,YAAY,EAAE,CAAC,EAAE,KAAK,EAAE,UAAU,EAAE,EAAE,CAAC;QACtD,IAAI,CAAC,OAAO,GAAG,CAAC,CAAC;IAClB,CAAC;IAED,aAAa,CAAC,MAAe,EAAE,SAAiB;QAC/C,MAAM,QAAQ,GAAG,oBAAoB,CAAC,MAAM,EAAE,IAAI,CAAC,OAAO,EAAE,SAAS,CAAC,CAAC;QACvE,IAAI,CAAC,iBAAiB,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;QACxC,OAAO,QAAQ,CAAC;IACjB,CAAC;IAED,iBAAiB,CAAC,MAAiC;QAClD,uBAAuB,CAAC,MAAM,EAAE,IAAI,CAAC,OAAO,EAAE;YAC7C,iBAAiB,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC;YACrE,UAAU,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC;SACxC,CAAC,CAAC;IACJ,CAAC;IAED,6FAA6F;IAC7F,cAAc,CAAC,MAAiC;QAC/C,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;YAC5B,QAAQ,KAAK,CAAC,IAAI,EAAE,CAAC;gBACpB,KAAK,OAAO,EAAE,CAAC;oBACd,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,GAAG,KAAK,EAAE,GAAG,KAAK,CAAC;oBACxC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,EAAE,KAAK,CAAC,CAAC;oBAClC,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;oBAC9B,IAAI,KAAK,CAAC,IAAI,KAAK,SAAS;wBAAE,IAAI,CAAC,KAAK,GAAG,EAAE,GAAG,IAAI,CAAC,KAAK,EAAE,YAAY,EAAE,IAAI,CAAC,KAAK,CAAC,YAAY,GAAG,CAAC,EAAE,CAAC;oBACxG,MAAM;gBACP,CAAC;gBACD,KAAK,OAAO,EAAE,CAAC;oBACd,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,GAAG,GAAG,EAAE,GAAG,KAAK,CAAC;oBACtC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,EAAE,GAAG,CAAC,CAAC;oBAC5B,IAAI,CAAC,KAAK,GAAG,EAAE,GAAG,IAAI,CAAC,KAAK,EAAE,KAAK,EAAE,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,EAAE,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC;oBAC7E,MAAM;gBACP,CAAC;gBACD,KAAK,OAAO;oBACX,IAAI,KAAK,CAAC,EAAE,KAAK,QAAQ;wBAAE,IAAI,CAAC,YAAY,CAAC,MAAM,CAAC,WAAW,CAAC,KAAK,CAAC,SAAS,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC;;wBACxF,IAAI,CAAC,yBAAyB,CAAC,KAAK,CAAC,CAAC;oBAC3C,MAAM;gBACP,KAAK,MAAM;oBACV,IAAI,KAAK,CAAC,EAAE,KAAK,QAAQ;wBAAE,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,WAAW,CAAC,KAAK,CAAC,SAAS,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC;;wBACtF,IAAI,CAAC,yBAAyB,CAAC,KAAK,CAAC,CAAC;oBAC3C,MAAM;YACR,CAAC;YACD,IAAI,CAAC,OAAO,GAAG,KAAK,CAAC,GAAG,GAAG,CAAC,CAAC;QAC9B,CAAC;QACD,OAAO,IAAI,CAAC,KAAK,CAAC;IACnB,CAAC;IAED,UAAU,CAAC,OAAoB;QAC9B,MAAM,IAAI,GAAG,IAAI,CAAC,cAAc,CAAC,OAAO,CAAC,CAAC;QAE1C,MAAM,aAAa,GAAG,CAAC,OAAe,EAAW,EAAE;YAClD,IAAI,IAAI,CAAC,KAAK,KAAK,MAAM;gBAAE,OAAO,IAAI,CAAC;YACvC,OAAO,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;QACnC,CAAC,CAAC;QACF,MAAM,WAAW,GAAG,IAAI,oBAAoB,EAAE,CAAC;QAC/C,IAAI,YAAY,GAAG,CAAC,CAAC;QACrB,KAAK,MAAM,KAAK,IAAI,IAAI,CAAC,YAAY,EAAE,CAAC;YACvC,IAAI,CAAC,aAAa,CAAC,KAAK,CAAC,EAAE,CAAC;gBAAE,SAAS;YACvC,WAAW,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,EAAE,KAAK,CAAC,CAAC;YACzC,WAAW,CAAC,YAAY,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;YACrC,IAAI,KAAK,CAAC,IAAI,KAAK,SAAS;gBAAE,YAAY,EAAE,CAAC;QAC9C,CAAC;QACD,WAAW,CAAC,KAAK,GAAG,EAAE,GAAG,WAAW,CAAC,KAAK,EAAE,YAAY,EAAE,CAAC;QAE3D,KAAK,MAAM,MAAM,IAAI,IAAI,CAAC,YAAY,CAAC,MAAM,EAAE,EAAE,CAAC;YACjD,MAAM,SAAS,GAAG,4BAA4B,CAC7C;gBACC,IAAI,EAAE,OAAO;gBACb,EAAE,EAAE,KAAK;gBACT,GAAG,EAAE,MAAM,CAAC,GAAG;gBACf,SAAS,EAAE,MAAM,CAAC,OAAO,CAAC,SAAS;gBACnC,GAAG,EAAE,MAAM,CAAC,OAAO,CAAC,GAAG;gBACvB,KAAK,EAAE,MAAM,CAAC,KAAK;aACnB,EACD,IAAI,EACJ,aAAa,CACb,CAAC;YACF,IAAI,SAAS,KAAK,SAAS;gBAAE,WAAW,CAAC,yBAAyB,CAAC,SAAS,CAAC,CAAC;QAC/E,CAAC;QAED,KAAK,MAAM,MAAM,IAAI,IAAI,CAAC,UAAU,CAAC,MAAM,EAAE,EAAE,CAAC;YAC/C,KAAK,MAAM,OAAO,IAAI,MAAM,CAAC,QAAQ,EAAE,CAAC;gBACvC,MAAM,SAAS,GAAG,4BAA4B,CAC7C;oBACC,IAAI,EAAE,MAAM;oBACZ,EAAE,EAAE,QAAQ;oBACZ,GAAG,EAAE,OAAO,CAAC,GAAG;oBAChB,SAAS,EAAE,MAAM,CAAC,OAAO,CAAC,SAAS;oBACnC,GAAG,EAAE,MAAM,CAAC,OAAO,CAAC,GAAG;oBACvB,KAAK,EAAE,OAAO,CAAC,KAAK;iBACpB,EACD,IAAI,EACJ,aAAa,CACb,CAAC;gBACF,IAAI,SAAS,KAAK,SAAS;oBAAE,WAAW,CAAC,yBAAyB,CAAC,SAAS,CAAC,CAAC;YAC/E,CAAC;QACF,CAAC;QACD,WAAW,CAAC,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC;QACnC,OAAO,WAAW,CAAC;IACpB,CAAC;IAEO,cAAc,CAAC,OAAoB;QAC1C,IAAI,OAAO,CAAC,KAAK,KAAK,MAAM;YAAE,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC;QAEvD,MAAM,QAAQ,GAAG,IAAI,GAAG,EAAU,CAAC;QACnC,MAAM,IAAI,GAAG,gBAAgB,CAAC,OAAO,EAAE;YACtC,GAAG,EAAE,IAAI,CAAC,QAAQ,CAAC,SAAS,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,EAAE,KAAK;YACpD,SAAS,EAAE,CAAC,OAAO,EAAE,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,QAAQ;YAC3D,WAAW,EAAE,CAAC,OAAO,EAAE,EAAE,CAAC,QAAQ,CAAC,GAAG,CAAC,OAAO,CAAC;SAC/C,CAAC,CAAC;QACH,IACC,IAAI,CAAC,QAAQ,CAAC,UAAU,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,KAAK,SAAS;YACvD,IAAI,CAAC,QAAQ,CAAC,SAAS,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,KAAK,SAAS,EACrD,CAAC;YACF,MAAM,IAAI,KAAK,CAAC,iBAAiB,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,MAAM,CAAC,gCAAgC,CAAC,CAAC;QAClG,CAAC;QACD,OAAO,EAAE,GAAG,IAAI,EAAE,QAAQ,EAAE,CAAC;IAC9B,CAAC;IAEO,yBAAyB,CAAC,KAAwD;QACzF,MAAM,GAAG,GAAG,WAAW,CAAC,KAAK,CAAC,SAAS,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC;QACpD,IAAI,KAAK,CAAC,IAAI,KAAK,OAAO,EAAE,CAAC;YAC5B,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,GAAG,EAAE;gBAC1B,OAAO,EAAE,KAAK,CAAU,KAAK,CAAC,SAAS,EAAE,KAAK,CAAC,GAAG,CAAC;gBACnD,KAAK,EAAE,KAAK,CAAC,KAAK;gBAClB,GAAG,EAAE,KAAK,CAAC,GAAG;aACd,CAAC,CAAC;YACH,OAAO;QACR,CAAC;QAED,MAAM,OAAO,GAAG,EAAE,GAAG,EAAE,KAAK,CAAC,GAAG,EAAE,KAAK,EAAE,KAAK,CAAC,KAAK,EAAE,CAAC;QACvD,MAAM,MAAM,GAAG,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QACxC,IAAI,MAAM,KAAK,SAAS,EAAE,CAAC;YAC1B,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,GAAG,EAAE;gBACxB,OAAO,EAAE,IAAI,CAAU,KAAK,CAAC,SAAS,EAAE,KAAK,CAAC,GAAG,CAAC;gBAClD,QAAQ,EAAE,CAAC,OAAO,CAAC;aACnB,CAAC,CAAC;QACJ,CAAC;aAAM,CAAC;YACP,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QAC/B,CAAC;IACF,CAAC;IAED,cAAc,CAAC,OAAe;QAC7B,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC,OAAO,CAAC,IAAI,OAAO,GAAG,CAAC,EAAE,CAAC;YACnD,MAAM,IAAI,KAAK,CAAC,6CAA6C,OAAO,EAAE,CAAC,CAAC;QACzE,CAAC;QACD,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;IAChD,CAAC;IAED,UAAU,CAAC,GAAsB;QAChC,MAAM,KAAK,GAAG,IAAI,GAAG,EAAiB,CAAC;QACvC,KAAK,MAAM,EAAE,IAAI,GAAG,EAAE,CAAC;YACtB,MAAM,KAAK,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;YACnC,IAAI,KAAK,KAAK,SAAS;gBAAE,KAAK,CAAC,GAAG,CAAC,EAAE,EAAE,KAAK,CAAC,CAAC;QAC/C,CAAC;QACD,OAAO,KAAK,CAAC;IACd,CAAC;IAED,QAAQ,CAAI,OAAiB;QAC5B,OAAO,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,WAAW,CAAC,OAAO,CAAC,SAAS,EAAE,OAAO,CAAC,GAAG,CAAC,CAA+B,CAAC;IACzG,CAAC;IAED,UAAU,CAAI,MAAgB;QAC7B,OAAO,CAAC,GAAG,IAAI,CAAC,YAAY,CAAC,MAAM,EAAE,CAAC;aACpC,MAAM,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,OAAO,CAAC,SAAS,KAAK,MAAM,CAAC,SAAS,IAAI,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,UAAU,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;aAC9G,IAAI,CAAC,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC,WAAW,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,CAAqB,CAAC;IAC/F,CAAC;IAED,QAAQ,CAAI,OAAqB,EAAE,OAAyB;QAC3D,MAAM,QAAQ,GAAG,sBAAsB,CAAC,OAAO,CAAC,CAAC;QACjD,MAAM,QAAQ,GAAG,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,WAAW,CAAC,OAAO,CAAC,SAAS,EAAE,OAAO,CAAC,GAAG,CAAC,CAAC,EAAE,QAAQ,IAAI,EAAE,CAAC;QAClG,MAAM,QAAQ,GAAG,QAAQ,CAAC,MAAM,CAAC,CAAC,OAAO,EAAE,EAAE;YAC5C,IAAI,QAAQ,CAAC,MAAM,KAAK,SAAS;gBAAE,OAAO,IAAI,CAAC;YAC/C,OAAO,QAAQ,CAAC,KAAK,KAAK,KAAK,CAAC,CAAC,CAAC,OAAO,CAAC,GAAG,GAAG,QAAQ,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,OAAO,CAAC,GAAG,GAAG,QAAQ,CAAC,MAAM,CAAC,GAAG,CAAC;QACzG,CAAC,CAAC,CAAC;QACH,MAAM,OAAO,GAAG,QAAQ,CAAC,KAAK,KAAK,KAAK,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,GAAG,QAAQ,CAAC,CAAC,OAAO,EAAE,CAAC;QAC9E,OAAO,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,QAAQ,CAAC,KAAK,CAAqB,CAAC;IAC7D,CAAC;IAED,UAAU,CAAC,KAAwB;QAClC,MAAM,KAAK,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;QAC5C,IAAI,KAAK,KAAK,SAAS;YAAE,MAAM,IAAI,KAAK,CAAC,yBAAyB,KAAK,CAAC,KAAK,EAAE,CAAC,CAAC;QAEjF,MAAM,IAAI,GAAY,EAAE,CAAC;QACzB,IAAI,KAAK,GAAsB,KAAK,CAAC;QACrC,OAAO,KAAK,KAAK,SAAS,EAAE,CAAC;YAC5B,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;YACjB,IAAI,KAAK,CAAC,QAAQ,KAAK,IAAI;gBAAE,MAAM;YACnC,KAAK,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;YACzC,IAAI,KAAK,KAAK,SAAS;gBAAE,MAAM,IAAI,KAAK,CAAC,gCAAgC,CAAC,CAAC;QAC5E,CAAC;QACD,IAAI,KAAK,CAAC,KAAK,KAAK,aAAa;YAAE,IAAI,CAAC,OAAO,EAAE,CAAC;QAElD,MAAM,OAAO,GAAY,EAAE,CAAC;QAC5B,KAAK,MAAM,SAAS,IAAI,IAAI,EAAE,CAAC;YAC9B,OAAO,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;YACxB,IAAI,SAAS,CAAC,EAAE,KAAK,KAAK,CAAC,QAAQ,IAAI,SAAS,CAAC,IAAI,KAAK,KAAK,CAAC,UAAU;gBAAE,MAAM;QACnF,CAAC;QACD,MAAM,QAAQ,GAAG,OAAO;aACtB,MAAM,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC,KAAK,CAAC,IAAI,KAAK,SAAS,IAAI,SAAS,CAAC,IAAI,KAAK,KAAK,CAAC,IAAI,CAAC;aAChF,MAAM,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC,KAAK,CAAC,UAAU,KAAK,SAAS,IAAI,SAAS,CAAC,UAAU,KAAK,KAAK,CAAC,UAAU,CAAC;aAClG,MAAM,CACN,CAAC,SAAS,EAAE,EAAE,CACb,KAAK,CAAC,MAAM,KAAK,SAAS;YAC1B,CAAC,KAAK,CAAC,KAAK,KAAK,aAAa,CAAC,CAAC,CAAC,SAAS,CAAC,GAAG,GAAG,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,SAAS,CAAC,GAAG,GAAG,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CACtG,CAAC;QACH,OAAO,KAAK,CAAC,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC;IAC3F,CAAC;IAED,mBAAmB,CAAC,KAAwB;QAC3C,OAAO,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;YAC7C,EAAE,EAAE,KAAK,CAAC,EAAE;YACZ,QAAQ,EAAE,KAAK,CAAC,QAAQ;YACxB,GAAG,EAAE,KAAK,CAAC,GAAG;YACd,SAAS,EAAE,KAAK,CAAC,SAAS;YAC1B,IAAI,EAAE,KAAK,CAAC,IAAI;YAChB,GAAG,CAAC,KAAK,CAAC,UAAU,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,UAAU,EAAE,KAAK,CAAC,UAAU,EAAE,CAAC;SAC3E,CAAC,CAAC,CAAC;IACL,CAAC;IAED,WAAW,CAAC,KAAgB;QAC3B,MAAM,KAAK,GAAG,KAAK,CAAC,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC,iBAAiB,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC;QAC1G,MAAM,OAAO,GAAY,EAAE,CAAC;QAC5B,MAAM,UAAU,GAAG,KAAK,CAAC,KAAK,KAAK,MAAM,CAAC;QAC1C,IAAI,KAAK,GAAG,UAAU,CAAC,CAAC,CAAC,IAAI,CAAC,YAAY,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QAC1D,OAAO,KAAK,IAAI,CAAC,IAAI,KAAK,GAAG,IAAI,CAAC,YAAY,CAAC,MAAM,IAAI,OAAO,CAAC,MAAM,GAAG,KAAK,EAAE,CAAC;YACjF,MAAM,KAAK,GAAG,IAAI,CAAC,YAAY,CAAC,KAAK,CAAE,CAAC;YACxC,IACC,CAAC,KAAK,CAAC,IAAI,KAAK,SAAS,IAAI,KAAK,CAAC,IAAI,KAAK,KAAK,CAAC,IAAI,CAAC;gBACvD,CAAC,KAAK,CAAC,UAAU,KAAK,SAAS,IAAI,KAAK,CAAC,UAAU,KAAK,KAAK,CAAC,UAAU,CAAC;gBACzE,CAAC,KAAK,CAAC,OAAO,KAAK,SAAS,IAAI,KAAK,CAAC,GAAG,IAAI,KAAK,CAAC,OAAO,CAAC;gBAC3D,CAAC,KAAK,CAAC,KAAK,KAAK,SAAS,IAAI,KAAK,CAAC,GAAG,IAAI,KAAK,CAAC,KAAK,CAAC,EACtD,CAAC;gBACF,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;YACrB,CAAC;YACD,KAAK,IAAI,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QAC9B,CAAC;QACD,OAAO,OAAO,CAAC;IAChB,CAAC;IAED,SAAS,CAAC,KAAgB;QACzB,MAAM,IAAI,GAAG,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,EAAE,CAAC;aACnC,MAAM,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,KAAK,CAAC,OAAO,KAAK,SAAS,IAAI,GAAG,CAAC,GAAG,IAAI,KAAK,CAAC,OAAO,CAAC;aACxE,MAAM,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,KAAK,CAAC,KAAK,KAAK,SAAS,IAAI,GAAG,CAAC,GAAG,IAAI,KAAK,CAAC,KAAK,CAAC;aACpE,IAAI,CAAC,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC,CAAC,KAAK,CAAC,KAAK,KAAK,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC;QAChG,OAAO,KAAK,CAAC,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC;IACnF,CAAC;IAED,QAAQ;QACP,OAAO,IAAI,CAAC,KAAK,CAAC;IACnB,CAAC;IAED,UAAU;QACT,OAAO,IAAI,CAAC,OAAO,CAAC;IACrB,CAAC;CACD","sourcesContent":["import { addUsage, emptyUsage } from \"../utils/usage.ts\";\nimport {\n\ttype CommittedListAppendWrite,\n\ttype CommittedValueSetWrite,\n\ttype CommittedWrite,\n\ttype PreparedCommit,\n\tprepareStorageCommit,\n\tvalidateCommittedWrites,\n} from \"./commit.ts\";\nimport { projectForkCurrentStateWrite, selectBranchFork } from \"./fork-policy.ts\";\n\nexport type {\n\tCommittedEntryWrite,\n\tCommittedListAppendWrite,\n\tCommittedListDeleteWrite,\n\tCommittedUsageWrite,\n\tCommittedValueDeleteWrite,\n\tCommittedValueSetWrite,\n\tCommittedWrite,\n\tPreparedCommit,\n} from \"./commit.ts\";\n\nimport type {\n\tEntry,\n\tEntryScan,\n\tEntryStructure,\n\tForkOptions,\n\tSessionStats,\n\tStorageBranchScan,\n\tUsageRow,\n\tUsageScan,\n\tWrite,\n} from \"./types.ts\";\nimport {\n\tbranchTip,\n\ttype ListElement,\n\ttype ListReadOptions,\n\tlaneConfig,\n\tlaneState,\n\tlist,\n\tresolveListReadOptions,\n\ttype StoredValue,\n\ttype Value,\n\ttype ValueList,\n\tvalue,\n} from \"./values.ts\";\n\ninterface StoredListSnapshot {\n\taddress: ValueList<unknown>;\n\telements: ListElement<unknown>[];\n}\n\ntype MemoryForkPlan =\n\t| { scope: \"tree\" }\n\t| { scope: \"branch\"; branch: string; destinationTip: string | null; entryIds: Set<string> };\n\nfunction physicalKey(namespace: string, key: string): string {\n\treturn `${namespace}\\u0000${key}`;\n}\n\nfunction compareKeys(left: string, right: string): number {\n\tconst leftCodePoints = Array.from(left, (character) => character.codePointAt(0)!);\n\tconst rightCodePoints = Array.from(right, (character) => character.codePointAt(0)!);\n\tconst length = Math.min(leftCodePoints.length, rightCodePoints.length);\n\tfor (let index = 0; index < length; index++) {\n\t\tconst difference = leftCodePoints[index]! - rightCodePoints[index]!;\n\t\tif (difference !== 0) return difference;\n\t}\n\treturn leftCodePoints.length - rightCodePoints.length;\n}\n\n/**\n * Complete materialized session state for MemoryStorage and JsonlStorage.\n *\n * This is intentionally unsuitable for database backends and long-running sessions that may not fit in memory.\n * Those backends should query indexed durable state and update durable aggregates within each commit transaction.\n */\nexport class InMemoryStorageState {\n\tprivate readonly entries: Map<string, Entry>;\n\tprivate readonly entriesBySeq: Entry[];\n\tprivate readonly scalarValues: Map<string, StoredValue<unknown>>;\n\tprivate readonly listValues: Map<string, StoredListSnapshot>;\n\tprivate readonly usage: Map<string, UsageRow>;\n\tprivate stats: SessionStats;\n\tprivate nextSeq: number;\n\n\tconstructor() {\n\t\tthis.entries = new Map();\n\t\tthis.entriesBySeq = [];\n\t\tthis.scalarValues = new Map();\n\t\tthis.listValues = new Map();\n\t\tthis.usage = new Map();\n\t\tthis.stats = { messageCount: 0, usage: emptyUsage() };\n\t\tthis.nextSeq = 1;\n\t}\n\n\tprepareCommit(writes: Write[], timestamp: number): PreparedCommit {\n\t\tconst prepared = prepareStorageCommit(writes, this.nextSeq, timestamp);\n\t\tthis.validateCommitted(prepared.writes);\n\t\treturn prepared;\n\t}\n\n\tvalidateCommitted(writes: readonly CommittedWrite[]): void {\n\t\tvalidateCommittedWrites(writes, this.nextSeq, {\n\t\t\thasEntryOrUsageId: (id) => this.entries.has(id) || this.usage.has(id),\n\t\t\thasEntryId: (id) => this.entries.has(id),\n\t\t});\n\t}\n\n\t/** Apply writes already accepted by validateCommitted() and return the post-apply totals. */\n\tapplyValidated(writes: readonly CommittedWrite[]): SessionStats {\n\t\tfor (const write of writes) {\n\t\t\tswitch (write.kind) {\n\t\t\t\tcase \"entry\": {\n\t\t\t\t\tconst { kind: _kind, ...entry } = write;\n\t\t\t\t\tthis.entries.set(entry.id, entry);\n\t\t\t\t\tthis.entriesBySeq.push(entry);\n\t\t\t\t\tif (entry.type === \"message\") this.stats = { ...this.stats, messageCount: this.stats.messageCount + 1 };\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tcase \"usage\": {\n\t\t\t\t\tconst { kind: _kind, ...row } = write;\n\t\t\t\t\tthis.usage.set(row.id, row);\n\t\t\t\t\tthis.stats = { ...this.stats, usage: addUsage(this.stats.usage, row.usage) };\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tcase \"value\":\n\t\t\t\t\tif (write.op === \"delete\") this.scalarValues.delete(physicalKey(write.namespace, write.key));\n\t\t\t\t\telse this.applyValueSetOrListAppend(write);\n\t\t\t\t\tbreak;\n\t\t\t\tcase \"list\":\n\t\t\t\t\tif (write.op === \"delete\") this.listValues.delete(physicalKey(write.namespace, write.key));\n\t\t\t\t\telse this.applyValueSetOrListAppend(write);\n\t\t\t\t\tbreak;\n\t\t\t}\n\t\t\tthis.nextSeq = write.seq + 1;\n\t\t}\n\t\treturn this.stats;\n\t}\n\n\tcreateFork(options: ForkOptions): InMemoryStorageState {\n\t\tconst plan = this.selectForkPlan(options);\n\n\t\tconst isEntryCopied = (entryId: string): boolean => {\n\t\t\tif (plan.scope === \"tree\") return true;\n\t\t\treturn plan.entryIds.has(entryId);\n\t\t};\n\t\tconst destination = new InMemoryStorageState();\n\t\tlet messageCount = 0;\n\t\tfor (const entry of this.entriesBySeq) {\n\t\t\tif (!isEntryCopied(entry.id)) continue;\n\t\t\tdestination.entries.set(entry.id, entry);\n\t\t\tdestination.entriesBySeq.push(entry);\n\t\t\tif (entry.type === \"message\") messageCount++;\n\t\t}\n\t\tdestination.stats = { ...destination.stats, messageCount };\n\n\t\tfor (const stored of this.scalarValues.values()) {\n\t\t\tconst projected = projectForkCurrentStateWrite(\n\t\t\t\t{\n\t\t\t\t\tkind: \"value\",\n\t\t\t\t\top: \"set\",\n\t\t\t\t\tseq: stored.seq,\n\t\t\t\t\tnamespace: stored.address.namespace,\n\t\t\t\t\tkey: stored.address.key,\n\t\t\t\t\tvalue: stored.value,\n\t\t\t\t},\n\t\t\t\tplan,\n\t\t\t\tisEntryCopied,\n\t\t\t);\n\t\t\tif (projected !== undefined) destination.applyValueSetOrListAppend(projected);\n\t\t}\n\n\t\tfor (const stored of this.listValues.values()) {\n\t\t\tfor (const element of stored.elements) {\n\t\t\t\tconst projected = projectForkCurrentStateWrite(\n\t\t\t\t\t{\n\t\t\t\t\t\tkind: \"list\",\n\t\t\t\t\t\top: \"append\",\n\t\t\t\t\t\tseq: element.seq,\n\t\t\t\t\t\tnamespace: stored.address.namespace,\n\t\t\t\t\t\tkey: stored.address.key,\n\t\t\t\t\t\tvalue: element.value,\n\t\t\t\t\t},\n\t\t\t\t\tplan,\n\t\t\t\t\tisEntryCopied,\n\t\t\t\t);\n\t\t\t\tif (projected !== undefined) destination.applyValueSetOrListAppend(projected);\n\t\t\t}\n\t\t}\n\t\tdestination.nextSeq = this.nextSeq;\n\t\treturn destination;\n\t}\n\n\tprivate selectForkPlan(options: ForkOptions): MemoryForkPlan {\n\t\tif (options.scope === \"tree\") return { scope: \"tree\" };\n\n\t\tconst entryIds = new Set<string>();\n\t\tconst plan = selectBranchFork(options, {\n\t\t\ttip: this.getValue(branchTip(options.branch))?.value,\n\t\t\tgetParent: (entryId) => this.entries.get(entryId)?.parentId,\n\t\t\tselectEntry: (entryId) => entryIds.add(entryId),\n\t\t});\n\t\tif (\n\t\t\tthis.getValue(laneConfig(options.branch)) === undefined ||\n\t\t\tthis.getValue(laneState(options.branch)) === undefined\n\t\t) {\n\t\t\tthrow new Error(`Source branch ${JSON.stringify(options.branch)} is not a configured AgentLane`);\n\t\t}\n\t\treturn { ...plan, entryIds };\n\t}\n\n\tprivate applyValueSetOrListAppend(write: CommittedValueSetWrite | CommittedListAppendWrite): void {\n\t\tconst key = physicalKey(write.namespace, write.key);\n\t\tif (write.kind === \"value\") {\n\t\t\tthis.scalarValues.set(key, {\n\t\t\t\taddress: value<unknown>(write.namespace, write.key),\n\t\t\t\tvalue: write.value,\n\t\t\t\tseq: write.seq,\n\t\t\t});\n\t\t\treturn;\n\t\t}\n\n\t\tconst element = { seq: write.seq, value: write.value };\n\t\tconst stored = this.listValues.get(key);\n\t\tif (stored === undefined) {\n\t\t\tthis.listValues.set(key, {\n\t\t\t\taddress: list<unknown>(write.namespace, write.key),\n\t\t\t\telements: [element],\n\t\t\t});\n\t\t} else {\n\t\t\tstored.elements.push(element);\n\t\t}\n\t}\n\n\tadvanceNextSeq(nextSeq: number): void {\n\t\tif (!Number.isSafeInteger(nextSeq) || nextSeq < 1) {\n\t\t\tthrow new Error(`Invalid storage sequence high-water mark: ${nextSeq}`);\n\t\t}\n\t\tthis.nextSeq = Math.max(this.nextSeq, nextSeq);\n\t}\n\n\tgetEntries(ids: readonly string[]): Map<string, Entry> {\n\t\tconst found = new Map<string, Entry>();\n\t\tfor (const id of ids) {\n\t\t\tconst entry = this.entries.get(id);\n\t\t\tif (entry !== undefined) found.set(id, entry);\n\t\t}\n\t\treturn found;\n\t}\n\n\tgetValue<T>(address: Value<T>): StoredValue<T> | undefined {\n\t\treturn this.scalarValues.get(physicalKey(address.namespace, address.key)) as StoredValue<T> | undefined;\n\t}\n\n\tscanValues<T>(prefix: Value<T>): StoredValue<T>[] {\n\t\treturn [...this.scalarValues.values()]\n\t\t\t.filter((stored) => stored.address.namespace === prefix.namespace && stored.address.key.startsWith(prefix.key))\n\t\t\t.sort((left, right) => compareKeys(left.address.key, right.address.key)) as StoredValue<T>[];\n\t}\n\n\treadList<T>(address: ValueList<T>, options?: ListReadOptions): ListElement<T>[] {\n\t\tconst resolved = resolveListReadOptions(options);\n\t\tconst elements = this.listValues.get(physicalKey(address.namespace, address.key))?.elements ?? [];\n\t\tconst filtered = elements.filter((element) => {\n\t\t\tif (resolved.cursor === undefined) return true;\n\t\t\treturn resolved.order === \"asc\" ? element.seq > resolved.cursor.seq : element.seq < resolved.cursor.seq;\n\t\t});\n\t\tconst ordered = resolved.order === \"asc\" ? filtered : [...filtered].reverse();\n\t\treturn ordered.slice(0, resolved.limit) as ListElement<T>[];\n\t}\n\n\tscanBranch(query: StorageBranchScan): Entry[] {\n\t\tconst start = this.entries.get(query.start);\n\t\tif (start === undefined) throw new Error(`Unknown branch start: ${query.start}`);\n\n\t\tconst path: Entry[] = [];\n\t\tlet entry: Entry | undefined = start;\n\t\twhile (entry !== undefined) {\n\t\t\tpath.push(entry);\n\t\t\tif (entry.parentId === null) break;\n\t\t\tentry = this.entries.get(entry.parentId);\n\t\t\tif (entry === undefined) throw new Error(\"Corrupt branch: missing parent\");\n\t\t}\n\t\tif (query.order === \"oldestFirst\") path.reverse();\n\n\t\tconst stopped: Entry[] = [];\n\t\tfor (const candidate of path) {\n\t\t\tstopped.push(candidate);\n\t\t\tif (candidate.id === query.stopAtId || candidate.type === query.stopAtType) break;\n\t\t}\n\t\tconst filtered = stopped\n\t\t\t.filter((candidate) => query.type === undefined || candidate.type === query.type)\n\t\t\t.filter((candidate) => query.customType === undefined || candidate.customType === query.customType)\n\t\t\t.filter(\n\t\t\t\t(candidate) =>\n\t\t\t\t\tquery.cursor === undefined ||\n\t\t\t\t\t(query.order === \"oldestFirst\" ? candidate.seq > query.cursor.seq : candidate.seq < query.cursor.seq),\n\t\t\t);\n\t\treturn query.limit === undefined ? filtered : filtered.slice(0, Math.max(0, query.limit));\n\t}\n\n\tscanBranchStructure(query: StorageBranchScan): EntryStructure[] {\n\t\treturn this.scanBranch(query).map((entry) => ({\n\t\t\tid: entry.id,\n\t\t\tparentId: entry.parentId,\n\t\t\tseq: entry.seq,\n\t\t\ttimestamp: entry.timestamp,\n\t\t\ttype: entry.type,\n\t\t\t...(entry.customType === undefined ? {} : { customType: entry.customType }),\n\t\t}));\n\t}\n\n\tscanEntries(query: EntryScan): Entry[] {\n\t\tconst limit = query.limit === undefined ? Number.POSITIVE_INFINITY : Math.max(0, Math.trunc(query.limit));\n\t\tconst entries: Entry[] = [];\n\t\tconst descending = query.order === \"desc\";\n\t\tlet index = descending ? this.entriesBySeq.length - 1 : 0;\n\t\twhile (index >= 0 && index < this.entriesBySeq.length && entries.length < limit) {\n\t\t\tconst entry = this.entriesBySeq[index]!;\n\t\t\tif (\n\t\t\t\t(query.type === undefined || entry.type === query.type) &&\n\t\t\t\t(query.customType === undefined || entry.customType === query.customType) &&\n\t\t\t\t(query.fromSeq === undefined || entry.seq >= query.fromSeq) &&\n\t\t\t\t(query.toSeq === undefined || entry.seq <= query.toSeq)\n\t\t\t) {\n\t\t\t\tentries.push(entry);\n\t\t\t}\n\t\t\tindex += descending ? -1 : 1;\n\t\t}\n\t\treturn entries;\n\t}\n\n\tscanUsage(query: UsageScan): UsageRow[] {\n\t\tconst rows = [...this.usage.values()]\n\t\t\t.filter((row) => query.fromSeq === undefined || row.seq >= query.fromSeq)\n\t\t\t.filter((row) => query.toSeq === undefined || row.seq <= query.toSeq)\n\t\t\t.sort((left, right) => (query.order === \"desc\" ? right.seq - left.seq : left.seq - right.seq));\n\t\treturn query.limit === undefined ? rows : rows.slice(0, Math.max(0, query.limit));\n\t}\n\n\tgetStats(): SessionStats {\n\t\treturn this.stats;\n\t}\n\n\tgetNextSeq(): number {\n\t\treturn this.nextSeq;\n\t}\n}\n"]}
@@ -1,7 +1,11 @@
1
- export * from "./context.ts";
2
- export type { JsonlSessionCreateOptions, JsonlSessionListOptions, JsonlSessionMetadata, JsonlSessionRepoFileSystem, JsonlSessionRepoOptions, JsonlV4Header, } from "./jsonl.ts";
3
- export { JsonlSessionRepo } from "./jsonl.ts";
4
- export * from "./memory.ts";
5
- export * from "./session.ts";
1
+ export type { CommittedEntryWrite, CommittedListAppendWrite, CommittedListDeleteWrite, CommittedUsageWrite, CommittedValueDeleteWrite, CommittedValueSetWrite, CommittedWrite, CommitValidationState, PreparedCommit, } from "./commit.ts";
2
+ export { commitWrite, insertEntry, insertUsage, prepareStorageCommit, validateCommittedWrites } from "./commit.ts";
3
+ export { createForkSnapshot, type ForkSourceSnapshot } from "./fork.ts";
4
+ export { type ForkCurrentStatePlan, projectForkCurrentStateWrite } from "./fork-policy.ts";
5
+ export { JSONL_STORAGE_VERSION, type JsonlSessionCreateOptions, type JsonlSessionListOptions, type JsonlSessionMetadata, JsonlSessionRepo, type JsonlSessionRepoOptions, } from "./jsonl/index.ts";
6
+ export type { MemorySessionRepoOptions } from "./memory.ts";
7
+ export { MemorySessionRepo } from "./memory.ts";
8
+ export { SessionBranchExistsError, SessionInvalidBranchError, SessionInvariantError, SessionPendingAssistantMessageError, SessionUnknownTargetError, StorageBackedSession, type StorageBackedSessionOptions, } from "./session.ts";
6
9
  export * from "./types.ts";
10
+ export * from "./values.ts";
7
11
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/harness/session/index.ts"],"names":[],"mappings":"AAAA,cAAc,cAAc,CAAC;AAC7B,YAAY,EACX,yBAAyB,EACzB,uBAAuB,EACvB,oBAAoB,EACpB,0BAA0B,EAC1B,uBAAuB,EACvB,aAAa,GACb,MAAM,YAAY,CAAC;AACpB,OAAO,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAC9C,cAAc,aAAa,CAAC;AAC5B,cAAc,cAAc,CAAC;AAC7B,cAAc,YAAY,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/harness/session/index.ts"],"names":[],"mappings":"AAAA,YAAY,EACX,mBAAmB,EACnB,wBAAwB,EACxB,wBAAwB,EACxB,mBAAmB,EACnB,yBAAyB,EACzB,sBAAsB,EACtB,cAAc,EACd,qBAAqB,EACrB,cAAc,GACd,MAAM,aAAa,CAAC;AACrB,OAAO,EAAE,WAAW,EAAE,WAAW,EAAE,WAAW,EAAE,oBAAoB,EAAE,uBAAuB,EAAE,MAAM,aAAa,CAAC;AACnH,OAAO,EAAE,kBAAkB,EAAE,KAAK,kBAAkB,EAAE,MAAM,WAAW,CAAC;AACxE,OAAO,EAAE,KAAK,oBAAoB,EAAE,4BAA4B,EAAE,MAAM,kBAAkB,CAAC;AAC3F,OAAO,EACN,qBAAqB,EACrB,KAAK,yBAAyB,EAC9B,KAAK,uBAAuB,EAC5B,KAAK,oBAAoB,EACzB,gBAAgB,EAChB,KAAK,uBAAuB,GAC5B,MAAM,kBAAkB,CAAC;AAC1B,YAAY,EAAE,wBAAwB,EAAE,MAAM,aAAa,CAAC;AAC5D,OAAO,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAChD,OAAO,EACN,wBAAwB,EACxB,yBAAyB,EACzB,qBAAqB,EACrB,mCAAmC,EACnC,yBAAyB,EACzB,oBAAoB,EACpB,KAAK,2BAA2B,GAChC,MAAM,cAAc,CAAC;AACtB,cAAc,YAAY,CAAC;AAC3B,cAAc,aAAa,CAAC"}
@@ -1,6 +1,9 @@
1
- export * from "./context.js";
2
- export { JsonlSessionRepo } from "./jsonl.js";
3
- export * from "./memory.js";
4
- export * from "./session.js";
1
+ export { commitWrite, insertEntry, insertUsage, prepareStorageCommit, validateCommittedWrites } from "./commit.js";
2
+ export { createForkSnapshot } from "./fork.js";
3
+ export { projectForkCurrentStateWrite } from "./fork-policy.js";
4
+ export { JSONL_STORAGE_VERSION, JsonlSessionRepo, } from "./jsonl/index.js";
5
+ export { MemorySessionRepo } from "./memory.js";
6
+ export { SessionBranchExistsError, SessionInvalidBranchError, SessionInvariantError, SessionPendingAssistantMessageError, SessionUnknownTargetError, StorageBackedSession, } from "./session.js";
5
7
  export * from "./types.js";
8
+ export * from "./values.js";
6
9
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/harness/session/index.ts"],"names":[],"mappings":"AAAA,cAAc,cAAc,CAAC;AAS7B,OAAO,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAC9C,cAAc,aAAa,CAAC;AAC5B,cAAc,cAAc,CAAC;AAC7B,cAAc,YAAY,CAAC","sourcesContent":["export * from \"./context.ts\";\nexport type {\n\tJsonlSessionCreateOptions,\n\tJsonlSessionListOptions,\n\tJsonlSessionMetadata,\n\tJsonlSessionRepoFileSystem,\n\tJsonlSessionRepoOptions,\n\tJsonlV4Header,\n} from \"./jsonl.ts\";\nexport { JsonlSessionRepo } from \"./jsonl.ts\";\nexport * from \"./memory.ts\";\nexport * from \"./session.ts\";\nexport * from \"./types.ts\";\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/harness/session/index.ts"],"names":[],"mappings":"AAWA,OAAO,EAAE,WAAW,EAAE,WAAW,EAAE,WAAW,EAAE,oBAAoB,EAAE,uBAAuB,EAAE,MAAM,aAAa,CAAC;AACnH,OAAO,EAAE,kBAAkB,EAA2B,MAAM,WAAW,CAAC;AACxE,OAAO,EAA6B,4BAA4B,EAAE,MAAM,kBAAkB,CAAC;AAC3F,OAAO,EACN,qBAAqB,EAIrB,gBAAgB,GAEhB,MAAM,kBAAkB,CAAC;AAE1B,OAAO,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAChD,OAAO,EACN,wBAAwB,EACxB,yBAAyB,EACzB,qBAAqB,EACrB,mCAAmC,EACnC,yBAAyB,EACzB,oBAAoB,GAEpB,MAAM,cAAc,CAAC;AACtB,cAAc,YAAY,CAAC;AAC3B,cAAc,aAAa,CAAC","sourcesContent":["export type {\n\tCommittedEntryWrite,\n\tCommittedListAppendWrite,\n\tCommittedListDeleteWrite,\n\tCommittedUsageWrite,\n\tCommittedValueDeleteWrite,\n\tCommittedValueSetWrite,\n\tCommittedWrite,\n\tCommitValidationState,\n\tPreparedCommit,\n} from \"./commit.ts\";\nexport { commitWrite, insertEntry, insertUsage, prepareStorageCommit, validateCommittedWrites } from \"./commit.ts\";\nexport { createForkSnapshot, type ForkSourceSnapshot } from \"./fork.ts\";\nexport { type ForkCurrentStatePlan, projectForkCurrentStateWrite } from \"./fork-policy.ts\";\nexport {\n\tJSONL_STORAGE_VERSION,\n\ttype JsonlSessionCreateOptions,\n\ttype JsonlSessionListOptions,\n\ttype JsonlSessionMetadata,\n\tJsonlSessionRepo,\n\ttype JsonlSessionRepoOptions,\n} from \"./jsonl/index.ts\";\nexport type { MemorySessionRepoOptions } from \"./memory.ts\";\nexport { MemorySessionRepo } from \"./memory.ts\";\nexport {\n\tSessionBranchExistsError,\n\tSessionInvalidBranchError,\n\tSessionInvariantError,\n\tSessionPendingAssistantMessageError,\n\tSessionUnknownTargetError,\n\tStorageBackedSession,\n\ttype StorageBackedSessionOptions,\n} from \"./session.ts\";\nexport * from \"./types.ts\";\nexport * from \"./values.ts\";\n"]}
@@ -1,10 +1,21 @@
1
1
  import { type Result } from "../../types.ts";
2
- import type { SessionMutation } from "../state.ts";
3
- import { JsonlDecodeError } from "./errors.ts";
4
- import type { JsonlSessionMetadata, JsonlV4Header } from "./types.ts";
5
- export declare function parseHeader(line: string): Result<JsonlV4Header, JsonlDecodeError>;
6
- export declare function encodeHeader(header: JsonlV4Header): string;
7
- export declare function metadataFromHeader(header: JsonlV4Header, path: string, modifiedAt: number): JsonlSessionMetadata;
8
- export declare function parseMutation(line: string): Result<SessionMutation, JsonlDecodeError>;
9
- export declare function encodeMutation(mutation: SessionMutation): string;
2
+ import { type JsonlStorageHeader } from "./types.ts";
3
+ export interface LegacyV3SessionHeader {
4
+ type: "session";
5
+ version: 3;
6
+ id: string;
7
+ timestamp: string;
8
+ cwd: string;
9
+ parentSession?: string;
10
+ }
11
+ export declare function isLegacyV3SessionHeader(value: unknown): value is LegacyV3SessionHeader;
12
+ export declare function isJsonlStorageHeader(value: unknown): value is JsonlStorageHeader;
13
+ export type JsonlParsedSessionHeader = {
14
+ format: "v4";
15
+ header: JsonlStorageHeader;
16
+ } | {
17
+ format: "v3-legacy";
18
+ header: LegacyV3SessionHeader;
19
+ };
20
+ export declare function parseJsonlSessionHeader(line: string): Result<JsonlParsedSessionHeader, Error>;
10
21
  //# sourceMappingURL=codec.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"codec.d.ts","sourceRoot":"","sources":["../../../../src/harness/session/jsonl/codec.ts"],"names":[],"mappings":"AAAA,OAAO,EAAW,KAAK,MAAM,EAAE,MAAM,gBAAgB,CAAC;AACtD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAEnD,OAAO,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAC/C,OAAO,KAAK,EAAE,oBAAoB,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAkGtE,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAAC,aAAa,EAAE,gBAAgB,CAAC,CAOjF;AAED,wBAAgB,YAAY,CAAC,MAAM,EAAE,aAAa,GAAG,MAAM,CAE1D;AAED,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,aAAa,EAAE,IAAI,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,oBAAoB,CAchH;AA2FD,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAAC,eAAe,EAAE,gBAAgB,CAAC,CAOrF;AAED,wBAAgB,cAAc,CAAC,QAAQ,EAAE,eAAe,GAAG,MAAM,CAWhE"}
1
+ {"version":3,"file":"codec.d.ts","sourceRoot":"","sources":["../../../../src/harness/session/jsonl/codec.ts"],"names":[],"mappings":"AAAA,OAAO,EAAW,KAAK,MAAM,EAAE,MAAM,gBAAgB,CAAC;AACtD,OAAO,EAAwB,KAAK,kBAAkB,EAAE,MAAM,YAAY,CAAC;AAE3E,MAAM,WAAW,qBAAqB;IACrC,IAAI,EAAE,SAAS,CAAC;IAChB,OAAO,EAAE,CAAC,CAAC;IACX,EAAE,EAAE,MAAM,CAAC;IACX,SAAS,EAAE,MAAM,CAAC;IAClB,GAAG,EAAE,MAAM,CAAC;IACZ,aAAa,CAAC,EAAE,MAAM,CAAC;CACvB;AAUD,wBAAgB,uBAAuB,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,qBAAqB,CAWtF;AAED,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,kBAAkB,CAahF;AAED,MAAM,MAAM,wBAAwB,GACjC;IAAE,MAAM,EAAE,IAAI,CAAC;IAAC,MAAM,EAAE,kBAAkB,CAAA;CAAE,GAC5C;IAAE,MAAM,EAAE,WAAW,CAAC;IAAC,MAAM,EAAE,qBAAqB,CAAA;CAAE,CAAC;AAE1D,wBAAgB,uBAAuB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAAC,wBAAwB,EAAE,KAAK,CAAC,CAU7F"}