@earendil-works/pi-agent-core 0.84.4 → 0.85.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/README.md +4 -0
- package/dist/agent-loop.d.ts.map +1 -1
- package/dist/agent-loop.js +9 -0
- package/dist/agent-loop.js.map +1 -1
- package/dist/harness/agent-harness.d.ts +639 -384
- package/dist/harness/agent-harness.d.ts.map +1 -1
- package/dist/harness/agent-harness.js +5 -251
- package/dist/harness/agent-harness.js.map +1 -1
- package/dist/harness/compaction/branch-summarization.d.ts +12 -6
- package/dist/harness/compaction/branch-summarization.d.ts.map +1 -1
- package/dist/harness/compaction/branch-summarization.js +33 -26
- package/dist/harness/compaction/branch-summarization.js.map +1 -1
- package/dist/harness/compaction/compaction.d.ts +30 -8
- package/dist/harness/compaction/compaction.d.ts.map +1 -1
- package/dist/harness/compaction/compaction.js +53 -63
- package/dist/harness/compaction/compaction.js.map +1 -1
- package/dist/harness/config.d.ts +9 -0
- package/dist/harness/config.d.ts.map +1 -0
- package/dist/harness/config.js +27 -0
- package/dist/harness/config.js.map +1 -0
- package/dist/harness/context.d.ts +9 -0
- package/dist/harness/context.d.ts.map +1 -0
- package/dist/harness/context.js +13 -0
- package/dist/harness/context.js.map +1 -0
- package/dist/harness/env/nodejs.d.ts +24 -28
- package/dist/harness/env/nodejs.d.ts.map +1 -1
- package/dist/harness/env/nodejs.js +239 -86
- package/dist/harness/env/nodejs.js.map +1 -1
- package/dist/harness/events.d.ts +20 -38
- package/dist/harness/events.d.ts.map +1 -1
- package/dist/harness/events.js +240 -55
- package/dist/harness/events.js.map +1 -1
- package/dist/harness/execution/assistant.d.ts +42 -0
- package/dist/harness/execution/assistant.d.ts.map +1 -0
- package/dist/harness/execution/assistant.js +82 -0
- package/dist/harness/execution/assistant.js.map +1 -0
- package/dist/harness/execution/effect-gate.d.ts +22 -0
- package/dist/harness/execution/effect-gate.d.ts.map +1 -0
- package/dist/harness/execution/effect-gate.js +49 -0
- package/dist/harness/execution/effect-gate.js.map +1 -0
- package/dist/harness/execution/tools.d.ts +67 -0
- package/dist/harness/execution/tools.d.ts.map +1 -0
- package/dist/harness/execution/tools.js +121 -0
- package/dist/harness/execution/tools.js.map +1 -0
- package/dist/harness/hooks.d.ts +38 -0
- package/dist/harness/hooks.d.ts.map +1 -0
- package/dist/harness/hooks.js +406 -0
- package/dist/harness/hooks.js.map +1 -0
- package/dist/harness/messages.d.ts +2 -2
- package/dist/harness/messages.d.ts.map +1 -1
- package/dist/harness/messages.js.map +1 -1
- package/dist/harness/prompt-templates.d.ts +3 -2
- package/dist/harness/prompt-templates.d.ts.map +1 -1
- package/dist/harness/prompt-templates.js +17 -17
- package/dist/harness/prompt-templates.js.map +1 -1
- package/dist/harness/result.d.ts +93 -0
- package/dist/harness/result.d.ts.map +1 -1
- package/dist/harness/result.js +40 -0
- package/dist/harness/result.js.map +1 -1
- package/dist/harness/runtime/drive/boundary.d.ts +28 -0
- package/dist/harness/runtime/drive/boundary.d.ts.map +1 -0
- package/dist/harness/runtime/drive/boundary.js +170 -0
- package/dist/harness/runtime/drive/boundary.js.map +1 -0
- package/dist/harness/runtime/drive/checkpoint.d.ts +8 -0
- package/dist/harness/runtime/drive/checkpoint.d.ts.map +1 -0
- package/dist/harness/runtime/drive/checkpoint.js +133 -0
- package/dist/harness/runtime/drive/checkpoint.js.map +1 -0
- package/dist/harness/runtime/drive/deferred.d.ts +15 -0
- package/dist/harness/runtime/drive/deferred.d.ts.map +1 -0
- package/dist/harness/runtime/drive/deferred.js +179 -0
- package/dist/harness/runtime/drive/deferred.js.map +1 -0
- package/dist/harness/runtime/drive/generation.d.ts +8 -0
- package/dist/harness/runtime/drive/generation.d.ts.map +1 -0
- package/dist/harness/runtime/drive/generation.js +205 -0
- package/dist/harness/runtime/drive/generation.js.map +1 -0
- package/dist/harness/runtime/drive/reconcile.d.ts +5 -0
- package/dist/harness/runtime/drive/reconcile.d.ts.map +1 -0
- package/dist/harness/runtime/drive/reconcile.js +140 -0
- package/dist/harness/runtime/drive/reconcile.js.map +1 -0
- package/dist/harness/runtime/drive/recovery.d.ts +8 -0
- package/dist/harness/runtime/drive/recovery.d.ts.map +1 -0
- package/dist/harness/runtime/drive/recovery.js +85 -0
- package/dist/harness/runtime/drive/recovery.js.map +1 -0
- package/dist/harness/runtime/drive/response.d.ts +23 -0
- package/dist/harness/runtime/drive/response.d.ts.map +1 -0
- package/dist/harness/runtime/drive/response.js +394 -0
- package/dist/harness/runtime/drive/response.js.map +1 -0
- package/dist/harness/runtime/drive/retry.d.ts +4 -0
- package/dist/harness/runtime/drive/retry.d.ts.map +1 -0
- package/dist/harness/runtime/drive/retry.js +37 -0
- package/dist/harness/runtime/drive/retry.js.map +1 -0
- package/dist/harness/runtime/drive/structural.d.ts +32 -0
- package/dist/harness/runtime/drive/structural.d.ts.map +1 -0
- package/dist/harness/runtime/drive/structural.js +929 -0
- package/dist/harness/runtime/drive/structural.js.map +1 -0
- package/dist/harness/runtime/drive/terminal.d.ts +7 -0
- package/dist/harness/runtime/drive/terminal.d.ts.map +1 -0
- package/dist/harness/runtime/drive/terminal.js +49 -0
- package/dist/harness/runtime/drive/terminal.js.map +1 -0
- package/dist/harness/runtime/drive/tool-placement.d.ts +14 -0
- package/dist/harness/runtime/drive/tool-placement.d.ts.map +1 -0
- package/dist/harness/runtime/drive/tool-placement.js +244 -0
- package/dist/harness/runtime/drive/tool-placement.js.map +1 -0
- package/dist/harness/runtime/drive/tools.d.ts +6 -0
- package/dist/harness/runtime/drive/tools.d.ts.map +1 -0
- package/dist/harness/runtime/drive/tools.js +449 -0
- package/dist/harness/runtime/drive/tools.js.map +1 -0
- package/dist/harness/runtime/drive.d.ts +6 -0
- package/dist/harness/runtime/drive.d.ts.map +1 -0
- package/dist/harness/runtime/drive.js +93 -0
- package/dist/harness/runtime/drive.js.map +1 -0
- package/dist/harness/runtime/harness.d.ts +59 -0
- package/dist/harness/runtime/harness.d.ts.map +1 -0
- package/dist/harness/runtime/harness.js +311 -0
- package/dist/harness/runtime/harness.js.map +1 -0
- package/dist/harness/runtime/index.d.ts +2 -0
- package/dist/harness/runtime/index.d.ts.map +1 -0
- package/dist/harness/runtime/index.js +2 -0
- package/dist/harness/runtime/index.js.map +1 -0
- package/dist/harness/runtime/lane.d.ts +101 -0
- package/dist/harness/runtime/lane.d.ts.map +1 -0
- package/dist/harness/runtime/lane.js +1575 -0
- package/dist/harness/runtime/lane.js.map +1 -0
- package/dist/harness/runtime/progress.d.ts +15 -0
- package/dist/harness/runtime/progress.d.ts.map +1 -0
- package/dist/harness/runtime/progress.js +66 -0
- package/dist/harness/runtime/progress.js.map +1 -0
- package/dist/harness/runtime/reducer.d.ts +5 -0
- package/dist/harness/runtime/reducer.d.ts.map +1 -0
- package/dist/harness/runtime/reducer.js +240 -0
- package/dist/harness/runtime/reducer.js.map +1 -0
- package/dist/harness/runtime/restore.d.ts +24 -0
- package/dist/harness/runtime/restore.d.ts.map +1 -0
- package/dist/harness/runtime/restore.js +117 -0
- package/dist/harness/runtime/restore.js.map +1 -0
- package/dist/harness/runtime/transcript.d.ts +21 -0
- package/dist/harness/runtime/transcript.d.ts.map +1 -0
- package/dist/harness/runtime/transcript.js +72 -0
- package/dist/harness/runtime/transcript.js.map +1 -0
- package/dist/harness/runtime/types.d.ts +105 -0
- package/dist/harness/runtime/types.d.ts.map +1 -0
- package/dist/harness/runtime/types.js +61 -0
- package/dist/harness/runtime/types.js.map +1 -0
- package/dist/harness/session/commit.d.ts +53 -0
- package/dist/harness/session/commit.d.ts.map +1 -0
- package/dist/harness/session/commit.js +57 -0
- package/dist/harness/session/commit.js.map +1 -0
- package/dist/harness/session/context.d.ts +6 -18
- package/dist/harness/session/context.d.ts.map +1 -1
- package/dist/harness/session/context.js +31 -49
- package/dist/harness/session/context.js.map +1 -1
- package/dist/harness/session/fork-policy.d.ts +13 -0
- package/dist/harness/session/fork-policy.d.ts.map +1 -0
- package/dist/harness/session/fork-policy.js +22 -0
- package/dist/harness/session/fork-policy.js.map +1 -0
- package/dist/harness/session/fork.d.ts +18 -0
- package/dist/harness/session/fork.d.ts.map +1 -0
- package/dist/harness/session/fork.js +127 -0
- package/dist/harness/session/fork.js.map +1 -0
- package/dist/harness/session/in-memory-storage-state.d.ts +39 -0
- package/dist/harness/session/in-memory-storage-state.d.ts.map +1 -0
- package/dist/harness/session/in-memory-storage-state.js +216 -0
- package/dist/harness/session/in-memory-storage-state.js.map +1 -0
- package/dist/harness/session/index.d.ts +9 -5
- package/dist/harness/session/index.d.ts.map +1 -1
- package/dist/harness/session/index.js +7 -4
- package/dist/harness/session/index.js.map +1 -1
- package/dist/harness/session/jsonl/codec.d.ts +19 -8
- package/dist/harness/session/jsonl/codec.d.ts.map +1 -1
- package/dist/harness/session/jsonl/codec.js +34 -218
- package/dist/harness/session/jsonl/codec.js.map +1 -1
- package/dist/harness/session/jsonl/index.d.ts +4 -0
- package/dist/harness/session/jsonl/index.d.ts.map +1 -0
- package/dist/harness/session/jsonl/index.js +4 -0
- package/dist/harness/session/jsonl/index.js.map +1 -0
- package/dist/harness/session/jsonl/legacy-v3.d.ts +18 -0
- package/dist/harness/session/jsonl/legacy-v3.d.ts.map +1 -0
- package/dist/harness/session/jsonl/legacy-v3.js +383 -0
- package/dist/harness/session/jsonl/legacy-v3.js.map +1 -0
- package/dist/harness/session/jsonl/repo.d.ts +26 -19
- package/dist/harness/session/jsonl/repo.d.ts.map +1 -1
- package/dist/harness/session/jsonl/repo.js +266 -156
- package/dist/harness/session/jsonl/repo.js.map +1 -1
- package/dist/harness/session/jsonl/storage.d.ts +39 -41
- package/dist/harness/session/jsonl/storage.d.ts.map +1 -1
- package/dist/harness/session/jsonl/storage.js +238 -181
- package/dist/harness/session/jsonl/storage.js.map +1 -1
- package/dist/harness/session/jsonl/types.d.ts +23 -22
- package/dist/harness/session/jsonl/types.d.ts.map +1 -1
- package/dist/harness/session/jsonl/types.js +2 -1
- package/dist/harness/session/jsonl/types.js.map +1 -1
- package/dist/harness/session/memory.d.ts +46 -40
- package/dist/harness/session/memory.d.ts.map +1 -1
- package/dist/harness/session/memory.js +346 -113
- package/dist/harness/session/memory.js.map +1 -1
- package/dist/harness/session/mutation-line.d.ts +8 -0
- package/dist/harness/session/mutation-line.d.ts.map +1 -0
- package/dist/harness/session/mutation-line.js +21 -0
- package/dist/harness/session/mutation-line.js.map +1 -0
- package/dist/harness/session/session.d.ts +78 -46
- package/dist/harness/session/session.d.ts.map +1 -1
- package/dist/harness/session/session.js +343 -209
- package/dist/harness/session/session.js.map +1 -1
- package/dist/harness/session/testing/benchmark/datasets.d.ts +12 -0
- package/dist/harness/session/testing/benchmark/datasets.d.ts.map +1 -0
- package/dist/harness/session/testing/benchmark/datasets.js +24 -0
- package/dist/harness/session/testing/benchmark/datasets.js.map +1 -0
- package/dist/harness/session/testing/benchmark/session-repo.d.ts +42 -0
- package/dist/harness/session/testing/benchmark/session-repo.d.ts.map +1 -0
- package/dist/harness/session/testing/benchmark/session-repo.js +127 -0
- package/dist/harness/session/testing/benchmark/session-repo.js.map +1 -0
- package/dist/harness/session/testing/benchmark/storage.d.ts +25 -0
- package/dist/harness/session/testing/benchmark/storage.d.ts.map +1 -0
- package/dist/harness/session/testing/benchmark/storage.js +114 -0
- package/dist/harness/session/testing/benchmark/storage.js.map +1 -0
- package/dist/harness/session/testing/conformance/session-repo.d.ts +21 -0
- package/dist/harness/session/testing/conformance/session-repo.d.ts.map +1 -0
- package/dist/harness/session/testing/conformance/session-repo.js +590 -0
- package/dist/harness/session/testing/conformance/session-repo.js.map +1 -0
- package/dist/harness/session/testing/conformance/storage.d.ts +4 -0
- package/dist/harness/session/testing/conformance/storage.d.ts.map +1 -0
- package/dist/harness/session/testing/conformance/storage.js +600 -0
- package/dist/harness/session/testing/conformance/storage.js.map +1 -0
- package/dist/harness/session/testing/gating-storage.d.ts +26 -0
- package/dist/harness/session/testing/gating-storage.d.ts.map +1 -0
- package/dist/harness/session/testing/gating-storage.js +100 -0
- package/dist/harness/session/testing/gating-storage.js.map +1 -0
- package/dist/harness/session/testing/index.d.ts +9 -2
- package/dist/harness/session/testing/index.d.ts.map +1 -1
- package/dist/harness/session/testing/index.js +8 -1
- package/dist/harness/session/testing/index.js.map +1 -1
- package/dist/harness/session/testing/instrumented-storage.d.ts +11 -0
- package/dist/harness/session/testing/instrumented-storage.d.ts.map +1 -0
- package/dist/harness/session/testing/instrumented-storage.js +16 -0
- package/dist/harness/session/testing/instrumented-storage.js.map +1 -0
- package/dist/harness/session/testing/storage-decorator.d.ts +20 -0
- package/dist/harness/session/testing/storage-decorator.d.ts.map +1 -0
- package/dist/harness/session/testing/storage-decorator.js +41 -0
- package/dist/harness/session/testing/storage-decorator.js.map +1 -0
- package/dist/harness/session/testing/types.d.ts +5 -7
- package/dist/harness/session/testing/types.d.ts.map +1 -1
- package/dist/harness/session/testing/types.js.map +1 -1
- package/dist/harness/session/types.d.ts +424 -259
- package/dist/harness/session/types.d.ts.map +1 -1
- package/dist/harness/session/types.js +7 -8
- package/dist/harness/session/types.js.map +1 -1
- package/dist/harness/session/values.d.ts +95 -0
- package/dist/harness/session/values.d.ts.map +1 -0
- package/dist/harness/session/values.js +81 -0
- package/dist/harness/session/values.js.map +1 -0
- package/dist/harness/skills.d.ts +3 -2
- package/dist/harness/skills.d.ts.map +1 -1
- package/dist/harness/skills.js +29 -26
- package/dist/harness/skills.js.map +1 -1
- package/dist/harness/telemetry.d.ts +64 -43
- package/dist/harness/telemetry.d.ts.map +1 -1
- package/dist/harness/telemetry.js +45 -26
- package/dist/harness/telemetry.js.map +1 -1
- package/dist/harness/tools/bash.d.ts +4 -4
- package/dist/harness/tools/bash.d.ts.map +1 -1
- package/dist/harness/tools/bash.js +66 -93
- package/dist/harness/tools/bash.js.map +1 -1
- package/dist/harness/tools/edit.d.ts.map +1 -1
- package/dist/harness/tools/edit.js +10 -10
- package/dist/harness/tools/edit.js.map +1 -1
- package/dist/harness/tools/file-mutation-queue.d.ts +2 -1
- package/dist/harness/tools/file-mutation-queue.d.ts.map +1 -1
- package/dist/harness/tools/file-mutation-queue.js +5 -5
- package/dist/harness/tools/file-mutation-queue.js.map +1 -1
- package/dist/harness/tools/path-utils.d.ts +3 -2
- package/dist/harness/tools/path-utils.d.ts.map +1 -1
- package/dist/harness/tools/path-utils.js +5 -5
- package/dist/harness/tools/path-utils.js.map +1 -1
- package/dist/harness/tools/read.d.ts +2 -1
- package/dist/harness/tools/read.d.ts.map +1 -1
- package/dist/harness/tools/read.js +4 -6
- package/dist/harness/tools/read.js.map +1 -1
- package/dist/harness/tools/write.d.ts.map +1 -1
- package/dist/harness/tools/write.js +7 -7
- package/dist/harness/tools/write.js.map +1 -1
- package/dist/harness/types.d.ts +108 -45
- package/dist/harness/types.d.ts.map +1 -1
- package/dist/harness/types.js.map +1 -1
- package/dist/harness/utils/adaptive-publisher.d.ts +24 -0
- package/dist/harness/utils/adaptive-publisher.d.ts.map +1 -0
- package/dist/harness/utils/adaptive-publisher.js +79 -0
- package/dist/harness/utils/adaptive-publisher.js.map +1 -0
- package/dist/harness/utils/output-capture.d.ts +31 -0
- package/dist/harness/utils/output-capture.d.ts.map +1 -0
- package/dist/harness/utils/output-capture.js +217 -0
- package/dist/harness/utils/output-capture.js.map +1 -0
- package/dist/harness/utils/shell-output.d.ts +12 -5
- package/dist/harness/utils/shell-output.d.ts.map +1 -1
- package/dist/harness/utils/shell-output.js +64 -174
- package/dist/harness/utils/shell-output.js.map +1 -1
- package/dist/harness/utils/truncate.d.ts +1 -0
- package/dist/harness/utils/truncate.d.ts.map +1 -1
- package/dist/harness/utils/truncate.js +1 -1
- package/dist/harness/utils/truncate.js.map +1 -1
- package/dist/harness/utils/usage.d.ts +4 -0
- package/dist/harness/utils/usage.d.ts.map +1 -0
- package/dist/harness/utils/usage.js +33 -0
- package/dist/harness/utils/usage.js.map +1 -0
- package/dist/index.d.ts +4 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -6
- package/dist/index.js.map +1 -1
- package/dist/proxy.d.ts +2 -0
- package/dist/proxy.d.ts.map +1 -1
- package/dist/proxy.js +40 -10
- package/dist/proxy.js.map +1 -1
- package/dist/search/index.d.ts +24 -16
- package/dist/search/index.d.ts.map +1 -1
- package/dist/search/index.js +1 -1
- package/dist/search/index.js.map +1 -1
- package/dist/types.d.ts +2 -0
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js.map +1 -1
- package/package.json +25 -4
- package/dist/harness/reducer.d.ts +0 -100
- package/dist/harness/reducer.d.ts.map +0 -1
- package/dist/harness/reducer.js +0 -415
- package/dist/harness/reducer.js.map +0 -1
- package/dist/harness/session/jsonl/errors.d.ts +0 -9
- package/dist/harness/session/jsonl/errors.d.ts.map +0 -1
- package/dist/harness/session/jsonl/errors.js +0 -19
- package/dist/harness/session/jsonl/errors.js.map +0 -1
- package/dist/harness/session/jsonl.d.ts +0 -3
- package/dist/harness/session/jsonl.d.ts.map +0 -1
- package/dist/harness/session/jsonl.js +0 -2
- package/dist/harness/session/jsonl.js.map +0 -1
- package/dist/harness/session/state.d.ts +0 -65
- package/dist/harness/session/state.d.ts.map +0 -1
- package/dist/harness/session/state.js +0 -319
- package/dist/harness/session/state.js.map +0 -1
- package/dist/harness/session/testing/conformance.d.ts +0 -4
- package/dist/harness/session/testing/conformance.d.ts.map +0 -1
- package/dist/harness/session/testing/conformance.js +0 -762
- package/dist/harness/session/testing/conformance.js.map +0 -1
- package/dist/search/scanning.d.ts +0 -29
- package/dist/search/scanning.d.ts.map +0 -1
- package/dist/search/scanning.js +0 -103
- package/dist/search/scanning.js.map +0 -1
|
@@ -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,
|
|
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","sourcesContent":["import { err, ok, type Result } from \"../../types.ts\";\nimport { JSONL_FORMAT_VERSION, type JsonlStorageHeader } from \"./types.ts\";\n\nexport interface LegacyV3SessionHeader {\n\ttype: \"session\";\n\tversion: 3;\n\tid: string;\n\ttimestamp: string;\n\tcwd: string;\n\tparentSession?: string;\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n\treturn typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\nfunction isSafeIntegerAtLeast(value: unknown, minimum: number): value is number {\n\treturn Number.isSafeInteger(value) && (value as number) >= minimum;\n}\n\nexport function isLegacyV3SessionHeader(value: unknown): value is LegacyV3SessionHeader {\n\treturn (\n\t\tisRecord(value) &&\n\t\tvalue.type === \"session\" &&\n\t\tvalue.version === 3 &&\n\t\ttypeof value.id === \"string\" &&\n\t\ttypeof value.cwd === \"string\" &&\n\t\ttypeof value.timestamp === \"string\" &&\n\t\tNumber.isFinite(Date.parse(value.timestamp)) &&\n\t\t(value.parentSession === undefined || typeof value.parentSession === \"string\")\n\t);\n}\n\nexport function isJsonlStorageHeader(value: unknown): value is JsonlStorageHeader {\n\treturn (\n\t\tisRecord(value) &&\n\t\tvalue.kind === \"header\" &&\n\t\tvalue.v === JSONL_FORMAT_VERSION &&\n\t\ttypeof value.id === \"string\" &&\n\t\ttypeof value.cwd === \"string\" &&\n\t\tisSafeIntegerAtLeast(value.storageVersion, 1) &&\n\t\tisSafeIntegerAtLeast(value.createdAt, 0) &&\n\t\t(value.nextSeq === undefined || isSafeIntegerAtLeast(value.nextSeq, 1)) &&\n\t\t(value.parentSessionId === undefined || typeof value.parentSessionId === \"string\") &&\n\t\t(value.legacyParentSessionPath === undefined || typeof value.legacyParentSessionPath === \"string\")\n\t);\n}\n\nexport type JsonlParsedSessionHeader =\n\t| { format: \"v4\"; header: JsonlStorageHeader }\n\t| { format: \"v3-legacy\"; header: LegacyV3SessionHeader };\n\nexport function parseJsonlSessionHeader(line: string): Result<JsonlParsedSessionHeader, Error> {\n\tlet value: unknown;\n\ttry {\n\t\tvalue = JSON.parse(line);\n\t} catch (error) {\n\t\treturn err(new Error(\"Invalid JSONL session header: not valid JSON\", { cause: error }));\n\t}\n\tif (isJsonlStorageHeader(value)) return ok({ format: \"v4\", header: value });\n\tif (isLegacyV3SessionHeader(value)) return ok({ format: \"v3-legacy\", header: value });\n\treturn err(new Error(\"Unsupported JSONL session header\"));\n}\n"]}
|
|
@@ -1,229 +1,45 @@
|
|
|
1
1
|
import { err, ok } from "../../types.js";
|
|
2
|
-
import {
|
|
3
|
-
|
|
4
|
-
"message",
|
|
5
|
-
"model_change",
|
|
6
|
-
"thinking_level_change",
|
|
7
|
-
"active_tools_change",
|
|
8
|
-
"compaction",
|
|
9
|
-
"branch_summary",
|
|
10
|
-
"custom",
|
|
11
|
-
]);
|
|
12
|
-
const RECORD_TYPES = new Set([
|
|
13
|
-
"operation_started",
|
|
14
|
-
"abort_requested",
|
|
15
|
-
"operation_finished",
|
|
16
|
-
"step_attempt",
|
|
17
|
-
"tool_started",
|
|
18
|
-
"queue_enqueued",
|
|
19
|
-
"queue_cancelled",
|
|
20
|
-
"write_deferred",
|
|
21
|
-
"usage",
|
|
22
|
-
]);
|
|
23
|
-
const OPERATION_KINDS = new Set(["run", "compaction", "navigation"]);
|
|
24
|
-
function isObject(value) {
|
|
2
|
+
import { JSONL_FORMAT_VERSION } from "./types.js";
|
|
3
|
+
function isRecord(value) {
|
|
25
4
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
26
5
|
}
|
|
27
|
-
function
|
|
6
|
+
function isSafeIntegerAtLeast(value, minimum) {
|
|
7
|
+
return Number.isSafeInteger(value) && value >= minimum;
|
|
8
|
+
}
|
|
9
|
+
export function isLegacyV3SessionHeader(value) {
|
|
10
|
+
return (isRecord(value) &&
|
|
11
|
+
value.type === "session" &&
|
|
12
|
+
value.version === 3 &&
|
|
13
|
+
typeof value.id === "string" &&
|
|
14
|
+
typeof value.cwd === "string" &&
|
|
15
|
+
typeof value.timestamp === "string" &&
|
|
16
|
+
Number.isFinite(Date.parse(value.timestamp)) &&
|
|
17
|
+
(value.parentSession === undefined || typeof value.parentSession === "string"));
|
|
18
|
+
}
|
|
19
|
+
export function isJsonlStorageHeader(value) {
|
|
20
|
+
return (isRecord(value) &&
|
|
21
|
+
value.kind === "header" &&
|
|
22
|
+
value.v === JSONL_FORMAT_VERSION &&
|
|
23
|
+
typeof value.id === "string" &&
|
|
24
|
+
typeof value.cwd === "string" &&
|
|
25
|
+
isSafeIntegerAtLeast(value.storageVersion, 1) &&
|
|
26
|
+
isSafeIntegerAtLeast(value.createdAt, 0) &&
|
|
27
|
+
(value.nextSeq === undefined || isSafeIntegerAtLeast(value.nextSeq, 1)) &&
|
|
28
|
+
(value.parentSessionId === undefined || typeof value.parentSessionId === "string") &&
|
|
29
|
+
(value.legacyParentSessionPath === undefined || typeof value.legacyParentSessionPath === "string"));
|
|
30
|
+
}
|
|
31
|
+
export function parseJsonlSessionHeader(line) {
|
|
28
32
|
let value;
|
|
29
33
|
try {
|
|
30
34
|
value = JSON.parse(line);
|
|
31
35
|
}
|
|
32
36
|
catch (error) {
|
|
33
|
-
|
|
34
|
-
}
|
|
35
|
-
if (!isObject(value))
|
|
36
|
-
throw new JsonlDecodeError("schema", "is not a JSON object");
|
|
37
|
-
return value;
|
|
38
|
-
}
|
|
39
|
-
function requireString(value, field) {
|
|
40
|
-
if (typeof value !== "string")
|
|
41
|
-
throw new JsonlDecodeError("schema", `has invalid ${field}`);
|
|
42
|
-
return value;
|
|
43
|
-
}
|
|
44
|
-
function requireSequence(value) {
|
|
45
|
-
if (!Number.isSafeInteger(value) || value <= 0) {
|
|
46
|
-
throw new JsonlDecodeError("schema", "has invalid seq");
|
|
47
|
-
}
|
|
48
|
-
return value;
|
|
49
|
-
}
|
|
50
|
-
function requireTimestamp(value) {
|
|
51
|
-
if (!Number.isSafeInteger(value) || value < 0) {
|
|
52
|
-
throw new JsonlDecodeError("schema", "has invalid timestamp");
|
|
53
|
-
}
|
|
54
|
-
return value;
|
|
55
|
-
}
|
|
56
|
-
function requireNullableId(value, field) {
|
|
57
|
-
if (value !== null && typeof value !== "string") {
|
|
58
|
-
throw new JsonlDecodeError("schema", `has invalid ${field}`);
|
|
59
|
-
}
|
|
60
|
-
return value;
|
|
61
|
-
}
|
|
62
|
-
function decodeHeader(line) {
|
|
63
|
-
const value = parseObject(line);
|
|
64
|
-
if (value.kind !== "header")
|
|
65
|
-
throw new JsonlDecodeError("schema", "is not a header");
|
|
66
|
-
if (value.version !== 4)
|
|
67
|
-
throw new JsonlDecodeError("schema", "has unsupported session version");
|
|
68
|
-
const parentSessionId = value.parentSessionId;
|
|
69
|
-
if (parentSessionId !== undefined && typeof parentSessionId !== "string") {
|
|
70
|
-
throw new JsonlDecodeError("schema", "has invalid parentSessionId");
|
|
71
|
-
}
|
|
72
|
-
const legacyParentSessionPath = value.legacyParentSessionPath;
|
|
73
|
-
if (legacyParentSessionPath !== undefined && typeof legacyParentSessionPath !== "string") {
|
|
74
|
-
throw new JsonlDecodeError("schema", "has invalid legacyParentSessionPath");
|
|
75
|
-
}
|
|
76
|
-
if (parentSessionId !== undefined && legacyParentSessionPath !== undefined) {
|
|
77
|
-
throw new JsonlDecodeError("schema", "has both parentSessionId and legacyParentSessionPath");
|
|
78
|
-
}
|
|
79
|
-
const metadataValue = value.metadata;
|
|
80
|
-
if (metadataValue !== undefined && !isObject(metadataValue)) {
|
|
81
|
-
throw new JsonlDecodeError("schema", "has invalid metadata");
|
|
82
|
-
}
|
|
83
|
-
const metadata = metadataValue;
|
|
84
|
-
return {
|
|
85
|
-
kind: "header",
|
|
86
|
-
version: 4,
|
|
87
|
-
id: requireString(value.id, "id"),
|
|
88
|
-
createdAt: requireTimestamp(value.createdAt),
|
|
89
|
-
cwd: requireString(value.cwd, "cwd"),
|
|
90
|
-
parentSessionId,
|
|
91
|
-
legacyParentSessionPath,
|
|
92
|
-
metadata,
|
|
93
|
-
};
|
|
94
|
-
}
|
|
95
|
-
export function parseHeader(line) {
|
|
96
|
-
try {
|
|
97
|
-
return ok(decodeHeader(line));
|
|
98
|
-
}
|
|
99
|
-
catch (error) {
|
|
100
|
-
if (error instanceof JsonlDecodeError)
|
|
101
|
-
return err(error);
|
|
102
|
-
throw error;
|
|
103
|
-
}
|
|
104
|
-
}
|
|
105
|
-
export function encodeHeader(header) {
|
|
106
|
-
return `${JSON.stringify(header)}\n`;
|
|
107
|
-
}
|
|
108
|
-
export function metadataFromHeader(header, path, modifiedAt) {
|
|
109
|
-
return {
|
|
110
|
-
id: header.id,
|
|
111
|
-
createdAt: header.createdAt,
|
|
112
|
-
cwd: header.cwd,
|
|
113
|
-
path,
|
|
114
|
-
modifiedAt,
|
|
115
|
-
sourceFormat: 4,
|
|
116
|
-
...(header.parentSessionId === undefined ? {} : { parentSessionId: header.parentSessionId }),
|
|
117
|
-
...(header.legacyParentSessionPath === undefined
|
|
118
|
-
? {}
|
|
119
|
-
: { legacyParentSessionPath: header.legacyParentSessionPath }),
|
|
120
|
-
...(header.metadata === undefined ? {} : { metadata: header.metadata }),
|
|
121
|
-
};
|
|
122
|
-
}
|
|
123
|
-
function parseEntryMutation(value, seq) {
|
|
124
|
-
const lane = value.lane === undefined ? undefined : requireString(value.lane, "lane");
|
|
125
|
-
const id = requireString(value.id, "id");
|
|
126
|
-
const type = requireString(value.type, "entry type");
|
|
127
|
-
if (!ENTRY_TYPES.has(type)) {
|
|
128
|
-
throw new JsonlDecodeError("schema", `has unknown entry type ${type}`);
|
|
129
|
-
}
|
|
130
|
-
const parentId = requireNullableId(value.parentId, "parentId");
|
|
131
|
-
const timestamp = requireTimestamp(value.timestamp);
|
|
132
|
-
if (type === "custom")
|
|
133
|
-
requireString(value.customType, "customType");
|
|
134
|
-
const { kind: _kind, lane: _lane, ...entryFields } = value;
|
|
135
|
-
const entry = { ...entryFields, id, type, parentId, seq, timestamp };
|
|
136
|
-
return lane === undefined ? { kind: "entry", entry } : { kind: "entry", lane, entry };
|
|
137
|
-
}
|
|
138
|
-
function parseRecordMutation(value, seq) {
|
|
139
|
-
const id = requireString(value.id, "id");
|
|
140
|
-
const lane = requireString(value.lane, "lane");
|
|
141
|
-
const type = requireString(value.type, "record type");
|
|
142
|
-
if (!RECORD_TYPES.has(type)) {
|
|
143
|
-
throw new JsonlDecodeError("schema", `has unknown record type ${type}`);
|
|
144
|
-
}
|
|
145
|
-
const timestamp = requireTimestamp(value.timestamp);
|
|
146
|
-
if (type === "operation_started") {
|
|
147
|
-
if (!isObject(value.intent))
|
|
148
|
-
throw new JsonlDecodeError("schema", "has invalid intent");
|
|
149
|
-
const operationKind = requireString(value.intent.kind, "operation kind");
|
|
150
|
-
if (!OPERATION_KINDS.has(operationKind)) {
|
|
151
|
-
throw new JsonlDecodeError("schema", `has unknown operation kind ${operationKind}`);
|
|
152
|
-
}
|
|
153
|
-
}
|
|
154
|
-
if (type === "operation_finished")
|
|
155
|
-
requireString(value.runId, "runId");
|
|
156
|
-
const { kind: _kind, ...recordFields } = value;
|
|
157
|
-
return {
|
|
158
|
-
kind: "record",
|
|
159
|
-
record: { ...recordFields, id, lane, type, seq, timestamp },
|
|
160
|
-
};
|
|
161
|
-
}
|
|
162
|
-
function parseLaneMutation(value, seq) {
|
|
163
|
-
return {
|
|
164
|
-
kind: "lane",
|
|
165
|
-
seq,
|
|
166
|
-
lane: requireString(value.lane, "lane"),
|
|
167
|
-
leafId: requireNullableId(value.leafId, "leafId"),
|
|
168
|
-
};
|
|
169
|
-
}
|
|
170
|
-
function parseFactMutation(value, seq) {
|
|
171
|
-
if (value.fact === "name") {
|
|
172
|
-
if (value.name !== undefined && typeof value.name !== "string") {
|
|
173
|
-
throw new JsonlDecodeError("schema", "has invalid name");
|
|
174
|
-
}
|
|
175
|
-
return { kind: "fact", seq, fact: "name", name: value.name };
|
|
176
|
-
}
|
|
177
|
-
if (value.fact === "label") {
|
|
178
|
-
if (value.label !== undefined && typeof value.label !== "string") {
|
|
179
|
-
throw new JsonlDecodeError("schema", "has invalid label");
|
|
180
|
-
}
|
|
181
|
-
return {
|
|
182
|
-
kind: "fact",
|
|
183
|
-
seq,
|
|
184
|
-
fact: "label",
|
|
185
|
-
targetId: requireString(value.targetId, "targetId"),
|
|
186
|
-
label: value.label,
|
|
187
|
-
};
|
|
188
|
-
}
|
|
189
|
-
throw new JsonlDecodeError("schema", "has unknown fact type");
|
|
190
|
-
}
|
|
191
|
-
function decodeMutation(line) {
|
|
192
|
-
const value = parseObject(line);
|
|
193
|
-
const seq = requireSequence(value.seq);
|
|
194
|
-
switch (value.kind) {
|
|
195
|
-
case "entry":
|
|
196
|
-
return parseEntryMutation(value, seq);
|
|
197
|
-
case "record":
|
|
198
|
-
return parseRecordMutation(value, seq);
|
|
199
|
-
case "lane":
|
|
200
|
-
return parseLaneMutation(value, seq);
|
|
201
|
-
case "fact":
|
|
202
|
-
return parseFactMutation(value, seq);
|
|
203
|
-
default:
|
|
204
|
-
throw new JsonlDecodeError("schema", "has unknown mutation kind");
|
|
205
|
-
}
|
|
206
|
-
}
|
|
207
|
-
export function parseMutation(line) {
|
|
208
|
-
try {
|
|
209
|
-
return ok(decodeMutation(line));
|
|
210
|
-
}
|
|
211
|
-
catch (error) {
|
|
212
|
-
if (error instanceof JsonlDecodeError)
|
|
213
|
-
return err(error);
|
|
214
|
-
throw error;
|
|
215
|
-
}
|
|
216
|
-
}
|
|
217
|
-
export function encodeMutation(mutation) {
|
|
218
|
-
switch (mutation.kind) {
|
|
219
|
-
case "entry":
|
|
220
|
-
return `${JSON.stringify({ kind: "entry", lane: mutation.lane, ...mutation.entry })}\n`;
|
|
221
|
-
case "record":
|
|
222
|
-
return `${JSON.stringify({ kind: "record", ...mutation.record })}\n`;
|
|
223
|
-
case "lane":
|
|
224
|
-
return `${JSON.stringify(mutation)}\n`;
|
|
225
|
-
case "fact":
|
|
226
|
-
return `${JSON.stringify(mutation)}\n`;
|
|
37
|
+
return err(new Error("Invalid JSONL session header: not valid JSON", { cause: error }));
|
|
227
38
|
}
|
|
39
|
+
if (isJsonlStorageHeader(value))
|
|
40
|
+
return ok({ format: "v4", header: value });
|
|
41
|
+
if (isLegacyV3SessionHeader(value))
|
|
42
|
+
return ok({ format: "v3-legacy", header: value });
|
|
43
|
+
return err(new Error("Unsupported JSONL session header"));
|
|
228
44
|
}
|
|
229
45
|
//# sourceMappingURL=codec.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"codec.js","sourceRoot":"","sources":["../../../../src/harness/session/jsonl/codec.ts"],"names":[],"mappings":"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","sourcesContent":["import { err, ok, type Result } from \"../../types.ts\";\nimport type { SessionMutation } from \"../state.ts\";\nimport type { Entry, LaneRecord } from \"../types.ts\";\nimport { JsonlDecodeError } from \"./errors.ts\";\nimport type { JsonlSessionMetadata, JsonlV4Header } from \"./types.ts\";\n\nconst ENTRY_TYPES = new Set<Entry[\"type\"]>([\n\t\"message\",\n\t\"model_change\",\n\t\"thinking_level_change\",\n\t\"active_tools_change\",\n\t\"compaction\",\n\t\"branch_summary\",\n\t\"custom\",\n]);\nconst RECORD_TYPES = new Set<LaneRecord[\"type\"]>([\n\t\"operation_started\",\n\t\"abort_requested\",\n\t\"operation_finished\",\n\t\"step_attempt\",\n\t\"tool_started\",\n\t\"queue_enqueued\",\n\t\"queue_cancelled\",\n\t\"write_deferred\",\n\t\"usage\",\n]);\nconst OPERATION_KINDS = new Set([\"run\", \"compaction\", \"navigation\"]);\n\nfunction isObject(value: unknown): value is Record<string, unknown> {\n\treturn typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\nfunction parseObject(line: string): Record<string, unknown> {\n\tlet value: unknown;\n\ttry {\n\t\tvalue = JSON.parse(line);\n\t} catch (error) {\n\t\tthrow new JsonlDecodeError(\"syntax\", \"is not valid JSON\", error instanceof Error ? error : undefined);\n\t}\n\tif (!isObject(value)) throw new JsonlDecodeError(\"schema\", \"is not a JSON object\");\n\treturn value;\n}\n\nfunction requireString(value: unknown, field: string): string {\n\tif (typeof value !== \"string\") throw new JsonlDecodeError(\"schema\", `has invalid ${field}`);\n\treturn value;\n}\n\nfunction requireSequence(value: unknown): number {\n\tif (!Number.isSafeInteger(value) || (value as number) <= 0) {\n\t\tthrow new JsonlDecodeError(\"schema\", \"has invalid seq\");\n\t}\n\treturn value as number;\n}\n\nfunction requireTimestamp(value: unknown): number {\n\tif (!Number.isSafeInteger(value) || (value as number) < 0) {\n\t\tthrow new JsonlDecodeError(\"schema\", \"has invalid timestamp\");\n\t}\n\treturn value as number;\n}\n\nfunction requireNullableId(value: unknown, field: string): string | null {\n\tif (value !== null && typeof value !== \"string\") {\n\t\tthrow new JsonlDecodeError(\"schema\", `has invalid ${field}`);\n\t}\n\treturn value as string | null;\n}\n\nfunction decodeHeader(line: string): JsonlV4Header {\n\tconst value = parseObject(line);\n\tif (value.kind !== \"header\") throw new JsonlDecodeError(\"schema\", \"is not a header\");\n\tif (value.version !== 4) throw new JsonlDecodeError(\"schema\", \"has unsupported session version\");\n\tconst parentSessionId = value.parentSessionId;\n\tif (parentSessionId !== undefined && typeof parentSessionId !== \"string\") {\n\t\tthrow new JsonlDecodeError(\"schema\", \"has invalid parentSessionId\");\n\t}\n\tconst legacyParentSessionPath = value.legacyParentSessionPath;\n\tif (legacyParentSessionPath !== undefined && typeof legacyParentSessionPath !== \"string\") {\n\t\tthrow new JsonlDecodeError(\"schema\", \"has invalid legacyParentSessionPath\");\n\t}\n\tif (parentSessionId !== undefined && legacyParentSessionPath !== undefined) {\n\t\tthrow new JsonlDecodeError(\"schema\", \"has both parentSessionId and legacyParentSessionPath\");\n\t}\n\tconst metadataValue = value.metadata;\n\tif (metadataValue !== undefined && !isObject(metadataValue)) {\n\t\tthrow new JsonlDecodeError(\"schema\", \"has invalid metadata\");\n\t}\n\tconst metadata = metadataValue as JsonlV4Header[\"metadata\"];\n\treturn {\n\t\tkind: \"header\",\n\t\tversion: 4,\n\t\tid: requireString(value.id, \"id\"),\n\t\tcreatedAt: requireTimestamp(value.createdAt),\n\t\tcwd: requireString(value.cwd, \"cwd\"),\n\t\tparentSessionId,\n\t\tlegacyParentSessionPath,\n\t\tmetadata,\n\t};\n}\n\nexport function parseHeader(line: string): Result<JsonlV4Header, JsonlDecodeError> {\n\ttry {\n\t\treturn ok<JsonlV4Header, JsonlDecodeError>(decodeHeader(line));\n\t} catch (error) {\n\t\tif (error instanceof JsonlDecodeError) return err<JsonlV4Header, JsonlDecodeError>(error);\n\t\tthrow error;\n\t}\n}\n\nexport function encodeHeader(header: JsonlV4Header): string {\n\treturn `${JSON.stringify(header)}\\n`;\n}\n\nexport function metadataFromHeader(header: JsonlV4Header, path: string, modifiedAt: number): JsonlSessionMetadata {\n\treturn {\n\t\tid: header.id,\n\t\tcreatedAt: header.createdAt,\n\t\tcwd: header.cwd,\n\t\tpath,\n\t\tmodifiedAt,\n\t\tsourceFormat: 4,\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\t...(header.metadata === undefined ? {} : { metadata: header.metadata }),\n\t};\n}\n\nfunction parseEntryMutation(value: Record<string, unknown>, seq: number): Extract<SessionMutation, { kind: \"entry\" }> {\n\tconst lane = value.lane === undefined ? undefined : requireString(value.lane, \"lane\");\n\tconst id = requireString(value.id, \"id\");\n\tconst type = requireString(value.type, \"entry type\");\n\tif (!ENTRY_TYPES.has(type as Entry[\"type\"])) {\n\t\tthrow new JsonlDecodeError(\"schema\", `has unknown entry type ${type}`);\n\t}\n\tconst parentId = requireNullableId(value.parentId, \"parentId\");\n\tconst timestamp = requireTimestamp(value.timestamp);\n\tif (type === \"custom\") requireString(value.customType, \"customType\");\n\tconst { kind: _kind, lane: _lane, ...entryFields } = value;\n\tconst entry = { ...entryFields, id, type, parentId, seq, timestamp } as unknown as Entry;\n\treturn lane === undefined ? { kind: \"entry\", entry } : { kind: \"entry\", lane, entry };\n}\n\nfunction parseRecordMutation(\n\tvalue: Record<string, unknown>,\n\tseq: number,\n): Extract<SessionMutation, { kind: \"record\" }> {\n\tconst id = requireString(value.id, \"id\");\n\tconst lane = requireString(value.lane, \"lane\");\n\tconst type = requireString(value.type, \"record type\");\n\tif (!RECORD_TYPES.has(type as LaneRecord[\"type\"])) {\n\t\tthrow new JsonlDecodeError(\"schema\", `has unknown record type ${type}`);\n\t}\n\tconst timestamp = requireTimestamp(value.timestamp);\n\tif (type === \"operation_started\") {\n\t\tif (!isObject(value.intent)) throw new JsonlDecodeError(\"schema\", \"has invalid intent\");\n\t\tconst operationKind = requireString(value.intent.kind, \"operation kind\");\n\t\tif (!OPERATION_KINDS.has(operationKind)) {\n\t\t\tthrow new JsonlDecodeError(\"schema\", `has unknown operation kind ${operationKind}`);\n\t\t}\n\t}\n\tif (type === \"operation_finished\") requireString(value.runId, \"runId\");\n\tconst { kind: _kind, ...recordFields } = value;\n\treturn {\n\t\tkind: \"record\",\n\t\trecord: { ...recordFields, id, lane, type, seq, timestamp } as unknown as LaneRecord,\n\t};\n}\n\nfunction parseLaneMutation(value: Record<string, unknown>, seq: number): Extract<SessionMutation, { kind: \"lane\" }> {\n\treturn {\n\t\tkind: \"lane\",\n\t\tseq,\n\t\tlane: requireString(value.lane, \"lane\"),\n\t\tleafId: requireNullableId(value.leafId, \"leafId\"),\n\t};\n}\n\nfunction parseFactMutation(value: Record<string, unknown>, seq: number): Extract<SessionMutation, { kind: \"fact\" }> {\n\tif (value.fact === \"name\") {\n\t\tif (value.name !== undefined && typeof value.name !== \"string\") {\n\t\t\tthrow new JsonlDecodeError(\"schema\", \"has invalid name\");\n\t\t}\n\t\treturn { kind: \"fact\", seq, fact: \"name\", name: value.name };\n\t}\n\tif (value.fact === \"label\") {\n\t\tif (value.label !== undefined && typeof value.label !== \"string\") {\n\t\t\tthrow new JsonlDecodeError(\"schema\", \"has invalid label\");\n\t\t}\n\t\treturn {\n\t\t\tkind: \"fact\",\n\t\t\tseq,\n\t\t\tfact: \"label\",\n\t\t\ttargetId: requireString(value.targetId, \"targetId\"),\n\t\t\tlabel: value.label,\n\t\t};\n\t}\n\tthrow new JsonlDecodeError(\"schema\", \"has unknown fact type\");\n}\n\nfunction decodeMutation(line: string): SessionMutation {\n\tconst value = parseObject(line);\n\tconst seq = requireSequence(value.seq);\n\tswitch (value.kind) {\n\t\tcase \"entry\":\n\t\t\treturn parseEntryMutation(value, seq);\n\t\tcase \"record\":\n\t\t\treturn parseRecordMutation(value, seq);\n\t\tcase \"lane\":\n\t\t\treturn parseLaneMutation(value, seq);\n\t\tcase \"fact\":\n\t\t\treturn parseFactMutation(value, seq);\n\t\tdefault:\n\t\t\tthrow new JsonlDecodeError(\"schema\", \"has unknown mutation kind\");\n\t}\n}\n\nexport function parseMutation(line: string): Result<SessionMutation, JsonlDecodeError> {\n\ttry {\n\t\treturn ok<SessionMutation, JsonlDecodeError>(decodeMutation(line));\n\t} catch (error) {\n\t\tif (error instanceof JsonlDecodeError) return err<SessionMutation, JsonlDecodeError>(error);\n\t\tthrow error;\n\t}\n}\n\nexport function encodeMutation(mutation: SessionMutation): string {\n\tswitch (mutation.kind) {\n\t\tcase \"entry\":\n\t\t\treturn `${JSON.stringify({ kind: \"entry\", lane: mutation.lane, ...mutation.entry })}\\n`;\n\t\tcase \"record\":\n\t\t\treturn `${JSON.stringify({ kind: \"record\", ...mutation.record })}\\n`;\n\t\tcase \"lane\":\n\t\t\treturn `${JSON.stringify(mutation)}\\n`;\n\t\tcase \"fact\":\n\t\t\treturn `${JSON.stringify(mutation)}\\n`;\n\t}\n}\n"]}
|
|
1
|
+
{"version":3,"file":"codec.js","sourceRoot":"","sources":["../../../../src/harness/session/jsonl/codec.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,EAAE,EAAe,MAAM,gBAAgB,CAAC;AACtD,OAAO,EAAE,oBAAoB,EAA2B,MAAM,YAAY,CAAC;AAW3E,SAAS,QAAQ,CAAC,KAAc,EAAoC;IACnE,OAAO,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;AAAA,CAC5E;AAED,SAAS,oBAAoB,CAAC,KAAc,EAAE,OAAe,EAAmB;IAC/E,OAAO,MAAM,CAAC,aAAa,CAAC,KAAK,CAAC,IAAK,KAAgB,IAAI,OAAO,CAAC;AAAA,CACnE;AAED,MAAM,UAAU,uBAAuB,CAAC,KAAc,EAAkC;IACvF,OAAO,CACN,QAAQ,CAAC,KAAK,CAAC;QACf,KAAK,CAAC,IAAI,KAAK,SAAS;QACxB,KAAK,CAAC,OAAO,KAAK,CAAC;QACnB,OAAO,KAAK,CAAC,EAAE,KAAK,QAAQ;QAC5B,OAAO,KAAK,CAAC,GAAG,KAAK,QAAQ;QAC7B,OAAO,KAAK,CAAC,SAAS,KAAK,QAAQ;QACnC,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC;QAC5C,CAAC,KAAK,CAAC,aAAa,KAAK,SAAS,IAAI,OAAO,KAAK,CAAC,aAAa,KAAK,QAAQ,CAAC,CAC9E,CAAC;AAAA,CACF;AAED,MAAM,UAAU,oBAAoB,CAAC,KAAc,EAA+B;IACjF,OAAO,CACN,QAAQ,CAAC,KAAK,CAAC;QACf,KAAK,CAAC,IAAI,KAAK,QAAQ;QACvB,KAAK,CAAC,CAAC,KAAK,oBAAoB;QAChC,OAAO,KAAK,CAAC,EAAE,KAAK,QAAQ;QAC5B,OAAO,KAAK,CAAC,GAAG,KAAK,QAAQ;QAC7B,oBAAoB,CAAC,KAAK,CAAC,cAAc,EAAE,CAAC,CAAC;QAC7C,oBAAoB,CAAC,KAAK,CAAC,SAAS,EAAE,CAAC,CAAC;QACxC,CAAC,KAAK,CAAC,OAAO,KAAK,SAAS,IAAI,oBAAoB,CAAC,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC;QACvE,CAAC,KAAK,CAAC,eAAe,KAAK,SAAS,IAAI,OAAO,KAAK,CAAC,eAAe,KAAK,QAAQ,CAAC;QAClF,CAAC,KAAK,CAAC,uBAAuB,KAAK,SAAS,IAAI,OAAO,KAAK,CAAC,uBAAuB,KAAK,QAAQ,CAAC,CAClG,CAAC;AAAA,CACF;AAMD,MAAM,UAAU,uBAAuB,CAAC,IAAY,EAA2C;IAC9F,IAAI,KAAc,CAAC;IACnB,IAAI,CAAC;QACJ,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IAC1B,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QAChB,OAAO,GAAG,CAAC,IAAI,KAAK,CAAC,8CAA8C,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC;IACzF,CAAC;IACD,IAAI,oBAAoB,CAAC,KAAK,CAAC;QAAE,OAAO,EAAE,CAAC,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,CAAC;IAC5E,IAAI,uBAAuB,CAAC,KAAK,CAAC;QAAE,OAAO,EAAE,CAAC,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,CAAC;IACtF,OAAO,GAAG,CAAC,IAAI,KAAK,CAAC,kCAAkC,CAAC,CAAC,CAAC;AAAA,CAC1D","sourcesContent":["import { err, ok, type Result } from \"../../types.ts\";\nimport { JSONL_FORMAT_VERSION, type JsonlStorageHeader } from \"./types.ts\";\n\nexport interface LegacyV3SessionHeader {\n\ttype: \"session\";\n\tversion: 3;\n\tid: string;\n\ttimestamp: string;\n\tcwd: string;\n\tparentSession?: string;\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n\treturn typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\nfunction isSafeIntegerAtLeast(value: unknown, minimum: number): value is number {\n\treturn Number.isSafeInteger(value) && (value as number) >= minimum;\n}\n\nexport function isLegacyV3SessionHeader(value: unknown): value is LegacyV3SessionHeader {\n\treturn (\n\t\tisRecord(value) &&\n\t\tvalue.type === \"session\" &&\n\t\tvalue.version === 3 &&\n\t\ttypeof value.id === \"string\" &&\n\t\ttypeof value.cwd === \"string\" &&\n\t\ttypeof value.timestamp === \"string\" &&\n\t\tNumber.isFinite(Date.parse(value.timestamp)) &&\n\t\t(value.parentSession === undefined || typeof value.parentSession === \"string\")\n\t);\n}\n\nexport function isJsonlStorageHeader(value: unknown): value is JsonlStorageHeader {\n\treturn (\n\t\tisRecord(value) &&\n\t\tvalue.kind === \"header\" &&\n\t\tvalue.v === JSONL_FORMAT_VERSION &&\n\t\ttypeof value.id === \"string\" &&\n\t\ttypeof value.cwd === \"string\" &&\n\t\tisSafeIntegerAtLeast(value.storageVersion, 1) &&\n\t\tisSafeIntegerAtLeast(value.createdAt, 0) &&\n\t\t(value.nextSeq === undefined || isSafeIntegerAtLeast(value.nextSeq, 1)) &&\n\t\t(value.parentSessionId === undefined || typeof value.parentSessionId === \"string\") &&\n\t\t(value.legacyParentSessionPath === undefined || typeof value.legacyParentSessionPath === \"string\")\n\t);\n}\n\nexport type JsonlParsedSessionHeader =\n\t| { format: \"v4\"; header: JsonlStorageHeader }\n\t| { format: \"v3-legacy\"; header: LegacyV3SessionHeader };\n\nexport function parseJsonlSessionHeader(line: string): Result<JsonlParsedSessionHeader, Error> {\n\tlet value: unknown;\n\ttry {\n\t\tvalue = JSON.parse(line);\n\t} catch (error) {\n\t\treturn err(new Error(\"Invalid JSONL session header: not valid JSON\", { cause: error }));\n\t}\n\tif (isJsonlStorageHeader(value)) return ok({ format: \"v4\", header: value });\n\tif (isLegacyV3SessionHeader(value)) return ok({ format: \"v3-legacy\", header: value });\n\treturn err(new Error(\"Unsupported JSONL session header\"));\n}\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/harness/session/jsonl/index.ts"],"names":[],"mappings":"AAAA,cAAc,WAAW,CAAC;AAC1B,cAAc,cAAc,CAAC;AAC7B,cAAc,YAAY,CAAC","sourcesContent":["export * from \"./repo.ts\";\nexport * from \"./storage.ts\";\nexport * from \"./types.ts\";\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/harness/session/jsonl/index.ts"],"names":[],"mappings":"AAAA,cAAc,WAAW,CAAC;AAC1B,cAAc,cAAc,CAAC;AAC7B,cAAc,YAAY,CAAC","sourcesContent":["export * from \"./repo.ts\";\nexport * from \"./storage.ts\";\nexport * from \"./types.ts\";\n"]}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { Usage } from "@earendil-works/pi-ai";
|
|
2
|
+
import type { Context } from "../../context.ts";
|
|
3
|
+
import type { FileSystem } from "../../types.ts";
|
|
4
|
+
import type { CommittedWrite } from "../commit.ts";
|
|
5
|
+
import { type LegacyV3SessionHeader } from "./codec.ts";
|
|
6
|
+
import { type JsonlSessionMetadata, type JsonlStorageHeader } from "./types.ts";
|
|
7
|
+
export interface NormalizedLegacyV3Records {
|
|
8
|
+
writes: CommittedWrite[];
|
|
9
|
+
importedUsage: Usage;
|
|
10
|
+
nextSeq: number;
|
|
11
|
+
}
|
|
12
|
+
type JsonlSessionMetadataBase = Omit<JsonlSessionMetadata, "path" | "modifiedAt">;
|
|
13
|
+
export declare function metadataFromLegacyV3Header(fileSystem: FileSystem, header: LegacyV3SessionHeader, context: Context): Promise<JsonlSessionMetadataBase>;
|
|
14
|
+
export declare function normalizeLegacyV3Header(fileSystem: FileSystem, header: LegacyV3SessionHeader, context: Context): Promise<JsonlStorageHeader>;
|
|
15
|
+
/** Normalize the currently supported v3 records without touching their source file. */
|
|
16
|
+
export declare function normalizeLegacyV3Records(recordLines: readonly string[]): NormalizedLegacyV3Records;
|
|
17
|
+
export {};
|
|
18
|
+
//# sourceMappingURL=legacy-v3.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"legacy-v3.d.ts","sourceRoot":"","sources":["../../../../src/harness/session/jsonl/legacy-v3.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAA6B,KAAK,EAAE,MAAM,uBAAuB,CAAC;AAG9E,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAEhD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAEjD,OAAO,KAAK,EAA+C,cAAc,EAAE,MAAM,cAAc,CAAC;AAGhG,OAAO,EAAE,KAAK,qBAAqB,EAA2B,MAAM,YAAY,CAAC;AACjF,OAAO,EAGN,KAAK,oBAAoB,EACzB,KAAK,kBAAkB,EACvB,MAAM,YAAY,CAAC;AAmGpB,MAAM,WAAW,yBAAyB;IACzC,MAAM,EAAE,cAAc,EAAE,CAAC;IACzB,aAAa,EAAE,KAAK,CAAC;IACrB,OAAO,EAAE,MAAM,CAAC;CAChB;AAED,KAAK,wBAAwB,GAAG,IAAI,CAAC,oBAAoB,EAAE,MAAM,GAAG,YAAY,CAAC,CAAC;AAalF,wBAAsB,0BAA0B,CAC/C,UAAU,EAAE,UAAU,EACtB,MAAM,EAAE,qBAAqB,EAC7B,OAAO,EAAE,OAAO,GACd,OAAO,CAAC,wBAAwB,CAAC,CAanC;AAED,wBAAsB,uBAAuB,CAC5C,UAAU,EAAE,UAAU,EACtB,MAAM,EAAE,qBAAqB,EAC7B,OAAO,EAAE,OAAO,GACd,OAAO,CAAC,kBAAkB,CAAC,CAM7B;AAkWD,uFAAuF;AACvF,wBAAgB,wBAAwB,CAAC,WAAW,EAAE,SAAS,MAAM,EAAE,GAAG,yBAAyB,CAoBlG","sourcesContent":["import type { ImageContent, TextContent, Usage } from \"@earendil-works/pi-ai\";\nimport { uuidv7 } from \"@earendil-works/pi-ai/utils/uuid\";\nimport type { AgentMessage, ThinkingLevel } from \"../../../types.ts\";\nimport type { Context } from \"../../context.ts\";\nimport { createBranchSummaryMessage, createCompactionSummaryMessage } from \"../../messages.ts\";\nimport type { FileSystem } from \"../../types.ts\";\nimport { addUsage, emptyUsage } from \"../../utils/usage.ts\";\nimport type { CommittedEntryWrite, CommittedValueSetWrite, CommittedWrite } from \"../commit.ts\";\nimport type { JsonValue, LaneConfiguration } from \"../types.ts\";\nimport { branchTip, entryLabel, laneConfig, laneState, sessionName } from \"../values.ts\";\nimport { type LegacyV3SessionHeader, parseJsonlSessionHeader } from \"./codec.ts\";\nimport {\n\tJSONL_FORMAT_VERSION,\n\tJSONL_STORAGE_VERSION,\n\ttype JsonlSessionMetadata,\n\ttype JsonlStorageHeader,\n} from \"./types.ts\";\n\ninterface LegacyV3EntryBase {\n\ttype: string;\n\tid: string;\n\tparentId: string | null;\n\ttimestamp: string;\n}\n\ninterface LegacyV3MessageEntry extends LegacyV3EntryBase {\n\ttype: \"message\";\n\tmessage: AgentMessage;\n}\n\ninterface LegacyV3CustomEntry extends LegacyV3EntryBase {\n\ttype: \"custom\";\n\tcustomType: string;\n\tdata?: JsonValue;\n}\n\ninterface LegacyV3CustomMessageEntry extends LegacyV3EntryBase {\n\ttype: \"custom_message\";\n\tcustomType: string;\n\tcontent: string | (TextContent | ImageContent)[];\n\tdetails?: unknown;\n\tdisplay: boolean;\n}\n\ninterface LegacyV3BranchSummaryEntry extends LegacyV3EntryBase {\n\ttype: \"branch_summary\";\n\tfromId: string;\n\tsummary: string;\n\tdetails?: JsonValue;\n\tusage?: Usage;\n\tfromHook?: boolean;\n}\n\ninterface LegacyV3CompactionEntry extends LegacyV3EntryBase {\n\ttype: \"compaction\";\n\tsummary: string;\n\tfirstKeptEntryId: string;\n\ttokensBefore: number;\n\tdetails?: JsonValue;\n\tusage?: Usage;\n\tfromHook?: boolean;\n}\n\ninterface LegacyV3ModelChangeEntry extends LegacyV3EntryBase {\n\ttype: \"model_change\";\n\tprovider: string;\n\tmodelId: string;\n}\n\ninterface LegacyV3ThinkingLevelChangeEntry extends LegacyV3EntryBase {\n\ttype: \"thinking_level_change\";\n\tthinkingLevel: string;\n}\n\ninterface LegacyV3ActiveToolsChangeEntry extends LegacyV3EntryBase {\n\ttype: \"active_tools_change\";\n\tactiveToolNames: string[];\n}\n\ninterface LegacyV3SessionInfoEntry extends LegacyV3EntryBase {\n\ttype: \"session_info\";\n\tname?: string;\n}\n\ninterface LegacyV3LabelEntry extends LegacyV3EntryBase {\n\ttype: \"label\";\n\ttargetId: string;\n\tlabel?: string;\n}\n\ninterface ImportedCustomMessage {\n\trole: \"custom\";\n\tcustomType: string;\n\tcontent: string | (TextContent | ImageContent)[];\n\tdetails?: unknown;\n\tdisplay: boolean;\n\ttimestamp: number;\n}\n\ntype RetainedLegacyV3Entry =\n\t| LegacyV3MessageEntry\n\t| LegacyV3CustomEntry\n\t| LegacyV3CustomMessageEntry\n\t| LegacyV3BranchSummaryEntry\n\t| LegacyV3CompactionEntry;\n\ntype DiscardedLegacyV3Entry =\n\t| LegacyV3ModelChangeEntry\n\t| LegacyV3ThinkingLevelChangeEntry\n\t| LegacyV3ActiveToolsChangeEntry\n\t| LegacyV3SessionInfoEntry\n\t| LegacyV3LabelEntry;\n\ntype LegacyV3Entry = RetainedLegacyV3Entry | DiscardedLegacyV3Entry;\n\nexport interface NormalizedLegacyV3Records {\n\twrites: CommittedWrite[];\n\timportedUsage: Usage;\n\tnextSeq: number;\n}\n\ntype JsonlSessionMetadataBase = Omit<JsonlSessionMetadata, \"path\" | \"modifiedAt\">;\n\nasync function resolveLegacyV3ParentSessionId(\n\tfileSystem: FileSystem,\n\tparentSessionPath: string,\n\tcontext: Context,\n): Promise<string | undefined> {\n\tconst lines = await fileSystem.readTextLines(parentSessionPath, { maxLines: 1 }, context);\n\tif (!lines.ok || lines.value[0] === undefined) return undefined;\n\tconst parsed = parseJsonlSessionHeader(lines.value[0]);\n\treturn parsed.ok ? parsed.value.header.id : undefined;\n}\n\nexport async function metadataFromLegacyV3Header(\n\tfileSystem: FileSystem,\n\theader: LegacyV3SessionHeader,\n\tcontext: Context,\n): Promise<JsonlSessionMetadataBase> {\n\tconst metadata: JsonlSessionMetadataBase = {\n\t\tid: header.id,\n\t\tcreatedAt: Date.parse(header.timestamp),\n\t\tstorageVersion: JSONL_STORAGE_VERSION,\n\t\tcwd: header.cwd,\n\t};\n\tif (header.parentSession !== undefined) {\n\t\tconst parentSessionId = await resolveLegacyV3ParentSessionId(fileSystem, header.parentSession, context);\n\t\tif (parentSessionId !== undefined) metadata.parentSessionId = parentSessionId;\n\t\telse metadata.legacyParentSessionPath = header.parentSession;\n\t}\n\treturn metadata;\n}\n\nexport async function normalizeLegacyV3Header(\n\tfileSystem: FileSystem,\n\theader: LegacyV3SessionHeader,\n\tcontext: Context,\n): Promise<JsonlStorageHeader> {\n\treturn {\n\t\tv: JSONL_FORMAT_VERSION,\n\t\tkind: \"header\",\n\t\t...(await metadataFromLegacyV3Header(fileSystem, header, context)),\n\t};\n}\n\nfunction parseLegacyV3Entry(line: string, lineNumber: number): LegacyV3Entry {\n\tlet entry: LegacyV3Entry;\n\ttry {\n\t\tentry = JSON.parse(line) as LegacyV3Entry;\n\t} catch (error) {\n\t\tthrow new Error(`Invalid legacy v3 JSONL record at line ${lineNumber}: not valid JSON`, { cause: error });\n\t}\n\tconst recordType: unknown = entry.type;\n\tif (\n\t\trecordType !== \"message\" &&\n\t\trecordType !== \"custom\" &&\n\t\trecordType !== \"custom_message\" &&\n\t\trecordType !== \"branch_summary\" &&\n\t\trecordType !== \"compaction\" &&\n\t\trecordType !== \"model_change\" &&\n\t\trecordType !== \"thinking_level_change\" &&\n\t\trecordType !== \"active_tools_change\" &&\n\t\trecordType !== \"session_info\" &&\n\t\trecordType !== \"label\"\n\t) {\n\t\tthrow new Error(`Unsupported legacy v3 record type at line ${lineNumber}: ${String(recordType)}`);\n\t}\n\treturn entry;\n}\n\nfunction importedCustomMessage(entry: LegacyV3CustomMessageEntry): AgentMessage {\n\tconst message: ImportedCustomMessage = {\n\t\trole: \"custom\",\n\t\tcustomType: entry.customType,\n\t\tcontent: entry.content,\n\t\tdetails: entry.details,\n\t\tdisplay: entry.display,\n\t\ttimestamp: Date.parse(entry.timestamp),\n\t};\n\t// The coding-agent CustomAgentMessages declaration merge is not visible in this package.\n\treturn message as unknown as AgentMessage;\n}\n\nfunction isRetainedEntry(entry: LegacyV3Entry): entry is RetainedLegacyV3Entry {\n\treturn (\n\t\tentry.type !== \"model_change\" &&\n\t\tentry.type !== \"thinking_level_change\" &&\n\t\tentry.type !== \"active_tools_change\" &&\n\t\tentry.type !== \"session_info\" &&\n\t\tentry.type !== \"label\"\n\t);\n}\n\nclass RetainedIdResolver {\n\t/** Caches the reminted ID of each discarded legacy node's nearest retained ancestor, or null. */\n\tprivate resolvedIds = new Map<string, string | null>();\n\tprivate entriesById: Map<string, LegacyV3Entry>;\n\tprivate remintedIds: Map<string, string>;\n\n\t/**\n\t * @param entriesById Complete inventory of legacy physical nodes, including discarded nodes.\n\t * @param remintedIds Legacy-to-current ID map containing retained nodes only.\n\t */\n\tconstructor(entriesById: Map<string, LegacyV3Entry>, remintedIds: Map<string, string>) {\n\t\tthis.entriesById = entriesById;\n\t\tthis.remintedIds = remintedIds;\n\t}\n\n\t/**\n\t * Resolve a legacy node to its reminted ID, or to its nearest retained ancestor when discarded.\n\t * Returns null when the reference is null or no retained ancestor exists.\n\t */\n\tresolve(legacyId: string | null): string | null {\n\t\tconst traversedIds: string[] = [];\n\t\tconst visitedIds = new Set<string>();\n\t\tlet currentId = legacyId;\n\t\tlet resolvedId: string | null = null;\n\n\t\twhile (currentId !== null) {\n\t\t\tconst remintedId = this.remintedIds.get(currentId);\n\t\t\tif (remintedId !== undefined) {\n\t\t\t\tresolvedId = remintedId;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tif (this.resolvedIds.has(currentId)) {\n\t\t\t\tresolvedId = this.resolvedIds.get(currentId) ?? null;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tif (visitedIds.has(currentId)) throw new Error(`Cycle in legacy v3 parent chain at entry: ${currentId}`);\n\t\t\tvisitedIds.add(currentId);\n\t\t\tconst entry = this.entriesById.get(currentId);\n\t\t\tif (entry === undefined) throw new Error(`Missing legacy v3 entry reference: ${currentId}`);\n\t\t\ttraversedIds.push(currentId);\n\t\t\tcurrentId = entry.parentId;\n\t\t}\n\n\t\tfor (const traversedId of traversedIds) this.resolvedIds.set(traversedId, resolvedId);\n\t\treturn resolvedId;\n\t}\n}\n\nfunction requireRetainedId(resolver: RetainedIdResolver, legacyId: string): string {\n\tconst importedId = resolver.resolve(legacyId);\n\tif (importedId === null) throw new Error(`Legacy v3 entry reference has no retained ancestor: ${legacyId}`);\n\treturn importedId;\n}\n\nfunction resolveBranchSummaryFromId(resolver: RetainedIdResolver, legacyFromId: string): string | null {\n\t// Legacy branchWithSummary() encoded a root source as the \"root\" sentinel instead of null.\n\treturn legacyFromId === \"root\" ? null : resolver.resolve(legacyFromId);\n}\n\nfunction projectContextMessages(entry: LegacyV3Entry, resolver: RetainedIdResolver): AgentMessage[] {\n\tswitch (entry.type) {\n\t\tcase \"message\":\n\t\t\treturn [entry.message];\n\t\tcase \"custom_message\":\n\t\t\treturn [importedCustomMessage(entry)];\n\t\tcase \"branch_summary\":\n\t\t\treturn entry.summary\n\t\t\t\t? [\n\t\t\t\t\t\tcreateBranchSummaryMessage(\n\t\t\t\t\t\t\tentry.summary,\n\t\t\t\t\t\t\tresolveBranchSummaryFromId(resolver, entry.fromId),\n\t\t\t\t\t\t\tentry.timestamp,\n\t\t\t\t\t\t),\n\t\t\t\t\t]\n\t\t\t\t: [];\n\t\tcase \"compaction\":\n\t\t\treturn [createCompactionSummaryMessage(entry.summary, entry.tokensBefore, entry.timestamp)];\n\t\tcase \"custom\":\n\t\tcase \"model_change\":\n\t\tcase \"thinking_level_change\":\n\t\tcase \"active_tools_change\":\n\t\tcase \"session_info\":\n\t\tcase \"label\":\n\t\t\treturn [];\n\t}\n}\n\nfunction materializeRetainedTail(\n\tcompaction: LegacyV3CompactionEntry,\n\tentriesById: ReadonlyMap<string, LegacyV3Entry>,\n\tresolver: RetainedIdResolver,\n): AgentMessage[] {\n\tconst reversedTail: LegacyV3Entry[] = [];\n\tconst visited = new Set<string>();\n\tlet currentId = compaction.parentId;\n\twhile (currentId !== null) {\n\t\tif (visited.has(currentId)) throw new Error(`Cycle in legacy v3 parent chain at entry: ${currentId}`);\n\t\tvisited.add(currentId);\n\t\tconst entry = entriesById.get(currentId);\n\t\tif (entry === undefined) throw new Error(`Missing legacy v3 parent entry: ${currentId}`);\n\t\treversedTail.push(entry);\n\t\tif (currentId === compaction.firstKeptEntryId) {\n\t\t\treturn reversedTail.reverse().flatMap((tailEntry) => projectContextMessages(tailEntry, resolver));\n\t\t}\n\t\tcurrentId = entry.parentId;\n\t}\n\tthrow new Error(\n\t\t`Legacy v3 compaction ${compaction.id} firstKeptEntryId is not on its parent branch: ${compaction.firstKeptEntryId}`,\n\t);\n}\n\nfunction normalizeRetainedEntry(\n\tentry: RetainedLegacyV3Entry,\n\tseq: number,\n\tentriesById: ReadonlyMap<string, LegacyV3Entry>,\n\tresolver: RetainedIdResolver,\n): CommittedEntryWrite {\n\tconst committedBase = {\n\t\tkind: \"entry\" as const,\n\t\tid: requireRetainedId(resolver, entry.id),\n\t\tparentId: resolver.resolve(entry.parentId),\n\t\tseq,\n\t\ttimestamp: Date.parse(entry.timestamp),\n\t};\n\tif (entry.type === \"message\") {\n\t\treturn { ...committedBase, type: \"message\", message: entry.message };\n\t}\n\tif (entry.type === \"custom_message\") {\n\t\treturn {\n\t\t\t...committedBase,\n\t\t\ttype: \"message\",\n\t\t\tmessage: importedCustomMessage(entry),\n\t\t};\n\t}\n\tif (entry.type === \"branch_summary\") {\n\t\treturn {\n\t\t\t...committedBase,\n\t\t\ttype: \"branch_summary\",\n\t\t\tfromId: resolveBranchSummaryFromId(resolver, entry.fromId),\n\t\t\tsummary: entry.summary,\n\t\t\tdetails: entry.details,\n\t\t\tusage: entry.usage,\n\t\t\tfromHook: entry.fromHook ?? false,\n\t\t};\n\t}\n\tif (entry.type === \"compaction\") {\n\t\treturn {\n\t\t\t...committedBase,\n\t\t\ttype: \"compaction\",\n\t\t\tsummary: entry.summary,\n\t\t\tretainedTail: materializeRetainedTail(entry, entriesById, resolver),\n\t\t\ttokensBefore: entry.tokensBefore,\n\t\t\tdetails: entry.details,\n\t\t\tusage: entry.usage,\n\t\t\tfromHook: entry.fromHook ?? false,\n\t\t};\n\t}\n\treturn {\n\t\t...committedBase,\n\t\ttype: \"custom\",\n\t\tcustomType: entry.customType,\n\t\tdata: entry.data,\n\t};\n}\n\nconst THINKING_LEVELS = new Set<ThinkingLevel>([\"off\", \"minimal\", \"low\", \"medium\", \"high\", \"xhigh\", \"max\"]);\n\nfunction selectedConfiguration(\n\tentriesById: ReadonlyMap<string, LegacyV3Entry>,\n\tselectedId: string | null,\n): LaneConfiguration | undefined {\n\tlet model: LaneConfiguration[\"model\"] | undefined;\n\tlet thinkingLevel: ThinkingLevel | undefined;\n\tlet activeToolNames: string[] | undefined;\n\tlet sawModel = false;\n\tlet sawThinkingLevel = false;\n\tlet sawActiveToolNames = false;\n\tconst visited = new Set<string>();\n\tlet currentId = selectedId;\n\twhile (currentId !== null && (!sawModel || !sawThinkingLevel || !sawActiveToolNames)) {\n\t\tif (visited.has(currentId)) throw new Error(`Cycle in legacy v3 parent chain at entry: ${currentId}`);\n\t\tvisited.add(currentId);\n\t\tconst entry = entriesById.get(currentId);\n\t\tif (entry === undefined) throw new Error(`Missing legacy v3 entry reference: ${currentId}`);\n\t\tif (entry.type === \"model_change\" && !sawModel) {\n\t\t\tsawModel = true;\n\t\t\tif (\n\t\t\t\ttypeof entry.provider === \"string\" &&\n\t\t\t\tentry.provider.length !== 0 &&\n\t\t\t\ttypeof entry.modelId === \"string\" &&\n\t\t\t\tentry.modelId.length !== 0\n\t\t\t) {\n\t\t\t\tmodel = { provider: entry.provider, modelId: entry.modelId };\n\t\t\t}\n\t\t} else if (entry.type === \"thinking_level_change\" && !sawThinkingLevel) {\n\t\t\tsawThinkingLevel = true;\n\t\t\tif (typeof entry.thinkingLevel === \"string\" && THINKING_LEVELS.has(entry.thinkingLevel as ThinkingLevel)) {\n\t\t\t\tthinkingLevel = entry.thinkingLevel as ThinkingLevel;\n\t\t\t}\n\t\t} else if (entry.type === \"active_tools_change\" && !sawActiveToolNames) {\n\t\t\tsawActiveToolNames = true;\n\t\t\tif (Array.isArray(entry.activeToolNames) && entry.activeToolNames.every((name) => typeof name === \"string\")) {\n\t\t\t\tactiveToolNames = [...entry.activeToolNames];\n\t\t\t}\n\t\t}\n\t\tcurrentId = entry.parentId;\n\t}\n\tif (model === undefined || thinkingLevel === undefined) return undefined;\n\treturn { model, thinkingLevel, activeToolNames: activeToolNames ?? [] };\n}\n\nfunction normalizeLegacyV3Values(\n\tentries: readonly LegacyV3Entry[],\n\tentriesById: ReadonlyMap<string, LegacyV3Entry>,\n\tresolver: RetainedIdResolver,\n\tfirstSeq: number,\n): CommittedValueSetWrite[] {\n\tconst writes: CommittedValueSetWrite[] = [];\n\tlet latestSessionInfo: LegacyV3SessionInfoEntry | undefined;\n\tfor (const entry of entries) {\n\t\tif (entry.type === \"session_info\") latestSessionInfo = entry;\n\t}\n\tif (latestSessionInfo?.name) {\n\t\twrites.push({\n\t\t\tkind: \"value\",\n\t\t\top: \"set\",\n\t\t\tseq: firstSeq + writes.length,\n\t\t\tnamespace: sessionName.namespace,\n\t\t\tkey: sessionName.key,\n\t\t\tvalue: latestSessionInfo.name,\n\t\t});\n\t}\n\n\tconst labels = new Map<string, string>();\n\tfor (const entry of entries) {\n\t\tif (entry.type !== \"label\") continue;\n\t\tconst targetId = resolver.resolve(entry.targetId);\n\t\t// Labels have no current address when their target has no retained ancestor.\n\t\tif (targetId === null) continue;\n\t\t// Legacy v3 treated both undefined and the empty string as clearing a label.\n\t\tif (entry.label) labels.set(targetId, entry.label);\n\t\telse labels.delete(targetId);\n\t}\n\tfor (const [targetId, label] of labels) {\n\t\tconst address = entryLabel(targetId);\n\t\twrites.push({\n\t\t\tkind: \"value\",\n\t\t\top: \"set\",\n\t\t\tseq: firstSeq + writes.length,\n\t\t\tnamespace: address.namespace,\n\t\t\tkey: address.key,\n\t\t\tvalue: label,\n\t\t});\n\t}\n\n\tconst finalEntry = entries.at(-1);\n\tconst tipAddress = branchTip(\"main\");\n\twrites.push({\n\t\tkind: \"value\",\n\t\top: \"set\",\n\t\tseq: firstSeq + writes.length,\n\t\tnamespace: tipAddress.namespace,\n\t\tkey: tipAddress.key,\n\t\tvalue: finalEntry === undefined ? null : resolver.resolve(finalEntry.id),\n\t});\n\tconst configuration = selectedConfiguration(entriesById, finalEntry?.id ?? null);\n\tif (configuration !== undefined) {\n\t\tconst configAddress = laneConfig(\"main\");\n\t\twrites.push({\n\t\t\tkind: \"value\",\n\t\t\top: \"set\",\n\t\t\tseq: firstSeq + writes.length,\n\t\t\tnamespace: configAddress.namespace,\n\t\t\tkey: configAddress.key,\n\t\t\tvalue: configuration,\n\t\t});\n\t\tconst stateAddress = laneState(\"main\");\n\t\twrites.push({\n\t\t\tkind: \"value\",\n\t\t\top: \"set\",\n\t\t\tseq: firstSeq + writes.length,\n\t\t\tnamespace: stateAddress.namespace,\n\t\t\tkey: stateAddress.key,\n\t\t\tvalue: { currentOperationId: null, lastOperationId: null, inbox: [] },\n\t\t});\n\t}\n\treturn writes;\n}\n\nfunction aggregateImportedUsage(entries: readonly LegacyV3Entry[]): Usage {\n\tlet aggregate = emptyUsage();\n\tfor (const entry of entries) {\n\t\tlet usage: Usage | undefined;\n\t\tif (entry.type === \"message\") {\n\t\t\tif (entry.message.role === \"assistant\") usage = entry.message.usage;\n\t\t\telse if (entry.message.role === \"toolResult\") usage = entry.message.usage;\n\t\t} else if (entry.type === \"compaction\" || entry.type === \"branch_summary\") {\n\t\t\tusage = entry.usage;\n\t\t}\n\t\tif (usage !== undefined) aggregate = addUsage(aggregate, usage);\n\t}\n\treturn aggregate;\n}\n\n/** Normalize the currently supported v3 records without touching their source file. */\nexport function normalizeLegacyV3Records(recordLines: readonly string[]): NormalizedLegacyV3Records {\n\tconst entries = recordLines.map((line, index) => parseLegacyV3Entry(line, index + 2));\n\tconst entriesById = new Map<string, LegacyV3Entry>();\n\tfor (const entry of entries) {\n\t\tif (entriesById.has(entry.id)) throw new Error(`Duplicate legacy v3 entry id: ${entry.id}`);\n\t\tentriesById.set(entry.id, entry);\n\t}\n\tconst retainedEntries = entries.filter(isRetainedEntry);\n\tconst remintedIds = new Map(retainedEntries.map((entry) => [entry.id, uuidv7(Date.parse(entry.timestamp))]));\n\tconst resolver = new RetainedIdResolver(entriesById, remintedIds);\n\tconst entryWrites = retainedEntries.map((entry, index) =>\n\t\tnormalizeRetainedEntry(entry, index + 1, entriesById, resolver),\n\t);\n\tconst valueWrites = normalizeLegacyV3Values(entries, entriesById, resolver, entryWrites.length + 1);\n\tconst writes: CommittedWrite[] = [...entryWrites, ...valueWrites];\n\treturn {\n\t\twrites,\n\t\timportedUsage: aggregateImportedUsage(entries),\n\t\tnextSeq: writes.length + 1,\n\t};\n}\n"]}
|