stitchkit 0.114.1 → 0.115.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 +37 -0
- package/dist/agent-runtime/coding-tool-files.d.ts.map +1 -1
- package/dist/agent-runtime/coding-tool-listing.d.ts.map +1 -1
- 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/contained-scan.d.ts +1 -1
- package/dist/agent-runtime/contained-scan.d.ts.map +1 -1
- package/dist/agent-runtime/sandbox-broker.d.ts.map +1 -1
- package/dist/agent-runtime/sandbox-bubblewrap-storage.d.ts.map +1 -1
- package/dist/application/directory-inbox-files.d.ts.map +1 -1
- package/dist/application/file-state-store.d.ts.map +1 -1
- package/dist/entrypoints/agent-runtime/coding-tools.js +6 -4
- package/dist/entrypoints/agent-runtime/harness.js +2 -1
- package/dist/entrypoints/agent-runtime/sandbox.js +13 -8
- package/dist/entrypoints/agent-runtime/sqlite/bun.js +8 -6
- package/dist/entrypoints/agent-runtime/sqlite/node.js +8 -6
- package/dist/entrypoints/agent-runtime/testing.js +8 -6
- package/dist/entrypoints/agent-runtime.js +8 -6
- package/dist/entrypoints/application/diagnostic-journal.js +2 -2
- package/dist/entrypoints/application/directory-inbox.js +10 -7
- package/dist/entrypoints/cli/publish.js +11 -8
- package/dist/entrypoints/cli.js +6 -3
- package/dist/entrypoints/files.js +10 -7
- package/dist/entrypoints/process/owner-loss.js +1 -1
- package/dist/entrypoints/process.js +3 -3
- package/dist/entrypoints/react/keyboard/testing.js +1 -1
- package/dist/entrypoints/react/keyboard.js +11 -11
- package/dist/entrypoints/server.js +4 -4
- package/dist/entrypoints/telegram.js +8 -5
- package/dist/entrypoints/tools.js +6 -3
- package/dist/files/chunk-spool.d.ts.map +1 -1
- package/dist/{index-2f9r0jgr.js → index-364k2zwa.js} +4 -4
- package/dist/{index-km2qw407.js → index-3qqdqwxe.js} +91 -36
- package/dist/{index-s47ac8zt.js → index-7yx8j6ay.js} +133 -156
- package/dist/{index-kdnfe0sr.js → index-90p34rts.js} +2 -2
- package/dist/{index-a3462dqf.js → index-944x38nv.js} +1 -1
- package/dist/{index-07dcf2yn.js → index-ac6vvm30.js} +5 -2
- package/dist/{index-qj1sy4ep.js → index-crmswbrt.js} +1 -1
- package/dist/{index-7r4knwf8.js → index-dr3t5n1v.js} +14 -4
- package/dist/{index-dc9ere5p.js → index-dx5cm9pc.js} +1 -1
- package/dist/{index-84bf5spd.js → index-f6m4c545.js} +5 -2
- package/dist/{index-hy802jnr.js → index-fdk4r4r6.js} +6 -3
- package/dist/index-j8kf56wx.js +100 -0
- package/dist/index-jj9228tt.js +6 -0
- package/dist/{index-t65erk4z.js → index-mgb7r8b8.js} +122 -62
- package/dist/{index-bh2ht9y5.js → index-n8z3rvzw.js} +4 -1
- package/dist/index-nregbbsc.js +107 -0
- package/dist/{index-j4zh647a.js → index-tt30h7mr.js} +4 -1
- package/dist/{index-zrtrjkbf.js → index-x0ddbj85.js} +148 -172
- package/dist/{index-p02zgk8x.js → index-y4rxnvgp.js} +6 -0
- package/dist/{index-5v5a9k2n.js → index-z3d6smer.js} +1 -1
- package/dist/{index-6b3pcq5z.js → index-zqkz4af9.js} +1 -1
- package/dist/internal/atomic-file.d.ts.map +1 -1
- package/dist/internal/atomic-staging.d.ts.map +1 -1
- package/dist/internal/contained-directory.d.ts +20 -0
- package/dist/internal/contained-directory.d.ts.map +1 -0
- package/dist/{agent-runtime → internal}/contained-files.d.ts +14 -13
- package/dist/internal/contained-files.d.ts.map +1 -0
- package/dist/internal/contained-handle.d.ts +30 -0
- package/dist/internal/contained-handle.d.ts.map +1 -0
- package/dist/internal/contained-write.d.ts +12 -0
- package/dist/internal/contained-write.d.ts.map +1 -0
- package/dist/internal/darwin-binding.d.ts +1 -1
- package/dist/internal/darwin-binding.d.ts.map +1 -1
- package/dist/internal/errno.d.ts +3 -0
- package/dist/internal/errno.d.ts.map +1 -0
- package/dist/internal/pinned-http.d.ts +27 -0
- package/dist/internal/pinned-http.d.ts.map +1 -0
- package/dist/internal/process-instance.d.ts.map +1 -1
- package/dist/internal/secure-fetch.d.ts +26 -6
- package/dist/internal/secure-fetch.d.ts.map +1 -1
- package/dist/internal/write-download.d.ts +5 -14
- package/dist/internal/write-download.d.ts.map +1 -1
- package/dist/process/group-diagnostics.d.ts +1 -0
- package/dist/process/group-diagnostics.d.ts.map +1 -1
- package/dist/process/group-settlement.d.ts +2 -0
- package/dist/process/group-settlement.d.ts.map +1 -1
- package/dist/process/group.d.ts.map +1 -1
- package/dist/process/owner-loss-control.d.ts.map +1 -1
- package/dist/react/keyboard/hooks.d.ts +2 -2
- package/dist/react/keyboard/hooks.d.ts.map +1 -1
- package/dist/react/keyboard/layers.d.ts +2 -0
- package/dist/react/keyboard/layers.d.ts.map +1 -1
- package/dist/telegram/broadcast-state.d.ts.map +1 -1
- package/dist/tools/cli/download.d.ts.map +1 -1
- package/dist/tools/cli/publication-storage.d.ts.map +1 -1
- package/dist/tools/cli/publication.d.ts.map +1 -1
- package/dist/tools/cli/view.d.ts.map +1 -1
- package/llms/agent-runtime.txt +16 -6
- package/llms/cli.txt +34 -2
- package/llms/process.txt +2 -2
- package/llms/react-keyboard.txt +18 -2
- package/llms/stitchkit.txt +3 -3
- package/llms/{upgrading-0.104.0-0.114.0.txt → upgrading-0.104.0-0.115.0.txt} +62 -3
- package/llms/upgrading.txt +1 -1
- package/llms-full.txt +132 -15
- package/llms.txt +5 -5
- 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/agent-runtime/contained-darwin.d.ts +0 -21
- package/dist/agent-runtime/contained-darwin.d.ts.map +0 -1
- package/dist/agent-runtime/contained-files.d.ts.map +0 -1
- package/dist/agent-runtime/contained-write.d.ts +0 -9
- package/dist/agent-runtime/contained-write.d.ts.map +0 -1
|
@@ -1,33 +1,35 @@
|
|
|
1
|
-
import {
|
|
2
|
-
loadDarwinBinding
|
|
3
|
-
} from "./index-2kbysk9s.js";
|
|
4
1
|
import {
|
|
5
2
|
NativeCommandError2
|
|
6
|
-
} from "./index-
|
|
3
|
+
} from "./index-f6m4c545.js";
|
|
7
4
|
import {
|
|
8
5
|
CommandStopped,
|
|
9
6
|
startNativeCommand
|
|
10
|
-
} from "./index-
|
|
7
|
+
} from "./index-dr3t5n1v.js";
|
|
8
|
+
import {
|
|
9
|
+
scanContainedFiles
|
|
10
|
+
} from "./index-nregbbsc.js";
|
|
11
|
+
import {
|
|
12
|
+
writeContainedFile
|
|
13
|
+
} from "./index-j8kf56wx.js";
|
|
11
14
|
import {
|
|
12
|
-
NumericFileHandle,
|
|
13
|
-
descriptorPath,
|
|
14
15
|
listContainedDirectory,
|
|
15
16
|
missingContainedDirectories,
|
|
17
|
+
UnapprovedContainedDirectoryError,
|
|
16
18
|
openContainedParent,
|
|
17
19
|
openContainedFile,
|
|
20
|
+
ContainedPathChangedError,
|
|
18
21
|
assertContainedFileCurrent,
|
|
19
22
|
assertContainedParentCurrent,
|
|
20
23
|
containedEntryMetadata,
|
|
21
24
|
openContainedParentFile,
|
|
22
|
-
readContainedUtf8Handle
|
|
23
|
-
|
|
24
|
-
} from "./index-zrtrjkbf.js";
|
|
25
|
+
readContainedUtf8Handle
|
|
26
|
+
} from "./index-x0ddbj85.js";
|
|
25
27
|
import {
|
|
26
28
|
defineRuntimeTool2
|
|
27
29
|
} from "./index-ega3yz4c.js";
|
|
28
30
|
import {
|
|
29
|
-
|
|
30
|
-
} from "./index-
|
|
31
|
+
errnoOf
|
|
32
|
+
} from "./index-jj9228tt.js";
|
|
31
33
|
import {
|
|
32
34
|
AppError2,
|
|
33
35
|
forbidden2,
|
|
@@ -250,7 +252,7 @@ async function recordAgentSandboxProbe2(input) {
|
|
|
250
252
|
}
|
|
251
253
|
|
|
252
254
|
// src/agent-runtime/coding-tools.ts
|
|
253
|
-
import
|
|
255
|
+
import path4 from "node:path";
|
|
254
256
|
import { z as z5 } from "zod";
|
|
255
257
|
|
|
256
258
|
// src/agent-runtime/coding-tool-files.ts
|
|
@@ -278,7 +280,8 @@ function codingPathRefusal(code, message, path, options = {}) {
|
|
|
278
280
|
});
|
|
279
281
|
}
|
|
280
282
|
function refuseMissingCodingPath(error, relative) {
|
|
281
|
-
|
|
283
|
+
refuseChangedPath(error, relative);
|
|
284
|
+
const code = errnoOf(error);
|
|
282
285
|
if (error instanceof Error && error.message.includes("is not a regular file")) {
|
|
283
286
|
codingPathRefusal("BAD_REQUEST", "This path is not a regular file", relative, {
|
|
284
287
|
hint: "Use list_directory to see what is here."
|
|
@@ -299,13 +302,55 @@ function refuseMissingCodingPath(error, relative) {
|
|
|
299
302
|
hint: "Read or write the target directly, by its own workspace-relative path."
|
|
300
303
|
});
|
|
301
304
|
}
|
|
302
|
-
if (code === "EISDIR") {
|
|
305
|
+
if (code === "EISDIR" || code === "ENXIO" || code === "EOPNOTSUPP") {
|
|
303
306
|
codingPathRefusal("BAD_REQUEST", "This path is not a regular file", relative, {
|
|
304
307
|
hint: "Use list_directory to see what is here."
|
|
305
308
|
});
|
|
306
309
|
}
|
|
307
310
|
throw error;
|
|
308
311
|
}
|
|
312
|
+
function refuseChangedPath(error, relative) {
|
|
313
|
+
if (error instanceof ContainedPathChangedError) {
|
|
314
|
+
codingPathRefusal("CONFLICT", "This path changed while it was being authorized", relative, {
|
|
315
|
+
hint: "Read it again and retry."
|
|
316
|
+
});
|
|
317
|
+
}
|
|
318
|
+
}
|
|
319
|
+
function refuseWriteConflict(error, relative, details = {}) {
|
|
320
|
+
refuseChangedPath(error, relative);
|
|
321
|
+
const code = errnoOf(error);
|
|
322
|
+
if (code === "ENOENT") {
|
|
323
|
+
codingPathRefusal("CONFLICT", "This path changed while it was being written", relative, {
|
|
324
|
+
details,
|
|
325
|
+
hint: "Read it again and retry."
|
|
326
|
+
});
|
|
327
|
+
}
|
|
328
|
+
if (code === "ENOTDIR") {
|
|
329
|
+
codingPathRefusal("CONFLICT", "A segment of this path is not a directory", relative, {
|
|
330
|
+
details,
|
|
331
|
+
hint: "Write under a different path, or remove the file blocking it."
|
|
332
|
+
});
|
|
333
|
+
}
|
|
334
|
+
if (code === "ELOOP") {
|
|
335
|
+
codingPathRefusal("FORBIDDEN", "This path is a symlink, which is not followed", relative, {
|
|
336
|
+
details,
|
|
337
|
+
hint: "Write to the target directly, by its own workspace-relative path."
|
|
338
|
+
});
|
|
339
|
+
}
|
|
340
|
+
if (code === "EISDIR") {
|
|
341
|
+
codingPathRefusal("CONFLICT", "This path is a directory", relative, {
|
|
342
|
+
details,
|
|
343
|
+
hint: "Write to a file path inside it, or choose another name."
|
|
344
|
+
});
|
|
345
|
+
}
|
|
346
|
+
if (code === "EEXIST") {
|
|
347
|
+
codingPathRefusal("CONFLICT", "This file already exists", relative, {
|
|
348
|
+
details,
|
|
349
|
+
hint: "Pass overwrite: true to replace it, or edit_file to change part of it."
|
|
350
|
+
});
|
|
351
|
+
}
|
|
352
|
+
throw error;
|
|
353
|
+
}
|
|
309
354
|
function refuseUnknownSpillReference(reference) {
|
|
310
355
|
codingRefusal("SPILL_REFERENCE_UNKNOWN", `No spilled output is held under \`${reference}\``, {
|
|
311
356
|
details: { reference },
|
|
@@ -343,6 +388,12 @@ function inputPath(root, requested, maxPathBytes) {
|
|
|
343
388
|
return resolved;
|
|
344
389
|
}
|
|
345
390
|
function boundedCodingRelativePath(root, requested, maxPathBytes) {
|
|
391
|
+
if (requested.includes("\x00")) {
|
|
392
|
+
codingRefusal("BAD_REQUEST", "Path segments cannot contain a NUL byte", {
|
|
393
|
+
details: { path: requested },
|
|
394
|
+
hint: "Pass the exact workspace-relative entry name without NUL bytes."
|
|
395
|
+
});
|
|
396
|
+
}
|
|
346
397
|
if (path.isAbsolute(requested))
|
|
347
398
|
inputPath(root, requested, maxPathBytes);
|
|
348
399
|
if (requested.includes("\\")) {
|
|
@@ -462,86 +513,6 @@ function utf8AlignedStart(data, start, end) {
|
|
|
462
513
|
return safe;
|
|
463
514
|
}
|
|
464
515
|
|
|
465
|
-
// src/agent-runtime/contained-write.ts
|
|
466
|
-
import { fchmod, write as writeDescriptor } from "node:fs";
|
|
467
|
-
import { rename, unlink, writeFile } from "node:fs/promises";
|
|
468
|
-
import path2 from "node:path";
|
|
469
|
-
async function writeDescriptorFully(descriptor, content) {
|
|
470
|
-
const bytes = Buffer.from(content);
|
|
471
|
-
let offset = 0;
|
|
472
|
-
while (offset < bytes.byteLength) {
|
|
473
|
-
const written = await new Promise((resolve, reject) => {
|
|
474
|
-
writeDescriptor(descriptor, bytes, offset, bytes.byteLength - offset, null, (error, bytesWritten) => error ? reject(error) : resolve(bytesWritten));
|
|
475
|
-
});
|
|
476
|
-
if (written === 0)
|
|
477
|
-
throw new Error("Contained file write made no progress");
|
|
478
|
-
offset += written;
|
|
479
|
-
}
|
|
480
|
-
}
|
|
481
|
-
async function chmodDescriptor(descriptor, mode) {
|
|
482
|
-
await new Promise((resolve, reject) => {
|
|
483
|
-
fchmod(descriptor, mode & 4095, (error) => error ? reject(error) : resolve());
|
|
484
|
-
});
|
|
485
|
-
}
|
|
486
|
-
async function createDarwinFile(parent, name, content, mode) {
|
|
487
|
-
const binding = loadDarwinBinding();
|
|
488
|
-
const descriptor = binding.createFileAt(parent.fd, name, mode & 4095);
|
|
489
|
-
let failed;
|
|
490
|
-
try {
|
|
491
|
-
await writeDescriptorFully(descriptor, content);
|
|
492
|
-
await chmodDescriptor(descriptor, mode);
|
|
493
|
-
} catch (error) {
|
|
494
|
-
failed = error;
|
|
495
|
-
} finally {
|
|
496
|
-
try {
|
|
497
|
-
await new NumericFileHandle(descriptor).close();
|
|
498
|
-
} catch (error) {
|
|
499
|
-
failed ??= error;
|
|
500
|
-
}
|
|
501
|
-
}
|
|
502
|
-
if (failed) {
|
|
503
|
-
binding.unlinkAt(parent.fd, name);
|
|
504
|
-
throw failed;
|
|
505
|
-
}
|
|
506
|
-
}
|
|
507
|
-
async function writeContainedFile(input) {
|
|
508
|
-
const mode = input.mode ?? 438;
|
|
509
|
-
if (!input.replace) {
|
|
510
|
-
if (process.platform === "darwin") {
|
|
511
|
-
await createDarwinFile(input.parent.handle, input.parent.basename, input.content, mode);
|
|
512
|
-
return;
|
|
513
|
-
}
|
|
514
|
-
await writeFile(path2.join(descriptorPath(input.parent.handle), input.parent.basename), input.content, { flag: "wx", mode });
|
|
515
|
-
return;
|
|
516
|
-
}
|
|
517
|
-
const temporary = stagingName();
|
|
518
|
-
if (process.platform === "darwin") {
|
|
519
|
-
const binding = loadDarwinBinding();
|
|
520
|
-
let created = false;
|
|
521
|
-
try {
|
|
522
|
-
await createDarwinFile(input.parent.handle, temporary, input.content, mode);
|
|
523
|
-
created = true;
|
|
524
|
-
binding.renameAt(input.parent.handle.fd, temporary, input.parent.basename);
|
|
525
|
-
} catch (error) {
|
|
526
|
-
if (created)
|
|
527
|
-
binding.unlinkAt(input.parent.handle.fd, temporary);
|
|
528
|
-
throw error;
|
|
529
|
-
}
|
|
530
|
-
return;
|
|
531
|
-
}
|
|
532
|
-
const directory = descriptorPath(input.parent.handle);
|
|
533
|
-
const temporaryPath = path2.join(directory, temporary);
|
|
534
|
-
try {
|
|
535
|
-
await writeFile(temporaryPath, input.content, { flag: "wx", mode });
|
|
536
|
-
await rename(temporaryPath, path2.join(directory, input.parent.basename));
|
|
537
|
-
} catch (error) {
|
|
538
|
-
await unlink(temporaryPath).catch(() => {
|
|
539
|
-
return;
|
|
540
|
-
});
|
|
541
|
-
throw error;
|
|
542
|
-
}
|
|
543
|
-
}
|
|
544
|
-
|
|
545
516
|
// src/agent-runtime/coding-tool-files.ts
|
|
546
517
|
async function digestFile(handle, size) {
|
|
547
518
|
const hash = createHash("sha256");
|
|
@@ -556,6 +527,17 @@ async function digestFile(handle, size) {
|
|
|
556
527
|
}
|
|
557
528
|
return hash.digest("hex");
|
|
558
529
|
}
|
|
530
|
+
async function openAuthorizedWriteParent(root, relative, createsDirectories) {
|
|
531
|
+
return openContainedParent(root, relative, { createDirectories: createsDirectories }).catch((error) => {
|
|
532
|
+
if (error instanceof UnapprovedContainedDirectoryError) {
|
|
533
|
+
codingPathRefusal("CONFLICT", "The directory creation plan changed during authorization", relative, {
|
|
534
|
+
details: { createsDirectories },
|
|
535
|
+
hint: "Retry the write so the host can authorize the current directories."
|
|
536
|
+
});
|
|
537
|
+
}
|
|
538
|
+
refuseWriteConflict(error, relative, { createsDirectories });
|
|
539
|
+
});
|
|
540
|
+
}
|
|
559
541
|
function createFileCodingTools(config, limits) {
|
|
560
542
|
const read = defineRuntimeTool2({
|
|
561
543
|
name: "read_file",
|
|
@@ -576,7 +558,7 @@ function createFileCodingTools(config, limits) {
|
|
|
576
558
|
let sha256;
|
|
577
559
|
try {
|
|
578
560
|
await authorizeCodingTool(config, { operation: "read", path: relative });
|
|
579
|
-
await assertContainedFileCurrent(root, relative, handle);
|
|
561
|
+
await assertContainedFileCurrent(root, relative, handle).catch((error) => refuseMissingCodingPath(error, relative));
|
|
580
562
|
const metadata = await handle.stat();
|
|
581
563
|
if (!metadata.isFile()) {
|
|
582
564
|
codingPathRefusal("BAD_REQUEST", "This path is not a regular file", relative, {
|
|
@@ -639,14 +621,7 @@ function createFileCodingTools(config, limits) {
|
|
|
639
621
|
hint: "Write a smaller file, or split it."
|
|
640
622
|
});
|
|
641
623
|
}
|
|
642
|
-
const createsDirectories = await missingContainedDirectories(root, relative).catch((error) =>
|
|
643
|
-
if (error.code === "ENOTDIR") {
|
|
644
|
-
codingPathRefusal("CONFLICT", "A segment of this path is not a directory", relative, {
|
|
645
|
-
hint: "Write under a different path, or remove the file blocking it."
|
|
646
|
-
});
|
|
647
|
-
}
|
|
648
|
-
throw error;
|
|
649
|
-
});
|
|
624
|
+
const createsDirectories = await missingContainedDirectories(root, relative).catch((error) => refuseWriteConflict(error, relative));
|
|
650
625
|
await authorizeCodingTool(config, {
|
|
651
626
|
operation: "write",
|
|
652
627
|
path: relative,
|
|
@@ -654,42 +629,39 @@ function createFileCodingTools(config, limits) {
|
|
|
654
629
|
overwrite: input.overwrite,
|
|
655
630
|
createsDirectories
|
|
656
631
|
});
|
|
657
|
-
|
|
658
|
-
const
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
hint: "Pass overwrite: true to replace it, or edit_file to change part of it."
|
|
686
|
-
});
|
|
632
|
+
await withCodingPathLock(`${root}:${relative}`, async () => {
|
|
633
|
+
const parent = await openAuthorizedWriteParent(root, relative, createsDirectories);
|
|
634
|
+
try {
|
|
635
|
+
await assertContainedParentCurrent(root, relative, parent.handle).catch((error) => refuseWriteConflict(error, relative));
|
|
636
|
+
const current = await containedEntryMetadata(parent);
|
|
637
|
+
if (input.overwrite) {
|
|
638
|
+
if (current?.isSymbolicLink()) {
|
|
639
|
+
codingPathRefusal("FORBIDDEN", "This path is a symlink", relative, {
|
|
640
|
+
hint: "Coding tools never write through symlinks; write to the target directly."
|
|
641
|
+
});
|
|
642
|
+
}
|
|
643
|
+
await writeContainedFile({
|
|
644
|
+
parent,
|
|
645
|
+
content: input.content,
|
|
646
|
+
replace: true,
|
|
647
|
+
...current && { mode: current.mode }
|
|
648
|
+
}).catch((error) => refuseWriteConflict(error, relative));
|
|
649
|
+
} else {
|
|
650
|
+
if (current) {
|
|
651
|
+
codingPathRefusal("CONFLICT", "This file already exists", relative, {
|
|
652
|
+
hint: "Pass overwrite: true to replace it, or edit_file to change part of it."
|
|
653
|
+
});
|
|
654
|
+
}
|
|
655
|
+
await writeContainedFile({
|
|
656
|
+
parent,
|
|
657
|
+
content: input.content,
|
|
658
|
+
replace: false
|
|
659
|
+
}).catch((error) => refuseWriteConflict(error, relative));
|
|
687
660
|
}
|
|
688
|
-
|
|
661
|
+
} finally {
|
|
662
|
+
await parent.handle.close();
|
|
689
663
|
}
|
|
690
|
-
}
|
|
691
|
-
await parent.handle.close();
|
|
692
|
-
}
|
|
664
|
+
});
|
|
693
665
|
return { path: relative, bytes, createdDirectories: createsDirectories };
|
|
694
666
|
}
|
|
695
667
|
});
|
|
@@ -698,7 +670,7 @@ function createFileCodingTools(config, limits) {
|
|
|
698
670
|
|
|
699
671
|
// src/agent-runtime/coding-tool-listing.ts
|
|
700
672
|
import { realpath as realpath3 } from "node:fs/promises";
|
|
701
|
-
import
|
|
673
|
+
import path2 from "node:path";
|
|
702
674
|
import { z as z3 } from "zod";
|
|
703
675
|
var DEFAULT_EXCLUDED_DIRECTORIES = [
|
|
704
676
|
".git",
|
|
@@ -773,12 +745,7 @@ function createListingCodingTools(config, limits) {
|
|
|
773
745
|
await authorizeCodingPathChain(config, relative);
|
|
774
746
|
await authorizeCodingTool(config, { operation: "list", path: relative });
|
|
775
747
|
const listing = await listContainedDirectory(root, relative, limits.maxListEntries, (candidate) => isCodingPathAuthorized(config, candidate)).catch((error) => {
|
|
776
|
-
if (error
|
|
777
|
-
codingPathRefusal("BAD_REQUEST", "This path is not a directory", relative, {
|
|
778
|
-
hint: "Pass a directory; use read_file for a file."
|
|
779
|
-
});
|
|
780
|
-
}
|
|
781
|
-
if (error.code === "ENOENT") {
|
|
748
|
+
if (errnoOf(error) === "ENOENT") {
|
|
782
749
|
codingPathRefusal("NOT_FOUND", "This directory does not exist", relative, {
|
|
783
750
|
hint: "List a parent directory to see what is there."
|
|
784
751
|
});
|
|
@@ -794,7 +761,7 @@ function createListingCodingTools(config, limits) {
|
|
|
794
761
|
truncated: listing.truncated,
|
|
795
762
|
...listing.denied.length > 0 && {
|
|
796
763
|
denied: listing.denied.map((entry) => ({
|
|
797
|
-
path: relative === "." ? entry.name :
|
|
764
|
+
path: relative === "." ? entry.name : path2.join(relative, entry.name),
|
|
798
765
|
kind: entry.kind
|
|
799
766
|
})),
|
|
800
767
|
deniedTruncated: listing.deniedTruncated
|
|
@@ -832,10 +799,10 @@ function createListingCodingTools(config, limits) {
|
|
|
832
799
|
maxDepth: limits.maxSearchDepth,
|
|
833
800
|
maxFiles: limits.maxSearchFiles,
|
|
834
801
|
symlinks: "skip",
|
|
835
|
-
excludeDirectory: (directory) => directory.split(
|
|
802
|
+
excludeDirectory: (directory) => directory.split(path2.sep).some((segment) => excluded.has(segment)),
|
|
836
803
|
authorizePath: (candidate) => isCodingPathAuthorized(config, candidate)
|
|
837
804
|
});
|
|
838
|
-
const prefix = relative === "." ? "" : `${relative}${
|
|
805
|
+
const prefix = relative === "." ? "" : `${relative}${path2.sep}`;
|
|
839
806
|
const matched = scan.files.filter((file) => file.relative.startsWith(prefix)).map((file) => file.relative).filter((candidate) => matcher.test(candidate.slice(prefix.length))).sort();
|
|
840
807
|
const paths = matched.slice(0, limits.maxSearchResults);
|
|
841
808
|
const scopedDenied = scan.denied.filter((entry) => entry.relative.startsWith(prefix));
|
|
@@ -862,7 +829,7 @@ function createListingCodingTools(config, limits) {
|
|
|
862
829
|
// src/agent-runtime/coding-tool-search-patch.ts
|
|
863
830
|
import { createHash as createHash2 } from "node:crypto";
|
|
864
831
|
import { realpath as realpath4 } from "node:fs/promises";
|
|
865
|
-
import
|
|
832
|
+
import path3 from "node:path";
|
|
866
833
|
import { z as z4 } from "zod";
|
|
867
834
|
var SearchInputSchema = z4.object({
|
|
868
835
|
query: z4.string().min(1),
|
|
@@ -943,7 +910,7 @@ async function searchFiles(config, limits, input) {
|
|
|
943
910
|
readMaxBytes: limits.maxReadBytes,
|
|
944
911
|
skipUnreadable: true
|
|
945
912
|
},
|
|
946
|
-
excludeDirectory: (relative) => relative.split(
|
|
913
|
+
excludeDirectory: (relative) => relative.split(path3.sep).some((segment) => excluded.has(segment)),
|
|
947
914
|
includeFile: (candidate) => {
|
|
948
915
|
if (included && !included.test(candidate)) {
|
|
949
916
|
rejectedByInclude += 1;
|
|
@@ -1019,8 +986,12 @@ async function editFile(config, limits, input) {
|
|
|
1019
986
|
const parent = await openContainedParent(root, relative).catch((error) => refuseMissingCodingPath(error, relative));
|
|
1020
987
|
try {
|
|
1021
988
|
return await withCodingPathLock(`${root}:${relative}`, async () => {
|
|
1022
|
-
const
|
|
1023
|
-
|
|
989
|
+
const readCurrent = async () => {
|
|
990
|
+
const handle = await openContainedParentFile(parent).catch((error) => refuseMissingCodingPath(error, relative));
|
|
991
|
+
return readContainedUtf8Handle(handle, limits.maxWriteBytes).finally(() => handle.close());
|
|
992
|
+
};
|
|
993
|
+
await authorizeCodingTool(config, { operation: "read", path: relative });
|
|
994
|
+
const read = await readCurrent();
|
|
1024
995
|
const source = read.text;
|
|
1025
996
|
const baseSha256 = sha256(source);
|
|
1026
997
|
if (input.expectedSha256 !== undefined && baseSha256 !== input.expectedSha256) {
|
|
@@ -1064,14 +1035,20 @@ async function editFile(config, limits, input) {
|
|
|
1064
1035
|
replacements,
|
|
1065
1036
|
dryRun: input.dryRun
|
|
1066
1037
|
});
|
|
1067
|
-
await assertContainedParentCurrent(root, relative, parent.handle);
|
|
1038
|
+
await assertContainedParentCurrent(root, relative, parent.handle).catch((error) => refuseWriteConflict(error, relative));
|
|
1068
1039
|
if (!input.dryRun) {
|
|
1040
|
+
if (sha256((await readCurrent()).text) !== baseSha256) {
|
|
1041
|
+
conflict2("The file changed since it was read", {
|
|
1042
|
+
message: "The file changed since it was read",
|
|
1043
|
+
path: relative
|
|
1044
|
+
});
|
|
1045
|
+
}
|
|
1069
1046
|
await writeContainedFile({
|
|
1070
1047
|
parent,
|
|
1071
1048
|
content: changed,
|
|
1072
1049
|
replace: true,
|
|
1073
1050
|
mode: read.mode
|
|
1074
|
-
});
|
|
1051
|
+
}).catch((error) => refuseWriteConflict(error, relative));
|
|
1075
1052
|
}
|
|
1076
1053
|
return {
|
|
1077
1054
|
path: relative,
|
|
@@ -1383,10 +1360,10 @@ var AGENT_CODING_TOOL_NAMES = {
|
|
|
1383
1360
|
writeFile: "write_file"
|
|
1384
1361
|
};
|
|
1385
1362
|
function createAgentCodingTools2(config) {
|
|
1386
|
-
if (!
|
|
1363
|
+
if (!path4.isAbsolute(config.root))
|
|
1387
1364
|
throw new Error("Coding tool root must be absolute");
|
|
1388
1365
|
for (const executable of Object.values(config.executables ?? {})) {
|
|
1389
|
-
if (!
|
|
1366
|
+
if (!path4.isAbsolute(executable)) {
|
|
1390
1367
|
throw new Error("Coding tool executables must be absolute paths");
|
|
1391
1368
|
}
|
|
1392
1369
|
}
|
|
@@ -5,10 +5,10 @@ import {
|
|
|
5
5
|
fetchGuarded,
|
|
6
6
|
PrivateAddressRefusal,
|
|
7
7
|
readCapped
|
|
8
|
-
} from "./index-
|
|
8
|
+
} from "./index-mgb7r8b8.js";
|
|
9
9
|
import {
|
|
10
10
|
writeFileAtomicSync2
|
|
11
|
-
} from "./index-
|
|
11
|
+
} from "./index-ac6vvm30.js";
|
|
12
12
|
import {
|
|
13
13
|
raceAbort
|
|
14
14
|
} from "./index-b0kddvzw.js";
|
|
@@ -6,7 +6,10 @@ import {
|
|
|
6
6
|
} from "./index-b56nnscm.js";
|
|
7
7
|
import {
|
|
8
8
|
stagingPath
|
|
9
|
-
} from "./index-
|
|
9
|
+
} from "./index-tt30h7mr.js";
|
|
10
|
+
import {
|
|
11
|
+
errnoOf
|
|
12
|
+
} from "./index-jj9228tt.js";
|
|
10
13
|
|
|
11
14
|
// src/internal/atomic-file.ts
|
|
12
15
|
import { closeSync, fchmodSync, fsyncSync, openSync, unlinkSync, writeSync } from "node:fs";
|
|
@@ -27,7 +30,7 @@ async function writeFileAtomic2(target, data, options = {}) {
|
|
|
27
30
|
return writeAtomicFileData(target, data, options);
|
|
28
31
|
}
|
|
29
32
|
function isMissing(error) {
|
|
30
|
-
return
|
|
33
|
+
return errnoOf(error) === "ENOENT";
|
|
31
34
|
}
|
|
32
35
|
async function writeAtomicFileStaged(target, stage, options, io = { open, unlink, publish: publishAtomicFile }) {
|
|
33
36
|
const mode = options.mode ?? DEFAULT_MODE;
|
|
@@ -11,7 +11,10 @@ import {
|
|
|
11
11
|
spawnBunChild,
|
|
12
12
|
spawnBunInheritedChild,
|
|
13
13
|
ownerLossGuardEntry
|
|
14
|
-
} from "./index-
|
|
14
|
+
} from "./index-f6m4c545.js";
|
|
15
|
+
import {
|
|
16
|
+
errnoOf
|
|
17
|
+
} from "./index-jj9228tt.js";
|
|
15
18
|
import {
|
|
16
19
|
raceAbort
|
|
17
20
|
} from "./index-b0kddvzw.js";
|
|
@@ -30,7 +33,8 @@ var ObservationSchema = z.object({
|
|
|
30
33
|
groupId: z.number().int().positive(),
|
|
31
34
|
observations: z.number().int().nonnegative(),
|
|
32
35
|
lastStates: z.array(z.string().max(32)).max(16),
|
|
33
|
-
elapsedMs: z.number().int().nonnegative()
|
|
36
|
+
elapsedMs: z.number().int().nonnegative(),
|
|
37
|
+
reason: z.string().max(32).optional()
|
|
34
38
|
});
|
|
35
39
|
var observations = new WeakMap;
|
|
36
40
|
|
|
@@ -119,6 +123,12 @@ function processGroups(timeoutMs) {
|
|
|
119
123
|
});
|
|
120
124
|
});
|
|
121
125
|
}
|
|
126
|
+
function observationFailureReason(cause) {
|
|
127
|
+
if (!(cause instanceof Error))
|
|
128
|
+
return "unknown";
|
|
129
|
+
const signal = "signal" in cause && typeof cause.signal === "string" ? cause.signal : undefined;
|
|
130
|
+
return (errnoOf(cause) ?? signal ?? cause.name).slice(0, 32);
|
|
131
|
+
}
|
|
122
132
|
async function waitForProcessGroupExit(pid, deadline, killLiveMembers) {
|
|
123
133
|
if (pid === undefined)
|
|
124
134
|
return;
|
|
@@ -155,7 +165,7 @@ async function waitForProcessGroupExit(pid, deadline, killLiveMembers) {
|
|
|
155
165
|
} catch (cause) {
|
|
156
166
|
if (cause instanceof GroupSettlementError)
|
|
157
167
|
throw cause;
|
|
158
|
-
throw new GroupSettlementError("Could not observe command process group settlement", { ...observation(), failure: "observation" }, cause);
|
|
168
|
+
throw new GroupSettlementError("Could not observe command process group settlement", { ...observation(), failure: "observation", reason: observationFailureReason(cause) }, cause);
|
|
159
169
|
}
|
|
160
170
|
}
|
|
161
171
|
|
|
@@ -185,7 +195,7 @@ function deniedOnDarwin(error) {
|
|
|
185
195
|
return process.platform === "darwin" && error instanceof Error && "code" in error && error.code === "EPERM";
|
|
186
196
|
}
|
|
187
197
|
function isErrno(error, code) {
|
|
188
|
-
return error
|
|
198
|
+
return errnoOf(error) === code;
|
|
189
199
|
}
|
|
190
200
|
function signalGroup(pid, signal) {
|
|
191
201
|
if (pid === undefined)
|
|
@@ -1,3 +1,6 @@
|
|
|
1
|
+
import {
|
|
2
|
+
errnoOf
|
|
3
|
+
} from "./index-jj9228tt.js";
|
|
1
4
|
import {
|
|
2
5
|
MAX_TIMER_MS
|
|
3
6
|
} from "./index-eemvahkc.js";
|
|
@@ -177,7 +180,7 @@ function abortOwnerLossLaunch(pid) {
|
|
|
177
180
|
try {
|
|
178
181
|
process.kill(-pid, "SIGKILL");
|
|
179
182
|
} catch (error) {
|
|
180
|
-
if (
|
|
183
|
+
if (errnoOf(error) !== "ESRCH")
|
|
181
184
|
throw error;
|
|
182
185
|
}
|
|
183
186
|
}
|
|
@@ -575,7 +578,7 @@ function runOwnerLossGuard(signalTarget, executable, args) {
|
|
|
575
578
|
try {
|
|
576
579
|
process.kill(targetPid, signal);
|
|
577
580
|
} catch (error) {
|
|
578
|
-
if (
|
|
581
|
+
if (errnoOf(error) !== "ESRCH")
|
|
579
582
|
throw error;
|
|
580
583
|
}
|
|
581
584
|
};
|
|
@@ -1,15 +1,18 @@
|
|
|
1
1
|
import {
|
|
2
2
|
withExclusiveLock2
|
|
3
|
-
} from "./index-
|
|
3
|
+
} from "./index-zqkz4af9.js";
|
|
4
4
|
import {
|
|
5
5
|
readBoundedFile
|
|
6
6
|
} from "./index-m616f0yz.js";
|
|
7
7
|
import {
|
|
8
8
|
writeAtomicFileData
|
|
9
|
-
} from "./index-
|
|
9
|
+
} from "./index-ac6vvm30.js";
|
|
10
10
|
import {
|
|
11
11
|
publishAtomicFile
|
|
12
12
|
} from "./index-b56nnscm.js";
|
|
13
|
+
import {
|
|
14
|
+
errnoOf
|
|
15
|
+
} from "./index-jj9228tt.js";
|
|
13
16
|
import {
|
|
14
17
|
assertPositiveSafeInteger
|
|
15
18
|
} from "./index-0s4xebbg.js";
|
|
@@ -21,7 +24,7 @@ var NATIVE_IO = { write: writeAtomicFileData, lock: withExclusiveLock2 };
|
|
|
21
24
|
var DEFAULT_MAX_BYTES = 64 * 1024 * 1024;
|
|
22
25
|
var encode = (state) => `${JSON.stringify(state)}
|
|
23
26
|
`;
|
|
24
|
-
var missing = (error) =>
|
|
27
|
+
var missing = (error) => errnoOf(error) === "ENOENT";
|
|
25
28
|
function createFileStateStore2(path, options) {
|
|
26
29
|
return createFileStateStoreOn(path, options, NATIVE_IO);
|
|
27
30
|
}
|