@draht/agent-core 2026.9.5-1 → 2026.10.4-2
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 +27 -2
- package/dist/agent-loop.d.ts.map +1 -1
- package/dist/agent-loop.js +167 -62
- package/dist/agent-loop.js.map +1 -1
- package/dist/agent.d.ts +14 -4
- package/dist/agent.d.ts.map +1 -1
- package/dist/agent.js +65 -19
- package/dist/agent.js.map +1 -1
- package/dist/harness/agent-harness.d.ts +713 -91
- package/dist/harness/agent-harness.d.ts.map +1 -1
- package/dist/harness/agent-harness.js +5 -950
- package/dist/harness/agent-harness.js.map +1 -1
- package/dist/harness/compaction/branch-summarization.d.ts +23 -10
- package/dist/harness/compaction/branch-summarization.d.ts.map +1 -1
- package/dist/harness/compaction/branch-summarization.js +39 -36
- package/dist/harness/compaction/branch-summarization.js.map +1 -1
- package/dist/harness/compaction/compaction.d.ts +37 -18
- package/dist/harness/compaction/compaction.d.ts.map +1 -1
- package/dist/harness/compaction/compaction.js +74 -97
- 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 +35 -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 +25 -27
- package/dist/harness/env/nodejs.d.ts.map +1 -1
- package/dist/harness/env/nodejs.js +336 -103
- package/dist/harness/env/nodejs.js.map +1 -1
- package/dist/harness/events.d.ts +24 -0
- package/dist/harness/events.d.ts.map +1 -0
- package/dist/harness/events.js +233 -0
- package/dist/harness/events.js.map +1 -0
- 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 +119 -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 +4 -4
- package/dist/harness/messages.d.ts.map +1 -1
- package/dist/harness/messages.js +4 -3
- package/dist/harness/messages.js.map +1 -1
- package/dist/harness/pico3/bash.d.ts +10 -0
- package/dist/harness/pico3/bash.d.ts.map +1 -0
- package/dist/harness/pico3/bash.js +25 -0
- package/dist/harness/pico3/bash.js.map +1 -0
- package/dist/harness/pico3/bounded.d.ts +21 -0
- package/dist/harness/pico3/bounded.d.ts.map +1 -0
- package/dist/harness/pico3/bounded.js +98 -0
- package/dist/harness/pico3/bounded.js.map +1 -0
- package/dist/harness/pico3/chord.d.ts +41 -0
- package/dist/harness/pico3/chord.d.ts.map +1 -0
- package/dist/harness/pico3/chord.js +147 -0
- package/dist/harness/pico3/chord.js.map +1 -0
- package/dist/harness/pico3/context.d.ts +16 -0
- package/dist/harness/pico3/context.d.ts.map +1 -0
- package/dist/harness/pico3/context.js +88 -0
- package/dist/harness/pico3/context.js.map +1 -0
- package/dist/harness/pico3/harness.d.ts +198 -0
- package/dist/harness/pico3/harness.d.ts.map +1 -0
- package/dist/harness/pico3/harness.js +654 -0
- package/dist/harness/pico3/harness.js.map +1 -0
- package/dist/harness/pico3/hooks.d.ts +10 -0
- package/dist/harness/pico3/hooks.d.ts.map +1 -0
- package/dist/harness/pico3/hooks.js +33 -0
- package/dist/harness/pico3/hooks.js.map +1 -0
- package/dist/harness/pico3/index.d.ts +19 -0
- package/dist/harness/pico3/index.d.ts.map +1 -0
- package/dist/harness/pico3/index.js +15 -0
- package/dist/harness/pico3/index.js.map +1 -0
- package/dist/harness/pico3/jsonl.d.ts +58 -0
- package/dist/harness/pico3/jsonl.d.ts.map +1 -0
- package/dist/harness/pico3/jsonl.js +325 -0
- package/dist/harness/pico3/jsonl.js.map +1 -0
- package/dist/harness/pico3/kinds/collapse.d.ts +49 -0
- package/dist/harness/pico3/kinds/collapse.d.ts.map +1 -0
- package/dist/harness/pico3/kinds/collapse.js +191 -0
- package/dist/harness/pico3/kinds/collapse.js.map +1 -0
- package/dist/harness/pico3/kinds/entries.d.ts +78 -0
- package/dist/harness/pico3/kinds/entries.d.ts.map +1 -0
- package/dist/harness/pico3/kinds/entries.js +13 -0
- package/dist/harness/pico3/kinds/entries.js.map +1 -0
- package/dist/harness/pico3/kinds/frames.d.ts +9 -0
- package/dist/harness/pico3/kinds/frames.d.ts.map +1 -0
- package/dist/harness/pico3/kinds/frames.js +75 -0
- package/dist/harness/pico3/kinds/frames.js.map +1 -0
- package/dist/harness/pico3/kinds/generation.d.ts +94 -0
- package/dist/harness/pico3/kinds/generation.d.ts.map +1 -0
- package/dist/harness/pico3/kinds/generation.js +504 -0
- package/dist/harness/pico3/kinds/generation.js.map +1 -0
- package/dist/harness/pico3/kinds/job.d.ts +44 -0
- package/dist/harness/pico3/kinds/job.d.ts.map +1 -0
- package/dist/harness/pico3/kinds/job.js +143 -0
- package/dist/harness/pico3/kinds/job.js.map +1 -0
- package/dist/harness/pico3/kinds/plugin.d.ts +15 -0
- package/dist/harness/pico3/kinds/plugin.d.ts.map +1 -0
- package/dist/harness/pico3/kinds/plugin.js +35 -0
- package/dist/harness/pico3/kinds/plugin.js.map +1 -0
- package/dist/harness/pico3/kinds/post-tools.d.ts +22 -0
- package/dist/harness/pico3/kinds/post-tools.d.ts.map +1 -0
- package/dist/harness/pico3/kinds/post-tools.js +145 -0
- package/dist/harness/pico3/kinds/post-tools.js.map +1 -0
- package/dist/harness/pico3/kinds/task-api.d.ts +3 -0
- package/dist/harness/pico3/kinds/task-api.d.ts.map +1 -0
- package/dist/harness/pico3/kinds/task-api.js +45 -0
- package/dist/harness/pico3/kinds/task-api.js.map +1 -0
- package/dist/harness/pico3/kinds/tool.d.ts +43 -0
- package/dist/harness/pico3/kinds/tool.d.ts.map +1 -0
- package/dist/harness/pico3/kinds/tool.js +373 -0
- package/dist/harness/pico3/kinds/tool.js.map +1 -0
- package/dist/harness/pico3/legacy-tracker.d.ts +11 -0
- package/dist/harness/pico3/legacy-tracker.d.ts.map +1 -0
- package/dist/harness/pico3/legacy-tracker.js +41 -0
- package/dist/harness/pico3/legacy-tracker.js.map +1 -0
- package/dist/harness/pico3/membrane.d.ts +23 -0
- package/dist/harness/pico3/membrane.d.ts.map +1 -0
- package/dist/harness/pico3/membrane.js +141 -0
- package/dist/harness/pico3/membrane.js.map +1 -0
- package/dist/harness/pico3/memory.d.ts +53 -0
- package/dist/harness/pico3/memory.d.ts.map +1 -0
- package/dist/harness/pico3/memory.js +264 -0
- package/dist/harness/pico3/memory.js.map +1 -0
- package/dist/harness/pico3/scheduler.d.ts +49 -0
- package/dist/harness/pico3/scheduler.d.ts.map +1 -0
- package/dist/harness/pico3/scheduler.js +438 -0
- package/dist/harness/pico3/scheduler.js.map +1 -0
- package/dist/harness/pico3/session.d.ts +264 -0
- package/dist/harness/pico3/session.d.ts.map +1 -0
- package/dist/harness/pico3/session.js +1348 -0
- package/dist/harness/pico3/session.js.map +1 -0
- package/dist/harness/pico3/system.d.ts +126 -0
- package/dist/harness/pico3/system.d.ts.map +1 -0
- package/dist/harness/pico3/system.js +244 -0
- package/dist/harness/pico3/system.js.map +1 -0
- package/dist/harness/pico3/types.d.ts +973 -0
- package/dist/harness/pico3/types.d.ts.map +1 -0
- package/dist/harness/pico3/types.js +106 -0
- package/dist/harness/pico3/types.js.map +1 -0
- package/dist/harness/pico3/view.d.ts +34 -0
- package/dist/harness/pico3/view.d.ts.map +1 -0
- package/dist/harness/pico3/view.js +411 -0
- package/dist/harness/pico3/view.js.map +1 -0
- 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 +18 -23
- package/dist/harness/prompt-templates.js.map +1 -1
- package/dist/harness/result.d.ts +133 -0
- package/dist/harness/result.d.ts.map +1 -0
- package/dist/harness/result.js +81 -0
- package/dist/harness/result.js.map +1 -0
- 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 +173 -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 +34 -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 +219 -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 +118 -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 +10 -0
- package/dist/harness/session/context.d.ts.map +1 -0
- package/dist/harness/session/context.js +49 -0
- package/dist/harness/session/context.js.map +1 -0
- package/dist/harness/session/fork-policy.d.ts +21 -0
- package/dist/harness/session/fork-policy.d.ts.map +1 -0
- package/dist/harness/session/fork-policy.js +55 -0
- package/dist/harness/session/fork-policy.js.map +1 -0
- package/dist/harness/session/fork.d.ts +16 -0
- package/dist/harness/session/fork.d.ts.map +1 -0
- package/dist/harness/session/fork.js +79 -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 +276 -0
- package/dist/harness/session/in-memory-storage-state.js.map +1 -0
- package/dist/harness/session/index.d.ts +11 -0
- package/dist/harness/session/index.d.ts.map +1 -0
- package/dist/harness/session/index.js +9 -0
- package/dist/harness/session/index.js.map +1 -0
- package/dist/harness/session/jsonl/codec.d.ts +21 -0
- package/dist/harness/session/jsonl/codec.d.ts.map +1 -0
- package/dist/harness/session/jsonl/codec.js +45 -0
- package/dist/harness/session/jsonl/codec.js.map +1 -0
- package/dist/harness/session/jsonl/fork.d.ts +38 -0
- package/dist/harness/session/jsonl/fork.d.ts.map +1 -0
- package/dist/harness/session/jsonl/fork.js +264 -0
- package/dist/harness/session/jsonl/fork.js.map +1 -0
- 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/io.d.ts +14 -0
- package/dist/harness/session/jsonl/io.d.ts.map +1 -0
- package/dist/harness/session/jsonl/io.js +86 -0
- package/dist/harness/session/jsonl/io.js.map +1 -0
- package/dist/harness/session/jsonl/legacy-v3.d.ts +44 -0
- package/dist/harness/session/jsonl/legacy-v3.d.ts.map +1 -0
- package/dist/harness/session/jsonl/legacy-v3.js +462 -0
- package/dist/harness/session/jsonl/legacy-v3.js.map +1 -0
- package/dist/harness/session/jsonl/repo.d.ts +35 -0
- package/dist/harness/session/jsonl/repo.d.ts.map +1 -0
- package/dist/harness/session/jsonl/repo.js +301 -0
- package/dist/harness/session/jsonl/repo.js.map +1 -0
- package/dist/harness/session/jsonl/storage.d.ts +41 -0
- package/dist/harness/session/jsonl/storage.d.ts.map +1 -0
- package/dist/harness/session/jsonl/storage.js +200 -0
- package/dist/harness/session/jsonl/storage.js.map +1 -0
- package/dist/harness/session/jsonl/types.d.ts +39 -0
- package/dist/harness/session/jsonl/types.d.ts.map +1 -0
- package/dist/harness/session/jsonl/types.js +3 -0
- package/dist/harness/session/jsonl/types.js.map +1 -0
- package/dist/harness/session/memory.d.ts +48 -0
- package/dist/harness/session/memory.d.ts.map +1 -0
- package/dist/harness/session/memory.js +369 -0
- package/dist/harness/session/memory.js.map +1 -0
- 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 +79 -46
- package/dist/harness/session/session.d.ts.map +1 -1
- package/dist/harness/session/session.js +320 -220
- 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 +23 -0
- package/dist/harness/session/testing/conformance/session-repo.d.ts.map +1 -0
- package/dist/harness/session/testing/conformance/session-repo.js +809 -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 +10 -0
- package/dist/harness/session/testing/index.d.ts.map +1 -0
- package/dist/harness/session/testing/index.js +9 -0
- package/dist/harness/session/testing/index.js.map +1 -0
- 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 +12 -0
- package/dist/harness/session/testing/types.d.ts.map +1 -0
- package/dist/harness/session/testing/types.js +2 -0
- package/dist/harness/session/testing/types.js.map +1 -0
- package/dist/harness/session/types.d.ts +512 -0
- package/dist/harness/session/types.d.ts.map +1 -0
- package/dist/harness/session/types.js +9 -0
- package/dist/harness/session/types.js.map +1 -0
- 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 +6 -4
- package/dist/harness/skills.d.ts.map +1 -1
- package/dist/harness/skills.js +59 -44
- package/dist/harness/skills.js.map +1 -1
- package/dist/harness/telemetry.d.ts +1242 -0
- package/dist/harness/telemetry.d.ts.map +1 -0
- package/dist/harness/telemetry.js +527 -0
- package/dist/harness/telemetry.js.map +1 -0
- 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/image.js +1 -1
- package/dist/harness/tools/image.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 +126 -502
- package/dist/harness/types.d.ts.map +1 -1
- package/dist/harness/types.js +10 -16
- 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 +13 -9
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +9 -13
- package/dist/index.js.map +1 -1
- package/dist/proxy.d.ts +6 -3
- package/dist/proxy.d.ts.map +1 -1
- package/dist/proxy.js +8 -0
- package/dist/proxy.js.map +1 -1
- package/dist/search/index.d.ts +29 -0
- package/dist/search/index.d.ts.map +1 -0
- package/dist/search/index.js +2 -0
- package/dist/search/index.js.map +1 -0
- package/dist/types.d.ts +107 -31
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js.map +1 -1
- package/package.json +50 -4
- package/dist/harness/session/jsonl-repo.d.ts +0 -26
- package/dist/harness/session/jsonl-repo.d.ts.map +0 -1
- package/dist/harness/session/jsonl-repo.js +0 -100
- package/dist/harness/session/jsonl-repo.js.map +0 -1
- package/dist/harness/session/jsonl-storage.d.ts +0 -42
- package/dist/harness/session/jsonl-storage.d.ts.map +0 -1
- package/dist/harness/session/jsonl-storage.js +0 -286
- package/dist/harness/session/jsonl-storage.js.map +0 -1
- package/dist/harness/session/memory-repo.d.ts +0 -18
- package/dist/harness/session/memory-repo.d.ts.map +0 -1
- package/dist/harness/session/memory-repo.js +0 -44
- package/dist/harness/session/memory-repo.js.map +0 -1
- package/dist/harness/session/memory-storage.d.ts +0 -33
- package/dist/harness/session/memory-storage.d.ts.map +0 -1
- package/dist/harness/session/memory-storage.js +0 -163
- package/dist/harness/session/memory-storage.js.map +0 -1
- package/dist/harness/session/repo-utils.d.ts +0 -11
- package/dist/harness/session/repo-utils.d.ts.map +0 -1
- package/dist/harness/session/repo-utils.js +0 -39
- package/dist/harness/session/repo-utils.js.map +0 -1
|
@@ -1,15 +1,16 @@
|
|
|
1
1
|
import { spawn } from "node:child_process";
|
|
2
2
|
import { randomUUID } from "node:crypto";
|
|
3
|
-
import { constants,
|
|
4
|
-
import { access, appendFile, lstat, mkdir, mkdtemp, readdir, readFile, realpath, rm, writeFile, } from "node:fs/promises";
|
|
3
|
+
import { constants, createWriteStream } from "node:fs";
|
|
4
|
+
import { access, appendFile, lstat, mkdir, mkdtemp, open as openFile, readdir, readFile, realpath, rename, rm, writeFile, } from "node:fs/promises";
|
|
5
5
|
import { homedir, constants as osConstants, tmpdir } from "node:os";
|
|
6
|
-
import { isAbsolute, join, resolve } from "node:path";
|
|
7
|
-
import { createInterface } from "node:readline";
|
|
6
|
+
import { basename, isAbsolute, join, resolve } from "node:path";
|
|
8
7
|
import { fileURLToPath } from "node:url";
|
|
9
8
|
import { ExecutionError, err, FileError, ok, toError, } from "../types.js";
|
|
9
|
+
import { OutputCapture } from "../utils/output-capture.js";
|
|
10
10
|
const MAX_TIMEOUT_MS = 2_147_483_647;
|
|
11
11
|
const MAX_TIMEOUT_SECONDS = MAX_TIMEOUT_MS / 1000;
|
|
12
12
|
const EXIT_STDIO_GRACE_MS = 100;
|
|
13
|
+
const SPILL_HIGH_WATER_MARK = 8 * 1024 * 1024;
|
|
13
14
|
function resolveTimeoutMs(timeout) {
|
|
14
15
|
if (timeout === undefined)
|
|
15
16
|
return ok(undefined);
|
|
@@ -54,7 +55,7 @@ function fileInfoFromStats(path, stats) {
|
|
|
54
55
|
if (!kind)
|
|
55
56
|
return err(new FileError("invalid", "Unsupported file type", path));
|
|
56
57
|
return ok({
|
|
57
|
-
name: path
|
|
58
|
+
name: basename(path),
|
|
58
59
|
path,
|
|
59
60
|
kind,
|
|
60
61
|
size: stats.size,
|
|
@@ -64,13 +65,15 @@ function fileInfoFromStats(path, stats) {
|
|
|
64
65
|
function isNodeError(error) {
|
|
65
66
|
return error instanceof Error && "code" in error;
|
|
66
67
|
}
|
|
67
|
-
function toFileError(error,
|
|
68
|
+
function toFileError(error, fallbackPath) {
|
|
68
69
|
if (error instanceof FileError)
|
|
69
70
|
return error;
|
|
70
71
|
const cause = toError(error);
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
72
|
+
const nodeError = isNodeError(error) ? error : undefined;
|
|
73
|
+
const path = typeof nodeError?.path === "string" ? nodeError.path : fallbackPath;
|
|
74
|
+
if (nodeError) {
|
|
75
|
+
const message = nodeError.message;
|
|
76
|
+
switch (nodeError.code) {
|
|
74
77
|
case "ABORT_ERR":
|
|
75
78
|
return new FileError("aborted", message, path, cause);
|
|
76
79
|
case "ENOENT":
|
|
@@ -224,7 +227,7 @@ function killProcessTree(pid) {
|
|
|
224
227
|
}
|
|
225
228
|
}
|
|
226
229
|
}
|
|
227
|
-
function waitForChildProcess(child) {
|
|
230
|
+
function waitForChildProcess(child, spillIsDraining) {
|
|
228
231
|
return new Promise((resolvePromise, reject) => {
|
|
229
232
|
let settled = false;
|
|
230
233
|
let exited = false;
|
|
@@ -260,7 +263,12 @@ function waitForChildProcess(child) {
|
|
|
260
263
|
const armIdleTimer = () => {
|
|
261
264
|
if (postExitTimer)
|
|
262
265
|
clearTimeout(postExitTimer);
|
|
263
|
-
postExitTimer = setTimeout(() =>
|
|
266
|
+
postExitTimer = setTimeout(() => {
|
|
267
|
+
if (spillIsDraining())
|
|
268
|
+
armIdleTimer();
|
|
269
|
+
else
|
|
270
|
+
finalize();
|
|
271
|
+
}, EXIT_STDIO_GRACE_MS);
|
|
264
272
|
};
|
|
265
273
|
const onData = () => {
|
|
266
274
|
if (exited && !settled)
|
|
@@ -303,21 +311,92 @@ function waitForChildProcess(child) {
|
|
|
303
311
|
child.once("close", onClose);
|
|
304
312
|
});
|
|
305
313
|
}
|
|
314
|
+
/** Strict LF reader; Node readline does not report whether its final line was newline-terminated. */
|
|
315
|
+
class NodeTextLineReader {
|
|
316
|
+
file;
|
|
317
|
+
path;
|
|
318
|
+
decoder = new TextDecoder();
|
|
319
|
+
chunk = new Uint8Array(64 * 1024);
|
|
320
|
+
byteOffset = 0;
|
|
321
|
+
buffered = "";
|
|
322
|
+
ended = false;
|
|
323
|
+
closed = false;
|
|
324
|
+
constructor(file, path) {
|
|
325
|
+
this.file = file;
|
|
326
|
+
this.path = path;
|
|
327
|
+
}
|
|
328
|
+
async readLine(context) {
|
|
329
|
+
const aborted = abortResult(context.abortSignal, this.path);
|
|
330
|
+
if (aborted)
|
|
331
|
+
return aborted;
|
|
332
|
+
if (this.closed)
|
|
333
|
+
return err(new FileError("invalid", "Text line reader is closed", this.path));
|
|
334
|
+
try {
|
|
335
|
+
while (true) {
|
|
336
|
+
const newline = this.buffered.indexOf("\n");
|
|
337
|
+
if (newline !== -1) {
|
|
338
|
+
const text = this.buffered.slice(0, newline);
|
|
339
|
+
this.buffered = this.buffered.slice(newline + 1);
|
|
340
|
+
return ok({ text, terminated: true });
|
|
341
|
+
}
|
|
342
|
+
if (this.ended) {
|
|
343
|
+
if (this.buffered.length === 0)
|
|
344
|
+
return ok(undefined);
|
|
345
|
+
const text = this.buffered;
|
|
346
|
+
this.buffered = "";
|
|
347
|
+
return ok({ text, terminated: false });
|
|
348
|
+
}
|
|
349
|
+
// Explicit positions allow an aborted read to be retried without skipping bytes.
|
|
350
|
+
const { bytesRead } = await this.file.read(this.chunk, 0, this.chunk.length, this.byteOffset);
|
|
351
|
+
const afterReadAbort = abortResult(context.abortSignal, this.path);
|
|
352
|
+
if (afterReadAbort)
|
|
353
|
+
return afterReadAbort;
|
|
354
|
+
this.byteOffset += bytesRead;
|
|
355
|
+
if (bytesRead === 0) {
|
|
356
|
+
this.buffered += this.decoder.decode();
|
|
357
|
+
this.ended = true;
|
|
358
|
+
}
|
|
359
|
+
else {
|
|
360
|
+
this.buffered += this.decoder.decode(this.chunk.subarray(0, bytesRead), { stream: true });
|
|
361
|
+
}
|
|
362
|
+
}
|
|
363
|
+
}
|
|
364
|
+
catch (error) {
|
|
365
|
+
return err(toFileError(error, this.path));
|
|
366
|
+
}
|
|
367
|
+
}
|
|
368
|
+
async close(_context) {
|
|
369
|
+
if (this.closed)
|
|
370
|
+
return;
|
|
371
|
+
this.closed = true;
|
|
372
|
+
this.buffered = "";
|
|
373
|
+
try {
|
|
374
|
+
await this.file.close();
|
|
375
|
+
}
|
|
376
|
+
catch {
|
|
377
|
+
// Closing is best-effort, including after cancellation or an earlier I/O failure.
|
|
378
|
+
}
|
|
379
|
+
}
|
|
380
|
+
}
|
|
306
381
|
export class NodeExecutionEnv {
|
|
382
|
+
cwd;
|
|
383
|
+
shellPath;
|
|
384
|
+
shellEnv;
|
|
385
|
+
activeChildPids = new Set();
|
|
307
386
|
constructor(options) {
|
|
308
|
-
this.activeChildPids = new Set();
|
|
309
387
|
this.cwd = options.cwd;
|
|
310
388
|
this.shellPath = options.shellPath;
|
|
311
389
|
this.shellEnv = options.shellEnv;
|
|
312
390
|
}
|
|
313
|
-
async absolutePath(path) {
|
|
391
|
+
async absolutePath(path, _context) {
|
|
314
392
|
return ok(resolvePath(this.cwd, path));
|
|
315
393
|
}
|
|
316
|
-
async joinPath(parts) {
|
|
394
|
+
async joinPath(parts, _context) {
|
|
317
395
|
return ok(join(...parts));
|
|
318
396
|
}
|
|
319
|
-
async exec(command, options) {
|
|
320
|
-
|
|
397
|
+
async exec(command, options, context) {
|
|
398
|
+
const signal = context.abortSignal;
|
|
399
|
+
if (signal?.aborted)
|
|
321
400
|
return err(new ExecutionError("aborted", "aborted"));
|
|
322
401
|
const timeoutMsResult = resolveTimeoutMs(options?.timeout);
|
|
323
402
|
if (!timeoutMsResult.ok)
|
|
@@ -335,30 +414,119 @@ export class NodeExecutionEnv {
|
|
|
335
414
|
return err(new ExecutionError("spawn_error", `Working directory does not exist: ${cwd}\nCannot execute bash commands.`, cause));
|
|
336
415
|
}
|
|
337
416
|
return await new Promise((resolvePromise) => {
|
|
338
|
-
let stdout = "";
|
|
339
|
-
let stderr = "";
|
|
340
417
|
let settled = false;
|
|
341
418
|
let timedOut = false;
|
|
342
419
|
let callbackError;
|
|
420
|
+
let spillError;
|
|
343
421
|
let child;
|
|
344
422
|
let timeoutId;
|
|
423
|
+
const spillPrefix = [];
|
|
424
|
+
let spillPath;
|
|
425
|
+
const spillQueue = [];
|
|
426
|
+
let spillStart;
|
|
427
|
+
let spillStream;
|
|
428
|
+
let spillBackpressured = false;
|
|
345
429
|
const onAbort = () => {
|
|
346
|
-
if (child?.pid)
|
|
430
|
+
if (child?.pid)
|
|
347
431
|
killProcessTree(child.pid);
|
|
348
|
-
}
|
|
349
432
|
};
|
|
433
|
+
const failCallback = (error) => {
|
|
434
|
+
if (callbackError !== undefined)
|
|
435
|
+
return;
|
|
436
|
+
const cause = toError(error);
|
|
437
|
+
callbackError = new ExecutionError("callback_error", cause.message, cause);
|
|
438
|
+
onAbort();
|
|
439
|
+
};
|
|
440
|
+
let capture;
|
|
441
|
+
try {
|
|
442
|
+
capture = new OutputCapture(options?.capture, context, {
|
|
443
|
+
onUpdate: options?.onUpdate,
|
|
444
|
+
onError: failCallback,
|
|
445
|
+
});
|
|
446
|
+
}
|
|
447
|
+
catch (error) {
|
|
448
|
+
const cause = toError(error);
|
|
449
|
+
resolvePromise(err(new ExecutionError("unknown", cause.message, cause)));
|
|
450
|
+
return;
|
|
451
|
+
}
|
|
350
452
|
const settle = (result) => {
|
|
453
|
+
if (settled)
|
|
454
|
+
return;
|
|
455
|
+
settled = true;
|
|
351
456
|
if (timeoutId)
|
|
352
457
|
clearTimeout(timeoutId);
|
|
353
|
-
if (
|
|
354
|
-
|
|
458
|
+
if (signal)
|
|
459
|
+
signal.removeEventListener("abort", onAbort);
|
|
355
460
|
if (child?.pid)
|
|
356
461
|
this.activeChildPids.delete(child.pid);
|
|
357
|
-
|
|
358
|
-
return;
|
|
359
|
-
settled = true;
|
|
462
|
+
capture.dispose();
|
|
360
463
|
resolvePromise(result);
|
|
361
464
|
};
|
|
465
|
+
const pauseOutput = () => {
|
|
466
|
+
child?.stdout?.pause();
|
|
467
|
+
child?.stderr?.pause();
|
|
468
|
+
};
|
|
469
|
+
const resumeOutput = () => {
|
|
470
|
+
if (callbackError || spillError || timedOut || signal?.aborted || spillBackpressured)
|
|
471
|
+
return;
|
|
472
|
+
child?.stdout?.resume();
|
|
473
|
+
child?.stderr?.resume();
|
|
474
|
+
};
|
|
475
|
+
const failSpill = (error) => {
|
|
476
|
+
if (spillError !== undefined)
|
|
477
|
+
return;
|
|
478
|
+
const cause = toError(error);
|
|
479
|
+
spillError = new ExecutionError("unknown", `Failed to preserve complete shell output: ${cause.message}`, cause);
|
|
480
|
+
spillBackpressured = false;
|
|
481
|
+
onAbort();
|
|
482
|
+
};
|
|
483
|
+
const writeSpill = (chunk) => {
|
|
484
|
+
if (spillStream === undefined || chunk.length === 0)
|
|
485
|
+
return;
|
|
486
|
+
if (spillStream.write(chunk) || spillBackpressured)
|
|
487
|
+
return;
|
|
488
|
+
spillBackpressured = true;
|
|
489
|
+
pauseOutput();
|
|
490
|
+
spillStream.once("drain", () => {
|
|
491
|
+
spillBackpressured = false;
|
|
492
|
+
resumeOutput();
|
|
493
|
+
});
|
|
494
|
+
};
|
|
495
|
+
const startSpill = (chunk) => {
|
|
496
|
+
if (spillStream !== undefined) {
|
|
497
|
+
writeSpill(chunk);
|
|
498
|
+
return;
|
|
499
|
+
}
|
|
500
|
+
spillQueue.push(chunk);
|
|
501
|
+
if (spillStart !== undefined)
|
|
502
|
+
return;
|
|
503
|
+
pauseOutput();
|
|
504
|
+
spillStart = (async () => {
|
|
505
|
+
const created = await this.createTempFile({ prefix: "draht-output-", suffix: ".log" }, context);
|
|
506
|
+
if (!created.ok)
|
|
507
|
+
throw created.error;
|
|
508
|
+
spillPath = created.value;
|
|
509
|
+
capture.setSpillPath(spillPath);
|
|
510
|
+
spillStream = createWriteStream(spillPath, { flags: "a", highWaterMark: SPILL_HIGH_WATER_MARK });
|
|
511
|
+
spillStream.on("error", failSpill);
|
|
512
|
+
for (const queued of spillQueue)
|
|
513
|
+
writeSpill(queued);
|
|
514
|
+
spillQueue.length = 0;
|
|
515
|
+
})()
|
|
516
|
+
.catch(failSpill)
|
|
517
|
+
.finally(resumeOutput);
|
|
518
|
+
};
|
|
519
|
+
const finishSpill = async () => {
|
|
520
|
+
await spillStart;
|
|
521
|
+
const stream = spillStream;
|
|
522
|
+
if (stream === undefined || spillError !== undefined || stream.destroyed)
|
|
523
|
+
return;
|
|
524
|
+
await new Promise((resolveFinish) => {
|
|
525
|
+
stream.once("error", () => resolveFinish());
|
|
526
|
+
stream.once("finish", resolveFinish);
|
|
527
|
+
stream.end();
|
|
528
|
+
});
|
|
529
|
+
};
|
|
362
530
|
try {
|
|
363
531
|
const commandFromStdin = shellConfig.value.commandTransport === "stdin";
|
|
364
532
|
child = spawn(shellConfig.value.shell, commandFromStdin ? shellConfig.value.args : [...shellConfig.value.args, command], {
|
|
@@ -381,47 +549,54 @@ export class NodeExecutionEnv {
|
|
|
381
549
|
return;
|
|
382
550
|
}
|
|
383
551
|
timeoutId =
|
|
384
|
-
timeoutMs
|
|
385
|
-
?
|
|
552
|
+
timeoutMs === undefined
|
|
553
|
+
? undefined
|
|
554
|
+
: setTimeout(() => {
|
|
386
555
|
timedOut = true;
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
: undefined;
|
|
392
|
-
if (options?.abortSignal) {
|
|
393
|
-
if (options.abortSignal.aborted) {
|
|
556
|
+
onAbort();
|
|
557
|
+
}, timeoutMs);
|
|
558
|
+
if (signal) {
|
|
559
|
+
if (signal.aborted)
|
|
394
560
|
onAbort();
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
options.abortSignal.addEventListener("abort", onAbort, { once: true });
|
|
398
|
-
}
|
|
561
|
+
else
|
|
562
|
+
signal.addEventListener("abort", onAbort, { once: true });
|
|
399
563
|
}
|
|
400
|
-
|
|
401
|
-
child.stderr?.setEncoding("utf8");
|
|
402
|
-
child.stdout?.on("data", (chunk) => {
|
|
403
|
-
stdout += chunk;
|
|
564
|
+
const feed = (chunk) => {
|
|
404
565
|
try {
|
|
405
|
-
|
|
566
|
+
const wasTruncated = capture.truncated;
|
|
567
|
+
capture.push(chunk);
|
|
568
|
+
if (!options?.capture?.spill || chunk.length === 0)
|
|
569
|
+
return;
|
|
570
|
+
if (spillPath !== undefined || wasTruncated) {
|
|
571
|
+
startSpill(chunk);
|
|
572
|
+
}
|
|
573
|
+
else if (capture.truncated) {
|
|
574
|
+
for (const prefix of spillPrefix)
|
|
575
|
+
startSpill(prefix);
|
|
576
|
+
spillPrefix.length = 0;
|
|
577
|
+
startSpill(chunk);
|
|
578
|
+
}
|
|
579
|
+
else {
|
|
580
|
+
spillPrefix.push(chunk);
|
|
581
|
+
}
|
|
406
582
|
}
|
|
407
583
|
catch (error) {
|
|
408
|
-
|
|
409
|
-
callbackError = new ExecutionError("callback_error", cause.message, cause);
|
|
410
|
-
onAbort();
|
|
584
|
+
failCallback(error);
|
|
411
585
|
}
|
|
412
|
-
}
|
|
413
|
-
child.
|
|
414
|
-
|
|
586
|
+
};
|
|
587
|
+
child.stdout?.on("data", feed);
|
|
588
|
+
child.stderr?.on("data", feed);
|
|
589
|
+
void waitForChildProcess(child, () => spillError === undefined &&
|
|
590
|
+
spillStart !== undefined &&
|
|
591
|
+
(spillStream === undefined || spillBackpressured)).then(async ({ code, signal: exitSignal }) => {
|
|
592
|
+
await finishSpill();
|
|
415
593
|
try {
|
|
416
|
-
|
|
594
|
+
capture.finish();
|
|
595
|
+
capture.flush();
|
|
417
596
|
}
|
|
418
597
|
catch (error) {
|
|
419
|
-
|
|
420
|
-
callbackError = new ExecutionError("callback_error", cause.message, cause);
|
|
421
|
-
onAbort();
|
|
598
|
+
failCallback(error);
|
|
422
599
|
}
|
|
423
|
-
});
|
|
424
|
-
void waitForChildProcess(child).then(({ code, signal: exitSignal }) => {
|
|
425
600
|
if (callbackError) {
|
|
426
601
|
settle(err(callbackError));
|
|
427
602
|
return;
|
|
@@ -430,106 +605,150 @@ export class NodeExecutionEnv {
|
|
|
430
605
|
settle(err(new ExecutionError("timeout", `timeout:${options?.timeout}`)));
|
|
431
606
|
return;
|
|
432
607
|
}
|
|
433
|
-
if (
|
|
608
|
+
if (signal?.aborted) {
|
|
434
609
|
settle(err(new ExecutionError("aborted", "aborted")));
|
|
435
610
|
return;
|
|
436
611
|
}
|
|
612
|
+
if (spillError) {
|
|
613
|
+
settle(err(spillError));
|
|
614
|
+
return;
|
|
615
|
+
}
|
|
616
|
+
const output = capture.snapshot();
|
|
437
617
|
// A process killed by a signal (e.g. OOM killer) has no exit code; map it
|
|
438
618
|
// to the conventional 128 + signal number so callers do not mistake it
|
|
439
619
|
// for a successful exit.
|
|
440
620
|
const exitCode = code ?? (exitSignal ? 128 + (osConstants.signals[exitSignal] ?? 0) : 1);
|
|
441
|
-
settle(ok({
|
|
621
|
+
settle(ok({
|
|
622
|
+
exitCode,
|
|
623
|
+
truncation: output.truncation,
|
|
624
|
+
...(output.spillPath === undefined ? {} : { spillPath: output.spillPath }),
|
|
625
|
+
...(output.lastLineBytes === undefined ? {} : { lastLineBytes: output.lastLineBytes }),
|
|
626
|
+
}));
|
|
442
627
|
}, (error) => settle(err(new ExecutionError("spawn_error", error.message, error))));
|
|
443
628
|
});
|
|
444
629
|
}
|
|
445
|
-
async
|
|
630
|
+
async openTextLineReader(path, context) {
|
|
446
631
|
const resolved = resolvePath(this.cwd, path);
|
|
447
|
-
const aborted = abortResult(abortSignal, resolved);
|
|
632
|
+
const aborted = abortResult(context.abortSignal, resolved);
|
|
448
633
|
if (aborted)
|
|
449
634
|
return aborted;
|
|
450
635
|
try {
|
|
451
|
-
|
|
636
|
+
const file = await openFile(resolved, "r");
|
|
637
|
+
const afterOpenAbort = abortResult(context.abortSignal, resolved);
|
|
638
|
+
if (afterOpenAbort) {
|
|
639
|
+
await file.close().catch(() => undefined);
|
|
640
|
+
return afterOpenAbort;
|
|
641
|
+
}
|
|
642
|
+
return ok(new NodeTextLineReader(file, resolved));
|
|
452
643
|
}
|
|
453
644
|
catch (error) {
|
|
454
645
|
return err(toFileError(error, resolved));
|
|
455
646
|
}
|
|
456
647
|
}
|
|
457
|
-
async
|
|
648
|
+
async readTextFile(path, context) {
|
|
458
649
|
const resolved = resolvePath(this.cwd, path);
|
|
459
|
-
const
|
|
650
|
+
const signal = context.abortSignal;
|
|
651
|
+
const aborted = abortResult(signal, resolved);
|
|
460
652
|
if (aborted)
|
|
461
653
|
return aborted;
|
|
654
|
+
try {
|
|
655
|
+
return ok(await readFile(resolved, { encoding: "utf8", signal }));
|
|
656
|
+
}
|
|
657
|
+
catch (error) {
|
|
658
|
+
return err(toFileError(error, resolved));
|
|
659
|
+
}
|
|
660
|
+
}
|
|
661
|
+
async readTextLines(path, options, context) {
|
|
462
662
|
if (options?.maxLines !== undefined && options.maxLines <= 0)
|
|
463
663
|
return ok([]);
|
|
464
|
-
|
|
465
|
-
|
|
664
|
+
const opened = await this.openTextLineReader(path, context);
|
|
665
|
+
if (!opened.ok)
|
|
666
|
+
return opened;
|
|
667
|
+
const lines = [];
|
|
466
668
|
try {
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
if (loopAbort)
|
|
473
|
-
return loopAbort;
|
|
474
|
-
lines.push(line);
|
|
475
|
-
if (options?.maxLines !== undefined && lines.length >= options.maxLines)
|
|
669
|
+
while (options?.maxLines === undefined || lines.length < options.maxLines) {
|
|
670
|
+
const line = await opened.value.readLine(context);
|
|
671
|
+
if (!line.ok)
|
|
672
|
+
return line;
|
|
673
|
+
if (line.value === undefined)
|
|
476
674
|
break;
|
|
675
|
+
lines.push(line.value.text);
|
|
477
676
|
}
|
|
478
|
-
const afterReadAbort = abortResult(options?.abortSignal, resolved);
|
|
479
|
-
if (afterReadAbort)
|
|
480
|
-
return afterReadAbort;
|
|
481
677
|
return ok(lines);
|
|
482
678
|
}
|
|
483
|
-
catch (error) {
|
|
484
|
-
return err(toFileError(error, resolved));
|
|
485
|
-
}
|
|
486
679
|
finally {
|
|
487
|
-
|
|
488
|
-
stream?.destroy();
|
|
680
|
+
await opened.value.close(context);
|
|
489
681
|
}
|
|
490
682
|
}
|
|
491
|
-
async readBinaryFile(path,
|
|
683
|
+
async readBinaryFile(path, context) {
|
|
492
684
|
const resolved = resolvePath(this.cwd, path);
|
|
493
|
-
const
|
|
685
|
+
const signal = context.abortSignal;
|
|
686
|
+
const aborted = abortResult(signal, resolved);
|
|
494
687
|
if (aborted)
|
|
495
688
|
return aborted;
|
|
496
689
|
try {
|
|
497
|
-
return ok(await readFile(resolved, { signal
|
|
690
|
+
return ok(await readFile(resolved, { signal }));
|
|
498
691
|
}
|
|
499
692
|
catch (error) {
|
|
500
693
|
return err(toFileError(error, resolved));
|
|
501
694
|
}
|
|
502
695
|
}
|
|
503
|
-
async writeFile(path, content,
|
|
696
|
+
async writeFile(path, content, context) {
|
|
504
697
|
const resolved = resolvePath(this.cwd, path);
|
|
505
|
-
const
|
|
698
|
+
const signal = context.abortSignal;
|
|
699
|
+
const aborted = abortResult(signal, resolved);
|
|
506
700
|
if (aborted)
|
|
507
701
|
return aborted;
|
|
508
702
|
try {
|
|
509
703
|
await mkdir(resolve(resolved, ".."), { recursive: true });
|
|
510
|
-
const afterMkdirAbort = abortResult(
|
|
704
|
+
const afterMkdirAbort = abortResult(signal, resolved);
|
|
511
705
|
if (afterMkdirAbort)
|
|
512
706
|
return afterMkdirAbort;
|
|
513
|
-
await writeFile(resolved, content, { signal
|
|
707
|
+
await writeFile(resolved, content, { signal });
|
|
514
708
|
return ok(undefined);
|
|
515
709
|
}
|
|
516
710
|
catch (error) {
|
|
517
711
|
return err(toFileError(error, resolved));
|
|
518
712
|
}
|
|
519
713
|
}
|
|
520
|
-
async appendFile(path, content) {
|
|
714
|
+
async appendFile(path, content, context) {
|
|
521
715
|
const resolved = resolvePath(this.cwd, path);
|
|
716
|
+
const signal = context.abortSignal;
|
|
717
|
+
const aborted = abortResult(signal, resolved);
|
|
718
|
+
if (aborted)
|
|
719
|
+
return aborted;
|
|
522
720
|
try {
|
|
523
721
|
await mkdir(resolve(resolved, ".."), { recursive: true });
|
|
722
|
+
const afterMkdirAbort = abortResult(signal, resolved);
|
|
723
|
+
if (afterMkdirAbort)
|
|
724
|
+
return afterMkdirAbort;
|
|
524
725
|
await appendFile(resolved, content);
|
|
525
|
-
|
|
726
|
+
const afterAppendAbort = abortResult(signal, resolved);
|
|
727
|
+
return afterAppendAbort ?? ok(undefined);
|
|
526
728
|
}
|
|
527
729
|
catch (error) {
|
|
528
730
|
return err(toFileError(error, resolved));
|
|
529
731
|
}
|
|
530
732
|
}
|
|
531
|
-
async
|
|
733
|
+
async renameFile(sourcePath, destinationPath, context) {
|
|
734
|
+
const source = resolvePath(this.cwd, sourcePath);
|
|
735
|
+
const destination = resolvePath(this.cwd, destinationPath);
|
|
736
|
+
const aborted = abortResult(context.abortSignal, destination);
|
|
737
|
+
if (aborted)
|
|
738
|
+
return aborted;
|
|
739
|
+
try {
|
|
740
|
+
await rename(source, destination);
|
|
741
|
+
return ok(undefined);
|
|
742
|
+
}
|
|
743
|
+
catch (error) {
|
|
744
|
+
return err(toFileError(error, source));
|
|
745
|
+
}
|
|
746
|
+
}
|
|
747
|
+
async fileInfo(path, context) {
|
|
532
748
|
const resolved = resolvePath(this.cwd, path);
|
|
749
|
+
const aborted = abortResult(context.abortSignal, resolved);
|
|
750
|
+
if (aborted)
|
|
751
|
+
return aborted;
|
|
533
752
|
try {
|
|
534
753
|
return fileInfoFromStats(resolved, await lstat(resolved));
|
|
535
754
|
}
|
|
@@ -537,16 +756,17 @@ export class NodeExecutionEnv {
|
|
|
537
756
|
return err(toFileError(error, resolved));
|
|
538
757
|
}
|
|
539
758
|
}
|
|
540
|
-
async listDir(path,
|
|
759
|
+
async listDir(path, context) {
|
|
541
760
|
const resolved = resolvePath(this.cwd, path);
|
|
542
|
-
const
|
|
761
|
+
const signal = context.abortSignal;
|
|
762
|
+
const aborted = abortResult(signal, resolved);
|
|
543
763
|
if (aborted)
|
|
544
764
|
return aborted;
|
|
545
765
|
try {
|
|
546
766
|
const entries = await readdir(resolved, { withFileTypes: true });
|
|
547
767
|
const infos = [];
|
|
548
768
|
for (const entry of entries) {
|
|
549
|
-
const loopAbort = abortResult(
|
|
769
|
+
const loopAbort = abortResult(signal, resolved);
|
|
550
770
|
if (loopAbort)
|
|
551
771
|
return loopAbort;
|
|
552
772
|
const entryPath = resolve(resolved, entry.name);
|
|
@@ -565,8 +785,11 @@ export class NodeExecutionEnv {
|
|
|
565
785
|
return err(toFileError(error, resolved));
|
|
566
786
|
}
|
|
567
787
|
}
|
|
568
|
-
async canonicalPath(path) {
|
|
788
|
+
async canonicalPath(path, context) {
|
|
569
789
|
const resolved = resolvePath(this.cwd, path);
|
|
790
|
+
const aborted = abortResult(context.abortSignal, resolved);
|
|
791
|
+
if (aborted)
|
|
792
|
+
return aborted;
|
|
570
793
|
try {
|
|
571
794
|
return ok(await realpath(resolved));
|
|
572
795
|
}
|
|
@@ -574,16 +797,19 @@ export class NodeExecutionEnv {
|
|
|
574
797
|
return err(toFileError(error, resolved));
|
|
575
798
|
}
|
|
576
799
|
}
|
|
577
|
-
async exists(path) {
|
|
578
|
-
const result = await this.fileInfo(path);
|
|
800
|
+
async exists(path, context) {
|
|
801
|
+
const result = await this.fileInfo(path, context);
|
|
579
802
|
if (result.ok)
|
|
580
803
|
return ok(true);
|
|
581
804
|
if (result.error.code === "not_found")
|
|
582
805
|
return ok(false);
|
|
583
806
|
return err(result.error);
|
|
584
807
|
}
|
|
585
|
-
async createDir(path, options) {
|
|
808
|
+
async createDir(path, options, context) {
|
|
586
809
|
const resolved = resolvePath(this.cwd, path);
|
|
810
|
+
const aborted = abortResult(context.abortSignal, resolved);
|
|
811
|
+
if (aborted)
|
|
812
|
+
return aborted;
|
|
587
813
|
try {
|
|
588
814
|
await mkdir(resolved, { recursive: options?.recursive ?? true });
|
|
589
815
|
return ok(undefined);
|
|
@@ -592,8 +818,11 @@ export class NodeExecutionEnv {
|
|
|
592
818
|
return err(toFileError(error, resolved));
|
|
593
819
|
}
|
|
594
820
|
}
|
|
595
|
-
async remove(path, options) {
|
|
821
|
+
async remove(path, options, context) {
|
|
596
822
|
const resolved = resolvePath(this.cwd, path);
|
|
823
|
+
const aborted = abortResult(context.abortSignal, resolved);
|
|
824
|
+
if (aborted)
|
|
825
|
+
return aborted;
|
|
597
826
|
try {
|
|
598
827
|
await rm(resolved, { recursive: options?.recursive ?? false, force: options?.force ?? false });
|
|
599
828
|
return ok(undefined);
|
|
@@ -602,16 +831,20 @@ export class NodeExecutionEnv {
|
|
|
602
831
|
return err(toFileError(error, resolved));
|
|
603
832
|
}
|
|
604
833
|
}
|
|
605
|
-
async createTempDir(prefix
|
|
834
|
+
async createTempDir(prefix, context) {
|
|
835
|
+
const aborted = abortResult(context.abortSignal);
|
|
836
|
+
if (aborted)
|
|
837
|
+
return aborted;
|
|
606
838
|
try {
|
|
839
|
+
prefix ??= "tmp-";
|
|
607
840
|
return ok(await mkdtemp(join(tmpdir(), prefix)));
|
|
608
841
|
}
|
|
609
842
|
catch (error) {
|
|
610
843
|
return err(toFileError(error));
|
|
611
844
|
}
|
|
612
845
|
}
|
|
613
|
-
async createTempFile(options) {
|
|
614
|
-
const dir = await this.createTempDir("tmp-");
|
|
846
|
+
async createTempFile(options, context) {
|
|
847
|
+
const dir = await this.createTempDir("tmp-", context);
|
|
615
848
|
if (!dir.ok)
|
|
616
849
|
return dir;
|
|
617
850
|
const filePath = join(dir.value, `${options?.prefix ?? ""}${randomUUID()}${options?.suffix ?? ""}`);
|
|
@@ -623,7 +856,7 @@ export class NodeExecutionEnv {
|
|
|
623
856
|
return err(toFileError(error, filePath));
|
|
624
857
|
}
|
|
625
858
|
}
|
|
626
|
-
async cleanup() {
|
|
859
|
+
async cleanup(_context) {
|
|
627
860
|
for (const pid of this.activeChildPids)
|
|
628
861
|
killProcessTree(pid);
|
|
629
862
|
this.activeChildPids.clear();
|