@earendil-works/pi-agent-core 0.84.4 → 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 +9 -0
- package/dist/agent-loop.js.map +1 -1
- package/dist/harness/agent-harness.d.ts +639 -384
- package/dist/harness/agent-harness.d.ts.map +1 -1
- package/dist/harness/agent-harness.js +5 -251
- package/dist/harness/agent-harness.js.map +1 -1
- package/dist/harness/compaction/branch-summarization.d.ts +12 -6
- package/dist/harness/compaction/branch-summarization.d.ts.map +1 -1
- package/dist/harness/compaction/branch-summarization.js +33 -26
- package/dist/harness/compaction/branch-summarization.js.map +1 -1
- package/dist/harness/compaction/compaction.d.ts +30 -8
- package/dist/harness/compaction/compaction.d.ts.map +1 -1
- package/dist/harness/compaction/compaction.js +53 -63
- package/dist/harness/compaction/compaction.js.map +1 -1
- package/dist/harness/config.d.ts +9 -0
- package/dist/harness/config.d.ts.map +1 -0
- package/dist/harness/config.js +27 -0
- package/dist/harness/config.js.map +1 -0
- package/dist/harness/context.d.ts +9 -0
- package/dist/harness/context.d.ts.map +1 -0
- package/dist/harness/context.js +13 -0
- package/dist/harness/context.js.map +1 -0
- package/dist/harness/env/nodejs.d.ts +24 -28
- package/dist/harness/env/nodejs.d.ts.map +1 -1
- package/dist/harness/env/nodejs.js +239 -86
- package/dist/harness/env/nodejs.js.map +1 -1
- package/dist/harness/events.d.ts +20 -38
- package/dist/harness/events.d.ts.map +1 -1
- package/dist/harness/events.js +240 -55
- package/dist/harness/events.js.map +1 -1
- package/dist/harness/execution/assistant.d.ts +42 -0
- package/dist/harness/execution/assistant.d.ts.map +1 -0
- package/dist/harness/execution/assistant.js +82 -0
- package/dist/harness/execution/assistant.js.map +1 -0
- package/dist/harness/execution/effect-gate.d.ts +22 -0
- package/dist/harness/execution/effect-gate.d.ts.map +1 -0
- package/dist/harness/execution/effect-gate.js +49 -0
- package/dist/harness/execution/effect-gate.js.map +1 -0
- package/dist/harness/execution/tools.d.ts +67 -0
- package/dist/harness/execution/tools.d.ts.map +1 -0
- package/dist/harness/execution/tools.js +121 -0
- package/dist/harness/execution/tools.js.map +1 -0
- package/dist/harness/hooks.d.ts +38 -0
- package/dist/harness/hooks.d.ts.map +1 -0
- package/dist/harness/hooks.js +406 -0
- package/dist/harness/hooks.js.map +1 -0
- package/dist/harness/messages.d.ts +2 -2
- package/dist/harness/messages.d.ts.map +1 -1
- package/dist/harness/messages.js.map +1 -1
- package/dist/harness/prompt-templates.d.ts +3 -2
- package/dist/harness/prompt-templates.d.ts.map +1 -1
- package/dist/harness/prompt-templates.js +17 -17
- package/dist/harness/prompt-templates.js.map +1 -1
- package/dist/harness/result.d.ts +93 -0
- package/dist/harness/result.d.ts.map +1 -1
- package/dist/harness/result.js +40 -0
- package/dist/harness/result.js.map +1 -1
- package/dist/harness/runtime/drive/boundary.d.ts +28 -0
- package/dist/harness/runtime/drive/boundary.d.ts.map +1 -0
- package/dist/harness/runtime/drive/boundary.js +170 -0
- package/dist/harness/runtime/drive/boundary.js.map +1 -0
- package/dist/harness/runtime/drive/checkpoint.d.ts +8 -0
- package/dist/harness/runtime/drive/checkpoint.d.ts.map +1 -0
- package/dist/harness/runtime/drive/checkpoint.js +133 -0
- package/dist/harness/runtime/drive/checkpoint.js.map +1 -0
- package/dist/harness/runtime/drive/deferred.d.ts +15 -0
- package/dist/harness/runtime/drive/deferred.d.ts.map +1 -0
- package/dist/harness/runtime/drive/deferred.js +179 -0
- package/dist/harness/runtime/drive/deferred.js.map +1 -0
- package/dist/harness/runtime/drive/generation.d.ts +8 -0
- package/dist/harness/runtime/drive/generation.d.ts.map +1 -0
- package/dist/harness/runtime/drive/generation.js +205 -0
- package/dist/harness/runtime/drive/generation.js.map +1 -0
- package/dist/harness/runtime/drive/reconcile.d.ts +5 -0
- package/dist/harness/runtime/drive/reconcile.d.ts.map +1 -0
- package/dist/harness/runtime/drive/reconcile.js +140 -0
- package/dist/harness/runtime/drive/reconcile.js.map +1 -0
- package/dist/harness/runtime/drive/recovery.d.ts +8 -0
- package/dist/harness/runtime/drive/recovery.d.ts.map +1 -0
- package/dist/harness/runtime/drive/recovery.js +85 -0
- package/dist/harness/runtime/drive/recovery.js.map +1 -0
- package/dist/harness/runtime/drive/response.d.ts +23 -0
- package/dist/harness/runtime/drive/response.d.ts.map +1 -0
- package/dist/harness/runtime/drive/response.js +394 -0
- package/dist/harness/runtime/drive/response.js.map +1 -0
- package/dist/harness/runtime/drive/retry.d.ts +4 -0
- package/dist/harness/runtime/drive/retry.d.ts.map +1 -0
- package/dist/harness/runtime/drive/retry.js +37 -0
- package/dist/harness/runtime/drive/retry.js.map +1 -0
- package/dist/harness/runtime/drive/structural.d.ts +32 -0
- package/dist/harness/runtime/drive/structural.d.ts.map +1 -0
- package/dist/harness/runtime/drive/structural.js +929 -0
- package/dist/harness/runtime/drive/structural.js.map +1 -0
- package/dist/harness/runtime/drive/terminal.d.ts +7 -0
- package/dist/harness/runtime/drive/terminal.d.ts.map +1 -0
- package/dist/harness/runtime/drive/terminal.js +49 -0
- package/dist/harness/runtime/drive/terminal.js.map +1 -0
- package/dist/harness/runtime/drive/tool-placement.d.ts +14 -0
- package/dist/harness/runtime/drive/tool-placement.d.ts.map +1 -0
- package/dist/harness/runtime/drive/tool-placement.js +244 -0
- package/dist/harness/runtime/drive/tool-placement.js.map +1 -0
- package/dist/harness/runtime/drive/tools.d.ts +6 -0
- package/dist/harness/runtime/drive/tools.d.ts.map +1 -0
- package/dist/harness/runtime/drive/tools.js +449 -0
- package/dist/harness/runtime/drive/tools.js.map +1 -0
- package/dist/harness/runtime/drive.d.ts +6 -0
- package/dist/harness/runtime/drive.d.ts.map +1 -0
- package/dist/harness/runtime/drive.js +93 -0
- package/dist/harness/runtime/drive.js.map +1 -0
- package/dist/harness/runtime/harness.d.ts +59 -0
- package/dist/harness/runtime/harness.d.ts.map +1 -0
- package/dist/harness/runtime/harness.js +311 -0
- package/dist/harness/runtime/harness.js.map +1 -0
- package/dist/harness/runtime/index.d.ts +2 -0
- package/dist/harness/runtime/index.d.ts.map +1 -0
- package/dist/harness/runtime/index.js +2 -0
- package/dist/harness/runtime/index.js.map +1 -0
- package/dist/harness/runtime/lane.d.ts +101 -0
- package/dist/harness/runtime/lane.d.ts.map +1 -0
- package/dist/harness/runtime/lane.js +1575 -0
- package/dist/harness/runtime/lane.js.map +1 -0
- package/dist/harness/runtime/progress.d.ts +15 -0
- package/dist/harness/runtime/progress.d.ts.map +1 -0
- package/dist/harness/runtime/progress.js +66 -0
- package/dist/harness/runtime/progress.js.map +1 -0
- package/dist/harness/runtime/reducer.d.ts +5 -0
- package/dist/harness/runtime/reducer.d.ts.map +1 -0
- package/dist/harness/runtime/reducer.js +240 -0
- package/dist/harness/runtime/reducer.js.map +1 -0
- package/dist/harness/runtime/restore.d.ts +24 -0
- package/dist/harness/runtime/restore.d.ts.map +1 -0
- package/dist/harness/runtime/restore.js +117 -0
- package/dist/harness/runtime/restore.js.map +1 -0
- package/dist/harness/runtime/transcript.d.ts +21 -0
- package/dist/harness/runtime/transcript.d.ts.map +1 -0
- package/dist/harness/runtime/transcript.js +72 -0
- package/dist/harness/runtime/transcript.js.map +1 -0
- package/dist/harness/runtime/types.d.ts +105 -0
- package/dist/harness/runtime/types.d.ts.map +1 -0
- package/dist/harness/runtime/types.js +61 -0
- package/dist/harness/runtime/types.js.map +1 -0
- package/dist/harness/session/commit.d.ts +53 -0
- package/dist/harness/session/commit.d.ts.map +1 -0
- package/dist/harness/session/commit.js +57 -0
- package/dist/harness/session/commit.js.map +1 -0
- package/dist/harness/session/context.d.ts +6 -18
- package/dist/harness/session/context.d.ts.map +1 -1
- package/dist/harness/session/context.js +31 -49
- package/dist/harness/session/context.js.map +1 -1
- package/dist/harness/session/fork-policy.d.ts +13 -0
- package/dist/harness/session/fork-policy.d.ts.map +1 -0
- package/dist/harness/session/fork-policy.js +22 -0
- package/dist/harness/session/fork-policy.js.map +1 -0
- package/dist/harness/session/fork.d.ts +18 -0
- package/dist/harness/session/fork.d.ts.map +1 -0
- package/dist/harness/session/fork.js +127 -0
- package/dist/harness/session/fork.js.map +1 -0
- package/dist/harness/session/in-memory-storage-state.d.ts +39 -0
- package/dist/harness/session/in-memory-storage-state.d.ts.map +1 -0
- package/dist/harness/session/in-memory-storage-state.js +216 -0
- package/dist/harness/session/in-memory-storage-state.js.map +1 -0
- package/dist/harness/session/index.d.ts +9 -5
- package/dist/harness/session/index.d.ts.map +1 -1
- package/dist/harness/session/index.js +7 -4
- package/dist/harness/session/index.js.map +1 -1
- package/dist/harness/session/jsonl/codec.d.ts +19 -8
- package/dist/harness/session/jsonl/codec.d.ts.map +1 -1
- package/dist/harness/session/jsonl/codec.js +34 -218
- package/dist/harness/session/jsonl/codec.js.map +1 -1
- package/dist/harness/session/jsonl/index.d.ts +4 -0
- package/dist/harness/session/jsonl/index.d.ts.map +1 -0
- package/dist/harness/session/jsonl/index.js +4 -0
- package/dist/harness/session/jsonl/index.js.map +1 -0
- package/dist/harness/session/jsonl/legacy-v3.d.ts +18 -0
- package/dist/harness/session/jsonl/legacy-v3.d.ts.map +1 -0
- package/dist/harness/session/jsonl/legacy-v3.js +383 -0
- package/dist/harness/session/jsonl/legacy-v3.js.map +1 -0
- package/dist/harness/session/jsonl/repo.d.ts +26 -19
- package/dist/harness/session/jsonl/repo.d.ts.map +1 -1
- package/dist/harness/session/jsonl/repo.js +266 -156
- package/dist/harness/session/jsonl/repo.js.map +1 -1
- package/dist/harness/session/jsonl/storage.d.ts +39 -41
- package/dist/harness/session/jsonl/storage.d.ts.map +1 -1
- package/dist/harness/session/jsonl/storage.js +238 -181
- package/dist/harness/session/jsonl/storage.js.map +1 -1
- package/dist/harness/session/jsonl/types.d.ts +23 -22
- package/dist/harness/session/jsonl/types.d.ts.map +1 -1
- package/dist/harness/session/jsonl/types.js +2 -1
- package/dist/harness/session/jsonl/types.js.map +1 -1
- package/dist/harness/session/memory.d.ts +46 -40
- package/dist/harness/session/memory.d.ts.map +1 -1
- package/dist/harness/session/memory.js +346 -113
- package/dist/harness/session/memory.js.map +1 -1
- package/dist/harness/session/mutation-line.d.ts +8 -0
- package/dist/harness/session/mutation-line.d.ts.map +1 -0
- package/dist/harness/session/mutation-line.js +21 -0
- package/dist/harness/session/mutation-line.js.map +1 -0
- package/dist/harness/session/session.d.ts +78 -46
- package/dist/harness/session/session.d.ts.map +1 -1
- package/dist/harness/session/session.js +343 -209
- package/dist/harness/session/session.js.map +1 -1
- package/dist/harness/session/testing/benchmark/datasets.d.ts +12 -0
- package/dist/harness/session/testing/benchmark/datasets.d.ts.map +1 -0
- package/dist/harness/session/testing/benchmark/datasets.js +24 -0
- package/dist/harness/session/testing/benchmark/datasets.js.map +1 -0
- package/dist/harness/session/testing/benchmark/session-repo.d.ts +42 -0
- package/dist/harness/session/testing/benchmark/session-repo.d.ts.map +1 -0
- package/dist/harness/session/testing/benchmark/session-repo.js +127 -0
- package/dist/harness/session/testing/benchmark/session-repo.js.map +1 -0
- package/dist/harness/session/testing/benchmark/storage.d.ts +25 -0
- package/dist/harness/session/testing/benchmark/storage.d.ts.map +1 -0
- package/dist/harness/session/testing/benchmark/storage.js +114 -0
- package/dist/harness/session/testing/benchmark/storage.js.map +1 -0
- package/dist/harness/session/testing/conformance/session-repo.d.ts +21 -0
- package/dist/harness/session/testing/conformance/session-repo.d.ts.map +1 -0
- package/dist/harness/session/testing/conformance/session-repo.js +590 -0
- package/dist/harness/session/testing/conformance/session-repo.js.map +1 -0
- package/dist/harness/session/testing/conformance/storage.d.ts +4 -0
- package/dist/harness/session/testing/conformance/storage.d.ts.map +1 -0
- package/dist/harness/session/testing/conformance/storage.js +600 -0
- package/dist/harness/session/testing/conformance/storage.js.map +1 -0
- package/dist/harness/session/testing/gating-storage.d.ts +26 -0
- package/dist/harness/session/testing/gating-storage.d.ts.map +1 -0
- package/dist/harness/session/testing/gating-storage.js +100 -0
- package/dist/harness/session/testing/gating-storage.js.map +1 -0
- package/dist/harness/session/testing/index.d.ts +9 -2
- package/dist/harness/session/testing/index.d.ts.map +1 -1
- package/dist/harness/session/testing/index.js +8 -1
- package/dist/harness/session/testing/index.js.map +1 -1
- package/dist/harness/session/testing/instrumented-storage.d.ts +11 -0
- package/dist/harness/session/testing/instrumented-storage.d.ts.map +1 -0
- package/dist/harness/session/testing/instrumented-storage.js +16 -0
- package/dist/harness/session/testing/instrumented-storage.js.map +1 -0
- package/dist/harness/session/testing/storage-decorator.d.ts +20 -0
- package/dist/harness/session/testing/storage-decorator.d.ts.map +1 -0
- package/dist/harness/session/testing/storage-decorator.js +41 -0
- package/dist/harness/session/testing/storage-decorator.js.map +1 -0
- package/dist/harness/session/testing/types.d.ts +5 -7
- package/dist/harness/session/testing/types.d.ts.map +1 -1
- package/dist/harness/session/testing/types.js.map +1 -1
- package/dist/harness/session/types.d.ts +424 -259
- package/dist/harness/session/types.d.ts.map +1 -1
- package/dist/harness/session/types.js +7 -8
- package/dist/harness/session/types.js.map +1 -1
- package/dist/harness/session/values.d.ts +95 -0
- package/dist/harness/session/values.d.ts.map +1 -0
- package/dist/harness/session/values.js +81 -0
- package/dist/harness/session/values.js.map +1 -0
- package/dist/harness/skills.d.ts +3 -2
- package/dist/harness/skills.d.ts.map +1 -1
- package/dist/harness/skills.js +29 -26
- package/dist/harness/skills.js.map +1 -1
- package/dist/harness/telemetry.d.ts +64 -43
- package/dist/harness/telemetry.d.ts.map +1 -1
- package/dist/harness/telemetry.js +45 -26
- package/dist/harness/telemetry.js.map +1 -1
- package/dist/harness/tools/bash.d.ts +4 -4
- package/dist/harness/tools/bash.d.ts.map +1 -1
- package/dist/harness/tools/bash.js +66 -93
- package/dist/harness/tools/bash.js.map +1 -1
- package/dist/harness/tools/edit.d.ts.map +1 -1
- package/dist/harness/tools/edit.js +10 -10
- package/dist/harness/tools/edit.js.map +1 -1
- package/dist/harness/tools/file-mutation-queue.d.ts +2 -1
- package/dist/harness/tools/file-mutation-queue.d.ts.map +1 -1
- package/dist/harness/tools/file-mutation-queue.js +5 -5
- package/dist/harness/tools/file-mutation-queue.js.map +1 -1
- package/dist/harness/tools/path-utils.d.ts +3 -2
- package/dist/harness/tools/path-utils.d.ts.map +1 -1
- package/dist/harness/tools/path-utils.js +5 -5
- package/dist/harness/tools/path-utils.js.map +1 -1
- package/dist/harness/tools/read.d.ts +2 -1
- package/dist/harness/tools/read.d.ts.map +1 -1
- package/dist/harness/tools/read.js +4 -6
- package/dist/harness/tools/read.js.map +1 -1
- package/dist/harness/tools/write.d.ts.map +1 -1
- package/dist/harness/tools/write.js +7 -7
- package/dist/harness/tools/write.js.map +1 -1
- package/dist/harness/types.d.ts +108 -45
- package/dist/harness/types.d.ts.map +1 -1
- package/dist/harness/types.js.map +1 -1
- package/dist/harness/utils/adaptive-publisher.d.ts +24 -0
- package/dist/harness/utils/adaptive-publisher.d.ts.map +1 -0
- package/dist/harness/utils/adaptive-publisher.js +79 -0
- package/dist/harness/utils/adaptive-publisher.js.map +1 -0
- package/dist/harness/utils/output-capture.d.ts +31 -0
- package/dist/harness/utils/output-capture.d.ts.map +1 -0
- package/dist/harness/utils/output-capture.js +217 -0
- package/dist/harness/utils/output-capture.js.map +1 -0
- package/dist/harness/utils/shell-output.d.ts +12 -5
- package/dist/harness/utils/shell-output.d.ts.map +1 -1
- package/dist/harness/utils/shell-output.js +64 -174
- package/dist/harness/utils/shell-output.js.map +1 -1
- package/dist/harness/utils/truncate.d.ts +1 -0
- package/dist/harness/utils/truncate.d.ts.map +1 -1
- package/dist/harness/utils/truncate.js +1 -1
- package/dist/harness/utils/truncate.js.map +1 -1
- package/dist/harness/utils/usage.d.ts +4 -0
- package/dist/harness/utils/usage.d.ts.map +1 -0
- package/dist/harness/utils/usage.js +33 -0
- package/dist/harness/utils/usage.js.map +1 -0
- package/dist/index.d.ts +4 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -6
- package/dist/index.js.map +1 -1
- package/dist/proxy.d.ts +2 -0
- package/dist/proxy.d.ts.map +1 -1
- package/dist/proxy.js +40 -10
- package/dist/proxy.js.map +1 -1
- package/dist/search/index.d.ts +24 -16
- package/dist/search/index.d.ts.map +1 -1
- package/dist/search/index.js +1 -1
- package/dist/search/index.js.map +1 -1
- package/dist/types.d.ts +2 -0
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js.map +1 -1
- package/package.json +25 -4
- package/dist/harness/reducer.d.ts +0 -100
- package/dist/harness/reducer.d.ts.map +0 -1
- package/dist/harness/reducer.js +0 -415
- package/dist/harness/reducer.js.map +0 -1
- package/dist/harness/session/jsonl/errors.d.ts +0 -9
- package/dist/harness/session/jsonl/errors.d.ts.map +0 -1
- package/dist/harness/session/jsonl/errors.js +0 -19
- package/dist/harness/session/jsonl/errors.js.map +0 -1
- package/dist/harness/session/jsonl.d.ts +0 -3
- package/dist/harness/session/jsonl.d.ts.map +0 -1
- package/dist/harness/session/jsonl.js +0 -2
- package/dist/harness/session/jsonl.js.map +0 -1
- package/dist/harness/session/state.d.ts +0 -65
- package/dist/harness/session/state.d.ts.map +0 -1
- package/dist/harness/session/state.js +0 -319
- package/dist/harness/session/state.js.map +0 -1
- package/dist/harness/session/testing/conformance.d.ts +0 -4
- package/dist/harness/session/testing/conformance.d.ts.map +0 -1
- package/dist/harness/session/testing/conformance.js +0 -762
- package/dist/harness/session/testing/conformance.js.map +0 -1
- package/dist/search/scanning.d.ts +0 -29
- package/dist/search/scanning.d.ts.map +0 -1
- package/dist/search/scanning.js +0 -103
- package/dist/search/scanning.js.map +0 -1
|
@@ -1,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);
|
|
@@ -226,11 +228,12 @@ function killProcessTree(pid) {
|
|
|
226
228
|
}
|
|
227
229
|
}
|
|
228
230
|
}
|
|
229
|
-
function waitForChildProcess(child) {
|
|
231
|
+
function waitForChildProcess(child, spillIsDraining) {
|
|
230
232
|
return new Promise((resolvePromise, reject) => {
|
|
231
233
|
let settled = false;
|
|
232
234
|
let exited = false;
|
|
233
235
|
let exitCode = null;
|
|
236
|
+
let exitSignal = null;
|
|
234
237
|
let postExitTimer;
|
|
235
238
|
let stdoutEnded = child.stdout === null;
|
|
236
239
|
let stderrEnded = child.stderr === null;
|
|
@@ -245,23 +248,28 @@ function waitForChildProcess(child) {
|
|
|
245
248
|
child.stdout?.removeListener("data", onData);
|
|
246
249
|
child.stderr?.removeListener("data", onData);
|
|
247
250
|
};
|
|
248
|
-
const finalize = (
|
|
251
|
+
const finalize = () => {
|
|
249
252
|
if (settled)
|
|
250
253
|
return;
|
|
251
254
|
settled = true;
|
|
252
255
|
cleanup();
|
|
253
256
|
child.stdout?.destroy();
|
|
254
257
|
child.stderr?.destroy();
|
|
255
|
-
resolvePromise(code);
|
|
258
|
+
resolvePromise({ code: exitCode, signal: exitSignal });
|
|
256
259
|
};
|
|
257
260
|
const maybeFinalizeAfterExit = () => {
|
|
258
261
|
if (exited && stdoutEnded && stderrEnded)
|
|
259
|
-
finalize(
|
|
262
|
+
finalize();
|
|
260
263
|
};
|
|
261
264
|
const armIdleTimer = () => {
|
|
262
265
|
if (postExitTimer)
|
|
263
266
|
clearTimeout(postExitTimer);
|
|
264
|
-
postExitTimer = setTimeout(() =>
|
|
267
|
+
postExitTimer = setTimeout(() => {
|
|
268
|
+
if (spillIsDraining())
|
|
269
|
+
armIdleTimer();
|
|
270
|
+
else
|
|
271
|
+
finalize();
|
|
272
|
+
}, EXIT_STDIO_GRACE_MS);
|
|
265
273
|
};
|
|
266
274
|
const onData = () => {
|
|
267
275
|
if (exited && !settled)
|
|
@@ -282,14 +290,19 @@ function waitForChildProcess(child) {
|
|
|
282
290
|
cleanup();
|
|
283
291
|
reject(error);
|
|
284
292
|
};
|
|
285
|
-
const onExit = (code) => {
|
|
293
|
+
const onExit = (code, signal) => {
|
|
286
294
|
exited = true;
|
|
287
295
|
exitCode = code;
|
|
296
|
+
exitSignal = signal;
|
|
288
297
|
maybeFinalizeAfterExit();
|
|
289
298
|
if (!settled)
|
|
290
299
|
armIdleTimer();
|
|
291
300
|
};
|
|
292
|
-
const onClose = (code) =>
|
|
301
|
+
const onClose = (code, signal) => {
|
|
302
|
+
exitCode = code;
|
|
303
|
+
exitSignal = signal;
|
|
304
|
+
finalize();
|
|
305
|
+
};
|
|
293
306
|
child.stdout?.once("end", onStdoutEnd);
|
|
294
307
|
child.stderr?.once("end", onStderrEnd);
|
|
295
308
|
child.stdout?.on("data", onData);
|
|
@@ -309,14 +322,15 @@ export class NodeExecutionEnv {
|
|
|
309
322
|
this.shellPath = options.shellPath;
|
|
310
323
|
this.shellEnv = options.shellEnv;
|
|
311
324
|
}
|
|
312
|
-
async absolutePath(path) {
|
|
325
|
+
async absolutePath(path, _context) {
|
|
313
326
|
return ok(resolvePath(this.cwd, path));
|
|
314
327
|
}
|
|
315
|
-
async joinPath(parts) {
|
|
328
|
+
async joinPath(parts, _context) {
|
|
316
329
|
return ok(join(...parts));
|
|
317
330
|
}
|
|
318
|
-
async exec(command, options) {
|
|
319
|
-
|
|
331
|
+
async exec(command, options, context) {
|
|
332
|
+
const signal = context.abortSignal;
|
|
333
|
+
if (signal?.aborted)
|
|
320
334
|
return err(new ExecutionError("aborted", "aborted"));
|
|
321
335
|
const timeoutMsResult = resolveTimeoutMs(options?.timeout);
|
|
322
336
|
if (!timeoutMsResult.ok)
|
|
@@ -334,30 +348,119 @@ export class NodeExecutionEnv {
|
|
|
334
348
|
return err(new ExecutionError("spawn_error", `Working directory does not exist: ${cwd}\nCannot execute bash commands.`, cause));
|
|
335
349
|
}
|
|
336
350
|
return await new Promise((resolvePromise) => {
|
|
337
|
-
let stdout = "";
|
|
338
|
-
let stderr = "";
|
|
339
351
|
let settled = false;
|
|
340
352
|
let timedOut = false;
|
|
341
353
|
let callbackError;
|
|
354
|
+
let spillError;
|
|
342
355
|
let child;
|
|
343
356
|
let timeoutId;
|
|
357
|
+
const spillPrefix = [];
|
|
358
|
+
let spillPath;
|
|
359
|
+
const spillQueue = [];
|
|
360
|
+
let spillStart;
|
|
361
|
+
let spillStream;
|
|
362
|
+
let spillBackpressured = false;
|
|
344
363
|
const onAbort = () => {
|
|
345
|
-
if (child?.pid)
|
|
364
|
+
if (child?.pid)
|
|
346
365
|
killProcessTree(child.pid);
|
|
347
|
-
}
|
|
348
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
|
+
}
|
|
349
386
|
const settle = (result) => {
|
|
387
|
+
if (settled)
|
|
388
|
+
return;
|
|
389
|
+
settled = true;
|
|
350
390
|
if (timeoutId)
|
|
351
391
|
clearTimeout(timeoutId);
|
|
352
|
-
if (
|
|
353
|
-
|
|
392
|
+
if (signal)
|
|
393
|
+
signal.removeEventListener("abort", onAbort);
|
|
354
394
|
if (child?.pid)
|
|
355
395
|
this.activeChildPids.delete(child.pid);
|
|
356
|
-
|
|
357
|
-
return;
|
|
358
|
-
settled = true;
|
|
396
|
+
capture.dispose();
|
|
359
397
|
resolvePromise(result);
|
|
360
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
|
+
};
|
|
361
464
|
try {
|
|
362
465
|
const commandFromStdin = shellConfig.value.commandTransport === "stdin";
|
|
363
466
|
child = spawn(shellConfig.value.shell, commandFromStdin ? shellConfig.value.args : [...shellConfig.value.args, command], {
|
|
@@ -380,47 +483,54 @@ export class NodeExecutionEnv {
|
|
|
380
483
|
return;
|
|
381
484
|
}
|
|
382
485
|
timeoutId =
|
|
383
|
-
timeoutMs
|
|
384
|
-
?
|
|
486
|
+
timeoutMs === undefined
|
|
487
|
+
? undefined
|
|
488
|
+
: setTimeout(() => {
|
|
385
489
|
timedOut = true;
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
: undefined;
|
|
391
|
-
if (options?.abortSignal) {
|
|
392
|
-
if (options.abortSignal.aborted) {
|
|
490
|
+
onAbort();
|
|
491
|
+
}, timeoutMs);
|
|
492
|
+
if (signal) {
|
|
493
|
+
if (signal.aborted)
|
|
393
494
|
onAbort();
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
options.abortSignal.addEventListener("abort", onAbort, { once: true });
|
|
397
|
-
}
|
|
495
|
+
else
|
|
496
|
+
signal.addEventListener("abort", onAbort, { once: true });
|
|
398
497
|
}
|
|
399
|
-
|
|
400
|
-
child.stderr?.setEncoding("utf8");
|
|
401
|
-
child.stdout?.on("data", (chunk) => {
|
|
402
|
-
stdout += chunk;
|
|
498
|
+
const feed = (chunk) => {
|
|
403
499
|
try {
|
|
404
|
-
|
|
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
|
+
}
|
|
405
516
|
}
|
|
406
517
|
catch (error) {
|
|
407
|
-
|
|
408
|
-
callbackError = new ExecutionError("callback_error", cause.message, cause);
|
|
409
|
-
onAbort();
|
|
518
|
+
failCallback(error);
|
|
410
519
|
}
|
|
411
|
-
}
|
|
412
|
-
child.
|
|
413
|
-
|
|
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();
|
|
414
527
|
try {
|
|
415
|
-
|
|
528
|
+
capture.finish();
|
|
529
|
+
capture.flush();
|
|
416
530
|
}
|
|
417
531
|
catch (error) {
|
|
418
|
-
|
|
419
|
-
callbackError = new ExecutionError("callback_error", cause.message, cause);
|
|
420
|
-
onAbort();
|
|
532
|
+
failCallback(error);
|
|
421
533
|
}
|
|
422
|
-
});
|
|
423
|
-
void waitForChildProcess(child).then((code) => {
|
|
424
534
|
if (callbackError) {
|
|
425
535
|
settle(err(callbackError));
|
|
426
536
|
return;
|
|
@@ -429,29 +539,45 @@ export class NodeExecutionEnv {
|
|
|
429
539
|
settle(err(new ExecutionError("timeout", `timeout:${options?.timeout}`)));
|
|
430
540
|
return;
|
|
431
541
|
}
|
|
432
|
-
if (
|
|
542
|
+
if (signal?.aborted) {
|
|
433
543
|
settle(err(new ExecutionError("aborted", "aborted")));
|
|
434
544
|
return;
|
|
435
545
|
}
|
|
436
|
-
|
|
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
|
+
}));
|
|
437
561
|
}, (error) => settle(err(new ExecutionError("spawn_error", error.message, error))));
|
|
438
562
|
});
|
|
439
563
|
}
|
|
440
|
-
async readTextFile(path,
|
|
564
|
+
async readTextFile(path, context) {
|
|
441
565
|
const resolved = resolvePath(this.cwd, path);
|
|
442
|
-
const
|
|
566
|
+
const signal = context.abortSignal;
|
|
567
|
+
const aborted = abortResult(signal, resolved);
|
|
443
568
|
if (aborted)
|
|
444
569
|
return aborted;
|
|
445
570
|
try {
|
|
446
|
-
return ok(await readFile(resolved, { encoding: "utf8", signal
|
|
571
|
+
return ok(await readFile(resolved, { encoding: "utf8", signal }));
|
|
447
572
|
}
|
|
448
573
|
catch (error) {
|
|
449
574
|
return err(toFileError(error, resolved));
|
|
450
575
|
}
|
|
451
576
|
}
|
|
452
|
-
async readTextLines(path, options) {
|
|
577
|
+
async readTextLines(path, options, context) {
|
|
453
578
|
const resolved = resolvePath(this.cwd, path);
|
|
454
|
-
const
|
|
579
|
+
const signal = context.abortSignal;
|
|
580
|
+
const aborted = abortResult(signal, resolved);
|
|
455
581
|
if (aborted)
|
|
456
582
|
return aborted;
|
|
457
583
|
if (options?.maxLines !== undefined && options.maxLines <= 0)
|
|
@@ -459,18 +585,18 @@ export class NodeExecutionEnv {
|
|
|
459
585
|
let stream;
|
|
460
586
|
let lineReader;
|
|
461
587
|
try {
|
|
462
|
-
stream = createReadStream(resolved, { encoding: "utf8", signal
|
|
588
|
+
stream = createReadStream(resolved, { encoding: "utf8", signal });
|
|
463
589
|
lineReader = createInterface({ input: stream, crlfDelay: Infinity });
|
|
464
590
|
const lines = [];
|
|
465
591
|
for await (const line of lineReader) {
|
|
466
|
-
const loopAbort = abortResult(
|
|
592
|
+
const loopAbort = abortResult(signal, resolved);
|
|
467
593
|
if (loopAbort)
|
|
468
594
|
return loopAbort;
|
|
469
595
|
lines.push(line);
|
|
470
596
|
if (options?.maxLines !== undefined && lines.length >= options.maxLines)
|
|
471
597
|
break;
|
|
472
598
|
}
|
|
473
|
-
const afterReadAbort = abortResult(
|
|
599
|
+
const afterReadAbort = abortResult(signal, resolved);
|
|
474
600
|
if (afterReadAbort)
|
|
475
601
|
return afterReadAbort;
|
|
476
602
|
return ok(lines);
|
|
@@ -483,50 +609,60 @@ export class NodeExecutionEnv {
|
|
|
483
609
|
stream?.destroy();
|
|
484
610
|
}
|
|
485
611
|
}
|
|
486
|
-
async readBinaryFile(path,
|
|
612
|
+
async readBinaryFile(path, context) {
|
|
487
613
|
const resolved = resolvePath(this.cwd, path);
|
|
488
|
-
const
|
|
614
|
+
const signal = context.abortSignal;
|
|
615
|
+
const aborted = abortResult(signal, resolved);
|
|
489
616
|
if (aborted)
|
|
490
617
|
return aborted;
|
|
491
618
|
try {
|
|
492
|
-
return ok(await readFile(resolved, { signal
|
|
619
|
+
return ok(await readFile(resolved, { signal }));
|
|
493
620
|
}
|
|
494
621
|
catch (error) {
|
|
495
622
|
return err(toFileError(error, resolved));
|
|
496
623
|
}
|
|
497
624
|
}
|
|
498
|
-
async writeFile(path, content,
|
|
625
|
+
async writeFile(path, content, context) {
|
|
499
626
|
const resolved = resolvePath(this.cwd, path);
|
|
500
|
-
const
|
|
627
|
+
const signal = context.abortSignal;
|
|
628
|
+
const aborted = abortResult(signal, resolved);
|
|
501
629
|
if (aborted)
|
|
502
630
|
return aborted;
|
|
503
631
|
try {
|
|
504
632
|
await mkdir(resolve(resolved, ".."), { recursive: true });
|
|
505
|
-
const afterMkdirAbort = abortResult(
|
|
633
|
+
const afterMkdirAbort = abortResult(signal, resolved);
|
|
506
634
|
if (afterMkdirAbort)
|
|
507
635
|
return afterMkdirAbort;
|
|
508
|
-
await writeFile(resolved, content, { signal
|
|
636
|
+
await writeFile(resolved, content, { signal });
|
|
509
637
|
return ok(undefined);
|
|
510
638
|
}
|
|
511
639
|
catch (error) {
|
|
512
640
|
return err(toFileError(error, resolved));
|
|
513
641
|
}
|
|
514
642
|
}
|
|
515
|
-
async appendFile(path, content) {
|
|
643
|
+
async appendFile(path, content, context) {
|
|
516
644
|
const resolved = resolvePath(this.cwd, path);
|
|
645
|
+
const signal = context.abortSignal;
|
|
646
|
+
const aborted = abortResult(signal, resolved);
|
|
647
|
+
if (aborted)
|
|
648
|
+
return aborted;
|
|
517
649
|
try {
|
|
518
650
|
await mkdir(resolve(resolved, ".."), { recursive: true });
|
|
651
|
+
const afterMkdirAbort = abortResult(signal, resolved);
|
|
652
|
+
if (afterMkdirAbort)
|
|
653
|
+
return afterMkdirAbort;
|
|
519
654
|
await appendFile(resolved, content);
|
|
520
|
-
|
|
655
|
+
const afterAppendAbort = abortResult(signal, resolved);
|
|
656
|
+
return afterAppendAbort ?? ok(undefined);
|
|
521
657
|
}
|
|
522
658
|
catch (error) {
|
|
523
659
|
return err(toFileError(error, resolved));
|
|
524
660
|
}
|
|
525
661
|
}
|
|
526
|
-
async renameFile(sourcePath, destinationPath,
|
|
662
|
+
async renameFile(sourcePath, destinationPath, context) {
|
|
527
663
|
const source = resolvePath(this.cwd, sourcePath);
|
|
528
664
|
const destination = resolvePath(this.cwd, destinationPath);
|
|
529
|
-
const aborted = abortResult(abortSignal, destination);
|
|
665
|
+
const aborted = abortResult(context.abortSignal, destination);
|
|
530
666
|
if (aborted)
|
|
531
667
|
return aborted;
|
|
532
668
|
try {
|
|
@@ -537,8 +673,11 @@ export class NodeExecutionEnv {
|
|
|
537
673
|
return err(toFileError(error, source));
|
|
538
674
|
}
|
|
539
675
|
}
|
|
540
|
-
async fileInfo(path) {
|
|
676
|
+
async fileInfo(path, context) {
|
|
541
677
|
const resolved = resolvePath(this.cwd, path);
|
|
678
|
+
const aborted = abortResult(context.abortSignal, resolved);
|
|
679
|
+
if (aborted)
|
|
680
|
+
return aborted;
|
|
542
681
|
try {
|
|
543
682
|
return fileInfoFromStats(resolved, await lstat(resolved));
|
|
544
683
|
}
|
|
@@ -546,16 +685,17 @@ export class NodeExecutionEnv {
|
|
|
546
685
|
return err(toFileError(error, resolved));
|
|
547
686
|
}
|
|
548
687
|
}
|
|
549
|
-
async listDir(path,
|
|
688
|
+
async listDir(path, context) {
|
|
550
689
|
const resolved = resolvePath(this.cwd, path);
|
|
551
|
-
const
|
|
690
|
+
const signal = context.abortSignal;
|
|
691
|
+
const aborted = abortResult(signal, resolved);
|
|
552
692
|
if (aborted)
|
|
553
693
|
return aborted;
|
|
554
694
|
try {
|
|
555
695
|
const entries = await readdir(resolved, { withFileTypes: true });
|
|
556
696
|
const infos = [];
|
|
557
697
|
for (const entry of entries) {
|
|
558
|
-
const loopAbort = abortResult(
|
|
698
|
+
const loopAbort = abortResult(signal, resolved);
|
|
559
699
|
if (loopAbort)
|
|
560
700
|
return loopAbort;
|
|
561
701
|
const entryPath = resolve(resolved, entry.name);
|
|
@@ -574,8 +714,11 @@ export class NodeExecutionEnv {
|
|
|
574
714
|
return err(toFileError(error, resolved));
|
|
575
715
|
}
|
|
576
716
|
}
|
|
577
|
-
async canonicalPath(path) {
|
|
717
|
+
async canonicalPath(path, context) {
|
|
578
718
|
const resolved = resolvePath(this.cwd, path);
|
|
719
|
+
const aborted = abortResult(context.abortSignal, resolved);
|
|
720
|
+
if (aborted)
|
|
721
|
+
return aborted;
|
|
579
722
|
try {
|
|
580
723
|
return ok(await realpath(resolved));
|
|
581
724
|
}
|
|
@@ -583,16 +726,19 @@ export class NodeExecutionEnv {
|
|
|
583
726
|
return err(toFileError(error, resolved));
|
|
584
727
|
}
|
|
585
728
|
}
|
|
586
|
-
async exists(path) {
|
|
587
|
-
const result = await this.fileInfo(path);
|
|
729
|
+
async exists(path, context) {
|
|
730
|
+
const result = await this.fileInfo(path, context);
|
|
588
731
|
if (result.ok)
|
|
589
732
|
return ok(true);
|
|
590
733
|
if (result.error.code === "not_found")
|
|
591
734
|
return ok(false);
|
|
592
735
|
return err(result.error);
|
|
593
736
|
}
|
|
594
|
-
async createDir(path, options) {
|
|
737
|
+
async createDir(path, options, context) {
|
|
595
738
|
const resolved = resolvePath(this.cwd, path);
|
|
739
|
+
const aborted = abortResult(context.abortSignal, resolved);
|
|
740
|
+
if (aborted)
|
|
741
|
+
return aborted;
|
|
596
742
|
try {
|
|
597
743
|
await mkdir(resolved, { recursive: options?.recursive ?? true });
|
|
598
744
|
return ok(undefined);
|
|
@@ -601,8 +747,11 @@ export class NodeExecutionEnv {
|
|
|
601
747
|
return err(toFileError(error, resolved));
|
|
602
748
|
}
|
|
603
749
|
}
|
|
604
|
-
async remove(path, options) {
|
|
750
|
+
async remove(path, options, context) {
|
|
605
751
|
const resolved = resolvePath(this.cwd, path);
|
|
752
|
+
const aborted = abortResult(context.abortSignal, resolved);
|
|
753
|
+
if (aborted)
|
|
754
|
+
return aborted;
|
|
606
755
|
try {
|
|
607
756
|
await rm(resolved, { recursive: options?.recursive ?? false, force: options?.force ?? false });
|
|
608
757
|
return ok(undefined);
|
|
@@ -611,16 +760,20 @@ export class NodeExecutionEnv {
|
|
|
611
760
|
return err(toFileError(error, resolved));
|
|
612
761
|
}
|
|
613
762
|
}
|
|
614
|
-
async createTempDir(prefix
|
|
763
|
+
async createTempDir(prefix, context) {
|
|
764
|
+
const aborted = abortResult(context.abortSignal);
|
|
765
|
+
if (aborted)
|
|
766
|
+
return aborted;
|
|
615
767
|
try {
|
|
768
|
+
prefix ??= "tmp-";
|
|
616
769
|
return ok(await mkdtemp(join(tmpdir(), prefix)));
|
|
617
770
|
}
|
|
618
771
|
catch (error) {
|
|
619
772
|
return err(toFileError(error));
|
|
620
773
|
}
|
|
621
774
|
}
|
|
622
|
-
async createTempFile(options) {
|
|
623
|
-
const dir = await this.createTempDir("tmp-");
|
|
775
|
+
async createTempFile(options, context) {
|
|
776
|
+
const dir = await this.createTempDir("tmp-", context);
|
|
624
777
|
if (!dir.ok)
|
|
625
778
|
return dir;
|
|
626
779
|
const filePath = join(dir.value, `${options?.prefix ?? ""}${randomUUID()}${options?.suffix ?? ""}`);
|
|
@@ -632,7 +785,7 @@ export class NodeExecutionEnv {
|
|
|
632
785
|
return err(toFileError(error, filePath));
|
|
633
786
|
}
|
|
634
787
|
}
|
|
635
|
-
async cleanup() {
|
|
788
|
+
async cleanup(_context) {
|
|
636
789
|
for (const pid of this.activeChildPids)
|
|
637
790
|
killProcessTree(pid);
|
|
638
791
|
this.activeChildPids.clear();
|