@earendil-works/pi-agent-core 0.84.3 → 0.85.0
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 +32 -25
- 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 +242 -87
- 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 +5 -2
- 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,15 +1,17 @@
|
|
|
1
1
|
import { spawn } from "node:child_process";
|
|
2
2
|
import { randomUUID } from "node:crypto";
|
|
3
|
-
import { constants, createReadStream } from "node:fs";
|
|
3
|
+
import { constants, createReadStream, createWriteStream } from "node:fs";
|
|
4
4
|
import { access, appendFile, lstat, mkdir, mkdtemp, readdir, readFile, realpath, rename, rm, writeFile, } from "node:fs/promises";
|
|
5
|
-
import { homedir, tmpdir } from "node:os";
|
|
5
|
+
import { homedir, constants as osConstants, tmpdir } from "node:os";
|
|
6
6
|
import { basename, isAbsolute, join, resolve } from "node:path";
|
|
7
7
|
import { createInterface } from "node:readline";
|
|
8
8
|
import { fileURLToPath } from "node:url";
|
|
9
9
|
import { ExecutionError, err, FileError, ok, toError, } from "../types.js";
|
|
10
|
+
import { OutputCapture } from "../utils/output-capture.js";
|
|
10
11
|
const MAX_TIMEOUT_MS = 2_147_483_647;
|
|
11
12
|
const MAX_TIMEOUT_SECONDS = MAX_TIMEOUT_MS / 1000;
|
|
12
13
|
const EXIT_STDIO_GRACE_MS = 100;
|
|
14
|
+
const SPILL_HIGH_WATER_MARK = 8 * 1024 * 1024;
|
|
13
15
|
function resolveTimeoutMs(timeout) {
|
|
14
16
|
if (timeout === undefined)
|
|
15
17
|
return ok(undefined);
|
|
@@ -201,11 +203,13 @@ function getShellEnv(baseEnv, extraEnv, inheritEnv = true) {
|
|
|
201
203
|
function killProcessTree(pid) {
|
|
202
204
|
if (process.platform === "win32") {
|
|
203
205
|
try {
|
|
204
|
-
spawn("taskkill", ["/F", "/T", "/PID", String(pid)], {
|
|
206
|
+
const child = spawn(join(process.env.SystemRoot ?? "C:\\Windows", "System32", "taskkill.exe"), ["/F", "/T", "/PID", String(pid)], {
|
|
205
207
|
stdio: "ignore",
|
|
206
208
|
detached: true,
|
|
207
209
|
windowsHide: true,
|
|
208
210
|
});
|
|
211
|
+
// A failed spawn emits "error" asynchronously; consume it to avoid crashing Node.
|
|
212
|
+
child.once("error", () => { });
|
|
209
213
|
}
|
|
210
214
|
catch {
|
|
211
215
|
// Ignore errors.
|
|
@@ -224,11 +228,12 @@ function killProcessTree(pid) {
|
|
|
224
228
|
}
|
|
225
229
|
}
|
|
226
230
|
}
|
|
227
|
-
function waitForChildProcess(child) {
|
|
231
|
+
function waitForChildProcess(child, spillIsDraining) {
|
|
228
232
|
return new Promise((resolvePromise, reject) => {
|
|
229
233
|
let settled = false;
|
|
230
234
|
let exited = false;
|
|
231
235
|
let exitCode = null;
|
|
236
|
+
let exitSignal = null;
|
|
232
237
|
let postExitTimer;
|
|
233
238
|
let stdoutEnded = child.stdout === null;
|
|
234
239
|
let stderrEnded = child.stderr === null;
|
|
@@ -243,23 +248,28 @@ function waitForChildProcess(child) {
|
|
|
243
248
|
child.stdout?.removeListener("data", onData);
|
|
244
249
|
child.stderr?.removeListener("data", onData);
|
|
245
250
|
};
|
|
246
|
-
const finalize = (
|
|
251
|
+
const finalize = () => {
|
|
247
252
|
if (settled)
|
|
248
253
|
return;
|
|
249
254
|
settled = true;
|
|
250
255
|
cleanup();
|
|
251
256
|
child.stdout?.destroy();
|
|
252
257
|
child.stderr?.destroy();
|
|
253
|
-
resolvePromise(code);
|
|
258
|
+
resolvePromise({ code: exitCode, signal: exitSignal });
|
|
254
259
|
};
|
|
255
260
|
const maybeFinalizeAfterExit = () => {
|
|
256
261
|
if (exited && stdoutEnded && stderrEnded)
|
|
257
|
-
finalize(
|
|
262
|
+
finalize();
|
|
258
263
|
};
|
|
259
264
|
const armIdleTimer = () => {
|
|
260
265
|
if (postExitTimer)
|
|
261
266
|
clearTimeout(postExitTimer);
|
|
262
|
-
postExitTimer = setTimeout(() =>
|
|
267
|
+
postExitTimer = setTimeout(() => {
|
|
268
|
+
if (spillIsDraining())
|
|
269
|
+
armIdleTimer();
|
|
270
|
+
else
|
|
271
|
+
finalize();
|
|
272
|
+
}, EXIT_STDIO_GRACE_MS);
|
|
263
273
|
};
|
|
264
274
|
const onData = () => {
|
|
265
275
|
if (exited && !settled)
|
|
@@ -280,14 +290,19 @@ function waitForChildProcess(child) {
|
|
|
280
290
|
cleanup();
|
|
281
291
|
reject(error);
|
|
282
292
|
};
|
|
283
|
-
const onExit = (code) => {
|
|
293
|
+
const onExit = (code, signal) => {
|
|
284
294
|
exited = true;
|
|
285
295
|
exitCode = code;
|
|
296
|
+
exitSignal = signal;
|
|
286
297
|
maybeFinalizeAfterExit();
|
|
287
298
|
if (!settled)
|
|
288
299
|
armIdleTimer();
|
|
289
300
|
};
|
|
290
|
-
const onClose = (code) =>
|
|
301
|
+
const onClose = (code, signal) => {
|
|
302
|
+
exitCode = code;
|
|
303
|
+
exitSignal = signal;
|
|
304
|
+
finalize();
|
|
305
|
+
};
|
|
291
306
|
child.stdout?.once("end", onStdoutEnd);
|
|
292
307
|
child.stderr?.once("end", onStderrEnd);
|
|
293
308
|
child.stdout?.on("data", onData);
|
|
@@ -307,14 +322,15 @@ export class NodeExecutionEnv {
|
|
|
307
322
|
this.shellPath = options.shellPath;
|
|
308
323
|
this.shellEnv = options.shellEnv;
|
|
309
324
|
}
|
|
310
|
-
async absolutePath(path) {
|
|
325
|
+
async absolutePath(path, _context) {
|
|
311
326
|
return ok(resolvePath(this.cwd, path));
|
|
312
327
|
}
|
|
313
|
-
async joinPath(parts) {
|
|
328
|
+
async joinPath(parts, _context) {
|
|
314
329
|
return ok(join(...parts));
|
|
315
330
|
}
|
|
316
|
-
async exec(command, options) {
|
|
317
|
-
|
|
331
|
+
async exec(command, options, context) {
|
|
332
|
+
const signal = context.abortSignal;
|
|
333
|
+
if (signal?.aborted)
|
|
318
334
|
return err(new ExecutionError("aborted", "aborted"));
|
|
319
335
|
const timeoutMsResult = resolveTimeoutMs(options?.timeout);
|
|
320
336
|
if (!timeoutMsResult.ok)
|
|
@@ -332,30 +348,119 @@ export class NodeExecutionEnv {
|
|
|
332
348
|
return err(new ExecutionError("spawn_error", `Working directory does not exist: ${cwd}\nCannot execute bash commands.`, cause));
|
|
333
349
|
}
|
|
334
350
|
return await new Promise((resolvePromise) => {
|
|
335
|
-
let stdout = "";
|
|
336
|
-
let stderr = "";
|
|
337
351
|
let settled = false;
|
|
338
352
|
let timedOut = false;
|
|
339
353
|
let callbackError;
|
|
354
|
+
let spillError;
|
|
340
355
|
let child;
|
|
341
356
|
let timeoutId;
|
|
357
|
+
const spillPrefix = [];
|
|
358
|
+
let spillPath;
|
|
359
|
+
const spillQueue = [];
|
|
360
|
+
let spillStart;
|
|
361
|
+
let spillStream;
|
|
362
|
+
let spillBackpressured = false;
|
|
342
363
|
const onAbort = () => {
|
|
343
|
-
if (child?.pid)
|
|
364
|
+
if (child?.pid)
|
|
344
365
|
killProcessTree(child.pid);
|
|
345
|
-
}
|
|
346
366
|
};
|
|
367
|
+
const failCallback = (error) => {
|
|
368
|
+
if (callbackError !== undefined)
|
|
369
|
+
return;
|
|
370
|
+
const cause = toError(error);
|
|
371
|
+
callbackError = new ExecutionError("callback_error", cause.message, cause);
|
|
372
|
+
onAbort();
|
|
373
|
+
};
|
|
374
|
+
let capture;
|
|
375
|
+
try {
|
|
376
|
+
capture = new OutputCapture(options?.capture, context, {
|
|
377
|
+
onUpdate: options?.onUpdate,
|
|
378
|
+
onError: failCallback,
|
|
379
|
+
});
|
|
380
|
+
}
|
|
381
|
+
catch (error) {
|
|
382
|
+
const cause = toError(error);
|
|
383
|
+
resolvePromise(err(new ExecutionError("unknown", cause.message, cause)));
|
|
384
|
+
return;
|
|
385
|
+
}
|
|
347
386
|
const settle = (result) => {
|
|
387
|
+
if (settled)
|
|
388
|
+
return;
|
|
389
|
+
settled = true;
|
|
348
390
|
if (timeoutId)
|
|
349
391
|
clearTimeout(timeoutId);
|
|
350
|
-
if (
|
|
351
|
-
|
|
392
|
+
if (signal)
|
|
393
|
+
signal.removeEventListener("abort", onAbort);
|
|
352
394
|
if (child?.pid)
|
|
353
395
|
this.activeChildPids.delete(child.pid);
|
|
354
|
-
|
|
355
|
-
return;
|
|
356
|
-
settled = true;
|
|
396
|
+
capture.dispose();
|
|
357
397
|
resolvePromise(result);
|
|
358
398
|
};
|
|
399
|
+
const pauseOutput = () => {
|
|
400
|
+
child?.stdout?.pause();
|
|
401
|
+
child?.stderr?.pause();
|
|
402
|
+
};
|
|
403
|
+
const resumeOutput = () => {
|
|
404
|
+
if (callbackError || spillError || timedOut || signal?.aborted || spillBackpressured)
|
|
405
|
+
return;
|
|
406
|
+
child?.stdout?.resume();
|
|
407
|
+
child?.stderr?.resume();
|
|
408
|
+
};
|
|
409
|
+
const failSpill = (error) => {
|
|
410
|
+
if (spillError !== undefined)
|
|
411
|
+
return;
|
|
412
|
+
const cause = toError(error);
|
|
413
|
+
spillError = new ExecutionError("unknown", `Failed to preserve complete shell output: ${cause.message}`, cause);
|
|
414
|
+
spillBackpressured = false;
|
|
415
|
+
onAbort();
|
|
416
|
+
};
|
|
417
|
+
const writeSpill = (chunk) => {
|
|
418
|
+
if (spillStream === undefined || chunk.length === 0)
|
|
419
|
+
return;
|
|
420
|
+
if (spillStream.write(chunk) || spillBackpressured)
|
|
421
|
+
return;
|
|
422
|
+
spillBackpressured = true;
|
|
423
|
+
pauseOutput();
|
|
424
|
+
spillStream.once("drain", () => {
|
|
425
|
+
spillBackpressured = false;
|
|
426
|
+
resumeOutput();
|
|
427
|
+
});
|
|
428
|
+
};
|
|
429
|
+
const startSpill = (chunk) => {
|
|
430
|
+
if (spillStream !== undefined) {
|
|
431
|
+
writeSpill(chunk);
|
|
432
|
+
return;
|
|
433
|
+
}
|
|
434
|
+
spillQueue.push(chunk);
|
|
435
|
+
if (spillStart !== undefined)
|
|
436
|
+
return;
|
|
437
|
+
pauseOutput();
|
|
438
|
+
spillStart = (async () => {
|
|
439
|
+
const created = await this.createTempFile({ prefix: "pi-output-", suffix: ".log" }, context);
|
|
440
|
+
if (!created.ok)
|
|
441
|
+
throw created.error;
|
|
442
|
+
spillPath = created.value;
|
|
443
|
+
capture.setSpillPath(spillPath);
|
|
444
|
+
spillStream = createWriteStream(spillPath, { flags: "a", highWaterMark: SPILL_HIGH_WATER_MARK });
|
|
445
|
+
spillStream.on("error", failSpill);
|
|
446
|
+
for (const queued of spillQueue)
|
|
447
|
+
writeSpill(queued);
|
|
448
|
+
spillQueue.length = 0;
|
|
449
|
+
})()
|
|
450
|
+
.catch(failSpill)
|
|
451
|
+
.finally(resumeOutput);
|
|
452
|
+
};
|
|
453
|
+
const finishSpill = async () => {
|
|
454
|
+
await spillStart;
|
|
455
|
+
const stream = spillStream;
|
|
456
|
+
if (stream === undefined || spillError !== undefined || stream.destroyed)
|
|
457
|
+
return;
|
|
458
|
+
await new Promise((resolveFinish) => {
|
|
459
|
+
stream.once("error", () => resolveFinish());
|
|
460
|
+
stream.once("finish", resolveFinish);
|
|
461
|
+
stream.end();
|
|
462
|
+
});
|
|
463
|
+
};
|
|
359
464
|
try {
|
|
360
465
|
const commandFromStdin = shellConfig.value.commandTransport === "stdin";
|
|
361
466
|
child = spawn(shellConfig.value.shell, commandFromStdin ? shellConfig.value.args : [...shellConfig.value.args, command], {
|
|
@@ -378,47 +483,54 @@ export class NodeExecutionEnv {
|
|
|
378
483
|
return;
|
|
379
484
|
}
|
|
380
485
|
timeoutId =
|
|
381
|
-
timeoutMs
|
|
382
|
-
?
|
|
486
|
+
timeoutMs === undefined
|
|
487
|
+
? undefined
|
|
488
|
+
: setTimeout(() => {
|
|
383
489
|
timedOut = true;
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
: undefined;
|
|
389
|
-
if (options?.abortSignal) {
|
|
390
|
-
if (options.abortSignal.aborted) {
|
|
490
|
+
onAbort();
|
|
491
|
+
}, timeoutMs);
|
|
492
|
+
if (signal) {
|
|
493
|
+
if (signal.aborted)
|
|
391
494
|
onAbort();
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
options.abortSignal.addEventListener("abort", onAbort, { once: true });
|
|
395
|
-
}
|
|
495
|
+
else
|
|
496
|
+
signal.addEventListener("abort", onAbort, { once: true });
|
|
396
497
|
}
|
|
397
|
-
|
|
398
|
-
child.stderr?.setEncoding("utf8");
|
|
399
|
-
child.stdout?.on("data", (chunk) => {
|
|
400
|
-
stdout += chunk;
|
|
498
|
+
const feed = (chunk) => {
|
|
401
499
|
try {
|
|
402
|
-
|
|
500
|
+
const wasTruncated = capture.truncated;
|
|
501
|
+
capture.push(chunk);
|
|
502
|
+
if (!options?.capture?.spill || chunk.length === 0)
|
|
503
|
+
return;
|
|
504
|
+
if (spillPath !== undefined || wasTruncated) {
|
|
505
|
+
startSpill(chunk);
|
|
506
|
+
}
|
|
507
|
+
else if (capture.truncated) {
|
|
508
|
+
for (const prefix of spillPrefix)
|
|
509
|
+
startSpill(prefix);
|
|
510
|
+
spillPrefix.length = 0;
|
|
511
|
+
startSpill(chunk);
|
|
512
|
+
}
|
|
513
|
+
else {
|
|
514
|
+
spillPrefix.push(chunk);
|
|
515
|
+
}
|
|
403
516
|
}
|
|
404
517
|
catch (error) {
|
|
405
|
-
|
|
406
|
-
callbackError = new ExecutionError("callback_error", cause.message, cause);
|
|
407
|
-
onAbort();
|
|
518
|
+
failCallback(error);
|
|
408
519
|
}
|
|
409
|
-
}
|
|
410
|
-
child.
|
|
411
|
-
|
|
520
|
+
};
|
|
521
|
+
child.stdout?.on("data", feed);
|
|
522
|
+
child.stderr?.on("data", feed);
|
|
523
|
+
void waitForChildProcess(child, () => spillError === undefined &&
|
|
524
|
+
spillStart !== undefined &&
|
|
525
|
+
(spillStream === undefined || spillBackpressured)).then(async ({ code, signal: exitSignal }) => {
|
|
526
|
+
await finishSpill();
|
|
412
527
|
try {
|
|
413
|
-
|
|
528
|
+
capture.finish();
|
|
529
|
+
capture.flush();
|
|
414
530
|
}
|
|
415
531
|
catch (error) {
|
|
416
|
-
|
|
417
|
-
callbackError = new ExecutionError("callback_error", cause.message, cause);
|
|
418
|
-
onAbort();
|
|
532
|
+
failCallback(error);
|
|
419
533
|
}
|
|
420
|
-
});
|
|
421
|
-
void waitForChildProcess(child).then((code) => {
|
|
422
534
|
if (callbackError) {
|
|
423
535
|
settle(err(callbackError));
|
|
424
536
|
return;
|
|
@@ -427,29 +539,45 @@ export class NodeExecutionEnv {
|
|
|
427
539
|
settle(err(new ExecutionError("timeout", `timeout:${options?.timeout}`)));
|
|
428
540
|
return;
|
|
429
541
|
}
|
|
430
|
-
if (
|
|
542
|
+
if (signal?.aborted) {
|
|
431
543
|
settle(err(new ExecutionError("aborted", "aborted")));
|
|
432
544
|
return;
|
|
433
545
|
}
|
|
434
|
-
|
|
546
|
+
if (spillError) {
|
|
547
|
+
settle(err(spillError));
|
|
548
|
+
return;
|
|
549
|
+
}
|
|
550
|
+
const output = capture.snapshot();
|
|
551
|
+
// A process killed by a signal (e.g. OOM killer) has no exit code; map it
|
|
552
|
+
// to the conventional 128 + signal number so callers do not mistake it
|
|
553
|
+
// for a successful exit.
|
|
554
|
+
const exitCode = code ?? (exitSignal ? 128 + (osConstants.signals[exitSignal] ?? 0) : 1);
|
|
555
|
+
settle(ok({
|
|
556
|
+
exitCode,
|
|
557
|
+
truncation: output.truncation,
|
|
558
|
+
...(output.spillPath === undefined ? {} : { spillPath: output.spillPath }),
|
|
559
|
+
...(output.lastLineBytes === undefined ? {} : { lastLineBytes: output.lastLineBytes }),
|
|
560
|
+
}));
|
|
435
561
|
}, (error) => settle(err(new ExecutionError("spawn_error", error.message, error))));
|
|
436
562
|
});
|
|
437
563
|
}
|
|
438
|
-
async readTextFile(path,
|
|
564
|
+
async readTextFile(path, context) {
|
|
439
565
|
const resolved = resolvePath(this.cwd, path);
|
|
440
|
-
const
|
|
566
|
+
const signal = context.abortSignal;
|
|
567
|
+
const aborted = abortResult(signal, resolved);
|
|
441
568
|
if (aborted)
|
|
442
569
|
return aborted;
|
|
443
570
|
try {
|
|
444
|
-
return ok(await readFile(resolved, { encoding: "utf8", signal
|
|
571
|
+
return ok(await readFile(resolved, { encoding: "utf8", signal }));
|
|
445
572
|
}
|
|
446
573
|
catch (error) {
|
|
447
574
|
return err(toFileError(error, resolved));
|
|
448
575
|
}
|
|
449
576
|
}
|
|
450
|
-
async readTextLines(path, options) {
|
|
577
|
+
async readTextLines(path, options, context) {
|
|
451
578
|
const resolved = resolvePath(this.cwd, path);
|
|
452
|
-
const
|
|
579
|
+
const signal = context.abortSignal;
|
|
580
|
+
const aborted = abortResult(signal, resolved);
|
|
453
581
|
if (aborted)
|
|
454
582
|
return aborted;
|
|
455
583
|
if (options?.maxLines !== undefined && options.maxLines <= 0)
|
|
@@ -457,18 +585,18 @@ export class NodeExecutionEnv {
|
|
|
457
585
|
let stream;
|
|
458
586
|
let lineReader;
|
|
459
587
|
try {
|
|
460
|
-
stream = createReadStream(resolved, { encoding: "utf8", signal
|
|
588
|
+
stream = createReadStream(resolved, { encoding: "utf8", signal });
|
|
461
589
|
lineReader = createInterface({ input: stream, crlfDelay: Infinity });
|
|
462
590
|
const lines = [];
|
|
463
591
|
for await (const line of lineReader) {
|
|
464
|
-
const loopAbort = abortResult(
|
|
592
|
+
const loopAbort = abortResult(signal, resolved);
|
|
465
593
|
if (loopAbort)
|
|
466
594
|
return loopAbort;
|
|
467
595
|
lines.push(line);
|
|
468
596
|
if (options?.maxLines !== undefined && lines.length >= options.maxLines)
|
|
469
597
|
break;
|
|
470
598
|
}
|
|
471
|
-
const afterReadAbort = abortResult(
|
|
599
|
+
const afterReadAbort = abortResult(signal, resolved);
|
|
472
600
|
if (afterReadAbort)
|
|
473
601
|
return afterReadAbort;
|
|
474
602
|
return ok(lines);
|
|
@@ -481,50 +609,60 @@ export class NodeExecutionEnv {
|
|
|
481
609
|
stream?.destroy();
|
|
482
610
|
}
|
|
483
611
|
}
|
|
484
|
-
async readBinaryFile(path,
|
|
612
|
+
async readBinaryFile(path, context) {
|
|
485
613
|
const resolved = resolvePath(this.cwd, path);
|
|
486
|
-
const
|
|
614
|
+
const signal = context.abortSignal;
|
|
615
|
+
const aborted = abortResult(signal, resolved);
|
|
487
616
|
if (aborted)
|
|
488
617
|
return aborted;
|
|
489
618
|
try {
|
|
490
|
-
return ok(await readFile(resolved, { signal
|
|
619
|
+
return ok(await readFile(resolved, { signal }));
|
|
491
620
|
}
|
|
492
621
|
catch (error) {
|
|
493
622
|
return err(toFileError(error, resolved));
|
|
494
623
|
}
|
|
495
624
|
}
|
|
496
|
-
async writeFile(path, content,
|
|
625
|
+
async writeFile(path, content, context) {
|
|
497
626
|
const resolved = resolvePath(this.cwd, path);
|
|
498
|
-
const
|
|
627
|
+
const signal = context.abortSignal;
|
|
628
|
+
const aborted = abortResult(signal, resolved);
|
|
499
629
|
if (aborted)
|
|
500
630
|
return aborted;
|
|
501
631
|
try {
|
|
502
632
|
await mkdir(resolve(resolved, ".."), { recursive: true });
|
|
503
|
-
const afterMkdirAbort = abortResult(
|
|
633
|
+
const afterMkdirAbort = abortResult(signal, resolved);
|
|
504
634
|
if (afterMkdirAbort)
|
|
505
635
|
return afterMkdirAbort;
|
|
506
|
-
await writeFile(resolved, content, { signal
|
|
636
|
+
await writeFile(resolved, content, { signal });
|
|
507
637
|
return ok(undefined);
|
|
508
638
|
}
|
|
509
639
|
catch (error) {
|
|
510
640
|
return err(toFileError(error, resolved));
|
|
511
641
|
}
|
|
512
642
|
}
|
|
513
|
-
async appendFile(path, content) {
|
|
643
|
+
async appendFile(path, content, context) {
|
|
514
644
|
const resolved = resolvePath(this.cwd, path);
|
|
645
|
+
const signal = context.abortSignal;
|
|
646
|
+
const aborted = abortResult(signal, resolved);
|
|
647
|
+
if (aborted)
|
|
648
|
+
return aborted;
|
|
515
649
|
try {
|
|
516
650
|
await mkdir(resolve(resolved, ".."), { recursive: true });
|
|
651
|
+
const afterMkdirAbort = abortResult(signal, resolved);
|
|
652
|
+
if (afterMkdirAbort)
|
|
653
|
+
return afterMkdirAbort;
|
|
517
654
|
await appendFile(resolved, content);
|
|
518
|
-
|
|
655
|
+
const afterAppendAbort = abortResult(signal, resolved);
|
|
656
|
+
return afterAppendAbort ?? ok(undefined);
|
|
519
657
|
}
|
|
520
658
|
catch (error) {
|
|
521
659
|
return err(toFileError(error, resolved));
|
|
522
660
|
}
|
|
523
661
|
}
|
|
524
|
-
async renameFile(sourcePath, destinationPath,
|
|
662
|
+
async renameFile(sourcePath, destinationPath, context) {
|
|
525
663
|
const source = resolvePath(this.cwd, sourcePath);
|
|
526
664
|
const destination = resolvePath(this.cwd, destinationPath);
|
|
527
|
-
const aborted = abortResult(abortSignal, destination);
|
|
665
|
+
const aborted = abortResult(context.abortSignal, destination);
|
|
528
666
|
if (aborted)
|
|
529
667
|
return aborted;
|
|
530
668
|
try {
|
|
@@ -535,8 +673,11 @@ export class NodeExecutionEnv {
|
|
|
535
673
|
return err(toFileError(error, source));
|
|
536
674
|
}
|
|
537
675
|
}
|
|
538
|
-
async fileInfo(path) {
|
|
676
|
+
async fileInfo(path, context) {
|
|
539
677
|
const resolved = resolvePath(this.cwd, path);
|
|
678
|
+
const aborted = abortResult(context.abortSignal, resolved);
|
|
679
|
+
if (aborted)
|
|
680
|
+
return aborted;
|
|
540
681
|
try {
|
|
541
682
|
return fileInfoFromStats(resolved, await lstat(resolved));
|
|
542
683
|
}
|
|
@@ -544,16 +685,17 @@ export class NodeExecutionEnv {
|
|
|
544
685
|
return err(toFileError(error, resolved));
|
|
545
686
|
}
|
|
546
687
|
}
|
|
547
|
-
async listDir(path,
|
|
688
|
+
async listDir(path, context) {
|
|
548
689
|
const resolved = resolvePath(this.cwd, path);
|
|
549
|
-
const
|
|
690
|
+
const signal = context.abortSignal;
|
|
691
|
+
const aborted = abortResult(signal, resolved);
|
|
550
692
|
if (aborted)
|
|
551
693
|
return aborted;
|
|
552
694
|
try {
|
|
553
695
|
const entries = await readdir(resolved, { withFileTypes: true });
|
|
554
696
|
const infos = [];
|
|
555
697
|
for (const entry of entries) {
|
|
556
|
-
const loopAbort = abortResult(
|
|
698
|
+
const loopAbort = abortResult(signal, resolved);
|
|
557
699
|
if (loopAbort)
|
|
558
700
|
return loopAbort;
|
|
559
701
|
const entryPath = resolve(resolved, entry.name);
|
|
@@ -572,8 +714,11 @@ export class NodeExecutionEnv {
|
|
|
572
714
|
return err(toFileError(error, resolved));
|
|
573
715
|
}
|
|
574
716
|
}
|
|
575
|
-
async canonicalPath(path) {
|
|
717
|
+
async canonicalPath(path, context) {
|
|
576
718
|
const resolved = resolvePath(this.cwd, path);
|
|
719
|
+
const aborted = abortResult(context.abortSignal, resolved);
|
|
720
|
+
if (aborted)
|
|
721
|
+
return aborted;
|
|
577
722
|
try {
|
|
578
723
|
return ok(await realpath(resolved));
|
|
579
724
|
}
|
|
@@ -581,16 +726,19 @@ export class NodeExecutionEnv {
|
|
|
581
726
|
return err(toFileError(error, resolved));
|
|
582
727
|
}
|
|
583
728
|
}
|
|
584
|
-
async exists(path) {
|
|
585
|
-
const result = await this.fileInfo(path);
|
|
729
|
+
async exists(path, context) {
|
|
730
|
+
const result = await this.fileInfo(path, context);
|
|
586
731
|
if (result.ok)
|
|
587
732
|
return ok(true);
|
|
588
733
|
if (result.error.code === "not_found")
|
|
589
734
|
return ok(false);
|
|
590
735
|
return err(result.error);
|
|
591
736
|
}
|
|
592
|
-
async createDir(path, options) {
|
|
737
|
+
async createDir(path, options, context) {
|
|
593
738
|
const resolved = resolvePath(this.cwd, path);
|
|
739
|
+
const aborted = abortResult(context.abortSignal, resolved);
|
|
740
|
+
if (aborted)
|
|
741
|
+
return aborted;
|
|
594
742
|
try {
|
|
595
743
|
await mkdir(resolved, { recursive: options?.recursive ?? true });
|
|
596
744
|
return ok(undefined);
|
|
@@ -599,8 +747,11 @@ export class NodeExecutionEnv {
|
|
|
599
747
|
return err(toFileError(error, resolved));
|
|
600
748
|
}
|
|
601
749
|
}
|
|
602
|
-
async remove(path, options) {
|
|
750
|
+
async remove(path, options, context) {
|
|
603
751
|
const resolved = resolvePath(this.cwd, path);
|
|
752
|
+
const aborted = abortResult(context.abortSignal, resolved);
|
|
753
|
+
if (aborted)
|
|
754
|
+
return aborted;
|
|
604
755
|
try {
|
|
605
756
|
await rm(resolved, { recursive: options?.recursive ?? false, force: options?.force ?? false });
|
|
606
757
|
return ok(undefined);
|
|
@@ -609,16 +760,20 @@ export class NodeExecutionEnv {
|
|
|
609
760
|
return err(toFileError(error, resolved));
|
|
610
761
|
}
|
|
611
762
|
}
|
|
612
|
-
async createTempDir(prefix
|
|
763
|
+
async createTempDir(prefix, context) {
|
|
764
|
+
const aborted = abortResult(context.abortSignal);
|
|
765
|
+
if (aborted)
|
|
766
|
+
return aborted;
|
|
613
767
|
try {
|
|
768
|
+
prefix ??= "tmp-";
|
|
614
769
|
return ok(await mkdtemp(join(tmpdir(), prefix)));
|
|
615
770
|
}
|
|
616
771
|
catch (error) {
|
|
617
772
|
return err(toFileError(error));
|
|
618
773
|
}
|
|
619
774
|
}
|
|
620
|
-
async createTempFile(options) {
|
|
621
|
-
const dir = await this.createTempDir("tmp-");
|
|
775
|
+
async createTempFile(options, context) {
|
|
776
|
+
const dir = await this.createTempDir("tmp-", context);
|
|
622
777
|
if (!dir.ok)
|
|
623
778
|
return dir;
|
|
624
779
|
const filePath = join(dir.value, `${options?.prefix ?? ""}${randomUUID()}${options?.suffix ?? ""}`);
|
|
@@ -630,7 +785,7 @@ export class NodeExecutionEnv {
|
|
|
630
785
|
return err(toFileError(error, filePath));
|
|
631
786
|
}
|
|
632
787
|
}
|
|
633
|
-
async cleanup() {
|
|
788
|
+
async cleanup(_context) {
|
|
634
789
|
for (const pid of this.activeChildPids)
|
|
635
790
|
killProcessTree(pid);
|
|
636
791
|
this.activeChildPids.clear();
|