stitchkit 0.120.0 → 0.121.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/CHANGELOG.md +42 -0
- package/dist/agent-runtime/coding-discovery.d.ts +25 -0
- package/dist/agent-runtime/coding-discovery.d.ts.map +1 -0
- package/dist/agent-runtime/coding-search-automaton.d.ts +37 -0
- package/dist/agent-runtime/coding-search-automaton.d.ts.map +1 -0
- package/dist/agent-runtime/coding-search-case-fold.d.ts +4 -0
- package/dist/agent-runtime/coding-search-case-fold.d.ts.map +1 -0
- package/dist/agent-runtime/coding-search-class-ranges.d.ts +10 -0
- package/dist/agent-runtime/coding-search-class-ranges.d.ts.map +1 -0
- package/dist/agent-runtime/coding-search-contract.d.ts +86 -0
- package/dist/agent-runtime/coding-search-contract.d.ts.map +1 -0
- package/dist/agent-runtime/coding-search-limits.d.ts +13 -0
- package/dist/agent-runtime/coding-search-limits.d.ts.map +1 -0
- package/dist/agent-runtime/coding-search-matcher.d.ts +33 -0
- package/dist/agent-runtime/coding-search-matcher.d.ts.map +1 -0
- package/dist/agent-runtime/coding-search-output.d.ts +5 -0
- package/dist/agent-runtime/coding-search-output.d.ts.map +1 -0
- package/dist/agent-runtime/coding-search-regex-syntax.d.ts +39 -0
- package/dist/agent-runtime/coding-search-regex-syntax.d.ts.map +1 -0
- package/dist/agent-runtime/coding-search-unit-classes.d.ts +31 -0
- package/dist/agent-runtime/coding-search-unit-classes.d.ts.map +1 -0
- package/dist/agent-runtime/coding-shell-process.d.ts +1 -0
- package/dist/agent-runtime/coding-shell-process.d.ts.map +1 -1
- package/dist/agent-runtime/coding-tool-contract.d.ts +8 -3
- package/dist/agent-runtime/coding-tool-contract.d.ts.map +1 -1
- package/dist/agent-runtime/coding-tool-files.d.ts.map +1 -1
- package/dist/agent-runtime/coding-tool-listing.d.ts +1 -11
- package/dist/agent-runtime/coding-tool-listing.d.ts.map +1 -1
- package/dist/agent-runtime/coding-tool-paths.d.ts +6 -2
- package/dist/agent-runtime/coding-tool-paths.d.ts.map +1 -1
- package/dist/agent-runtime/coding-tool-refusals.d.ts +6 -0
- package/dist/agent-runtime/coding-tool-refusals.d.ts.map +1 -1
- package/dist/agent-runtime/coding-tool-search-patch.d.ts.map +1 -1
- package/dist/agent-runtime/coding-tool-search.d.ts +113 -0
- package/dist/agent-runtime/coding-tool-search.d.ts.map +1 -0
- package/dist/agent-runtime/coding-tool-shell.d.ts.map +1 -1
- package/dist/agent-runtime/contained-scan-budget.d.ts +32 -0
- package/dist/agent-runtime/contained-scan-budget.d.ts.map +1 -0
- package/dist/agent-runtime/contained-scan-contract.d.ts +52 -0
- package/dist/agent-runtime/contained-scan-contract.d.ts.map +1 -0
- package/dist/agent-runtime/contained-scan.d.ts +48 -13
- package/dist/agent-runtime/contained-scan.d.ts.map +1 -1
- package/dist/agent-runtime/sandbox.d.ts +5 -1
- package/dist/agent-runtime/sandbox.d.ts.map +1 -1
- package/dist/agent-runtime/workspace-glob.d.ts +6 -0
- package/dist/agent-runtime/workspace-glob.d.ts.map +1 -0
- package/dist/entrypoints/agent-runtime/coding-tools.js +7 -7
- package/dist/entrypoints/agent-runtime/harness.js +3 -3
- package/dist/entrypoints/agent-runtime/sandbox.js +7 -7
- package/dist/entrypoints/agent-runtime/sqlite/bun.js +9 -9
- package/dist/entrypoints/agent-runtime/sqlite/node.js +9 -9
- package/dist/entrypoints/agent-runtime/testing.js +9 -9
- package/dist/entrypoints/agent-runtime.js +9 -9
- package/dist/entrypoints/application/diagnostic-journal.js +3 -3
- package/dist/entrypoints/application/directory-inbox.js +5 -5
- package/dist/entrypoints/cli/publish.js +4 -4
- package/dist/entrypoints/cli.js +4 -4
- package/dist/entrypoints/files.js +4 -4
- package/dist/entrypoints/process/owner-loss.js +2 -1
- package/dist/entrypoints/process.js +4 -4
- package/dist/entrypoints/server.js +5 -5
- package/dist/entrypoints/telegram.js +3 -3
- package/dist/entrypoints/tools/toolkit.js +4 -4
- package/dist/{index-pq2m7t46.js → index-0fra8xvy.js} +2 -2
- package/dist/{index-yb9n4pgj.js → index-10rg78vf.js} +1 -1
- package/dist/{index-3yb5kft5.js → index-4tyt1qya.js} +1 -1
- package/dist/{index-8xyf8h2k.js → index-6j15ktag.js} +1 -1
- package/dist/{index-zrdcmg6j.js → index-72xtvcvr.js} +40 -6
- package/dist/{index-e452syyh.js → index-aqmadanx.js} +2 -2
- package/dist/{index-1jwsfkfz.js → index-eeahxwvg.js} +60 -76
- package/dist/{index-nyyam9ce.js → index-f6pw75e1.js} +1 -1
- package/dist/{index-qevqn3d3.js → index-gq3fnq3f.js} +1 -1
- package/dist/{index-bz479f0x.js → index-gtx3eknx.js} +1 -1
- package/dist/{index-nn9qvkww.js → index-j95jp7ee.js} +45 -9
- package/dist/{index-2kbysk9s.js → index-m5m9rmvt.js} +2 -0
- package/dist/{index-r3db01kh.js → index-nwm3ww60.js} +1 -1
- package/dist/index-qaqxdbxf.js +2857 -0
- package/dist/index-s9a0fjh3.js +305 -0
- package/dist/internal/contained-directory.d.ts +1 -1
- package/dist/internal/contained-directory.d.ts.map +1 -1
- package/dist/internal/contained-files.d.ts +18 -51
- package/dist/internal/contained-files.d.ts.map +1 -1
- package/dist/internal/contained-read.d.ts +17 -0
- package/dist/internal/contained-read.d.ts.map +1 -0
- package/dist/internal/darwin-binding.d.ts +3 -1
- package/dist/internal/darwin-binding.d.ts.map +1 -1
- package/dist/process/bun-child.d.ts.map +1 -1
- package/dist/process/command-owner.d.ts.map +1 -1
- package/dist/process/group.d.ts +2 -0
- package/dist/process/group.d.ts.map +1 -1
- package/dist/process/launch.d.ts +1 -0
- package/dist/process/launch.d.ts.map +1 -1
- package/dist/process/owned-child.d.ts.map +1 -1
- package/dist/process/owner-loss-guard.d.ts.map +1 -1
- package/dist/process/owner-loss-protocol.d.ts +1 -0
- package/dist/process/owner-loss-protocol.d.ts.map +1 -1
- package/llms/agent-runtime-coding-tools.txt +9 -9
- package/llms/agent-runtime.2.txt +17 -0
- package/llms/agent-runtime.txt +59 -24
- package/llms/application.3.txt +5 -2
- package/llms/contract.txt +1 -1
- package/llms/process.txt +3 -1
- package/llms/server.5.txt +2 -0
- package/llms/stitchkit.txt +3 -3
- package/llms/{upgrading-0.106.0-0.120.0.txt → upgrading-0.106.0-0.121.0.txt} +53 -3
- package/llms/upgrading.txt +1 -1
- package/llms-full.txt +132 -23
- package/llms.txt +4 -4
- package/native/darwin-arm64.node +0 -0
- package/native/darwin-x64.node +0 -0
- package/native-assets.json +4 -4
- package/package.json +1 -1
- package/dist/index-0qyrcjfs.js +0 -1478
- package/dist/index-aa50qwv4.js +0 -107
package/dist/entrypoints/cli.js
CHANGED
|
@@ -16,14 +16,14 @@ import {
|
|
|
16
16
|
renderCliView2,
|
|
17
17
|
pollUntilDone2,
|
|
18
18
|
createCli2
|
|
19
|
-
} from "../index-
|
|
19
|
+
} from "../index-0fra8xvy.js";
|
|
20
20
|
import"../index-k42ckyzx.js";
|
|
21
21
|
import"../index-ct75c3at.js";
|
|
22
22
|
import"../index-x4p3kw1p.js";
|
|
23
23
|
import"../index-s3yxw6kt.js";
|
|
24
24
|
import"../index-69t14s4a.js";
|
|
25
25
|
import"../index-ycqhyars.js";
|
|
26
|
-
import"../index-
|
|
26
|
+
import"../index-m5m9rmvt.js";
|
|
27
27
|
import {
|
|
28
28
|
CliBuildSignatureSchema2,
|
|
29
29
|
cliManifestSigningPayload2,
|
|
@@ -43,8 +43,8 @@ import {
|
|
|
43
43
|
applyCliUpdate2,
|
|
44
44
|
rollbackCliUpdate2
|
|
45
45
|
} from "../index-8ryydawp.js";
|
|
46
|
-
import"../index-
|
|
47
|
-
import"../index-
|
|
46
|
+
import"../index-aqmadanx.js";
|
|
47
|
+
import"../index-eeahxwvg.js";
|
|
48
48
|
import {
|
|
49
49
|
argumentsDigest
|
|
50
50
|
} from "../index-r7a7r7ha.js";
|
|
@@ -2,13 +2,13 @@ import {
|
|
|
2
2
|
ManagedFilePathSchema2,
|
|
3
3
|
ManagedFileRefSchema2
|
|
4
4
|
} from "../index-xqhede6x.js";
|
|
5
|
-
import"../index-
|
|
6
|
-
import"../index-
|
|
7
|
-
import"../index-
|
|
5
|
+
import"../index-m5m9rmvt.js";
|
|
6
|
+
import"../index-gq3fnq3f.js";
|
|
7
|
+
import"../index-gtx3eknx.js";
|
|
8
8
|
import {
|
|
9
9
|
ExclusiveLockError2,
|
|
10
10
|
withExclusiveLock2
|
|
11
|
-
} from "../index-
|
|
11
|
+
} from "../index-nwm3ww60.js";
|
|
12
12
|
import {
|
|
13
13
|
ManagedFileError2,
|
|
14
14
|
createManagedFileBoundary2
|
|
@@ -1,15 +1,15 @@
|
|
|
1
|
-
import"../index-
|
|
1
|
+
import"../index-m5m9rmvt.js";
|
|
2
2
|
import {
|
|
3
3
|
ProcessInstanceSchema2,
|
|
4
4
|
observeProcessInstance2,
|
|
5
5
|
probeProcessOwner2
|
|
6
|
-
} from "../index-
|
|
6
|
+
} from "../index-gq3fnq3f.js";
|
|
7
7
|
import {
|
|
8
8
|
NativeCommandError2
|
|
9
|
-
} from "../index-
|
|
9
|
+
} from "../index-72xtvcvr.js";
|
|
10
10
|
import {
|
|
11
11
|
startNativeCommand
|
|
12
|
-
} from "../index-
|
|
12
|
+
} from "../index-j95jp7ee.js";
|
|
13
13
|
import {
|
|
14
14
|
untilAborted
|
|
15
15
|
} from "../index-a5qr2rj6.js";
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import"../index-
|
|
2
|
-
import"../index-
|
|
3
|
-
import"../index-
|
|
1
|
+
import"../index-m5m9rmvt.js";
|
|
2
|
+
import"../index-gq3fnq3f.js";
|
|
3
|
+
import"../index-gtx3eknx.js";
|
|
4
4
|
import {
|
|
5
5
|
errorCode2,
|
|
6
6
|
normalizeError2
|
|
@@ -53,11 +53,11 @@ import {
|
|
|
53
53
|
} from "../index-bgcwxhxh.js";
|
|
54
54
|
import {
|
|
55
55
|
createFileStateStore2
|
|
56
|
-
} from "../index-
|
|
56
|
+
} from "../index-6j15ktag.js";
|
|
57
57
|
import {
|
|
58
58
|
bindRealtimeServer2
|
|
59
59
|
} from "../index-2bqf0a74.js";
|
|
60
|
-
import"../index-
|
|
60
|
+
import"../index-nwm3ww60.js";
|
|
61
61
|
import {
|
|
62
62
|
withDeadline
|
|
63
63
|
} from "../index-9tqbxv5p.js";
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import {
|
|
2
2
|
backoffDelay
|
|
3
3
|
} from "../index-g6a3na27.js";
|
|
4
|
-
import"../index-
|
|
5
|
-
import"../index-
|
|
4
|
+
import"../index-m5m9rmvt.js";
|
|
5
|
+
import"../index-gq3fnq3f.js";
|
|
6
6
|
import {
|
|
7
7
|
attemptExclusiveLock
|
|
8
|
-
} from "../index-
|
|
8
|
+
} from "../index-gtx3eknx.js";
|
|
9
9
|
import {
|
|
10
10
|
TELEGRAM_SEND_FAILURE_REASONS2,
|
|
11
11
|
classifyTelegramSendFailure2
|
|
@@ -11,16 +11,16 @@ import {
|
|
|
11
11
|
} from "../../index-7zwtbak8.js";
|
|
12
12
|
import {
|
|
13
13
|
createCli2
|
|
14
|
-
} from "../../index-
|
|
15
|
-
import"../../index-
|
|
14
|
+
} from "../../index-0fra8xvy.js";
|
|
15
|
+
import"../../index-m5m9rmvt.js";
|
|
16
16
|
import {
|
|
17
17
|
mountMcp2,
|
|
18
18
|
buildMcpServer2,
|
|
19
19
|
createMcpHandler2,
|
|
20
20
|
createStdioMcpServer2
|
|
21
21
|
} from "../../index-knmnj11j.js";
|
|
22
|
-
import"../../index-
|
|
23
|
-
import"../../index-
|
|
22
|
+
import"../../index-aqmadanx.js";
|
|
23
|
+
import"../../index-eeahxwvg.js";
|
|
24
24
|
import"../../index-ff39f9dr.js";
|
|
25
25
|
import"../../index-aqwg2dm5.js";
|
|
26
26
|
|
|
@@ -25,12 +25,12 @@ import {
|
|
|
25
25
|
} from "./index-ycqhyars.js";
|
|
26
26
|
import {
|
|
27
27
|
writeContainedFile
|
|
28
|
-
} from "./index-
|
|
28
|
+
} from "./index-aqmadanx.js";
|
|
29
29
|
import {
|
|
30
30
|
openPinnedDirectory,
|
|
31
31
|
isSafeEntryName,
|
|
32
32
|
containedEntryMetadata
|
|
33
|
-
} from "./index-
|
|
33
|
+
} from "./index-eeahxwvg.js";
|
|
34
34
|
import {
|
|
35
35
|
pollUntil
|
|
36
36
|
} from "./index-bph35vpy.js";
|
|
@@ -1,3 +1,6 @@
|
|
|
1
|
+
import {
|
|
2
|
+
loadDarwinBinding
|
|
3
|
+
} from "./index-m5m9rmvt.js";
|
|
1
4
|
import {
|
|
2
5
|
errnoOf
|
|
3
6
|
} from "./index-jj9228tt.js";
|
|
@@ -269,6 +272,7 @@ function ownerLossGuardCommand(guard, executable, args) {
|
|
|
269
272
|
guard.entry,
|
|
270
273
|
OWNER_LOSS_GUARD_FLAG,
|
|
271
274
|
guard.signalTarget,
|
|
275
|
+
...guard.cwdDescriptor === undefined ? [] : ["--stitchkit-cwd-fd", "4"],
|
|
272
276
|
executable,
|
|
273
277
|
...args
|
|
274
278
|
];
|
|
@@ -407,10 +411,16 @@ function spawnBunChild(input) {
|
|
|
407
411
|
const guarded = ownerLoss !== undefined;
|
|
408
412
|
const command = guarded ? ownerLossGuardCommand(ownerLoss, input.executable, input.args) : [input.executable, ...input.args];
|
|
409
413
|
const subprocess = guarded ? Bun.spawn(command, {
|
|
410
|
-
cwd: input.cwd,
|
|
414
|
+
cwd: ownerLoss.cwdDescriptor === undefined ? input.cwd : undefined,
|
|
411
415
|
env: input.env,
|
|
412
416
|
detached: input.group,
|
|
413
|
-
stdio: [
|
|
417
|
+
stdio: [
|
|
418
|
+
"pipe",
|
|
419
|
+
"pipe",
|
|
420
|
+
"pipe",
|
|
421
|
+
"socket-fd",
|
|
422
|
+
...ownerLoss.cwdDescriptor === undefined ? [] : [ownerLoss.cwdDescriptor]
|
|
423
|
+
]
|
|
414
424
|
}) : Bun.spawn(command, {
|
|
415
425
|
cwd: input.cwd,
|
|
416
426
|
env: input.env,
|
|
@@ -446,10 +456,16 @@ function spawnBunInheritedChild(input) {
|
|
|
446
456
|
const guarded = ownerLoss !== undefined;
|
|
447
457
|
const command = guarded ? ownerLossGuardCommand(ownerLoss, input.executable, input.args) : [input.executable, ...input.args];
|
|
448
458
|
const subprocess = guarded ? Bun.spawn(command, {
|
|
449
|
-
cwd: input.cwd,
|
|
459
|
+
cwd: ownerLoss.cwdDescriptor === undefined ? input.cwd : undefined,
|
|
450
460
|
env: input.env,
|
|
451
461
|
detached: input.group,
|
|
452
|
-
stdio: [
|
|
462
|
+
stdio: [
|
|
463
|
+
"inherit",
|
|
464
|
+
"inherit",
|
|
465
|
+
"inherit",
|
|
466
|
+
"socket-fd",
|
|
467
|
+
...ownerLoss.cwdDescriptor === undefined ? [] : [ownerLoss.cwdDescriptor]
|
|
468
|
+
]
|
|
453
469
|
}) : Bun.spawn(command, {
|
|
454
470
|
cwd: input.cwd,
|
|
455
471
|
env: input.env,
|
|
@@ -484,6 +500,7 @@ function spawnBunGuardTarget(executable, args) {
|
|
|
484
500
|
|
|
485
501
|
// src/process/owner-loss-guard.ts
|
|
486
502
|
import { spawn } from "node:child_process";
|
|
503
|
+
import { closeSync } from "node:fs";
|
|
487
504
|
import { Socket } from "node:net";
|
|
488
505
|
import { fileURLToPath } from "node:url";
|
|
489
506
|
var FORWARDED_SIGNALS = [
|
|
@@ -547,7 +564,7 @@ function spawnBunTarget(executable, args, onStarted, onExit, onUnavailable) {
|
|
|
547
564
|
onStarted(child.pid);
|
|
548
565
|
child.exited.then(() => onExit(child.exitCode, child.signalCode));
|
|
549
566
|
}
|
|
550
|
-
function runOwnerLossGuard(signalTarget, executable, args) {
|
|
567
|
+
function runOwnerLossGuard(signalTarget, executable, args, cwdDescriptor) {
|
|
551
568
|
const bun = hostIsBun();
|
|
552
569
|
const control = bun ? connectOwnerLossSocket(3) : new Socket({ fd: 3, readable: true, writable: true });
|
|
553
570
|
let armed = true;
|
|
@@ -613,6 +630,20 @@ function runOwnerLossGuard(signalTarget, executable, args) {
|
|
|
613
630
|
removeForwarders();
|
|
614
631
|
refuseTarget(control, cause);
|
|
615
632
|
};
|
|
633
|
+
if (cwdDescriptor !== undefined) {
|
|
634
|
+
try {
|
|
635
|
+
if (process.platform === "darwin")
|
|
636
|
+
loadDarwinBinding().changeDirectory(cwdDescriptor);
|
|
637
|
+
else if (process.platform === "linux")
|
|
638
|
+
process.chdir(`/proc/self/fd/${cwdDescriptor}`);
|
|
639
|
+
else
|
|
640
|
+
throw new Error("Descriptor command directories require Linux or macOS");
|
|
641
|
+
closeSync(cwdDescriptor);
|
|
642
|
+
} catch (cause) {
|
|
643
|
+
targetUnavailable(cause);
|
|
644
|
+
return;
|
|
645
|
+
}
|
|
646
|
+
}
|
|
616
647
|
if (!bun)
|
|
617
648
|
spawnNodeTarget(executable, args, targetStarted, targetExit, targetUnavailable);
|
|
618
649
|
else
|
|
@@ -625,7 +656,10 @@ function startOwnerLossGuardEntry() {
|
|
|
625
656
|
const entry = process.argv[1];
|
|
626
657
|
if (entry === undefined || fileURLToPath(import.meta.url) !== entry)
|
|
627
658
|
return;
|
|
628
|
-
|
|
659
|
+
const pinnedCwd = process.argv[4] === "--stitchkit-cwd-fd";
|
|
660
|
+
if (pinnedCwd && process.argv[5] !== "4")
|
|
661
|
+
throw new Error("Invalid command directory descriptor");
|
|
662
|
+
runOwnerLossGuard(process.argv[3], process.argv[pinnedCwd ? 6 : 4], process.argv.slice(pinnedCwd ? 7 : 5), pinnedCwd ? 4 : undefined);
|
|
629
663
|
guardInvocation = true;
|
|
630
664
|
}
|
|
631
665
|
function bootstrapNativeCommandOwnerLoss2() {
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import {
|
|
2
2
|
loadDarwinBinding
|
|
3
|
-
} from "./index-
|
|
3
|
+
} from "./index-m5m9rmvt.js";
|
|
4
4
|
import {
|
|
5
5
|
descriptorPath,
|
|
6
6
|
NumericFileHandle
|
|
7
|
-
} from "./index-
|
|
7
|
+
} from "./index-eeahxwvg.js";
|
|
8
8
|
import {
|
|
9
9
|
stagingName
|
|
10
10
|
} from "./index-tt30h7mr.js";
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
loadDarwinBinding
|
|
3
|
-
} from "./index-
|
|
3
|
+
} from "./index-m5m9rmvt.js";
|
|
4
4
|
import {
|
|
5
5
|
errnoOf
|
|
6
6
|
} from "./index-jj9228tt.js";
|
|
@@ -90,6 +90,12 @@ async function openPinnedDirectory(absolute, options = {}, io = { realpath }) {
|
|
|
90
90
|
if (process.platform !== "linux" && process.platform !== "darwin") {
|
|
91
91
|
throw new Error("Contained filesystem operations support Linux and macOS only");
|
|
92
92
|
}
|
|
93
|
+
if (typeof absolute !== "string") {
|
|
94
|
+
const searchOnly = options.readable === false;
|
|
95
|
+
if (process.platform === "darwin")
|
|
96
|
+
return new NumericFileHandle(loadDarwinBinding().reopenDirectory(absolute.fd, searchOnly));
|
|
97
|
+
return open(`${descriptorPath(absolute)}/.`, directoryFlags(searchOnly));
|
|
98
|
+
}
|
|
93
99
|
let prefix = path.resolve(absolute);
|
|
94
100
|
const missing = [];
|
|
95
101
|
let canonical;
|
|
@@ -131,11 +137,8 @@ async function openPinnedDirectory(absolute, options = {}, io = { realpath }) {
|
|
|
131
137
|
|
|
132
138
|
// src/internal/contained-files.ts
|
|
133
139
|
import { constants as constants2 } from "node:fs";
|
|
134
|
-
import { lstat, open as open2, readdir } from "node:fs/promises";
|
|
140
|
+
import { lstat, open as open2, opendir, readdir } from "node:fs/promises";
|
|
135
141
|
import path2 from "node:path";
|
|
136
|
-
function containedEntryKind(entry) {
|
|
137
|
-
return entry.isDirectory() ? "directory" : entry.isSymbolicLink() ? "symlink" : entry.isFile() ? "file" : "other";
|
|
138
|
-
}
|
|
139
142
|
function sameIdentity(left, right) {
|
|
140
143
|
return left.dev === right.dev && left.ino === right.ino;
|
|
141
144
|
}
|
|
@@ -177,59 +180,48 @@ async function statAt(directory, name) {
|
|
|
177
180
|
throw error;
|
|
178
181
|
});
|
|
179
182
|
}
|
|
180
|
-
async function listAt(directory) {
|
|
183
|
+
async function listAt(directory, maxEntries, progress) {
|
|
184
|
+
progress?.check();
|
|
181
185
|
if (process.platform === "darwin") {
|
|
182
|
-
return loadDarwinBinding().listAt(directory.fd
|
|
186
|
+
return loadDarwinBinding().listAt(directory.fd, maxEntries, progress ? (entry) => {
|
|
187
|
+
if (entry)
|
|
188
|
+
progress.entry();
|
|
189
|
+
progress.check();
|
|
190
|
+
} : undefined).map(({ name, mode }) => ({ name, ...entryMetadata(mode) }));
|
|
191
|
+
}
|
|
192
|
+
if (maxEntries !== undefined) {
|
|
193
|
+
const stream = await opendir(descriptorPath(directory), { bufferSize: 1 });
|
|
194
|
+
const entries = [];
|
|
195
|
+
try {
|
|
196
|
+
while (entries.length < maxEntries) {
|
|
197
|
+
progress?.check();
|
|
198
|
+
const entry = await stream.read();
|
|
199
|
+
if (entry)
|
|
200
|
+
progress?.entry();
|
|
201
|
+
progress?.check();
|
|
202
|
+
if (!entry)
|
|
203
|
+
break;
|
|
204
|
+
entries.push(entry);
|
|
205
|
+
}
|
|
206
|
+
return entries;
|
|
207
|
+
} finally {
|
|
208
|
+
await stream.close();
|
|
209
|
+
}
|
|
183
210
|
}
|
|
184
211
|
return readdir(descriptorPath(directory), { withFileTypes: true });
|
|
185
212
|
}
|
|
186
|
-
async function
|
|
213
|
+
async function openContainedDirectory(root, relative, beforeOpen) {
|
|
187
214
|
let current = await openPinnedDirectory(root);
|
|
188
215
|
try {
|
|
189
|
-
if (relative !== ".")
|
|
216
|
+
if (relative !== ".")
|
|
190
217
|
for (const segment of safeSegments(relative)) {
|
|
218
|
+
beforeOpen?.();
|
|
191
219
|
current = await descend(current, await openDirectoryAt(current, segment));
|
|
192
220
|
}
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
raw.sort((left, right) => left.name.localeCompare(right.name));
|
|
196
|
-
const admitted = [];
|
|
197
|
-
const denied = [];
|
|
198
|
-
for (const entry of raw) {
|
|
199
|
-
const entryPath = relative === "." ? entry.name : path2.join(relative, entry.name);
|
|
200
|
-
if (authorizePath && !await authorizePath(entryPath)) {
|
|
201
|
-
denied.push({ name: entry.name, kind: containedEntryKind(entry) });
|
|
202
|
-
continue;
|
|
203
|
-
}
|
|
204
|
-
admitted.push(entry);
|
|
205
|
-
}
|
|
206
|
-
const entries = [];
|
|
207
|
-
for (const entry of admitted.slice(0, maxEntries)) {
|
|
208
|
-
const kind = containedEntryKind(entry);
|
|
209
|
-
if (kind !== "file") {
|
|
210
|
-
entries.push({ name: entry.name, kind });
|
|
211
|
-
continue;
|
|
212
|
-
}
|
|
213
|
-
const metadata = await statAt(current, entry.name);
|
|
214
|
-
entries.push({
|
|
215
|
-
name: entry.name,
|
|
216
|
-
kind,
|
|
217
|
-
...metadata && { bytes: metadata.size }
|
|
218
|
-
});
|
|
219
|
-
}
|
|
220
|
-
entries.sort((left, right) => {
|
|
221
|
-
if (left.kind === right.kind)
|
|
222
|
-
return left.name.localeCompare(right.name);
|
|
223
|
-
return left.kind === "directory" ? -1 : right.kind === "directory" ? 1 : 0;
|
|
224
|
-
});
|
|
225
|
-
return {
|
|
226
|
-
entries,
|
|
227
|
-
truncated: admitted.length > maxEntries,
|
|
228
|
-
denied: denied.slice(0, maxEntries),
|
|
229
|
-
deniedTruncated: denied.length > maxEntries
|
|
230
|
-
};
|
|
231
|
-
} finally {
|
|
221
|
+
return current;
|
|
222
|
+
} catch (error) {
|
|
232
223
|
await current.close();
|
|
224
|
+
throw error;
|
|
233
225
|
}
|
|
234
226
|
}
|
|
235
227
|
async function missingContainedDirectories(root, relative) {
|
|
@@ -265,27 +257,41 @@ function alternateSpellings(name) {
|
|
|
265
257
|
const swapped = [...name].map((letter) => letter === letter.toLowerCase() ? letter.toUpperCase() : letter.toLowerCase()).join("");
|
|
266
258
|
return [...new Set([swapped, name.normalize("NFC"), name.normalize("NFD")])].filter((spelling) => spelling !== name);
|
|
267
259
|
}
|
|
268
|
-
async function misspelledContainedSegment(root, relative) {
|
|
260
|
+
async function misspelledContainedSegment(root, relative, progress) {
|
|
269
261
|
const segments = safeSegments(relative);
|
|
270
|
-
|
|
262
|
+
const wait = (operation, disposeLate) => progress ? progress.wait(operation, disposeLate) : operation();
|
|
263
|
+
const dispose = (handle) => {
|
|
264
|
+
handle.close().catch(() => {
|
|
265
|
+
return;
|
|
266
|
+
});
|
|
267
|
+
};
|
|
268
|
+
let current = await wait(() => openPinnedDirectory(root), dispose);
|
|
271
269
|
try {
|
|
272
270
|
for (const [index, segment] of segments.entries()) {
|
|
273
|
-
|
|
271
|
+
progress?.check();
|
|
272
|
+
const exists = async (name) => await wait(() => statAt(current, name).catch(() => null)) !== null;
|
|
274
273
|
let folded = false;
|
|
275
274
|
for (const spelling of alternateSpellings(segment)) {
|
|
276
275
|
folded ||= await exists(spelling);
|
|
277
276
|
}
|
|
278
277
|
if (folded && await exists(segment)) {
|
|
279
|
-
const
|
|
278
|
+
const maximum = progress?.remainingEntries();
|
|
279
|
+
const entries = await wait(() => listAt(current, maximum, progress));
|
|
280
|
+
progress?.remainingEntries();
|
|
281
|
+
const stored = entries.some(({ name }) => name === segment);
|
|
280
282
|
if (!stored)
|
|
281
283
|
return segment;
|
|
282
284
|
}
|
|
283
285
|
if (index === segments.length - 1)
|
|
284
286
|
return;
|
|
285
|
-
|
|
287
|
+
progress?.directory();
|
|
288
|
+
const next = await wait(() => openDirectoryAt(current, segment).catch((error) => {
|
|
286
289
|
if (["ENOENT", "ENOTDIR", "ELOOP"].includes(errnoOf(error) ?? ""))
|
|
287
290
|
return null;
|
|
288
291
|
throw error;
|
|
292
|
+
}), (handle) => {
|
|
293
|
+
if (handle)
|
|
294
|
+
dispose(handle);
|
|
289
295
|
});
|
|
290
296
|
if (!next)
|
|
291
297
|
return;
|
|
@@ -395,27 +401,5 @@ async function openContainedParentFile(parent) {
|
|
|
395
401
|
}
|
|
396
402
|
return handle;
|
|
397
403
|
}
|
|
398
|
-
async function readContainedUtf8Handle(handle, maxBytes) {
|
|
399
|
-
const metadata = await handle.stat();
|
|
400
|
-
if (!metadata.isFile())
|
|
401
|
-
throw new Error("Contained path is not a regular file");
|
|
402
|
-
if (metadata.size > maxBytes)
|
|
403
|
-
throw new Error("Contained file exceeds byte budget");
|
|
404
|
-
const buffer = Buffer.alloc(metadata.size);
|
|
405
|
-
let offset = 0;
|
|
406
|
-
while (offset < buffer.byteLength) {
|
|
407
|
-
const { bytesRead } = await handle.read(buffer, offset, buffer.byteLength - offset, offset);
|
|
408
|
-
if (bytesRead === 0)
|
|
409
|
-
break;
|
|
410
|
-
offset += bytesRead;
|
|
411
|
-
}
|
|
412
|
-
if (offset !== metadata.size)
|
|
413
|
-
throw new Error("Contained file changed while being read");
|
|
414
|
-
return {
|
|
415
|
-
text: new TextDecoder("utf-8", { fatal: true }).decode(buffer),
|
|
416
|
-
bytes: offset,
|
|
417
|
-
mode: metadata.mode
|
|
418
|
-
};
|
|
419
|
-
}
|
|
420
404
|
|
|
421
|
-
export { descriptorPath, NumericFileHandle, openDirectoryAt, openPinnedDirectory, isSafeEntryName, openFileAt, listAt,
|
|
405
|
+
export { descriptorPath, NumericFileHandle, openDirectoryAt, openPinnedDirectory, isSafeEntryName, openFileAt, listAt, openContainedDirectory, missingContainedDirectories, misspelledContainedSegment, UnapprovedContainedDirectoryError, openContainedParent, openContainedFile, ContainedPathChangedError, assertContainedFileCurrent, assertContainedParentCurrent, containedEntryMetadata, openContainedParentFile };
|
|
@@ -11,7 +11,7 @@ import {
|
|
|
11
11
|
spawnBunChild,
|
|
12
12
|
spawnBunInheritedChild,
|
|
13
13
|
ownerLossGuardEntry
|
|
14
|
-
} from "./index-
|
|
14
|
+
} from "./index-72xtvcvr.js";
|
|
15
15
|
import {
|
|
16
16
|
errnoOf
|
|
17
17
|
} from "./index-jj9228tt.js";
|
|
@@ -173,7 +173,7 @@ async function waitForProcessGroupExit(pid, deadline, killLiveMembers) {
|
|
|
173
173
|
function createCommandDeadline(timeoutMs, reason) {
|
|
174
174
|
assertPositiveSafeInteger("Command deadline", timeoutMs, RangeError);
|
|
175
175
|
const controller = new AbortController;
|
|
176
|
-
|
|
176
|
+
let deadline = performance.now() + timeoutMs;
|
|
177
177
|
let timer;
|
|
178
178
|
const schedule = () => {
|
|
179
179
|
const remaining = deadline - performance.now();
|
|
@@ -188,6 +188,15 @@ function createCommandDeadline(timeoutMs, reason) {
|
|
|
188
188
|
cancel() {
|
|
189
189
|
if (timer !== undefined)
|
|
190
190
|
clearTimeout(timer);
|
|
191
|
+
},
|
|
192
|
+
restart(nextMs) {
|
|
193
|
+
assertPositiveSafeInteger("Command deadline", nextMs, RangeError);
|
|
194
|
+
if (controller.signal.aborted)
|
|
195
|
+
return;
|
|
196
|
+
if (timer !== undefined)
|
|
197
|
+
clearTimeout(timer);
|
|
198
|
+
deadline = performance.now() + nextMs;
|
|
199
|
+
schedule();
|
|
191
200
|
}
|
|
192
201
|
};
|
|
193
202
|
}
|
|
@@ -440,10 +449,16 @@ function nodeChild(input) {
|
|
|
440
449
|
});
|
|
441
450
|
const [executable, ...args] = ownerLossGuardCommand(input.ownerLoss, input.executable, input.args);
|
|
442
451
|
const child = spawn(executable, args, {
|
|
443
|
-
cwd: input.cwd,
|
|
452
|
+
cwd: input.ownerLoss.cwdDescriptor === undefined ? input.cwd : undefined,
|
|
444
453
|
env: input.env,
|
|
445
454
|
detached: input.group,
|
|
446
|
-
stdio: [
|
|
455
|
+
stdio: [
|
|
456
|
+
"pipe",
|
|
457
|
+
"pipe",
|
|
458
|
+
"pipe",
|
|
459
|
+
"pipe",
|
|
460
|
+
...input.ownerLoss.cwdDescriptor === undefined ? [] : [input.ownerLoss.cwdDescriptor]
|
|
461
|
+
]
|
|
447
462
|
});
|
|
448
463
|
const control = child.stdio[3];
|
|
449
464
|
if (!(control instanceof Duplex)) {
|
|
@@ -451,7 +466,12 @@ function nodeChild(input) {
|
|
|
451
466
|
throw new Error("Owner-loss guard supplied no control pipe");
|
|
452
467
|
}
|
|
453
468
|
attachOwnerLossControl(child, control);
|
|
454
|
-
|
|
469
|
+
const { stdin, stdout, stderr } = child;
|
|
470
|
+
if (!stdin || !stdout || !stderr) {
|
|
471
|
+
abortOwnerLossLaunch(child.pid);
|
|
472
|
+
throw new Error("Owner-loss guard supplied incomplete command pipes");
|
|
473
|
+
}
|
|
474
|
+
return Object.assign(child, { stdin, stdout, stderr });
|
|
455
475
|
}
|
|
456
476
|
var INHERITED_OUTPUT = {
|
|
457
477
|
destroyed: true,
|
|
@@ -497,10 +517,16 @@ function spawnInheritedCommand(input) {
|
|
|
497
517
|
});
|
|
498
518
|
const [executable, ...args] = ownerLossGuardCommand(input.ownerLoss, input.executable, input.args);
|
|
499
519
|
const spawned = spawn(executable, args, {
|
|
500
|
-
cwd: input.cwd,
|
|
520
|
+
cwd: input.ownerLoss.cwdDescriptor === undefined ? input.cwd : undefined,
|
|
501
521
|
env: input.env,
|
|
502
522
|
detached: input.group,
|
|
503
|
-
stdio: [
|
|
523
|
+
stdio: [
|
|
524
|
+
"inherit",
|
|
525
|
+
"inherit",
|
|
526
|
+
"inherit",
|
|
527
|
+
"pipe",
|
|
528
|
+
...input.ownerLoss.cwdDescriptor === undefined ? [] : [input.ownerLoss.cwdDescriptor]
|
|
529
|
+
]
|
|
504
530
|
});
|
|
505
531
|
const control = spawned.stdio[3];
|
|
506
532
|
if (!(control instanceof Duplex)) {
|
|
@@ -723,7 +749,13 @@ function launchNativeCommand({
|
|
|
723
749
|
cwd: options.cwd,
|
|
724
750
|
env: options.envPolicy === "ambient" ? { ...process.env, ...options.env } : options.env ?? {},
|
|
725
751
|
group: options.group === "own" && (driver?.group ?? true),
|
|
726
|
-
ownerLoss: options.ownerLoss === "terminate"
|
|
752
|
+
ownerLoss: options.ownerLoss === "terminate" || driver?.cwdDescriptor !== undefined ? {
|
|
753
|
+
entry: ownerLossGuardEntry(),
|
|
754
|
+
signalTarget: options.stop.target,
|
|
755
|
+
...driver?.cwdDescriptor !== undefined && {
|
|
756
|
+
cwdDescriptor: driver.cwdDescriptor
|
|
757
|
+
}
|
|
758
|
+
} : undefined
|
|
727
759
|
};
|
|
728
760
|
let inherited;
|
|
729
761
|
if (!launch) {
|
|
@@ -914,6 +946,7 @@ async function terminateOwnedGroup(child, closed, cleanupTimeoutMs) {
|
|
|
914
946
|
}
|
|
915
947
|
|
|
916
948
|
// src/process/command-owner.ts
|
|
949
|
+
var GUARD_START_FLOOR_MS = 5000;
|
|
917
950
|
function startNativeCommand(input, onSpawn, driver) {
|
|
918
951
|
const options = NativeCommandOptionsSchema.parse(input);
|
|
919
952
|
options.signal?.throwIfAborted();
|
|
@@ -937,7 +970,8 @@ function startNativeCommand(input, onSpawn, driver) {
|
|
|
937
970
|
options.signal?.removeEventListener("abort", abort);
|
|
938
971
|
killOn?.removeEventListener("abort", kill);
|
|
939
972
|
};
|
|
940
|
-
const
|
|
973
|
+
const guarded = options.ownerLoss === "terminate" || driver?.cwdDescriptor !== undefined;
|
|
974
|
+
const deadline = timeoutMs === undefined ? undefined : createCommandDeadline(guarded ? Math.max(timeoutMs, GUARD_START_FLOOR_MS) : timeoutMs, new NativeCommandError2("COMMAND_LIMIT", "Command deadline exceeded", {
|
|
941
975
|
reason: "deadline"
|
|
942
976
|
}));
|
|
943
977
|
const expired = () => controller.abort(deadline?.signal.reason);
|
|
@@ -1038,6 +1072,8 @@ function startNativeCommand(input, onSpawn, driver) {
|
|
|
1038
1072
|
]);
|
|
1039
1073
|
drains.catch((error) => controller.abort(error));
|
|
1040
1074
|
const pid = await raceAbort(started, controller.signal);
|
|
1075
|
+
if (timeoutMs !== undefined)
|
|
1076
|
+
deadline?.restart(timeoutMs);
|
|
1041
1077
|
if (pid !== undefined)
|
|
1042
1078
|
options.onLeaderStarted?.({ pid });
|
|
1043
1079
|
admitted.resolve();
|