@draht/agent-core 2026.10.20 → 2026.10.23-1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/agent-loop.d.ts +6 -1
- package/dist/agent-loop.d.ts.map +1 -1
- package/dist/agent-loop.js +16 -2
- package/dist/agent-loop.js.map +1 -1
- package/dist/agent.d.ts +8 -1
- package/dist/agent.d.ts.map +1 -1
- package/dist/agent.js +4 -0
- package/dist/agent.js.map +1 -1
- package/dist/index.d.ts +0 -22
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +0 -20
- package/dist/index.js.map +1 -1
- package/dist/proxy.d.ts +2 -5
- package/dist/proxy.d.ts.map +1 -1
- package/dist/proxy.js +2 -14
- package/dist/proxy.js.map +1 -1
- package/dist/types.d.ts +4 -0
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js.map +1 -1
- package/package.json +4 -47
- package/dist/harness/agent-harness.d.ts +0 -716
- package/dist/harness/agent-harness.d.ts.map +0 -1
- package/dist/harness/agent-harness.js +0 -6
- package/dist/harness/agent-harness.js.map +0 -1
- package/dist/harness/compaction/branch-summarization.d.ts +0 -68
- package/dist/harness/compaction/branch-summarization.d.ts.map +0 -1
- package/dist/harness/compaction/branch-summarization.js +0 -176
- package/dist/harness/compaction/branch-summarization.js.map +0 -1
- package/dist/harness/compaction/compaction.d.ts +0 -126
- package/dist/harness/compaction/compaction.d.ts.map +0 -1
- package/dist/harness/compaction/compaction.js +0 -561
- package/dist/harness/compaction/compaction.js.map +0 -1
- package/dist/harness/compaction/utils.d.ts +0 -28
- package/dist/harness/compaction/utils.d.ts.map +0 -1
- package/dist/harness/compaction/utils.js +0 -123
- package/dist/harness/compaction/utils.js.map +0 -1
- package/dist/harness/config.d.ts +0 -9
- package/dist/harness/config.d.ts.map +0 -1
- package/dist/harness/config.js +0 -35
- package/dist/harness/config.js.map +0 -1
- package/dist/harness/context.d.ts +0 -9
- package/dist/harness/context.d.ts.map +0 -1
- package/dist/harness/context.js +0 -13
- package/dist/harness/context.js.map +0 -1
- package/dist/harness/env/nodejs.d.ts +0 -43
- package/dist/harness/env/nodejs.d.ts.map +0 -1
- package/dist/harness/env/nodejs.js +0 -865
- package/dist/harness/env/nodejs.js.map +0 -1
- package/dist/harness/events.d.ts +0 -24
- package/dist/harness/events.d.ts.map +0 -1
- package/dist/harness/events.js +0 -233
- package/dist/harness/events.js.map +0 -1
- package/dist/harness/execution/assistant.d.ts +0 -42
- package/dist/harness/execution/assistant.d.ts.map +0 -1
- package/dist/harness/execution/assistant.js +0 -82
- package/dist/harness/execution/assistant.js.map +0 -1
- package/dist/harness/execution/effect-gate.d.ts +0 -22
- package/dist/harness/execution/effect-gate.d.ts.map +0 -1
- package/dist/harness/execution/effect-gate.js +0 -49
- package/dist/harness/execution/effect-gate.js.map +0 -1
- package/dist/harness/execution/tools.d.ts +0 -67
- package/dist/harness/execution/tools.d.ts.map +0 -1
- package/dist/harness/execution/tools.js +0 -119
- package/dist/harness/execution/tools.js.map +0 -1
- package/dist/harness/execution-env.d.ts +0 -4
- package/dist/harness/execution-env.d.ts.map +0 -1
- package/dist/harness/execution-env.js +0 -3
- package/dist/harness/execution-env.js.map +0 -1
- package/dist/harness/hooks.d.ts +0 -38
- package/dist/harness/hooks.d.ts.map +0 -1
- package/dist/harness/hooks.js +0 -406
- package/dist/harness/hooks.js.map +0 -1
- package/dist/harness/messages.d.ts +0 -51
- package/dist/harness/messages.d.ts.map +0 -1
- package/dist/harness/messages.js +0 -103
- package/dist/harness/messages.js.map +0 -1
- package/dist/harness/pico3/bash.d.ts +0 -10
- package/dist/harness/pico3/bash.d.ts.map +0 -1
- package/dist/harness/pico3/bash.js +0 -25
- package/dist/harness/pico3/bash.js.map +0 -1
- package/dist/harness/pico3/bounded.d.ts +0 -21
- package/dist/harness/pico3/bounded.d.ts.map +0 -1
- package/dist/harness/pico3/bounded.js +0 -98
- package/dist/harness/pico3/bounded.js.map +0 -1
- package/dist/harness/pico3/chord.d.ts +0 -41
- package/dist/harness/pico3/chord.d.ts.map +0 -1
- package/dist/harness/pico3/chord.js +0 -147
- package/dist/harness/pico3/chord.js.map +0 -1
- package/dist/harness/pico3/context.d.ts +0 -16
- package/dist/harness/pico3/context.d.ts.map +0 -1
- package/dist/harness/pico3/context.js +0 -88
- package/dist/harness/pico3/context.js.map +0 -1
- package/dist/harness/pico3/harness.d.ts +0 -198
- package/dist/harness/pico3/harness.d.ts.map +0 -1
- package/dist/harness/pico3/harness.js +0 -654
- package/dist/harness/pico3/harness.js.map +0 -1
- package/dist/harness/pico3/hooks.d.ts +0 -10
- package/dist/harness/pico3/hooks.d.ts.map +0 -1
- package/dist/harness/pico3/hooks.js +0 -33
- package/dist/harness/pico3/hooks.js.map +0 -1
- package/dist/harness/pico3/index.d.ts +0 -19
- package/dist/harness/pico3/index.d.ts.map +0 -1
- package/dist/harness/pico3/index.js +0 -15
- package/dist/harness/pico3/index.js.map +0 -1
- package/dist/harness/pico3/jsonl.d.ts +0 -58
- package/dist/harness/pico3/jsonl.d.ts.map +0 -1
- package/dist/harness/pico3/jsonl.js +0 -325
- package/dist/harness/pico3/jsonl.js.map +0 -1
- package/dist/harness/pico3/kinds/collapse.d.ts +0 -49
- package/dist/harness/pico3/kinds/collapse.d.ts.map +0 -1
- package/dist/harness/pico3/kinds/collapse.js +0 -191
- package/dist/harness/pico3/kinds/collapse.js.map +0 -1
- package/dist/harness/pico3/kinds/entries.d.ts +0 -78
- package/dist/harness/pico3/kinds/entries.d.ts.map +0 -1
- package/dist/harness/pico3/kinds/entries.js +0 -13
- package/dist/harness/pico3/kinds/entries.js.map +0 -1
- package/dist/harness/pico3/kinds/frames.d.ts +0 -9
- package/dist/harness/pico3/kinds/frames.d.ts.map +0 -1
- package/dist/harness/pico3/kinds/frames.js +0 -75
- package/dist/harness/pico3/kinds/frames.js.map +0 -1
- package/dist/harness/pico3/kinds/generation.d.ts +0 -94
- package/dist/harness/pico3/kinds/generation.d.ts.map +0 -1
- package/dist/harness/pico3/kinds/generation.js +0 -504
- package/dist/harness/pico3/kinds/generation.js.map +0 -1
- package/dist/harness/pico3/kinds/job.d.ts +0 -44
- package/dist/harness/pico3/kinds/job.d.ts.map +0 -1
- package/dist/harness/pico3/kinds/job.js +0 -143
- package/dist/harness/pico3/kinds/job.js.map +0 -1
- package/dist/harness/pico3/kinds/plugin.d.ts +0 -15
- package/dist/harness/pico3/kinds/plugin.d.ts.map +0 -1
- package/dist/harness/pico3/kinds/plugin.js +0 -35
- package/dist/harness/pico3/kinds/plugin.js.map +0 -1
- package/dist/harness/pico3/kinds/post-tools.d.ts +0 -22
- package/dist/harness/pico3/kinds/post-tools.d.ts.map +0 -1
- package/dist/harness/pico3/kinds/post-tools.js +0 -145
- package/dist/harness/pico3/kinds/post-tools.js.map +0 -1
- package/dist/harness/pico3/kinds/task-api.d.ts +0 -3
- package/dist/harness/pico3/kinds/task-api.d.ts.map +0 -1
- package/dist/harness/pico3/kinds/task-api.js +0 -45
- package/dist/harness/pico3/kinds/task-api.js.map +0 -1
- package/dist/harness/pico3/kinds/tool.d.ts +0 -43
- package/dist/harness/pico3/kinds/tool.d.ts.map +0 -1
- package/dist/harness/pico3/kinds/tool.js +0 -373
- package/dist/harness/pico3/kinds/tool.js.map +0 -1
- package/dist/harness/pico3/legacy-tracker.d.ts +0 -11
- package/dist/harness/pico3/legacy-tracker.d.ts.map +0 -1
- package/dist/harness/pico3/legacy-tracker.js +0 -41
- package/dist/harness/pico3/legacy-tracker.js.map +0 -1
- package/dist/harness/pico3/membrane.d.ts +0 -23
- package/dist/harness/pico3/membrane.d.ts.map +0 -1
- package/dist/harness/pico3/membrane.js +0 -141
- package/dist/harness/pico3/membrane.js.map +0 -1
- package/dist/harness/pico3/memory.d.ts +0 -53
- package/dist/harness/pico3/memory.d.ts.map +0 -1
- package/dist/harness/pico3/memory.js +0 -264
- package/dist/harness/pico3/memory.js.map +0 -1
- package/dist/harness/pico3/scheduler.d.ts +0 -49
- package/dist/harness/pico3/scheduler.d.ts.map +0 -1
- package/dist/harness/pico3/scheduler.js +0 -438
- package/dist/harness/pico3/scheduler.js.map +0 -1
- package/dist/harness/pico3/session.d.ts +0 -264
- package/dist/harness/pico3/session.d.ts.map +0 -1
- package/dist/harness/pico3/session.js +0 -1348
- package/dist/harness/pico3/session.js.map +0 -1
- package/dist/harness/pico3/system.d.ts +0 -126
- package/dist/harness/pico3/system.d.ts.map +0 -1
- package/dist/harness/pico3/system.js +0 -244
- package/dist/harness/pico3/system.js.map +0 -1
- package/dist/harness/pico3/types.d.ts +0 -973
- package/dist/harness/pico3/types.d.ts.map +0 -1
- package/dist/harness/pico3/types.js +0 -106
- package/dist/harness/pico3/types.js.map +0 -1
- package/dist/harness/pico3/view.d.ts +0 -34
- package/dist/harness/pico3/view.d.ts.map +0 -1
- package/dist/harness/pico3/view.js +0 -411
- package/dist/harness/pico3/view.js.map +0 -1
- package/dist/harness/prompt-templates.d.ts +0 -49
- package/dist/harness/prompt-templates.d.ts.map +0 -1
- package/dist/harness/prompt-templates.js +0 -225
- package/dist/harness/prompt-templates.js.map +0 -1
- package/dist/harness/result.d.ts +0 -133
- package/dist/harness/result.d.ts.map +0 -1
- package/dist/harness/result.js +0 -81
- package/dist/harness/result.js.map +0 -1
- package/dist/harness/runtime/drive/boundary.d.ts +0 -28
- package/dist/harness/runtime/drive/boundary.d.ts.map +0 -1
- package/dist/harness/runtime/drive/boundary.js +0 -173
- package/dist/harness/runtime/drive/boundary.js.map +0 -1
- package/dist/harness/runtime/drive/checkpoint.d.ts +0 -8
- package/dist/harness/runtime/drive/checkpoint.d.ts.map +0 -1
- package/dist/harness/runtime/drive/checkpoint.js +0 -133
- package/dist/harness/runtime/drive/checkpoint.js.map +0 -1
- package/dist/harness/runtime/drive/deferred.d.ts +0 -15
- package/dist/harness/runtime/drive/deferred.d.ts.map +0 -1
- package/dist/harness/runtime/drive/deferred.js +0 -179
- package/dist/harness/runtime/drive/deferred.js.map +0 -1
- package/dist/harness/runtime/drive/generation.d.ts +0 -8
- package/dist/harness/runtime/drive/generation.d.ts.map +0 -1
- package/dist/harness/runtime/drive/generation.js +0 -205
- package/dist/harness/runtime/drive/generation.js.map +0 -1
- package/dist/harness/runtime/drive/reconcile.d.ts +0 -5
- package/dist/harness/runtime/drive/reconcile.d.ts.map +0 -1
- package/dist/harness/runtime/drive/reconcile.js +0 -140
- package/dist/harness/runtime/drive/reconcile.js.map +0 -1
- package/dist/harness/runtime/drive/recovery.d.ts +0 -8
- package/dist/harness/runtime/drive/recovery.d.ts.map +0 -1
- package/dist/harness/runtime/drive/recovery.js +0 -85
- package/dist/harness/runtime/drive/recovery.js.map +0 -1
- package/dist/harness/runtime/drive/response.d.ts +0 -23
- package/dist/harness/runtime/drive/response.d.ts.map +0 -1
- package/dist/harness/runtime/drive/response.js +0 -394
- package/dist/harness/runtime/drive/response.js.map +0 -1
- package/dist/harness/runtime/drive/retry.d.ts +0 -4
- package/dist/harness/runtime/drive/retry.d.ts.map +0 -1
- package/dist/harness/runtime/drive/retry.js +0 -34
- package/dist/harness/runtime/drive/retry.js.map +0 -1
- package/dist/harness/runtime/drive/structural.d.ts +0 -32
- package/dist/harness/runtime/drive/structural.d.ts.map +0 -1
- package/dist/harness/runtime/drive/structural.js +0 -929
- package/dist/harness/runtime/drive/structural.js.map +0 -1
- package/dist/harness/runtime/drive/terminal.d.ts +0 -7
- package/dist/harness/runtime/drive/terminal.d.ts.map +0 -1
- package/dist/harness/runtime/drive/terminal.js +0 -49
- package/dist/harness/runtime/drive/terminal.js.map +0 -1
- package/dist/harness/runtime/drive/tool-placement.d.ts +0 -14
- package/dist/harness/runtime/drive/tool-placement.d.ts.map +0 -1
- package/dist/harness/runtime/drive/tool-placement.js +0 -219
- package/dist/harness/runtime/drive/tool-placement.js.map +0 -1
- package/dist/harness/runtime/drive/tools.d.ts +0 -6
- package/dist/harness/runtime/drive/tools.d.ts.map +0 -1
- package/dist/harness/runtime/drive/tools.js +0 -449
- package/dist/harness/runtime/drive/tools.js.map +0 -1
- package/dist/harness/runtime/drive.d.ts +0 -6
- package/dist/harness/runtime/drive.d.ts.map +0 -1
- package/dist/harness/runtime/drive.js +0 -93
- package/dist/harness/runtime/drive.js.map +0 -1
- package/dist/harness/runtime/harness.d.ts +0 -59
- package/dist/harness/runtime/harness.d.ts.map +0 -1
- package/dist/harness/runtime/harness.js +0 -311
- package/dist/harness/runtime/harness.js.map +0 -1
- package/dist/harness/runtime/index.d.ts +0 -2
- package/dist/harness/runtime/index.d.ts.map +0 -1
- package/dist/harness/runtime/index.js +0 -2
- package/dist/harness/runtime/index.js.map +0 -1
- package/dist/harness/runtime/lane.d.ts +0 -118
- package/dist/harness/runtime/lane.d.ts.map +0 -1
- package/dist/harness/runtime/lane.js +0 -1575
- package/dist/harness/runtime/lane.js.map +0 -1
- package/dist/harness/runtime/progress.d.ts +0 -15
- package/dist/harness/runtime/progress.d.ts.map +0 -1
- package/dist/harness/runtime/progress.js +0 -66
- package/dist/harness/runtime/progress.js.map +0 -1
- package/dist/harness/runtime/reducer.d.ts +0 -5
- package/dist/harness/runtime/reducer.d.ts.map +0 -1
- package/dist/harness/runtime/reducer.js +0 -240
- package/dist/harness/runtime/reducer.js.map +0 -1
- package/dist/harness/runtime/restore.d.ts +0 -24
- package/dist/harness/runtime/restore.d.ts.map +0 -1
- package/dist/harness/runtime/restore.js +0 -117
- package/dist/harness/runtime/restore.js.map +0 -1
- package/dist/harness/runtime/transcript.d.ts +0 -21
- package/dist/harness/runtime/transcript.d.ts.map +0 -1
- package/dist/harness/runtime/transcript.js +0 -72
- package/dist/harness/runtime/transcript.js.map +0 -1
- package/dist/harness/runtime/types.d.ts +0 -105
- package/dist/harness/runtime/types.d.ts.map +0 -1
- package/dist/harness/runtime/types.js +0 -61
- package/dist/harness/runtime/types.js.map +0 -1
- package/dist/harness/session/commit.d.ts +0 -53
- package/dist/harness/session/commit.d.ts.map +0 -1
- package/dist/harness/session/commit.js +0 -57
- package/dist/harness/session/commit.js.map +0 -1
- package/dist/harness/session/context.d.ts +0 -10
- package/dist/harness/session/context.d.ts.map +0 -1
- package/dist/harness/session/context.js +0 -49
- package/dist/harness/session/context.js.map +0 -1
- package/dist/harness/session/fork-policy.d.ts +0 -21
- package/dist/harness/session/fork-policy.d.ts.map +0 -1
- package/dist/harness/session/fork-policy.js +0 -55
- package/dist/harness/session/fork-policy.js.map +0 -1
- package/dist/harness/session/fork.d.ts +0 -16
- package/dist/harness/session/fork.d.ts.map +0 -1
- package/dist/harness/session/fork.js +0 -79
- package/dist/harness/session/fork.js.map +0 -1
- package/dist/harness/session/in-memory-storage-state.d.ts +0 -39
- package/dist/harness/session/in-memory-storage-state.d.ts.map +0 -1
- package/dist/harness/session/in-memory-storage-state.js +0 -276
- package/dist/harness/session/in-memory-storage-state.js.map +0 -1
- package/dist/harness/session/index.d.ts +0 -11
- package/dist/harness/session/index.d.ts.map +0 -1
- package/dist/harness/session/index.js +0 -9
- package/dist/harness/session/index.js.map +0 -1
- package/dist/harness/session/jsonl/codec.d.ts +0 -21
- package/dist/harness/session/jsonl/codec.d.ts.map +0 -1
- package/dist/harness/session/jsonl/codec.js +0 -45
- package/dist/harness/session/jsonl/codec.js.map +0 -1
- package/dist/harness/session/jsonl/fork.d.ts +0 -38
- package/dist/harness/session/jsonl/fork.d.ts.map +0 -1
- package/dist/harness/session/jsonl/fork.js +0 -264
- package/dist/harness/session/jsonl/fork.js.map +0 -1
- package/dist/harness/session/jsonl/index.d.ts +0 -4
- package/dist/harness/session/jsonl/index.d.ts.map +0 -1
- package/dist/harness/session/jsonl/index.js +0 -4
- package/dist/harness/session/jsonl/index.js.map +0 -1
- package/dist/harness/session/jsonl/io.d.ts +0 -14
- package/dist/harness/session/jsonl/io.d.ts.map +0 -1
- package/dist/harness/session/jsonl/io.js +0 -86
- package/dist/harness/session/jsonl/io.js.map +0 -1
- package/dist/harness/session/jsonl/legacy-v3.d.ts +0 -44
- package/dist/harness/session/jsonl/legacy-v3.d.ts.map +0 -1
- package/dist/harness/session/jsonl/legacy-v3.js +0 -462
- package/dist/harness/session/jsonl/legacy-v3.js.map +0 -1
- package/dist/harness/session/jsonl/repo.d.ts +0 -35
- package/dist/harness/session/jsonl/repo.d.ts.map +0 -1
- package/dist/harness/session/jsonl/repo.js +0 -301
- package/dist/harness/session/jsonl/repo.js.map +0 -1
- package/dist/harness/session/jsonl/storage.d.ts +0 -41
- package/dist/harness/session/jsonl/storage.d.ts.map +0 -1
- package/dist/harness/session/jsonl/storage.js +0 -200
- package/dist/harness/session/jsonl/storage.js.map +0 -1
- package/dist/harness/session/jsonl/types.d.ts +0 -39
- package/dist/harness/session/jsonl/types.d.ts.map +0 -1
- package/dist/harness/session/jsonl/types.js +0 -3
- package/dist/harness/session/jsonl/types.js.map +0 -1
- package/dist/harness/session/memory.d.ts +0 -48
- package/dist/harness/session/memory.d.ts.map +0 -1
- package/dist/harness/session/memory.js +0 -369
- package/dist/harness/session/memory.js.map +0 -1
- package/dist/harness/session/mutation-line.d.ts +0 -8
- package/dist/harness/session/mutation-line.d.ts.map +0 -1
- package/dist/harness/session/mutation-line.js +0 -21
- package/dist/harness/session/mutation-line.js.map +0 -1
- package/dist/harness/session/session.d.ts +0 -82
- package/dist/harness/session/session.d.ts.map +0 -1
- package/dist/harness/session/session.js +0 -361
- package/dist/harness/session/session.js.map +0 -1
- package/dist/harness/session/testing/benchmark/datasets.d.ts +0 -12
- package/dist/harness/session/testing/benchmark/datasets.d.ts.map +0 -1
- package/dist/harness/session/testing/benchmark/datasets.js +0 -24
- package/dist/harness/session/testing/benchmark/datasets.js.map +0 -1
- package/dist/harness/session/testing/benchmark/session-repo.d.ts +0 -42
- package/dist/harness/session/testing/benchmark/session-repo.d.ts.map +0 -1
- package/dist/harness/session/testing/benchmark/session-repo.js +0 -127
- package/dist/harness/session/testing/benchmark/session-repo.js.map +0 -1
- package/dist/harness/session/testing/benchmark/storage.d.ts +0 -25
- package/dist/harness/session/testing/benchmark/storage.d.ts.map +0 -1
- package/dist/harness/session/testing/benchmark/storage.js +0 -114
- package/dist/harness/session/testing/benchmark/storage.js.map +0 -1
- package/dist/harness/session/testing/conformance/session-repo.d.ts +0 -23
- package/dist/harness/session/testing/conformance/session-repo.d.ts.map +0 -1
- package/dist/harness/session/testing/conformance/session-repo.js +0 -809
- package/dist/harness/session/testing/conformance/session-repo.js.map +0 -1
- package/dist/harness/session/testing/conformance/storage.d.ts +0 -4
- package/dist/harness/session/testing/conformance/storage.d.ts.map +0 -1
- package/dist/harness/session/testing/conformance/storage.js +0 -600
- package/dist/harness/session/testing/conformance/storage.js.map +0 -1
- package/dist/harness/session/testing/gating-storage.d.ts +0 -26
- package/dist/harness/session/testing/gating-storage.d.ts.map +0 -1
- package/dist/harness/session/testing/gating-storage.js +0 -100
- package/dist/harness/session/testing/gating-storage.js.map +0 -1
- package/dist/harness/session/testing/index.d.ts +0 -10
- package/dist/harness/session/testing/index.d.ts.map +0 -1
- package/dist/harness/session/testing/index.js +0 -9
- package/dist/harness/session/testing/index.js.map +0 -1
- package/dist/harness/session/testing/instrumented-storage.d.ts +0 -11
- package/dist/harness/session/testing/instrumented-storage.d.ts.map +0 -1
- package/dist/harness/session/testing/instrumented-storage.js +0 -16
- package/dist/harness/session/testing/instrumented-storage.js.map +0 -1
- package/dist/harness/session/testing/storage-decorator.d.ts +0 -20
- package/dist/harness/session/testing/storage-decorator.d.ts.map +0 -1
- package/dist/harness/session/testing/storage-decorator.js +0 -41
- package/dist/harness/session/testing/storage-decorator.js.map +0 -1
- package/dist/harness/session/testing/types.d.ts +0 -12
- package/dist/harness/session/testing/types.d.ts.map +0 -1
- package/dist/harness/session/testing/types.js +0 -2
- package/dist/harness/session/testing/types.js.map +0 -1
- package/dist/harness/session/types.d.ts +0 -512
- package/dist/harness/session/types.d.ts.map +0 -1
- package/dist/harness/session/types.js +0 -9
- package/dist/harness/session/types.js.map +0 -1
- package/dist/harness/session/values.d.ts +0 -95
- package/dist/harness/session/values.d.ts.map +0 -1
- package/dist/harness/session/values.js +0 -81
- package/dist/harness/session/values.js.map +0 -1
- package/dist/harness/skills.d.ts +0 -46
- package/dist/harness/skills.d.ts.map +0 -1
- package/dist/harness/skills.js +0 -326
- package/dist/harness/skills.js.map +0 -1
- package/dist/harness/system-prompt.d.ts +0 -3
- package/dist/harness/system-prompt.d.ts.map +0 -1
- package/dist/harness/system-prompt.js +0 -30
- package/dist/harness/system-prompt.js.map +0 -1
- package/dist/harness/telemetry.d.ts +0 -1242
- package/dist/harness/telemetry.d.ts.map +0 -1
- package/dist/harness/telemetry.js +0 -527
- package/dist/harness/telemetry.js.map +0 -1
- package/dist/harness/tools/bash.d.ts +0 -27
- package/dist/harness/tools/bash.d.ts.map +0 -1
- package/dist/harness/tools/bash.js +0 -105
- package/dist/harness/tools/bash.js.map +0 -1
- package/dist/harness/tools/edit-diff.d.ts +0 -89
- package/dist/harness/tools/edit-diff.d.ts.map +0 -1
- package/dist/harness/tools/edit-diff.js +0 -386
- package/dist/harness/tools/edit-diff.js.map +0 -1
- package/dist/harness/tools/edit.d.ts +0 -19
- package/dist/harness/tools/edit.d.ts.map +0 -1
- package/dist/harness/tools/edit.js +0 -108
- package/dist/harness/tools/edit.js.map +0 -1
- package/dist/harness/tools/file-mutation-queue.d.ts +0 -5
- package/dist/harness/tools/file-mutation-queue.d.ts.map +0 -1
- package/dist/harness/tools/file-mutation-queue.js +0 -46
- package/dist/harness/tools/file-mutation-queue.js.map +0 -1
- package/dist/harness/tools/image.d.ts +0 -3
- package/dist/harness/tools/image.d.ts.map +0 -1
- package/dist/harness/tools/image.js +0 -106
- package/dist/harness/tools/image.js.map +0 -1
- package/dist/harness/tools/index.d.ts +0 -6
- package/dist/harness/tools/index.d.ts.map +0 -1
- package/dist/harness/tools/index.js +0 -5
- package/dist/harness/tools/index.js.map +0 -1
- package/dist/harness/tools/path-utils.d.ts +0 -5
- package/dist/harness/tools/path-utils.d.ts.map +0 -1
- package/dist/harness/tools/path-utils.js +0 -26
- package/dist/harness/tools/path-utils.js.map +0 -1
- package/dist/harness/tools/read.d.ts +0 -35
- package/dist/harness/tools/read.d.ts.map +0 -1
- package/dist/harness/tools/read.js +0 -108
- package/dist/harness/tools/read.js.map +0 -1
- package/dist/harness/tools/tool-context.d.ts +0 -6
- package/dist/harness/tools/tool-context.d.ts.map +0 -1
- package/dist/harness/tools/tool-context.js +0 -2
- package/dist/harness/tools/tool-context.js.map +0 -1
- package/dist/harness/tools/write.d.ts +0 -11
- package/dist/harness/tools/write.d.ts.map +0 -1
- package/dist/harness/tools/write.js +0 -31
- package/dist/harness/tools/write.js.map +0 -1
- package/dist/harness/types.d.ts +0 -305
- package/dist/harness/types.d.ts.map +0 -1
- package/dist/harness/types.js +0 -75
- package/dist/harness/types.js.map +0 -1
- package/dist/harness/utils/adaptive-publisher.d.ts +0 -24
- package/dist/harness/utils/adaptive-publisher.d.ts.map +0 -1
- package/dist/harness/utils/adaptive-publisher.js +0 -79
- package/dist/harness/utils/adaptive-publisher.js.map +0 -1
- package/dist/harness/utils/output-capture.d.ts +0 -31
- package/dist/harness/utils/output-capture.d.ts.map +0 -1
- package/dist/harness/utils/output-capture.js +0 -217
- package/dist/harness/utils/output-capture.js.map +0 -1
- package/dist/harness/utils/shell-output.d.ts +0 -29
- package/dist/harness/utils/shell-output.d.ts.map +0 -1
- package/dist/harness/utils/shell-output.js +0 -71
- package/dist/harness/utils/shell-output.js.map +0 -1
- package/dist/harness/utils/truncate.d.ts +0 -71
- package/dist/harness/utils/truncate.d.ts.map +0 -1
- package/dist/harness/utils/truncate.js +0 -296
- package/dist/harness/utils/truncate.js.map +0 -1
- package/dist/harness/utils/usage.d.ts +0 -4
- package/dist/harness/utils/usage.d.ts.map +0 -1
- package/dist/harness/utils/usage.js +0 -33
- package/dist/harness/utils/usage.js.map +0 -1
- package/dist/node.d.ts +0 -3
- package/dist/node.d.ts.map +0 -1
- package/dist/node.js +0 -3
- package/dist/node.js.map +0 -1
- package/dist/search/index.d.ts +0 -29
- package/dist/search/index.d.ts.map +0 -1
- package/dist/search/index.js +0 -2
- package/dist/search/index.js.map +0 -1
|
@@ -1,301 +0,0 @@
|
|
|
1
|
-
import { uuidv7 } from "@draht/ai/utils/uuid";
|
|
2
|
-
import { StorageBackedSession } from "../session.js";
|
|
3
|
-
import { parseJsonlSessionHeader } from "./codec.js";
|
|
4
|
-
import { runJsonlFork } from "./fork.js";
|
|
5
|
-
import { fileValue } from "./io.js";
|
|
6
|
-
import { LegacyV3Source, metadataFromLegacyV3Header } from "./legacy-v3.js";
|
|
7
|
-
import { JsonlStorage } from "./storage.js";
|
|
8
|
-
import { JSONL_FORMAT_VERSION, JSONL_STORAGE_VERSION, } from "./types.js";
|
|
9
|
-
function metadataFromHeader(header, path, modifiedAt) {
|
|
10
|
-
return {
|
|
11
|
-
id: header.id,
|
|
12
|
-
createdAt: header.createdAt,
|
|
13
|
-
storageVersion: header.storageVersion,
|
|
14
|
-
cwd: header.cwd,
|
|
15
|
-
path,
|
|
16
|
-
modifiedAt,
|
|
17
|
-
...(header.parentSessionId === undefined ? {} : { parentSessionId: header.parentSessionId }),
|
|
18
|
-
...(header.legacyParentSessionPath === undefined
|
|
19
|
-
? {}
|
|
20
|
-
: { legacyParentSessionPath: header.legacyParentSessionPath }),
|
|
21
|
-
};
|
|
22
|
-
}
|
|
23
|
-
function sessionDirectoryName(cwd) {
|
|
24
|
-
return `--${cwd.replace(/^[/\\]/, "").replace(/[/\\:]/g, "-")}--`;
|
|
25
|
-
}
|
|
26
|
-
function sessionFileName(createdAt, id) {
|
|
27
|
-
const timestamp = new Date(createdAt).toISOString().replace(/[:.]/g, "-");
|
|
28
|
-
return `${timestamp}_${encodeURIComponent(id)}.jsonl`;
|
|
29
|
-
}
|
|
30
|
-
/** File-backed format-4 session repository lifecycle. */
|
|
31
|
-
export class JsonlSessionRepo {
|
|
32
|
-
fileSystem;
|
|
33
|
-
sessionsRootInput;
|
|
34
|
-
now;
|
|
35
|
-
openSessions = new Map();
|
|
36
|
-
pendingCreates = new Set();
|
|
37
|
-
closed = false;
|
|
38
|
-
closePromise;
|
|
39
|
-
constructor(options) {
|
|
40
|
-
this.fileSystem = options.fileSystem;
|
|
41
|
-
this.sessionsRootInput = options.sessionsRoot;
|
|
42
|
-
this.now = options.now ?? Date.now;
|
|
43
|
-
}
|
|
44
|
-
async create(options, context) {
|
|
45
|
-
this.assertOpen();
|
|
46
|
-
const createdAt = this.now();
|
|
47
|
-
const { cwd, id } = await this.resolveCreateDestination(options.cwd, options.id, createdAt, context);
|
|
48
|
-
const key = this.sessionKey(cwd, id);
|
|
49
|
-
if (this.openSessions.has(key) || this.pendingCreates.has(key))
|
|
50
|
-
throw new Error(`Session already exists: ${id}`);
|
|
51
|
-
this.pendingCreates.add(key);
|
|
52
|
-
let path;
|
|
53
|
-
let storage;
|
|
54
|
-
try {
|
|
55
|
-
path = await this.resolveNewSessionPath(cwd, createdAt, id, context);
|
|
56
|
-
const header = {
|
|
57
|
-
v: JSONL_FORMAT_VERSION,
|
|
58
|
-
kind: "header",
|
|
59
|
-
id,
|
|
60
|
-
storageVersion: JSONL_STORAGE_VERSION,
|
|
61
|
-
createdAt,
|
|
62
|
-
cwd,
|
|
63
|
-
...(options.parentSessionId === undefined ? {} : { parentSessionId: options.parentSessionId }),
|
|
64
|
-
};
|
|
65
|
-
storage = await JsonlStorage.create({ fileSystem: this.fileSystem, path, now: this.now }, header, [], context);
|
|
66
|
-
const info = fileValue(await this.fileSystem.fileInfo(path, context), `Failed to read session ${path}`);
|
|
67
|
-
return this.publishOpenSession(metadataFromHeader(header, path, info.mtimeMs), storage, key);
|
|
68
|
-
}
|
|
69
|
-
catch (error) {
|
|
70
|
-
await storage?.close(context).catch(() => undefined);
|
|
71
|
-
if (path !== undefined)
|
|
72
|
-
await this.fileSystem.remove(path, { force: true }, context);
|
|
73
|
-
throw error;
|
|
74
|
-
}
|
|
75
|
-
finally {
|
|
76
|
-
this.pendingCreates.delete(key);
|
|
77
|
-
}
|
|
78
|
-
}
|
|
79
|
-
async open(metadata, context) {
|
|
80
|
-
this.assertOpen();
|
|
81
|
-
const key = this.sessionKey(metadata.cwd, metadata.id);
|
|
82
|
-
if (this.openSessions.has(key))
|
|
83
|
-
throw new Error(`Session is already open: ${metadata.id}`);
|
|
84
|
-
let storage;
|
|
85
|
-
try {
|
|
86
|
-
storage = await this.loadStorage(metadata, context);
|
|
87
|
-
return this.publishOpenSession(metadata, storage, key);
|
|
88
|
-
}
|
|
89
|
-
catch (error) {
|
|
90
|
-
await storage?.close(context);
|
|
91
|
-
throw error;
|
|
92
|
-
}
|
|
93
|
-
}
|
|
94
|
-
async list(options, context) {
|
|
95
|
-
options ??= {};
|
|
96
|
-
this.assertOpen();
|
|
97
|
-
const cwd = options.cwd === undefined
|
|
98
|
-
? undefined
|
|
99
|
-
: fileValue(await this.fileSystem.absolutePath(options.cwd, context), `Failed to resolve session cwd ${options.cwd}`);
|
|
100
|
-
const root = await this.root(context);
|
|
101
|
-
if (!fileValue(await this.fileSystem.exists(root, context), `Failed to check sessions root ${root}`))
|
|
102
|
-
return [];
|
|
103
|
-
const directories = cwd === undefined ? await this.sessionDirectories(root, context) : [await this.sessionDirectory(cwd, context)];
|
|
104
|
-
const metadata = [];
|
|
105
|
-
for (const directory of directories)
|
|
106
|
-
metadata.push(...(await this.listDirectory(directory, cwd, context)));
|
|
107
|
-
return metadata.sort((left, right) => right.createdAt - left.createdAt || left.id.localeCompare(right.id) || left.cwd.localeCompare(right.cwd));
|
|
108
|
-
}
|
|
109
|
-
async delete(metadata, context) {
|
|
110
|
-
this.assertOpen();
|
|
111
|
-
const key = this.sessionKey(metadata.cwd, metadata.id);
|
|
112
|
-
if (this.openSessions.has(key))
|
|
113
|
-
throw new Error(`Session is open: ${metadata.id}`);
|
|
114
|
-
if (!fileValue(await this.fileSystem.exists(metadata.path, context), `Failed to check session ${metadata.path}`)) {
|
|
115
|
-
throw new Error(`Session file does not exist: ${metadata.path}`);
|
|
116
|
-
}
|
|
117
|
-
fileValue(await this.fileSystem.remove(metadata.path, undefined, context), `Failed to delete session ${metadata.path}`);
|
|
118
|
-
}
|
|
119
|
-
async fork(source, options, context) {
|
|
120
|
-
this.assertOpen();
|
|
121
|
-
const createdAt = this.now();
|
|
122
|
-
const cwd = source.cwd;
|
|
123
|
-
const id = options.id ?? uuidv7(createdAt);
|
|
124
|
-
const destinationKey = this.sessionKey(cwd, id);
|
|
125
|
-
if (this.openSessions.has(destinationKey) || this.pendingCreates.has(destinationKey)) {
|
|
126
|
-
throw new Error(`Session already exists: ${id}`);
|
|
127
|
-
}
|
|
128
|
-
this.pendingCreates.add(destinationKey);
|
|
129
|
-
const sourceStorage = this.openSessions.get(this.sessionKey(source.cwd, source.id));
|
|
130
|
-
let path;
|
|
131
|
-
let storage;
|
|
132
|
-
try {
|
|
133
|
-
const input = await this.resolveForkInput(source, sourceStorage, context);
|
|
134
|
-
path = await this.resolveNewSessionPath(cwd, createdAt, id, context);
|
|
135
|
-
const header = {
|
|
136
|
-
v: JSONL_FORMAT_VERSION,
|
|
137
|
-
kind: "header",
|
|
138
|
-
id,
|
|
139
|
-
storageVersion: JSONL_STORAGE_VERSION,
|
|
140
|
-
createdAt,
|
|
141
|
-
cwd,
|
|
142
|
-
parentSessionId: source.id,
|
|
143
|
-
};
|
|
144
|
-
await runJsonlFork({
|
|
145
|
-
input,
|
|
146
|
-
fileSystem: this.fileSystem,
|
|
147
|
-
destinationPath: path,
|
|
148
|
-
destinationHeader: header,
|
|
149
|
-
fork: options,
|
|
150
|
-
}, context);
|
|
151
|
-
storage = await JsonlStorage.open({ fileSystem: this.fileSystem, path, now: this.now }, context);
|
|
152
|
-
const info = fileValue(await this.fileSystem.fileInfo(path, context), `Failed to read session ${path}`);
|
|
153
|
-
return this.publishOpenSession(metadataFromHeader(header, path, info.mtimeMs), storage, destinationKey);
|
|
154
|
-
}
|
|
155
|
-
catch (error) {
|
|
156
|
-
await storage?.close(context).catch(() => undefined);
|
|
157
|
-
if (path !== undefined)
|
|
158
|
-
await this.fileSystem.remove(path, { force: true }, context);
|
|
159
|
-
throw error;
|
|
160
|
-
}
|
|
161
|
-
finally {
|
|
162
|
-
this.pendingCreates.delete(destinationKey);
|
|
163
|
-
}
|
|
164
|
-
}
|
|
165
|
-
close(_context) {
|
|
166
|
-
if (this.closePromise !== undefined)
|
|
167
|
-
return this.closePromise;
|
|
168
|
-
this.closed = true;
|
|
169
|
-
// TODO: Define ownership semantics before deciding whether repository close should close session handles.
|
|
170
|
-
this.closePromise = Promise.resolve();
|
|
171
|
-
return this.closePromise;
|
|
172
|
-
}
|
|
173
|
-
async resolveCreateDestination(cwdInput, id, createdAt, context) {
|
|
174
|
-
const destinationId = id ?? uuidv7(createdAt);
|
|
175
|
-
const cwd = fileValue(await this.fileSystem.absolutePath(cwdInput, context), `Failed to resolve session cwd ${cwdInput}`);
|
|
176
|
-
return { cwd, id: destinationId };
|
|
177
|
-
}
|
|
178
|
-
async listDirectory(directory, cwd, context) {
|
|
179
|
-
if (!fileValue(await this.fileSystem.exists(directory, context), `Failed to check sessions directory ${directory}`)) {
|
|
180
|
-
return [];
|
|
181
|
-
}
|
|
182
|
-
const files = fileValue(await this.fileSystem.listDir(directory, context), `Failed to list sessions directory ${directory}`).filter((file) => file.kind !== "directory" && file.name.endsWith(".jsonl"));
|
|
183
|
-
const metadata = [];
|
|
184
|
-
for (const file of files) {
|
|
185
|
-
const discovered = await this.readSessionMetadata(file, context);
|
|
186
|
-
if (discovered === undefined)
|
|
187
|
-
continue;
|
|
188
|
-
// Directory encoding is lossy: /a/b and /a-b both map to --a-b--.
|
|
189
|
-
if (cwd === undefined || discovered.cwd === cwd)
|
|
190
|
-
metadata.push(discovered);
|
|
191
|
-
}
|
|
192
|
-
return metadata;
|
|
193
|
-
}
|
|
194
|
-
async readSessionMetadata(file, context) {
|
|
195
|
-
const lines = fileValue(await this.fileSystem.readTextLines(file.path, { maxLines: 1 }, context), `Failed to read session header ${file.path}`);
|
|
196
|
-
if (lines[0] === undefined)
|
|
197
|
-
return undefined;
|
|
198
|
-
const parsedHeader = parseJsonlSessionHeader(lines[0]);
|
|
199
|
-
if (!parsedHeader.ok)
|
|
200
|
-
return undefined;
|
|
201
|
-
if (parsedHeader.value.format === "v3-legacy") {
|
|
202
|
-
const metadata = await metadataFromLegacyV3Header(this.fileSystem, parsedHeader.value.header, context);
|
|
203
|
-
return { ...metadata, path: file.path, modifiedAt: file.mtimeMs };
|
|
204
|
-
}
|
|
205
|
-
return metadataFromHeader(parsedHeader.value.header, file.path, file.mtimeMs);
|
|
206
|
-
}
|
|
207
|
-
async sessionDirectories(root, context) {
|
|
208
|
-
return fileValue(await this.fileSystem.listDir(root, context), `Failed to list sessions root ${root}`)
|
|
209
|
-
.filter((entry) => entry.kind === "directory")
|
|
210
|
-
.map((entry) => entry.path);
|
|
211
|
-
}
|
|
212
|
-
async sessionDirectory(cwd, context) {
|
|
213
|
-
return fileValue(await this.fileSystem.joinPath([await this.root(context), sessionDirectoryName(cwd)], context), `Failed to resolve sessions directory for ${cwd}`);
|
|
214
|
-
}
|
|
215
|
-
async resolveNewSessionPath(cwd, createdAt, id, context) {
|
|
216
|
-
const directory = await this.sessionDirectory(cwd, context);
|
|
217
|
-
await this.assertSessionIdAvailable(directory, id, context);
|
|
218
|
-
fileValue(await this.fileSystem.createDir(directory, undefined, context), `Failed to create sessions directory ${directory}`);
|
|
219
|
-
return fileValue(await this.fileSystem.joinPath([directory, sessionFileName(createdAt, id)], context), `Failed to resolve path for session ${id}`);
|
|
220
|
-
}
|
|
221
|
-
async assertSessionIdAvailable(directory, id, context) {
|
|
222
|
-
if (!fileValue(await this.fileSystem.exists(directory, context), `Failed to check sessions directory ${directory}`))
|
|
223
|
-
return;
|
|
224
|
-
const suffix = `_${encodeURIComponent(id)}.jsonl`;
|
|
225
|
-
const idExists = fileValue(await this.fileSystem.listDir(directory, context), `Failed to list sessions directory ${directory}`).some((entry) => entry.kind !== "directory" && entry.name.endsWith(suffix));
|
|
226
|
-
if (idExists)
|
|
227
|
-
throw new Error(`Session already exists: ${id}`);
|
|
228
|
-
}
|
|
229
|
-
async resolveForkInput(source, storage, context) {
|
|
230
|
-
if (storage !== undefined) {
|
|
231
|
-
if (storage.isLegacyV3()) {
|
|
232
|
-
throw new Error("Cannot fork an open legacy v3 JSONL session; commit a non-empty transaction to upgrade it to format 4 first");
|
|
233
|
-
}
|
|
234
|
-
const nextSeq = await storage.captureForkNextSeq(context);
|
|
235
|
-
return { kind: "open", metadata: source, nextSeq };
|
|
236
|
-
}
|
|
237
|
-
if (await this.isLegacyV3ForkSource(source, context)) {
|
|
238
|
-
const normalized = await LegacyV3Source.read(this.fileSystem, source.path, context);
|
|
239
|
-
if (normalized.header.id !== source.id || normalized.header.cwd !== source.cwd) {
|
|
240
|
-
throw new Error(`Session identity does not match header: ${source.id}`);
|
|
241
|
-
}
|
|
242
|
-
return { kind: "legacy-v3", normalized };
|
|
243
|
-
}
|
|
244
|
-
return { kind: "closed", metadata: source };
|
|
245
|
-
}
|
|
246
|
-
async isLegacyV3ForkSource(source, context) {
|
|
247
|
-
const lines = fileValue(await this.fileSystem.readTextLines(source.path, { maxLines: 1 }, context), `Failed to read session header ${source.path}`);
|
|
248
|
-
if (lines[0] === undefined)
|
|
249
|
-
return false;
|
|
250
|
-
const parsed = parseJsonlSessionHeader(lines[0]);
|
|
251
|
-
return parsed.ok && parsed.value.format === "v3-legacy";
|
|
252
|
-
}
|
|
253
|
-
publishOpenSession(metadata, storage, key) {
|
|
254
|
-
if (this.openSessions.has(key))
|
|
255
|
-
throw new Error(`Session is already open: ${metadata.id}`);
|
|
256
|
-
const session = new StorageBackedSession(metadata, storage, {
|
|
257
|
-
onClose: () => {
|
|
258
|
-
if (this.openSessions.get(key) === storage)
|
|
259
|
-
this.openSessions.delete(key);
|
|
260
|
-
},
|
|
261
|
-
});
|
|
262
|
-
this.openSessions.set(key, storage);
|
|
263
|
-
return session;
|
|
264
|
-
}
|
|
265
|
-
sessionKey(cwd, id) {
|
|
266
|
-
return `${cwd}\0${id}`;
|
|
267
|
-
}
|
|
268
|
-
async loadStorage(metadata, context) {
|
|
269
|
-
if (!fileValue(await this.fileSystem.exists(metadata.path, context), `Failed to check session ${metadata.path}`)) {
|
|
270
|
-
throw new Error(`Session file does not exist: ${metadata.path}`);
|
|
271
|
-
}
|
|
272
|
-
const storage = await JsonlStorage.open({
|
|
273
|
-
fileSystem: this.fileSystem,
|
|
274
|
-
path: metadata.path,
|
|
275
|
-
now: this.now,
|
|
276
|
-
}, context);
|
|
277
|
-
try {
|
|
278
|
-
if (storage.header.id !== metadata.id || storage.header.cwd !== metadata.cwd) {
|
|
279
|
-
throw new Error(`Session identity does not match header: ${metadata.id}`);
|
|
280
|
-
}
|
|
281
|
-
if (storage.header.storageVersion !== JSONL_STORAGE_VERSION) {
|
|
282
|
-
throw new Error(`Session ${metadata.id} uses unsupported storage version ${storage.header.storageVersion}`);
|
|
283
|
-
}
|
|
284
|
-
return storage;
|
|
285
|
-
}
|
|
286
|
-
catch (error) {
|
|
287
|
-
await storage.close(context);
|
|
288
|
-
throw error;
|
|
289
|
-
}
|
|
290
|
-
}
|
|
291
|
-
root(context) {
|
|
292
|
-
return this.fileSystem
|
|
293
|
-
.absolutePath(this.sessionsRootInput, context)
|
|
294
|
-
.then((result) => fileValue(result, `Failed to resolve sessions root ${this.sessionsRootInput}`));
|
|
295
|
-
}
|
|
296
|
-
assertOpen() {
|
|
297
|
-
if (this.closed)
|
|
298
|
-
throw new Error("JsonlSessionRepo is closed");
|
|
299
|
-
}
|
|
300
|
-
}
|
|
301
|
-
//# sourceMappingURL=repo.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"repo.js","sourceRoot":"","sources":["../../../../src/harness/session/jsonl/repo.ts"],"names":[],"mappings":"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","sourcesContent":["import { uuidv7 } from \"@draht/ai/utils/uuid\";\nimport type { Context } from \"../../context.ts\";\nimport type { FileInfo, FileSystem } from \"../../types.ts\";\nimport { StorageBackedSession } from \"../session.ts\";\nimport type { ForkOptions, Session, SessionRepo } from \"../types.ts\";\nimport { parseJsonlSessionHeader } from \"./codec.ts\";\nimport { type JsonlForkInput, runJsonlFork } from \"./fork.ts\";\nimport { fileValue } from \"./io.ts\";\nimport { LegacyV3Source, metadataFromLegacyV3Header } from \"./legacy-v3.ts\";\nimport { JsonlStorage } from \"./storage.ts\";\nimport {\n\tJSONL_FORMAT_VERSION,\n\tJSONL_STORAGE_VERSION,\n\ttype JsonlSessionCreateOptions,\n\ttype JsonlSessionListOptions,\n\ttype JsonlSessionMetadata,\n\ttype JsonlSessionRepoOptions,\n\ttype JsonlStorageHeader,\n} from \"./types.ts\";\n\nfunction metadataFromHeader(header: JsonlStorageHeader, path: string, modifiedAt: number): JsonlSessionMetadata {\n\treturn {\n\t\tid: header.id,\n\t\tcreatedAt: header.createdAt,\n\t\tstorageVersion: header.storageVersion,\n\t\tcwd: header.cwd,\n\t\tpath,\n\t\tmodifiedAt,\n\t\t...(header.parentSessionId === undefined ? {} : { parentSessionId: header.parentSessionId }),\n\t\t...(header.legacyParentSessionPath === undefined\n\t\t\t? {}\n\t\t\t: { legacyParentSessionPath: header.legacyParentSessionPath }),\n\t};\n}\n\nfunction sessionDirectoryName(cwd: string): string {\n\treturn `--${cwd.replace(/^[/\\\\]/, \"\").replace(/[/\\\\:]/g, \"-\")}--`;\n}\n\nfunction sessionFileName(createdAt: number, id: string): string {\n\tconst timestamp = new Date(createdAt).toISOString().replace(/[:.]/g, \"-\");\n\treturn `${timestamp}_${encodeURIComponent(id)}.jsonl`;\n}\n\n/** File-backed format-4 session repository lifecycle. */\nexport class JsonlSessionRepo\n\timplements SessionRepo<JsonlSessionMetadata, JsonlSessionCreateOptions, JsonlSessionListOptions>\n{\n\tprivate readonly fileSystem: FileSystem;\n\tprivate readonly sessionsRootInput: string;\n\tprivate readonly now: () => number;\n\tprivate readonly openSessions = new Map<string, JsonlStorage>();\n\tprivate readonly pendingCreates = new Set<string>();\n\tprivate closed = false;\n\tprivate closePromise: Promise<void> | undefined;\n\n\tconstructor(options: JsonlSessionRepoOptions) {\n\t\tthis.fileSystem = options.fileSystem;\n\t\tthis.sessionsRootInput = options.sessionsRoot;\n\t\tthis.now = options.now ?? Date.now;\n\t}\n\n\tasync create(options: JsonlSessionCreateOptions, context: Context): Promise<Session<JsonlSessionMetadata>> {\n\t\tthis.assertOpen();\n\t\tconst createdAt = this.now();\n\t\tconst { cwd, id } = await this.resolveCreateDestination(options.cwd, options.id, createdAt, context);\n\t\tconst key = this.sessionKey(cwd, id);\n\t\tif (this.openSessions.has(key) || this.pendingCreates.has(key)) throw new Error(`Session already exists: ${id}`);\n\t\tthis.pendingCreates.add(key);\n\t\tlet path: string | undefined;\n\t\tlet storage: JsonlStorage | undefined;\n\t\ttry {\n\t\t\tpath = await this.resolveNewSessionPath(cwd, createdAt, id, context);\n\t\t\tconst header: JsonlStorageHeader = {\n\t\t\t\tv: JSONL_FORMAT_VERSION,\n\t\t\t\tkind: \"header\",\n\t\t\t\tid,\n\t\t\t\tstorageVersion: JSONL_STORAGE_VERSION,\n\t\t\t\tcreatedAt,\n\t\t\t\tcwd,\n\t\t\t\t...(options.parentSessionId === undefined ? {} : { parentSessionId: options.parentSessionId }),\n\t\t\t};\n\t\t\tstorage = await JsonlStorage.create({ fileSystem: this.fileSystem, path, now: this.now }, header, [], context);\n\t\t\tconst info = fileValue(await this.fileSystem.fileInfo(path, context), `Failed to read session ${path}`);\n\t\t\treturn this.publishOpenSession(metadataFromHeader(header, path, info.mtimeMs), storage, key);\n\t\t} catch (error) {\n\t\t\tawait storage?.close(context).catch(() => undefined);\n\t\t\tif (path !== undefined) await this.fileSystem.remove(path, { force: true }, context);\n\t\t\tthrow error;\n\t\t} finally {\n\t\t\tthis.pendingCreates.delete(key);\n\t\t}\n\t}\n\n\tasync open(metadata: JsonlSessionMetadata, context: Context): Promise<Session<JsonlSessionMetadata>> {\n\t\tthis.assertOpen();\n\t\tconst key = this.sessionKey(metadata.cwd, metadata.id);\n\t\tif (this.openSessions.has(key)) throw new Error(`Session is already open: ${metadata.id}`);\n\t\tlet storage: JsonlStorage | undefined;\n\t\ttry {\n\t\t\tstorage = await this.loadStorage(metadata, context);\n\t\t\treturn this.publishOpenSession(metadata, storage, key);\n\t\t} catch (error) {\n\t\t\tawait storage?.close(context);\n\t\t\tthrow error;\n\t\t}\n\t}\n\n\tasync list(options: JsonlSessionListOptions | undefined, context: Context): Promise<JsonlSessionMetadata[]> {\n\t\toptions ??= {};\n\t\tthis.assertOpen();\n\t\tconst cwd =\n\t\t\toptions.cwd === undefined\n\t\t\t\t? undefined\n\t\t\t\t: fileValue(\n\t\t\t\t\t\tawait this.fileSystem.absolutePath(options.cwd, context),\n\t\t\t\t\t\t`Failed to resolve session cwd ${options.cwd}`,\n\t\t\t\t\t);\n\t\tconst root = await this.root(context);\n\t\tif (!fileValue(await this.fileSystem.exists(root, context), `Failed to check sessions root ${root}`)) return [];\n\t\tconst directories =\n\t\t\tcwd === undefined ? await this.sessionDirectories(root, context) : [await this.sessionDirectory(cwd, context)];\n\t\tconst metadata: JsonlSessionMetadata[] = [];\n\t\tfor (const directory of directories) metadata.push(...(await this.listDirectory(directory, cwd, context)));\n\t\treturn metadata.sort(\n\t\t\t(left, right) =>\n\t\t\t\tright.createdAt - left.createdAt || left.id.localeCompare(right.id) || left.cwd.localeCompare(right.cwd),\n\t\t);\n\t}\n\n\tasync delete(metadata: JsonlSessionMetadata, context: Context): Promise<void> {\n\t\tthis.assertOpen();\n\t\tconst key = this.sessionKey(metadata.cwd, metadata.id);\n\t\tif (this.openSessions.has(key)) throw new Error(`Session is open: ${metadata.id}`);\n\t\tif (\n\t\t\t!fileValue(await this.fileSystem.exists(metadata.path, context), `Failed to check session ${metadata.path}`)\n\t\t) {\n\t\t\tthrow new Error(`Session file does not exist: ${metadata.path}`);\n\t\t}\n\t\tfileValue(\n\t\t\tawait this.fileSystem.remove(metadata.path, undefined, context),\n\t\t\t`Failed to delete session ${metadata.path}`,\n\t\t);\n\t}\n\n\tasync fork(\n\t\tsource: JsonlSessionMetadata,\n\t\toptions: ForkOptions,\n\t\tcontext: Context,\n\t): Promise<Session<JsonlSessionMetadata>> {\n\t\tthis.assertOpen();\n\t\tconst createdAt = this.now();\n\t\tconst cwd = source.cwd;\n\t\tconst id = options.id ?? uuidv7(createdAt);\n\t\tconst destinationKey = this.sessionKey(cwd, id);\n\t\tif (this.openSessions.has(destinationKey) || this.pendingCreates.has(destinationKey)) {\n\t\t\tthrow new Error(`Session already exists: ${id}`);\n\t\t}\n\t\tthis.pendingCreates.add(destinationKey);\n\n\t\tconst sourceStorage = this.openSessions.get(this.sessionKey(source.cwd, source.id));\n\t\tlet path: string | undefined;\n\t\tlet storage: JsonlStorage | undefined;\n\t\ttry {\n\t\t\tconst input = await this.resolveForkInput(source, sourceStorage, context);\n\t\t\tpath = await this.resolveNewSessionPath(cwd, createdAt, id, context);\n\t\t\tconst header: Omit<JsonlStorageHeader, \"nextSeq\"> = {\n\t\t\t\tv: JSONL_FORMAT_VERSION,\n\t\t\t\tkind: \"header\",\n\t\t\t\tid,\n\t\t\t\tstorageVersion: JSONL_STORAGE_VERSION,\n\t\t\t\tcreatedAt,\n\t\t\t\tcwd,\n\t\t\t\tparentSessionId: source.id,\n\t\t\t};\n\t\t\tawait runJsonlFork(\n\t\t\t\t{\n\t\t\t\t\tinput,\n\t\t\t\t\tfileSystem: this.fileSystem,\n\t\t\t\t\tdestinationPath: path,\n\t\t\t\t\tdestinationHeader: header,\n\t\t\t\t\tfork: options,\n\t\t\t\t},\n\t\t\t\tcontext,\n\t\t\t);\n\t\t\tstorage = await JsonlStorage.open({ fileSystem: this.fileSystem, path, now: this.now }, context);\n\t\t\tconst info = fileValue(await this.fileSystem.fileInfo(path, context), `Failed to read session ${path}`);\n\t\t\treturn this.publishOpenSession(metadataFromHeader(header, path, info.mtimeMs), storage, destinationKey);\n\t\t} catch (error) {\n\t\t\tawait storage?.close(context).catch(() => undefined);\n\t\t\tif (path !== undefined) await this.fileSystem.remove(path, { force: true }, context);\n\t\t\tthrow error;\n\t\t} finally {\n\t\t\tthis.pendingCreates.delete(destinationKey);\n\t\t}\n\t}\n\n\tclose(_context: Context): Promise<void> {\n\t\tif (this.closePromise !== undefined) return this.closePromise;\n\t\tthis.closed = true;\n\t\t// TODO: Define ownership semantics before deciding whether repository close should close session handles.\n\t\tthis.closePromise = Promise.resolve();\n\t\treturn this.closePromise;\n\t}\n\n\tprivate async resolveCreateDestination(\n\t\tcwdInput: string,\n\t\tid: string | undefined,\n\t\tcreatedAt: number,\n\t\tcontext: Context,\n\t): Promise<{ cwd: string; id: string }> {\n\t\tconst destinationId = id ?? uuidv7(createdAt);\n\t\tconst cwd = fileValue(\n\t\t\tawait this.fileSystem.absolutePath(cwdInput, context),\n\t\t\t`Failed to resolve session cwd ${cwdInput}`,\n\t\t);\n\t\treturn { cwd, id: destinationId };\n\t}\n\n\tprivate async listDirectory(\n\t\tdirectory: string,\n\t\tcwd: string | undefined,\n\t\tcontext: Context,\n\t): Promise<JsonlSessionMetadata[]> {\n\t\tif (\n\t\t\t!fileValue(await this.fileSystem.exists(directory, context), `Failed to check sessions directory ${directory}`)\n\t\t) {\n\t\t\treturn [];\n\t\t}\n\t\tconst files = fileValue(\n\t\t\tawait this.fileSystem.listDir(directory, context),\n\t\t\t`Failed to list sessions directory ${directory}`,\n\t\t).filter((file) => file.kind !== \"directory\" && file.name.endsWith(\".jsonl\"));\n\t\tconst metadata: JsonlSessionMetadata[] = [];\n\t\tfor (const file of files) {\n\t\t\tconst discovered = await this.readSessionMetadata(file, context);\n\t\t\tif (discovered === undefined) continue;\n\t\t\t// Directory encoding is lossy: /a/b and /a-b both map to --a-b--.\n\t\t\tif (cwd === undefined || discovered.cwd === cwd) metadata.push(discovered);\n\t\t}\n\t\treturn metadata;\n\t}\n\n\tprivate async readSessionMetadata(file: FileInfo, context: Context): Promise<JsonlSessionMetadata | undefined> {\n\t\tconst lines = fileValue(\n\t\t\tawait this.fileSystem.readTextLines(file.path, { maxLines: 1 }, context),\n\t\t\t`Failed to read session header ${file.path}`,\n\t\t);\n\t\tif (lines[0] === undefined) return undefined;\n\t\tconst parsedHeader = parseJsonlSessionHeader(lines[0]);\n\t\tif (!parsedHeader.ok) return undefined;\n\t\tif (parsedHeader.value.format === \"v3-legacy\") {\n\t\t\tconst metadata = await metadataFromLegacyV3Header(this.fileSystem, parsedHeader.value.header, context);\n\t\t\treturn { ...metadata, path: file.path, modifiedAt: file.mtimeMs };\n\t\t}\n\t\treturn metadataFromHeader(parsedHeader.value.header, file.path, file.mtimeMs);\n\t}\n\n\tprivate async sessionDirectories(root: string, context: Context): Promise<string[]> {\n\t\treturn fileValue(await this.fileSystem.listDir(root, context), `Failed to list sessions root ${root}`)\n\t\t\t.filter((entry) => entry.kind === \"directory\")\n\t\t\t.map((entry) => entry.path);\n\t}\n\n\tprivate async sessionDirectory(cwd: string, context: Context): Promise<string> {\n\t\treturn fileValue(\n\t\t\tawait this.fileSystem.joinPath([await this.root(context), sessionDirectoryName(cwd)], context),\n\t\t\t`Failed to resolve sessions directory for ${cwd}`,\n\t\t);\n\t}\n\n\tprivate async resolveNewSessionPath(cwd: string, createdAt: number, id: string, context: Context): Promise<string> {\n\t\tconst directory = await this.sessionDirectory(cwd, context);\n\t\tawait this.assertSessionIdAvailable(directory, id, context);\n\t\tfileValue(\n\t\t\tawait this.fileSystem.createDir(directory, undefined, context),\n\t\t\t`Failed to create sessions directory ${directory}`,\n\t\t);\n\t\treturn fileValue(\n\t\t\tawait this.fileSystem.joinPath([directory, sessionFileName(createdAt, id)], context),\n\t\t\t`Failed to resolve path for session ${id}`,\n\t\t);\n\t}\n\n\tprivate async assertSessionIdAvailable(directory: string, id: string, context: Context): Promise<void> {\n\t\tif (\n\t\t\t!fileValue(await this.fileSystem.exists(directory, context), `Failed to check sessions directory ${directory}`)\n\t\t)\n\t\t\treturn;\n\n\t\tconst suffix = `_${encodeURIComponent(id)}.jsonl`;\n\t\tconst idExists = fileValue(\n\t\t\tawait this.fileSystem.listDir(directory, context),\n\t\t\t`Failed to list sessions directory ${directory}`,\n\t\t).some((entry) => entry.kind !== \"directory\" && entry.name.endsWith(suffix));\n\t\tif (idExists) throw new Error(`Session already exists: ${id}`);\n\t}\n\n\tprivate async resolveForkInput(\n\t\tsource: JsonlSessionMetadata,\n\t\tstorage: JsonlStorage | undefined,\n\t\tcontext: Context,\n\t): Promise<JsonlForkInput> {\n\t\tif (storage !== undefined) {\n\t\t\tif (storage.isLegacyV3()) {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t\"Cannot fork an open legacy v3 JSONL session; commit a non-empty transaction to upgrade it to format 4 first\",\n\t\t\t\t);\n\t\t\t}\n\t\t\tconst nextSeq = await storage.captureForkNextSeq(context);\n\t\t\treturn { kind: \"open\", metadata: source, nextSeq };\n\t\t}\n\t\tif (await this.isLegacyV3ForkSource(source, context)) {\n\t\t\tconst normalized = await LegacyV3Source.read(this.fileSystem, source.path, context);\n\t\t\tif (normalized.header.id !== source.id || normalized.header.cwd !== source.cwd) {\n\t\t\t\tthrow new Error(`Session identity does not match header: ${source.id}`);\n\t\t\t}\n\t\t\treturn { kind: \"legacy-v3\", normalized };\n\t\t}\n\t\treturn { kind: \"closed\", metadata: source };\n\t}\n\n\tprivate async isLegacyV3ForkSource(source: JsonlSessionMetadata, context: Context): Promise<boolean> {\n\t\tconst lines = fileValue(\n\t\t\tawait this.fileSystem.readTextLines(source.path, { maxLines: 1 }, context),\n\t\t\t`Failed to read session header ${source.path}`,\n\t\t);\n\t\tif (lines[0] === undefined) return false;\n\t\tconst parsed = parseJsonlSessionHeader(lines[0]);\n\t\treturn parsed.ok && parsed.value.format === \"v3-legacy\";\n\t}\n\n\tprivate publishOpenSession(\n\t\tmetadata: JsonlSessionMetadata,\n\t\tstorage: JsonlStorage,\n\t\tkey: string,\n\t): StorageBackedSession<JsonlSessionMetadata> {\n\t\tif (this.openSessions.has(key)) throw new Error(`Session is already open: ${metadata.id}`);\n\t\tconst session = new StorageBackedSession(metadata, storage, {\n\t\t\tonClose: () => {\n\t\t\t\tif (this.openSessions.get(key) === storage) this.openSessions.delete(key);\n\t\t\t},\n\t\t});\n\t\tthis.openSessions.set(key, storage);\n\t\treturn session;\n\t}\n\n\tprivate sessionKey(cwd: string, id: string): string {\n\t\treturn `${cwd}\\0${id}`;\n\t}\n\n\tprivate async loadStorage(metadata: JsonlSessionMetadata, context: Context): Promise<JsonlStorage> {\n\t\tif (\n\t\t\t!fileValue(await this.fileSystem.exists(metadata.path, context), `Failed to check session ${metadata.path}`)\n\t\t) {\n\t\t\tthrow new Error(`Session file does not exist: ${metadata.path}`);\n\t\t}\n\t\tconst storage = await JsonlStorage.open(\n\t\t\t{\n\t\t\t\tfileSystem: this.fileSystem,\n\t\t\t\tpath: metadata.path,\n\t\t\t\tnow: this.now,\n\t\t\t},\n\t\t\tcontext,\n\t\t);\n\t\ttry {\n\t\t\tif (storage.header.id !== metadata.id || storage.header.cwd !== metadata.cwd) {\n\t\t\t\tthrow new Error(`Session identity does not match header: ${metadata.id}`);\n\t\t\t}\n\t\t\tif (storage.header.storageVersion !== JSONL_STORAGE_VERSION) {\n\t\t\t\tthrow new Error(`Session ${metadata.id} uses unsupported storage version ${storage.header.storageVersion}`);\n\t\t\t}\n\t\t\treturn storage;\n\t\t} catch (error) {\n\t\t\tawait storage.close(context);\n\t\t\tthrow error;\n\t\t}\n\t}\n\n\tprivate root(context: Context): Promise<string> {\n\t\treturn this.fileSystem\n\t\t\t.absolutePath(this.sessionsRootInput, context)\n\t\t\t.then((result) => fileValue(result, `Failed to resolve sessions root ${this.sessionsRootInput}`));\n\t}\n\n\tprivate assertOpen(): void {\n\t\tif (this.closed) throw new Error(\"JsonlSessionRepo is closed\");\n\t}\n}\n"]}
|
|
@@ -1,41 +0,0 @@
|
|
|
1
|
-
import type { Context } from "../../context.ts";
|
|
2
|
-
import type { CommitResult, Entry, EntryScan, EntryStructure, SessionStats, Storage, StorageBranchScan, UsageRow, UsageScan, Write } from "../types.ts";
|
|
3
|
-
import type { ListElement, ListReadOptions, StoredValue, Value, ValueList } from "../values.ts";
|
|
4
|
-
import { type JsonlStorageHeader, type JsonlStorageOptions } from "./types.ts";
|
|
5
|
-
/** JSONL storage backed by an injected filesystem capability. */
|
|
6
|
-
export declare class JsonlStorage implements Storage {
|
|
7
|
-
private readonly fileSystem;
|
|
8
|
-
private readonly path;
|
|
9
|
-
private readonly now;
|
|
10
|
-
readonly header: JsonlStorageHeader;
|
|
11
|
-
private backing;
|
|
12
|
-
private readonly storageState;
|
|
13
|
-
private commitQueue;
|
|
14
|
-
private state;
|
|
15
|
-
private closePromise;
|
|
16
|
-
private constructor();
|
|
17
|
-
static create(options: JsonlStorageOptions, header: JsonlStorageHeader, initialWrites: Write[], context: Context): Promise<JsonlStorage>;
|
|
18
|
-
static open(options: JsonlStorageOptions, context: Context): Promise<JsonlStorage>;
|
|
19
|
-
private static openV4;
|
|
20
|
-
private static openLegacyV3;
|
|
21
|
-
private replayCommitted;
|
|
22
|
-
commit(writes: Write[], context: Context): Promise<CommitResult>;
|
|
23
|
-
private applyCommit;
|
|
24
|
-
/** Atomically upgrade legacy v3 backing and preserve the first caller write as a v4 transaction. */
|
|
25
|
-
private upgradeLegacyV3ToV4;
|
|
26
|
-
getEntries(ids: string[], _context: Context): Promise<Map<string, Entry>>;
|
|
27
|
-
getValue<T>(address: Value<T>, _context: Context): Promise<StoredValue<T> | undefined>;
|
|
28
|
-
scanValues<T>(prefix: Value<T>, _context: Context): Promise<StoredValue<T>[]>;
|
|
29
|
-
readList<T>(address: ValueList<T>, options: ListReadOptions | undefined, _context: Context): Promise<ListElement<T>[]>;
|
|
30
|
-
scanBranch(query: StorageBranchScan, _context: Context): Promise<Entry[]>;
|
|
31
|
-
scanBranchStructure(query: StorageBranchScan, _context: Context): Promise<EntryStructure[]>;
|
|
32
|
-
scanEntries(query: EntryScan, _context: Context): Promise<Entry[]>;
|
|
33
|
-
scanUsage(query: UsageScan, _context: Context): Promise<UsageRow[]>;
|
|
34
|
-
getStats(_context: Context): Promise<SessionStats>;
|
|
35
|
-
private withImportedUsage;
|
|
36
|
-
isLegacyV3(): boolean;
|
|
37
|
-
/** Capture the first sequence a later source commit would use. */
|
|
38
|
-
captureForkNextSeq(_context: Context): Promise<number>;
|
|
39
|
-
close(_context: Context): Promise<void>;
|
|
40
|
-
}
|
|
41
|
-
//# sourceMappingURL=storage.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"storage.d.ts","sourceRoot":"","sources":["../../../../src/harness/session/jsonl/storage.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,200 +0,0 @@
|
|
|
1
|
-
import { uuidv7 } from "@draht/ai/utils/uuid";
|
|
2
|
-
import { insertUsage } from "../commit.js";
|
|
3
|
-
import { InMemoryStorageState } from "../in-memory-storage-state.js";
|
|
4
|
-
import { fileValue, parseJsonlTransaction, publishFileAtomically, publishJsonl, readJsonlHeader, serializeJsonlTransaction, } from "./io.js";
|
|
5
|
-
import { LegacyV3Source } from "./legacy-v3.js";
|
|
6
|
-
import { JSONL_STORAGE_VERSION } from "./types.js";
|
|
7
|
-
function splitCompleteLines(content) {
|
|
8
|
-
if (content.endsWith("\n"))
|
|
9
|
-
return { lines: content.slice(0, -1).split("\n"), torn: false };
|
|
10
|
-
const lastNewline = content.lastIndexOf("\n");
|
|
11
|
-
if (lastNewline === -1)
|
|
12
|
-
return { lines: [], torn: true };
|
|
13
|
-
return { lines: content.slice(0, lastNewline).split("\n"), torn: true };
|
|
14
|
-
}
|
|
15
|
-
/** JSONL storage backed by an injected filesystem capability. */
|
|
16
|
-
export class JsonlStorage {
|
|
17
|
-
fileSystem;
|
|
18
|
-
path;
|
|
19
|
-
now;
|
|
20
|
-
header;
|
|
21
|
-
backing;
|
|
22
|
-
storageState = new InMemoryStorageState();
|
|
23
|
-
commitQueue = Promise.resolve();
|
|
24
|
-
state = "open";
|
|
25
|
-
closePromise;
|
|
26
|
-
constructor(options, header, backing) {
|
|
27
|
-
this.fileSystem = options.fileSystem;
|
|
28
|
-
this.path = options.path;
|
|
29
|
-
this.now = options.now ?? Date.now;
|
|
30
|
-
this.header = header;
|
|
31
|
-
this.backing = backing;
|
|
32
|
-
}
|
|
33
|
-
static async create(options, header, initialWrites, context) {
|
|
34
|
-
const storage = new JsonlStorage(options, header, { kind: "v4" });
|
|
35
|
-
const prepared = storage.storageState.prepareCommit(initialWrites, storage.now());
|
|
36
|
-
await publishJsonl(options.fileSystem, options.path, header, context, async (append) => {
|
|
37
|
-
if (prepared.writes.length !== 0)
|
|
38
|
-
await append(prepared.writes);
|
|
39
|
-
});
|
|
40
|
-
storage.storageState.applyValidated(prepared.writes);
|
|
41
|
-
return storage;
|
|
42
|
-
}
|
|
43
|
-
static async open(options, context) {
|
|
44
|
-
const reader = fileValue(await options.fileSystem.openTextLineReader(options.path, context), `Failed to read JSONL storage ${options.path}`);
|
|
45
|
-
const parsed = await readJsonlHeader(reader, options.path, context).finally(() => reader.close(context));
|
|
46
|
-
return parsed.format === "v3-legacy"
|
|
47
|
-
? JsonlStorage.openLegacyV3(options, context)
|
|
48
|
-
: JsonlStorage.openV4(options, parsed.header, context);
|
|
49
|
-
}
|
|
50
|
-
static async openV4(options, header, context) {
|
|
51
|
-
const content = fileValue(await options.fileSystem.readTextFile(options.path, context), `Failed to read JSONL storage ${options.path}`);
|
|
52
|
-
const { lines, torn } = splitCompleteLines(content);
|
|
53
|
-
if (header.storageVersion !== JSONL_STORAGE_VERSION) {
|
|
54
|
-
throw new Error(`Session ${header.id} uses unsupported storage version ${header.storageVersion}`);
|
|
55
|
-
}
|
|
56
|
-
const storage = new JsonlStorage(options, header, { kind: "v4" });
|
|
57
|
-
for (let index = 1; index < lines.length; index++) {
|
|
58
|
-
const line = lines[index];
|
|
59
|
-
try {
|
|
60
|
-
storage.replayCommitted(parseJsonlTransaction(line));
|
|
61
|
-
}
|
|
62
|
-
catch (error) {
|
|
63
|
-
throw new Error(`Invalid JSONL storage ${options.path}: line ${index + 1}`, { cause: error });
|
|
64
|
-
}
|
|
65
|
-
}
|
|
66
|
-
if (header.nextSeq !== undefined)
|
|
67
|
-
storage.storageState.advanceNextSeq(header.nextSeq);
|
|
68
|
-
if (torn) {
|
|
69
|
-
await publishFileAtomically(options.fileSystem, options.path, context, (append) => append(`${lines.join("\n")}\n`));
|
|
70
|
-
}
|
|
71
|
-
return storage;
|
|
72
|
-
}
|
|
73
|
-
static async openLegacyV3(options, context) {
|
|
74
|
-
const source = await LegacyV3Source.read(options.fileSystem, options.path, context);
|
|
75
|
-
const storage = new JsonlStorage(options, { ...source.header, nextSeq: source.nextSeq }, { kind: "v3", source });
|
|
76
|
-
for await (const write of source.writes(context))
|
|
77
|
-
storage.replayCommitted([write]);
|
|
78
|
-
return storage;
|
|
79
|
-
}
|
|
80
|
-
replayCommitted(writes) {
|
|
81
|
-
this.storageState.validateCommitted(writes);
|
|
82
|
-
this.storageState.applyValidated(writes);
|
|
83
|
-
}
|
|
84
|
-
async commit(writes, context) {
|
|
85
|
-
if (this.state !== "open")
|
|
86
|
-
throw new Error("JsonlStorage is closed");
|
|
87
|
-
const result = this.commitQueue.then(() => this.applyCommit(writes, context));
|
|
88
|
-
this.commitQueue = result.then(() => undefined, () => undefined);
|
|
89
|
-
return result;
|
|
90
|
-
}
|
|
91
|
-
async applyCommit(writes, context) {
|
|
92
|
-
if (this.backing.kind === "v3" && writes.length !== 0) {
|
|
93
|
-
return this.upgradeLegacyV3ToV4(this.backing.source, writes, context);
|
|
94
|
-
}
|
|
95
|
-
const prepared = this.storageState.prepareCommit(writes, this.now());
|
|
96
|
-
if (prepared.writes.length !== 0) {
|
|
97
|
-
fileValue(await this.fileSystem.appendFile(this.path, `${serializeJsonlTransaction(prepared.writes)}\n`, context), `Failed to append JSONL storage ${this.path}`);
|
|
98
|
-
}
|
|
99
|
-
const stats = this.storageState.applyValidated(prepared.writes);
|
|
100
|
-
return { ...prepared.result, stats: this.withImportedUsage(stats) };
|
|
101
|
-
}
|
|
102
|
-
/** Atomically upgrade legacy v3 backing and preserve the first caller write as a v4 transaction. */
|
|
103
|
-
async upgradeLegacyV3ToV4(source, callerWrites, context) {
|
|
104
|
-
const timestamp = this.now();
|
|
105
|
-
const prepared = this.storageState.prepareCommit([
|
|
106
|
-
insertUsage({
|
|
107
|
-
id: uuidv7(timestamp),
|
|
108
|
-
usage: source.importedUsage,
|
|
109
|
-
adjustment: true,
|
|
110
|
-
details: { source: "v3-import" },
|
|
111
|
-
}),
|
|
112
|
-
...callerWrites,
|
|
113
|
-
], timestamp);
|
|
114
|
-
const nextSeq = prepared.result.firstSeq + prepared.writes.length;
|
|
115
|
-
const upgradedHeader = { ...this.header, nextSeq };
|
|
116
|
-
await publishJsonl(this.fileSystem, this.path, upgradedHeader, context, async (append) => {
|
|
117
|
-
for await (const write of source.writes(context))
|
|
118
|
-
await append([write]);
|
|
119
|
-
await append(prepared.writes);
|
|
120
|
-
});
|
|
121
|
-
const stats = this.storageState.applyValidated(prepared.writes);
|
|
122
|
-
this.backing = { kind: "v4" };
|
|
123
|
-
// The first sequence belongs to the internal usage adjustment; return only caller-write sequences.
|
|
124
|
-
return {
|
|
125
|
-
...prepared.result,
|
|
126
|
-
firstSeq: prepared.result.firstSeq + 1,
|
|
127
|
-
seqs: prepared.result.seqs.slice(1),
|
|
128
|
-
stats,
|
|
129
|
-
};
|
|
130
|
-
}
|
|
131
|
-
getEntries(ids, _context) {
|
|
132
|
-
if (this.state !== "open")
|
|
133
|
-
return Promise.reject(new Error("JsonlStorage is closed"));
|
|
134
|
-
return Promise.resolve(this.storageState.getEntries(ids));
|
|
135
|
-
}
|
|
136
|
-
getValue(address, _context) {
|
|
137
|
-
if (this.state !== "open")
|
|
138
|
-
return Promise.reject(new Error("JsonlStorage is closed"));
|
|
139
|
-
return Promise.resolve(this.storageState.getValue(address));
|
|
140
|
-
}
|
|
141
|
-
scanValues(prefix, _context) {
|
|
142
|
-
if (this.state !== "open")
|
|
143
|
-
return Promise.reject(new Error("JsonlStorage is closed"));
|
|
144
|
-
return Promise.resolve(this.storageState.scanValues(prefix));
|
|
145
|
-
}
|
|
146
|
-
async readList(address, options, _context) {
|
|
147
|
-
if (this.state !== "open")
|
|
148
|
-
throw new Error("JsonlStorage is closed");
|
|
149
|
-
return this.storageState.readList(address, options);
|
|
150
|
-
}
|
|
151
|
-
async scanBranch(query, _context) {
|
|
152
|
-
if (this.state !== "open")
|
|
153
|
-
throw new Error("JsonlStorage is closed");
|
|
154
|
-
return this.storageState.scanBranch(query);
|
|
155
|
-
}
|
|
156
|
-
async scanBranchStructure(query, _context) {
|
|
157
|
-
if (this.state !== "open")
|
|
158
|
-
throw new Error("JsonlStorage is closed");
|
|
159
|
-
return this.storageState.scanBranchStructure(query);
|
|
160
|
-
}
|
|
161
|
-
scanEntries(query, _context) {
|
|
162
|
-
if (this.state !== "open")
|
|
163
|
-
return Promise.reject(new Error("JsonlStorage is closed"));
|
|
164
|
-
return Promise.resolve(this.storageState.scanEntries(query));
|
|
165
|
-
}
|
|
166
|
-
scanUsage(query, _context) {
|
|
167
|
-
if (this.state !== "open")
|
|
168
|
-
return Promise.reject(new Error("JsonlStorage is closed"));
|
|
169
|
-
return Promise.resolve(this.storageState.scanUsage(query));
|
|
170
|
-
}
|
|
171
|
-
getStats(_context) {
|
|
172
|
-
if (this.state !== "open")
|
|
173
|
-
return Promise.reject(new Error("JsonlStorage is closed"));
|
|
174
|
-
return Promise.resolve(this.withImportedUsage(this.storageState.getStats()));
|
|
175
|
-
}
|
|
176
|
-
withImportedUsage(stats) {
|
|
177
|
-
return this.backing.kind === "v4" ? stats : { ...stats, usage: this.backing.source.importedUsage };
|
|
178
|
-
}
|
|
179
|
-
isLegacyV3() {
|
|
180
|
-
return this.backing.kind === "v3";
|
|
181
|
-
}
|
|
182
|
-
/** Capture the first sequence a later source commit would use. */
|
|
183
|
-
captureForkNextSeq(_context) {
|
|
184
|
-
if (this.state !== "open")
|
|
185
|
-
return Promise.reject(new Error("JsonlStorage is closed"));
|
|
186
|
-
const result = this.commitQueue.then(() => this.storageState.getNextSeq());
|
|
187
|
-
this.commitQueue = result.then(() => undefined, () => undefined);
|
|
188
|
-
return result;
|
|
189
|
-
}
|
|
190
|
-
close(_context) {
|
|
191
|
-
if (this.closePromise !== undefined)
|
|
192
|
-
return this.closePromise;
|
|
193
|
-
this.state = "closing";
|
|
194
|
-
this.closePromise = this.commitQueue.then(() => {
|
|
195
|
-
this.state = "closed";
|
|
196
|
-
});
|
|
197
|
-
return this.closePromise;
|
|
198
|
-
}
|
|
199
|
-
}
|
|
200
|
-
//# sourceMappingURL=storage.js.map
|