@jigging/jig 0.1.0-alpha.13 → 0.1.0-alpha.14
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 +29 -185
- package/dist/index.js +41 -2
- package/dist/project/author.d.ts +3 -0
- package/dist/project/commands.d.ts +10 -0
- package/libexec/evaluator/project-authoring-1.schema.json +40 -0
- package/libexec/evaluator/project-evaluator-sdk.bundle.js +41 -2
- package/libexec/installed-cli.js +1051 -317
- package/libexec/linux-rootless-supervisor.js +8 -4
- package/package.json +2 -1
package/libexec/installed-cli.js
CHANGED
|
@@ -6996,19 +6996,18 @@ var require_x509_transport_state = __commonJS((exports, module) => {
|
|
|
6996
6996
|
|
|
6997
6997
|
// src/installed-cli.ts
|
|
6998
6998
|
import { realpath as realpath14 } from "fs/promises";
|
|
6999
|
-
import { dirname as
|
|
6999
|
+
import { dirname as dirname9 } from "path";
|
|
7000
7000
|
import { fileURLToPath as fileURLToPath2 } from "url";
|
|
7001
7001
|
|
|
7002
7002
|
// src/cli.ts
|
|
7003
7003
|
import { randomBytes as randomBytes2 } from "crypto";
|
|
7004
|
-
import {
|
|
7005
|
-
import { basename, dirname as dirname3, resolve as resolve3 } from "path";
|
|
7004
|
+
import { resolve as resolve3 } from "path";
|
|
7006
7005
|
import { createInterface } from "readline/promises";
|
|
7007
7006
|
import { setTimeout as delay } from "timers/promises";
|
|
7008
7007
|
// package.json
|
|
7009
7008
|
var package_default = {
|
|
7010
7009
|
name: "@jigging/jig",
|
|
7011
|
-
version: "0.1.0-alpha.
|
|
7010
|
+
version: "0.1.0-alpha.14",
|
|
7012
7011
|
description: "A local, secure host for admitted FLOW packages",
|
|
7013
7012
|
license: "MPL-2.0",
|
|
7014
7013
|
repository: {
|
|
@@ -7050,6 +7049,7 @@ var package_default = {
|
|
|
7050
7049
|
"dist/index.js",
|
|
7051
7050
|
"dist/index.d.ts",
|
|
7052
7051
|
"dist/project/author.d.ts",
|
|
7052
|
+
"dist/project/commands.d.ts",
|
|
7053
7053
|
"dist/json.d.ts",
|
|
7054
7054
|
"libexec/installed-cli.js",
|
|
7055
7055
|
"libexec/linux-rootless-supervisor.js",
|
|
@@ -9325,6 +9325,43 @@ function normalizeProjectAdministrationDiagnostic(value) {
|
|
|
9325
9325
|
});
|
|
9326
9326
|
}
|
|
9327
9327
|
|
|
9328
|
+
// src/project/commands.ts
|
|
9329
|
+
function projectCommandPath(value) {
|
|
9330
|
+
if (typeof value !== "string" || value.length > 256 || !/^[A-Za-z0-9_][A-Za-z0-9_./-]*$/.test(value) || value.split("/").some((part) => part === "" || part === "." || part === "..") || value.split("/").length > 16)
|
|
9331
|
+
throw new TypeError("command file paths must be bounded relative paths without traversal");
|
|
9332
|
+
return value;
|
|
9333
|
+
}
|
|
9334
|
+
function normalizeProjectCommands(value) {
|
|
9335
|
+
if (value === null || typeof value !== "object" || Array.isArray(value))
|
|
9336
|
+
throw new TypeError("commands must be an object");
|
|
9337
|
+
const entries = Object.entries(value);
|
|
9338
|
+
if (entries.length > 8)
|
|
9339
|
+
throw new TypeError("commands exceed eight entries");
|
|
9340
|
+
const output = Object.create(null);
|
|
9341
|
+
for (const [name, item] of entries.sort(([a], [b]) => a < b ? -1 : a > b ? 1 : 0)) {
|
|
9342
|
+
if (!/^[a-z0-9]+(?:-[a-z0-9]+)*$/.test(name) || name.length > 64)
|
|
9343
|
+
throw new TypeError("command name must be a LocalName");
|
|
9344
|
+
if (item === null || typeof item !== "object" || Array.isArray(item) || Object.keys(item).length !== 1)
|
|
9345
|
+
throw new TypeError(`command ${name} must contain run or test`);
|
|
9346
|
+
const command = item;
|
|
9347
|
+
if (Object.hasOwn(command, "run")) {
|
|
9348
|
+
const path = projectCommandPath(command.run);
|
|
9349
|
+
if (!path.endsWith(".ts") && !path.endsWith(".js"))
|
|
9350
|
+
throw new TypeError("command run must name a .ts or .js entrypoint");
|
|
9351
|
+
output[name] = Object.freeze({ run: path });
|
|
9352
|
+
} else if (Object.hasOwn(command, "test") && Array.isArray(command.test)) {
|
|
9353
|
+
if (command.test.length === 0 || command.test.length > 16)
|
|
9354
|
+
throw new TypeError("command test must select one to sixteen test files");
|
|
9355
|
+
const paths = command.test.map(projectCommandPath);
|
|
9356
|
+
if (new Set(paths).size !== paths.length || paths.some((path) => !/\.(test|spec)\.(ts|js)$/.test(path)))
|
|
9357
|
+
throw new TypeError("command test must name distinct .test or .spec files");
|
|
9358
|
+
output[name] = Object.freeze({ test: Object.freeze(paths) });
|
|
9359
|
+
} else
|
|
9360
|
+
throw new TypeError(`command ${name} must contain run or test`);
|
|
9361
|
+
}
|
|
9362
|
+
return Object.freeze(output);
|
|
9363
|
+
}
|
|
9364
|
+
|
|
9328
9365
|
// src/project/author.ts
|
|
9329
9366
|
var LOCAL_NAME = /^[a-z0-9]+(?:-[a-z0-9]+)*$/;
|
|
9330
9367
|
var GLOB_CHARACTERS = /[*?\[\]{}]/;
|
|
@@ -9363,7 +9400,7 @@ function normalizePackageBindingDefinition(input) {
|
|
|
9363
9400
|
}
|
|
9364
9401
|
function normalizeBinding(input, canonical) {
|
|
9365
9402
|
const captured = snapshotJsonObject(input, "Binding definition");
|
|
9366
|
-
assertClosedObject(captured, canonical ? ["kind", "package", "settings", "slots"] : ["package", "settings", "slots"], "Binding definition");
|
|
9403
|
+
assertClosedObject(captured, canonical ? ["kind", "package", "settings", "slots", "commands"] : ["package", "settings", "slots", "commands"], "Binding definition");
|
|
9367
9404
|
if (canonical && captured.kind !== "package") {
|
|
9368
9405
|
throw new TypeError("Binding kind must be package");
|
|
9369
9406
|
}
|
|
@@ -9372,11 +9409,13 @@ function normalizeBinding(input, canonical) {
|
|
|
9372
9409
|
const packagePath = normalizeProjectPath(captured.package, "package");
|
|
9373
9410
|
const settings = Object.hasOwn(captured, "settings") ? expectJsonObject(captured.settings, "settings") : emptyRecord();
|
|
9374
9411
|
const slots = Object.hasOwn(captured, "slots") ? normalizeFlowSlots(captured.slots) : emptyRecord();
|
|
9412
|
+
const commands = normalizeProjectCommands(Object.hasOwn(captured, "commands") ? captured.commands : {});
|
|
9375
9413
|
return record({
|
|
9376
9414
|
kind: "package",
|
|
9377
9415
|
package: packagePath,
|
|
9378
9416
|
settings,
|
|
9379
|
-
slots
|
|
9417
|
+
slots,
|
|
9418
|
+
...Object.keys(commands).length === 0 ? {} : { commands }
|
|
9380
9419
|
});
|
|
9381
9420
|
}
|
|
9382
9421
|
function normalizeFlowSlots(value) {
|
|
@@ -9827,15 +9866,58 @@ import {
|
|
|
9827
9866
|
constants,
|
|
9828
9867
|
fstatSync,
|
|
9829
9868
|
opendirSync,
|
|
9869
|
+
openSync,
|
|
9830
9870
|
readFileSync,
|
|
9831
9871
|
readSync,
|
|
9832
|
-
realpathSync,
|
|
9833
9872
|
statfsSync,
|
|
9834
9873
|
writeSync
|
|
9835
9874
|
} from "fs";
|
|
9836
9875
|
import { createRequire } from "module";
|
|
9837
9876
|
import { dirname, posix, resolve as resolve2 } from "path";
|
|
9838
9877
|
import { getSystemErrorName } from "util";
|
|
9878
|
+
|
|
9879
|
+
// src/internal/linux-host-paths.ts
|
|
9880
|
+
import { realpathSync } from "fs";
|
|
9881
|
+
import { realpath } from "fs/promises";
|
|
9882
|
+
var LOADER_PATHS = [
|
|
9883
|
+
"/run/current-system/sw/share/nix-ld/lib/ld.so",
|
|
9884
|
+
"/lib64/ld-linux-x86-64.so.2"
|
|
9885
|
+
];
|
|
9886
|
+
function privateLinuxHostToolCandidates(name) {
|
|
9887
|
+
return [
|
|
9888
|
+
...name === "codex" ? [`/usr/local/bin/${name}`] : [],
|
|
9889
|
+
`/usr/bin/${name}`,
|
|
9890
|
+
`/bin/${name}`,
|
|
9891
|
+
`/run/current-system/sw/bin/${name}`
|
|
9892
|
+
];
|
|
9893
|
+
}
|
|
9894
|
+
async function resolvePrivateLinuxHostPath(candidates, resolve2 = realpath) {
|
|
9895
|
+
for (const path of candidates) {
|
|
9896
|
+
try {
|
|
9897
|
+
return await resolve2(path);
|
|
9898
|
+
} catch (error) {
|
|
9899
|
+
if (error.code !== "ENOENT")
|
|
9900
|
+
throw error;
|
|
9901
|
+
}
|
|
9902
|
+
}
|
|
9903
|
+
throw new Error("the required system-owned host file is unavailable");
|
|
9904
|
+
}
|
|
9905
|
+
function resolvePrivateLinuxHostLoader(resolve2 = realpath) {
|
|
9906
|
+
return resolvePrivateLinuxHostPath(LOADER_PATHS, resolve2);
|
|
9907
|
+
}
|
|
9908
|
+
function resolvePrivateLinuxHostLoaderSync(resolve2 = realpathSync) {
|
|
9909
|
+
for (const path of LOADER_PATHS) {
|
|
9910
|
+
try {
|
|
9911
|
+
return resolve2(path);
|
|
9912
|
+
} catch (error) {
|
|
9913
|
+
if (error.code !== "ENOENT")
|
|
9914
|
+
throw error;
|
|
9915
|
+
}
|
|
9916
|
+
}
|
|
9917
|
+
throw new Error("the required system-owned glibc loader is unavailable");
|
|
9918
|
+
}
|
|
9919
|
+
|
|
9920
|
+
// src/internal/linux-file-input.ts
|
|
9839
9921
|
var PRIVATE_FILE_LIMITS = Object.freeze({
|
|
9840
9922
|
bytes: 8 * 1024 * 1024,
|
|
9841
9923
|
files: 64,
|
|
@@ -9863,10 +9945,20 @@ class PrivateFileInputError extends Error {
|
|
|
9863
9945
|
constructor(reason, limit) {
|
|
9864
9946
|
super({
|
|
9865
9947
|
filesystem: "use a local ext4, XFS, Btrfs, or tmpfs filesystem",
|
|
9948
|
+
native: "Jig could not load its Linux file controls; check the supported glibc loader and libc installation",
|
|
9949
|
+
mount: "the selected attachment mount could not be identified; check that it is visible in the process mount namespace",
|
|
9950
|
+
symlink: "the selected attachment contains a symbolic link; select a directory and files without links",
|
|
9951
|
+
missing: "the selected attachment directory or file does not exist; check --attach and --select",
|
|
9952
|
+
access: "the selected attachment cannot be read by the current operator; check its file and directory permissions",
|
|
9953
|
+
"cross-mount": "the selected attachment crosses a mount boundary; select each mounted directory separately",
|
|
9954
|
+
kernel: "the kernel does not provide the required Linux file controls; check the supported-host requirements",
|
|
9866
9955
|
path: "select a relative path without traversal or links, within 16 components and 512 UTF-8 bytes",
|
|
9867
9956
|
protected: "Jig state and host control files cannot be selected as input",
|
|
9868
9957
|
linked: "select only singly linked regular files",
|
|
9958
|
+
"input-link": "the selected --input file cannot be a symbolic link",
|
|
9959
|
+
regular: "select a regular input file, not a directory or special file",
|
|
9869
9960
|
changed: "selected input changed during capture; capture a stable source tree",
|
|
9961
|
+
"input-changed": "the selected --input file changed during capture; retry with a stable file",
|
|
9870
9962
|
bytes: `selected file exceeds the remaining ${limit ?? 0}-byte input budget; select less data`,
|
|
9871
9963
|
files: "input exceeds 64 files; narrow the selection with --select",
|
|
9872
9964
|
entries: "input exceeds 256 tree entries; narrow the selection with --select",
|
|
@@ -9883,22 +9975,35 @@ function calls() {
|
|
|
9883
9975
|
if (process.platform !== "linux" || process.arch !== "x64")
|
|
9884
9976
|
throw new Error("Linux x64 file controls are unavailable");
|
|
9885
9977
|
const ffi = createRequire(import.meta.url)("bun:ffi");
|
|
9886
|
-
|
|
9887
|
-
|
|
9888
|
-
|
|
9889
|
-
|
|
9890
|
-
|
|
9891
|
-
|
|
9892
|
-
|
|
9893
|
-
|
|
9894
|
-
|
|
9895
|
-
|
|
9978
|
+
try {
|
|
9979
|
+
const libc = posix.join(dirname(resolvePrivateLinuxHostLoaderSync()), "libc.so.6");
|
|
9980
|
+
const { symbols } = ffi.dlopen(libc, {
|
|
9981
|
+
syscall: { args: ["i64", "i32", "ptr", "ptr", "u64"], returns: "i32" },
|
|
9982
|
+
memfd_create: { args: ["ptr", "u32"], returns: "i32" },
|
|
9983
|
+
fcntl: { args: ["i32", "i32", "i32"], returns: "i32" },
|
|
9984
|
+
renameat2: { args: ["i32", "ptr", "i32", "ptr", "u32"], returns: "i32" },
|
|
9985
|
+
__errno_location: { args: [], returns: "ptr" }
|
|
9986
|
+
});
|
|
9987
|
+
native = { ffi, symbols };
|
|
9988
|
+
return native;
|
|
9989
|
+
} catch {
|
|
9990
|
+
throw new PrivateFileInputError("native");
|
|
9991
|
+
}
|
|
9896
9992
|
}
|
|
9897
9993
|
function result(value) {
|
|
9898
9994
|
if (value >= 0)
|
|
9899
9995
|
return value;
|
|
9900
9996
|
const { ffi, symbols } = calls();
|
|
9901
9997
|
const code = getSystemErrorName(-ffi.read.i32(symbols.__errno_location()));
|
|
9998
|
+
const reason = {
|
|
9999
|
+
ELOOP: "symlink",
|
|
10000
|
+
ENOENT: "missing",
|
|
10001
|
+
EACCES: "access",
|
|
10002
|
+
EXDEV: "cross-mount",
|
|
10003
|
+
ENOSYS: "kernel"
|
|
10004
|
+
};
|
|
10005
|
+
if (Object.hasOwn(reason, code))
|
|
10006
|
+
throw new PrivateFileInputError(reason[code]);
|
|
9902
10007
|
throw Object.assign(new Error(`file boundary operation failed (${code})`), { code });
|
|
9903
10008
|
}
|
|
9904
10009
|
function cString(value) {
|
|
@@ -9944,12 +10049,12 @@ function privateOpenFileRoot(path) {
|
|
|
9944
10049
|
const mount = readFileSync("/proc/self/mountinfo", "utf8").split(`
|
|
9945
10050
|
`).find((line) => line.split(" ")[0] === mountId)?.split(" ");
|
|
9946
10051
|
if (mount === undefined)
|
|
9947
|
-
throw new
|
|
10052
|
+
throw new PrivateFileInputError("mount");
|
|
9948
10053
|
const decodeMountPath = (text) => text.replace(/\\([0-7]{3})/g, (_, octal) => String.fromCharCode(parseInt(octal, 8)));
|
|
9949
10054
|
const root = decodeMountPath(mount[3]), point = decodeMountPath(mount[4]);
|
|
9950
10055
|
const relative = posix.relative(point, absolute);
|
|
9951
10056
|
if (relative.startsWith("../") || posix.isAbsolute(relative))
|
|
9952
|
-
throw new
|
|
10057
|
+
throw new PrivateFileInputError("mount");
|
|
9953
10058
|
requireUnprotected(posix.join(root, relative));
|
|
9954
10059
|
return fd;
|
|
9955
10060
|
} catch (error) {
|
|
@@ -9986,6 +10091,39 @@ function privateReadRegularFile(parent, path, maxBytes) {
|
|
|
9986
10091
|
closeSync(fd);
|
|
9987
10092
|
}
|
|
9988
10093
|
}
|
|
10094
|
+
function privateReadOperatorFile(path, maxBytes) {
|
|
10095
|
+
let fd;
|
|
10096
|
+
try {
|
|
10097
|
+
fd = openSync(path, constants.O_RDONLY | constants.O_NONBLOCK | O_CLOEXEC | constants.O_NOFOLLOW);
|
|
10098
|
+
} catch (error) {
|
|
10099
|
+
if (error.code === "ELOOP") {
|
|
10100
|
+
throw new PrivateFileInputError("input-link");
|
|
10101
|
+
}
|
|
10102
|
+
throw error;
|
|
10103
|
+
}
|
|
10104
|
+
try {
|
|
10105
|
+
const before = fstatSync(fd, { bigint: true });
|
|
10106
|
+
if (!before.isFile())
|
|
10107
|
+
throw new PrivateFileInputError("regular");
|
|
10108
|
+
if (before.size > BigInt(maxBytes))
|
|
10109
|
+
throw new PrivateFileInputError("bytes", maxBytes);
|
|
10110
|
+
const bytes = Buffer.alloc(Number(before.size) + 1);
|
|
10111
|
+
let offset = 0;
|
|
10112
|
+
while (offset < bytes.length) {
|
|
10113
|
+
const count = readSync(fd, bytes, offset, bytes.length - offset, null);
|
|
10114
|
+
if (count === 0)
|
|
10115
|
+
break;
|
|
10116
|
+
offset += count;
|
|
10117
|
+
}
|
|
10118
|
+
const after = fstatSync(fd, { bigint: true });
|
|
10119
|
+
if (offset !== Number(before.size) || after.size !== before.size || after.mtimeNs !== before.mtimeNs || after.ctimeNs !== before.ctimeNs) {
|
|
10120
|
+
throw new PrivateFileInputError("input-changed");
|
|
10121
|
+
}
|
|
10122
|
+
return bytes.subarray(0, offset);
|
|
10123
|
+
} finally {
|
|
10124
|
+
closeSync(fd);
|
|
10125
|
+
}
|
|
10126
|
+
}
|
|
9989
10127
|
function privateCaptureAttachments(selections) {
|
|
9990
10128
|
const attachments = [];
|
|
9991
10129
|
const opened = [];
|
|
@@ -10141,28 +10279,6 @@ import { execFile } from "child_process";
|
|
|
10141
10279
|
import { constants as constants2 } from "fs";
|
|
10142
10280
|
import { access, readFile, readdir, realpath as realpath2, stat, statfs } from "fs/promises";
|
|
10143
10281
|
import { posix as posix2 } from "path";
|
|
10144
|
-
|
|
10145
|
-
// src/internal/linux-host-paths.ts
|
|
10146
|
-
import { realpath } from "fs/promises";
|
|
10147
|
-
function privateLinuxHostToolCandidates(name) {
|
|
10148
|
-
return [`/usr/bin/${name}`, `/bin/${name}`, `/run/current-system/sw/bin/${name}`];
|
|
10149
|
-
}
|
|
10150
|
-
async function resolvePrivateLinuxHostPath(candidates, resolve3 = realpath) {
|
|
10151
|
-
for (const path of candidates) {
|
|
10152
|
-
try {
|
|
10153
|
-
return await resolve3(path);
|
|
10154
|
-
} catch (error) {
|
|
10155
|
-
if (error.code !== "ENOENT")
|
|
10156
|
-
throw error;
|
|
10157
|
-
}
|
|
10158
|
-
}
|
|
10159
|
-
throw new Error("the required system-owned host file is unavailable");
|
|
10160
|
-
}
|
|
10161
|
-
function resolvePrivateLinuxHostLoader(resolve3 = realpath) {
|
|
10162
|
-
return resolvePrivateLinuxHostPath(["/run/current-system/sw/share/nix-ld/lib/ld.so", "/lib64/ld-linux-x86-64.so.2"], resolve3);
|
|
10163
|
-
}
|
|
10164
|
-
|
|
10165
|
-
// src/internal/linux-rootless-acquisition.ts
|
|
10166
10282
|
var CGROUP_ROOT = "/sys/fs/cgroup";
|
|
10167
10283
|
var CGROUP2_SUPER_MAGIC = 0x6367_7270n;
|
|
10168
10284
|
var MAX_PROCESS_OUTPUT_BYTES = 16 * 1024;
|
|
@@ -10644,7 +10760,7 @@ class PrivateLinuxCgroupBackend {
|
|
|
10644
10760
|
});
|
|
10645
10761
|
const cancel = () => writeControlBestEffort(control, { type: "cancel" });
|
|
10646
10762
|
signal?.addEventListener("abort", cancel, { once: true });
|
|
10647
|
-
const preparedMessage = requireSupervisorMessage(await withTimeout(
|
|
10763
|
+
const preparedMessage = requireSupervisorMessage(await withTimeout(readPrivateSupervisorMessage(messages, closed), this.#options.startupTimeoutMs, "rootless preparation"), "prepared");
|
|
10648
10764
|
preparedReached = true;
|
|
10649
10765
|
requirePreparedMessage(preparedMessage, data);
|
|
10650
10766
|
await requirePreparedCgroup(data);
|
|
@@ -10653,7 +10769,7 @@ class PrivateLinuxCgroupBackend {
|
|
|
10653
10769
|
if (signal?.aborted)
|
|
10654
10770
|
throw new Error("rootless Linux Run was cancelled before admission");
|
|
10655
10771
|
writeControl(control, { type: "admit" });
|
|
10656
|
-
const ready = requireSupervisorMessage(await withTimeout(
|
|
10772
|
+
const ready = requireSupervisorMessage(await withTimeout(readPrivateSupervisorMessage(messages, closed), this.#options.startupTimeoutMs, "rootless readiness"), "ready");
|
|
10657
10773
|
requireReadyMessage(ready, preparedMessage, data);
|
|
10658
10774
|
if (ready.supervisorPid !== supervisor.pid)
|
|
10659
10775
|
throw new Error("output owner identity changed");
|
|
@@ -11903,21 +12019,20 @@ function requireSupervisorMessage(value, type) {
|
|
|
11903
12019
|
}
|
|
11904
12020
|
return message;
|
|
11905
12021
|
}
|
|
11906
|
-
async function
|
|
12022
|
+
async function readPrivateSupervisorMessage(iterator, closed) {
|
|
12023
|
+
const pending = iterator.next().then((next) => {
|
|
12024
|
+
if (next.done)
|
|
12025
|
+
throw new Error("rootless supervisor control closed");
|
|
12026
|
+
return next.value;
|
|
12027
|
+
});
|
|
11907
12028
|
return await Promise.race([
|
|
11908
|
-
|
|
11909
|
-
|
|
11910
|
-
throw new Error("rootless supervisor control closed");
|
|
11911
|
-
return next.value;
|
|
11912
|
-
}),
|
|
11913
|
-
closed.then((exit) => {
|
|
11914
|
-
throw new Error(`rootless supervisor exited before completing (${exit.code ?? exit.signal})`);
|
|
11915
|
-
})
|
|
12029
|
+
pending,
|
|
12030
|
+
closed.then(() => withTimeout(pending, 1000, "rootless supervisor final channel drain"))
|
|
11916
12031
|
]);
|
|
11917
12032
|
}
|
|
11918
12033
|
async function waitForTerminal(iterator, closed) {
|
|
11919
12034
|
for (;; ) {
|
|
11920
|
-
const value = await
|
|
12035
|
+
const value = await readPrivateSupervisorMessage(iterator, closed);
|
|
11921
12036
|
if (dataType(value) === "terminal")
|
|
11922
12037
|
return normalizeFinal(value);
|
|
11923
12038
|
}
|
|
@@ -12194,6 +12309,7 @@ class PrivateRootRunFiles {
|
|
|
12194
12309
|
settings: request.settings,
|
|
12195
12310
|
capabilities: request.capabilities,
|
|
12196
12311
|
flowSlots: request.flowSlots,
|
|
12312
|
+
...request.commands === undefined ? {} : { commands: request.commands },
|
|
12197
12313
|
attachments: request.attachments
|
|
12198
12314
|
})))
|
|
12199
12315
|
});
|
|
@@ -12340,15 +12456,11 @@ async function executeRun(arguments_, runtime) {
|
|
|
12340
12456
|
try {
|
|
12341
12457
|
if (parsed.inputFile !== undefined) {
|
|
12342
12458
|
const path = resolve3(runtime.currentDirectory, parsed.inputFile);
|
|
12343
|
-
|
|
12344
|
-
try {
|
|
12345
|
-
input = decodeJson1(privateReadRegularFile(parent, basename(path), JSON_1_LIMITS.bytes));
|
|
12346
|
-
} finally {
|
|
12347
|
-
closeSync2(parent);
|
|
12348
|
-
}
|
|
12459
|
+
input = decodeJson1(privateReadOperatorFile(path, JSON_1_LIMITS.bytes));
|
|
12349
12460
|
}
|
|
12350
12461
|
} catch (error) {
|
|
12351
|
-
|
|
12462
|
+
const message = error instanceof PrivateFileInputError ? error.message : error instanceof Json1Error ? `the selected --input file is not FLOW JSON/1: ${error.message}` : error.code === "ENOENT" ? "the selected --input file does not exist" : error.code === "EACCES" ? "the selected --input file is not readable by the current operator" : "--input file capture failed; check that it is a stable, readable regular file";
|
|
12463
|
+
throw new CliDiagnostic("JIG_RUN_INPUT_INVALID", message, 1);
|
|
12352
12464
|
}
|
|
12353
12465
|
let capture;
|
|
12354
12466
|
try {
|
|
@@ -12676,7 +12788,7 @@ function renderFailure(error, runtime) {
|
|
|
12676
12788
|
}
|
|
12677
12789
|
if (error instanceof ProjectAdministrationError) {
|
|
12678
12790
|
const projected = projectError(error.code);
|
|
12679
|
-
const hint = error.diagnostic?.code === "PROJECT_AGENT_UNAVAILABLE" ? runtime.host.agentUnavailableHint ?? "configure the host Agent before review; check exported credentials, model, and selected client" : error.diagnostic?.code === "PACKAGE_BUN_NODE_MODULES" ? "move generated node_modules outside the Flow package; jig review prepares its locked production dependencies" : error.diagnostic?.code === "PACKAGE_BUN_PREPARATION_FAILED" ? "locked dependencies could not be prepared; check registry access and package availability" : undefined;
|
|
12791
|
+
const hint = error.diagnostic?.code === "PROJECT_AGENT_UNAVAILABLE" ? runtime.host.agentUnavailableHint ?? "configure the host Agent before review; check exported credentials, model, and selected client" : error.diagnostic?.code === "PROJECT_COMMAND_UNCONFIGURED" ? "select a Binding with reviewed commands for this Flow" : error.diagnostic?.code === "PACKAGE_BUN_NODE_MODULES" ? "move generated node_modules outside the Flow package; jig review prepares its locked production dependencies" : error.diagnostic?.code === "PACKAGE_BUN_PREPARATION_FAILED" ? "locked dependencies could not be prepared; check registry access and package availability" : undefined;
|
|
12680
12792
|
runtime.writeError(error.diagnostic !== undefined ? renderProjectDiagnostic(error, hint ?? projected.message) : renderDiagnostic(error.code, projected.message));
|
|
12681
12793
|
return projected.exitCode;
|
|
12682
12794
|
}
|
|
@@ -12759,9 +12871,9 @@ import { randomBytes as randomBytes4 } from "crypto";
|
|
|
12759
12871
|
import { connect, createServer as createServer2 } from "net";
|
|
12760
12872
|
|
|
12761
12873
|
// src/internal/file-delivery.ts
|
|
12762
|
-
import { closeSync as
|
|
12874
|
+
import { closeSync as closeSync2, fstatSync as fstatSync2, lstatSync, mkdirSync, opendirSync as opendirSync2 } from "fs";
|
|
12763
12875
|
import { mkdir as mkdir3, open as open2, rm as rm2, statfs as statfs3 } from "fs/promises";
|
|
12764
|
-
import { basename
|
|
12876
|
+
import { basename, dirname as dirname3, resolve as resolve4 } from "path";
|
|
12765
12877
|
import { randomBytes as randomBytes3 } from "crypto";
|
|
12766
12878
|
class PrivateFileDeliveryOwner {
|
|
12767
12879
|
signal;
|
|
@@ -12785,7 +12897,7 @@ class PrivateFileDeliveryOwner {
|
|
|
12785
12897
|
let parent;
|
|
12786
12898
|
try {
|
|
12787
12899
|
this.signal.throwIfAborted();
|
|
12788
|
-
const destination = resolve4(directory), parentPath =
|
|
12900
|
+
const destination = resolve4(directory), parentPath = dirname3(destination), leaf = privateFilePath(basename(destination));
|
|
12789
12901
|
if (destination === parentPath || leaf.includes("/"))
|
|
12790
12902
|
throw new TypeError("output requires a new directory");
|
|
12791
12903
|
parent = privateOpenFileRoot(parentPath);
|
|
@@ -12810,7 +12922,7 @@ class PrivateFileDeliveryOwner {
|
|
|
12810
12922
|
this.#destination = destination;
|
|
12811
12923
|
} finally {
|
|
12812
12924
|
if (parent !== undefined)
|
|
12813
|
-
|
|
12925
|
+
closeSync2(parent);
|
|
12814
12926
|
this.#preparing = false;
|
|
12815
12927
|
}
|
|
12816
12928
|
}
|
|
@@ -12868,7 +12980,7 @@ class PrivateFileDeliveryOwner {
|
|
|
12868
12980
|
} finally {
|
|
12869
12981
|
directory.closeSync();
|
|
12870
12982
|
if (fd !== output.fd)
|
|
12871
|
-
|
|
12983
|
+
closeSync2(fd);
|
|
12872
12984
|
}
|
|
12873
12985
|
};
|
|
12874
12986
|
walk("");
|
|
@@ -12892,7 +13004,7 @@ class PrivateFileDeliveryOwner {
|
|
|
12892
13004
|
for (const file of files) {
|
|
12893
13005
|
checkTime();
|
|
12894
13006
|
const destination = `${stagePath}/files/${file.path}`;
|
|
12895
|
-
await mkdir3(
|
|
13007
|
+
await mkdir3(dirname3(destination), { recursive: true, mode: 448 });
|
|
12896
13008
|
const handle = await open2(destination, "wx", 384);
|
|
12897
13009
|
try {
|
|
12898
13010
|
await handle.writeFile(file.contents);
|
|
@@ -12936,7 +13048,7 @@ class PrivateFileDeliveryOwner {
|
|
|
12936
13048
|
async close() {
|
|
12937
13049
|
await this.#cleanupStage();
|
|
12938
13050
|
if (this.#parent !== undefined) {
|
|
12939
|
-
|
|
13051
|
+
closeSync2(this.#parent);
|
|
12940
13052
|
this.#parent = undefined;
|
|
12941
13053
|
}
|
|
12942
13054
|
}
|
|
@@ -12947,7 +13059,7 @@ class PrivateFileDeliveryOwner {
|
|
|
12947
13059
|
if (before.dev !== after.dev || before.ino !== after.ino)
|
|
12948
13060
|
throw new Error("destination parent changed");
|
|
12949
13061
|
} finally {
|
|
12950
|
-
|
|
13062
|
+
closeSync2(current);
|
|
12951
13063
|
}
|
|
12952
13064
|
}
|
|
12953
13065
|
async#cleanupStage() {
|
|
@@ -12981,14 +13093,14 @@ function directoryContains(root, candidate) {
|
|
|
12981
13093
|
return true;
|
|
12982
13094
|
const next = privateOpenAt(current, "..", 2097152 | 65536, false);
|
|
12983
13095
|
const parent = fstatSync2(next, { bigint: true });
|
|
12984
|
-
|
|
13096
|
+
closeSync2(current);
|
|
12985
13097
|
current = next;
|
|
12986
13098
|
if (parent.dev === info.dev && parent.ino === info.ino)
|
|
12987
13099
|
return false;
|
|
12988
13100
|
}
|
|
12989
13101
|
throw new Error("output ancestry exceeds limit");
|
|
12990
13102
|
} finally {
|
|
12991
|
-
|
|
13103
|
+
closeSync2(current);
|
|
12992
13104
|
}
|
|
12993
13105
|
}
|
|
12994
13106
|
|
|
@@ -13204,7 +13316,7 @@ async function* messages(socket) {
|
|
|
13204
13316
|
|
|
13205
13317
|
// src/internal/claude-agent-provider.ts
|
|
13206
13318
|
import { lstat as lstat3, realpath as realpath5 } from "fs/promises";
|
|
13207
|
-
import { dirname as
|
|
13319
|
+
import { dirname as dirname4, join as join3 } from "path";
|
|
13208
13320
|
|
|
13209
13321
|
// src/internal/acp-agent-provider.ts
|
|
13210
13322
|
import { constants as constants3 } from "fs";
|
|
@@ -14627,7 +14739,7 @@ async function openPrivateClaudeAgentProvider(releaseRoot, environment = process
|
|
|
14627
14739
|
adapterPath: join3(releaseRoot, "libexec", "agent", "claude-agent-acp.js"),
|
|
14628
14740
|
executablePath,
|
|
14629
14741
|
certificatesPath: await ordinaryFile(HOST_CERTIFICATES_PATH, "host certificate bundle"),
|
|
14630
|
-
runtimeLibraryPath: await ordinaryFile(join3(
|
|
14742
|
+
runtimeLibraryPath: await ordinaryFile(join3(dirname4(await resolvePrivateLinuxHostLoader()), "librt.so.1"), "Claude runtime library")
|
|
14631
14743
|
});
|
|
14632
14744
|
const apiKey = environment.ANTHROPIC_API_KEY;
|
|
14633
14745
|
const authToken = environment.ANTHROPIC_AUTH_TOKEN;
|
|
@@ -14814,6 +14926,15 @@ var MAX_CREDENTIAL_BYTES = 64 * 1024 - 4;
|
|
|
14814
14926
|
var MAX_SECRET_BYTES = 16 * 1024;
|
|
14815
14927
|
var MAX_BASE_URL_CHARACTERS2 = 4096;
|
|
14816
14928
|
var encoder5 = new TextEncoder;
|
|
14929
|
+
|
|
14930
|
+
class PrivateCodexLoginUnavailableError extends Error {
|
|
14931
|
+
}
|
|
14932
|
+
|
|
14933
|
+
class PrivateCodexExecutableUnavailableError extends Error {
|
|
14934
|
+
}
|
|
14935
|
+
|
|
14936
|
+
class PrivateCodexSandboxUnavailableError extends Error {
|
|
14937
|
+
}
|
|
14817
14938
|
var decoder2 = new TextDecoder("utf-8", { fatal: true });
|
|
14818
14939
|
var OPENAI_API_KEY = "OPENAI_API_KEY";
|
|
14819
14940
|
var OPENAI_MODEL = "OPENAI_MODEL";
|
|
@@ -14831,15 +14952,12 @@ var PRIVATE_CODEX_REQUIREMENTS = [
|
|
|
14831
14952
|
].join(`
|
|
14832
14953
|
`);
|
|
14833
14954
|
async function openPrivateCodexAgentProvider(releaseRoot, environment = process.env) {
|
|
14834
|
-
const executablePath = environment.CODEX_PATH;
|
|
14835
|
-
if (executablePath === undefined || executablePath.length === 0) {
|
|
14836
|
-
throw new Error("the native Codex executable is unavailable");
|
|
14837
|
-
}
|
|
14955
|
+
const executablePath = await resolveCodexExecutable(environment.CODEX_PATH);
|
|
14838
14956
|
const support = Object.freeze({
|
|
14839
14957
|
launcherPath: join4(releaseRoot, "libexec", "agent", "codex-agent-launcher.js"),
|
|
14840
14958
|
adapterPath: join4(releaseRoot, "libexec", "agent", "codex-acp.js"),
|
|
14841
14959
|
executablePath,
|
|
14842
|
-
nativeBubblewrapPath: await nativeBubblewrapFor(executablePath),
|
|
14960
|
+
nativeBubblewrapPath: await nativeBubblewrapFor(executablePath, environment.JIG_BWRAP_PATH),
|
|
14843
14961
|
certificatesPath: await ordinaryFile2(HOST_CERTIFICATES_PATH2, "host certificate bundle"),
|
|
14844
14962
|
requirementsPath: join4(releaseRoot, "libexec", "agent", "codex-requirements.toml")
|
|
14845
14963
|
});
|
|
@@ -14862,7 +14980,12 @@ async function openPrivateCodexAgentProvider(releaseRoot, environment = process.
|
|
|
14862
14980
|
});
|
|
14863
14981
|
}
|
|
14864
14982
|
const sourceHome = environment.CODEX_HOME ?? join4(homedir(), ".codex");
|
|
14865
|
-
|
|
14983
|
+
let credential;
|
|
14984
|
+
try {
|
|
14985
|
+
credential = await projectPrivateCodexSubscriptionCredential(join4(sourceHome, "auth.json"));
|
|
14986
|
+
} catch {
|
|
14987
|
+
throw new PrivateCodexLoginUnavailableError("Codex file-backed login is unavailable");
|
|
14988
|
+
}
|
|
14866
14989
|
return await createPrivateCodexSubscriptionAgentProvider({
|
|
14867
14990
|
...support,
|
|
14868
14991
|
credential,
|
|
@@ -15031,12 +15154,51 @@ function codexEnvironment(subscription, model) {
|
|
|
15031
15154
|
SSL_CERT_FILE: SANDBOX_CERTIFICATES_PATH2
|
|
15032
15155
|
});
|
|
15033
15156
|
}
|
|
15034
|
-
async function
|
|
15035
|
-
|
|
15036
|
-
|
|
15037
|
-
|
|
15157
|
+
async function resolveCodexExecutable(selected) {
|
|
15158
|
+
if (selected !== undefined && (!selected.startsWith("/") || selected.includes("\x00"))) {
|
|
15159
|
+
throw new PrivateCodexExecutableUnavailableError("CODEX_PATH must be an absolute executable path");
|
|
15160
|
+
}
|
|
15161
|
+
try {
|
|
15162
|
+
const path = await resolvePrivateLinuxHostPath(selected === undefined ? privateLinuxHostToolCandidates("codex") : [selected]);
|
|
15163
|
+
const information = await lstat4(path);
|
|
15164
|
+
if (!information.isFile() || information.isSymbolicLink() || (information.mode & 73) === 0) {
|
|
15165
|
+
throw new PrivateCodexExecutableUnavailableError("the native Codex executable is invalid");
|
|
15166
|
+
}
|
|
15167
|
+
return path;
|
|
15168
|
+
} catch (error) {
|
|
15169
|
+
if (error instanceof PrivateCodexExecutableUnavailableError)
|
|
15170
|
+
throw error;
|
|
15171
|
+
throw new PrivateCodexExecutableUnavailableError("the native Codex executable is unavailable");
|
|
15172
|
+
}
|
|
15173
|
+
}
|
|
15174
|
+
async function nativeBubblewrapFor(executablePath, selected) {
|
|
15175
|
+
if (selected !== undefined && (!selected.startsWith("/") || selected.includes("\x00"))) {
|
|
15176
|
+
throw new PrivateCodexSandboxUnavailableError("JIG_BWRAP_PATH must be an absolute executable path");
|
|
15177
|
+
}
|
|
15178
|
+
try {
|
|
15179
|
+
let path;
|
|
15180
|
+
if (selected !== undefined) {
|
|
15181
|
+
path = await resolvePrivateLinuxHostPath([selected]);
|
|
15182
|
+
} else {
|
|
15183
|
+
const adjacent = join4(executablePath, "..", "..", "codex-resources", "bwrap");
|
|
15184
|
+
try {
|
|
15185
|
+
path = await exactFile2(adjacent, "Codex native Bubblewrap");
|
|
15186
|
+
} catch (error) {
|
|
15187
|
+
if (error.code !== "ENOENT")
|
|
15188
|
+
throw error;
|
|
15189
|
+
path = await resolvePrivateLinuxHostPath(privateLinuxHostToolCandidates("bwrap"));
|
|
15190
|
+
}
|
|
15191
|
+
}
|
|
15192
|
+
const information = await lstat4(path);
|
|
15193
|
+
if (!information.isFile() || information.isSymbolicLink() || (information.mode & 3072) !== 0 || (information.mode & 73) === 0) {
|
|
15194
|
+
throw new PrivateCodexSandboxUnavailableError("Codex native Bubblewrap is invalid");
|
|
15195
|
+
}
|
|
15196
|
+
return path;
|
|
15197
|
+
} catch (error) {
|
|
15198
|
+
if (error instanceof PrivateCodexSandboxUnavailableError)
|
|
15199
|
+
throw error;
|
|
15200
|
+
throw new PrivateCodexSandboxUnavailableError("Codex native Bubblewrap is unavailable");
|
|
15038
15201
|
}
|
|
15039
|
-
return path;
|
|
15040
15202
|
}
|
|
15041
15203
|
async function ordinaryFile2(path, label) {
|
|
15042
15204
|
const exact = await realpath6(path);
|
|
@@ -15143,7 +15305,7 @@ function requireBaseURL2(value) {
|
|
|
15143
15305
|
// src/internal/installed-bun-support.ts
|
|
15144
15306
|
import { constants as constants4 } from "fs";
|
|
15145
15307
|
import { access as access3, lstat as lstat5, realpath as realpath7 } from "fs/promises";
|
|
15146
|
-
import { dirname as
|
|
15308
|
+
import { dirname as dirname5, join as join5 } from "path";
|
|
15147
15309
|
var ELF_INTERPRETER = "/lib64/ld-linux-x86-64.so.2";
|
|
15148
15310
|
var LIBRARIES = Object.freeze([
|
|
15149
15311
|
"libc.so.6",
|
|
@@ -15193,7 +15355,7 @@ async function openPrivateInstalledBunSupport(location) {
|
|
|
15193
15355
|
const preparationWorkerPath = await exactRegularFile(join5(releaseRoot, "libexec", "preparation", "bun-native-preparation-worker.js"), false, "installed Bun preparation worker");
|
|
15194
15356
|
const agentWorkerPath = await exactRegularFile(join5(releaseRoot, "libexec", "agent", "openai-agent-worker.js"), false, "installed Agent provider worker");
|
|
15195
15357
|
const loaderPath = await exactRegularFile(await resolvePrivateLinuxHostLoader(), true, "supported-host ELF interpreter");
|
|
15196
|
-
const hostLibraryDirectory =
|
|
15358
|
+
const hostLibraryDirectory = dirname5(loaderPath);
|
|
15197
15359
|
const libraries = await Promise.all(LIBRARIES.map(async (name) => Object.freeze({
|
|
15198
15360
|
name,
|
|
15199
15361
|
path: await exactRegularFile(join5(hostLibraryDirectory, name), false, `supported-host library ${name}`)
|
|
@@ -15588,7 +15750,7 @@ function requireApi(value) {
|
|
|
15588
15750
|
import { constants as constants5 } from "fs";
|
|
15589
15751
|
import { access as access4, lstat as lstat6, readFile as readFile4, realpath as realpath8 } from "fs/promises";
|
|
15590
15752
|
import { homedir as homedir2 } from "os";
|
|
15591
|
-
import { dirname as
|
|
15753
|
+
import { dirname as dirname6, join as join6, resolve as resolve5 } from "path";
|
|
15592
15754
|
var PI_CLIENT = "pi";
|
|
15593
15755
|
var SANDBOX_LAUNCHER_PATH3 = "/agent/pi-agent-launcher.js";
|
|
15594
15756
|
var SANDBOX_ADAPTER_PATH3 = "/agent/pi-acp.js";
|
|
@@ -15613,7 +15775,7 @@ async function openPrivatePiAgentProvider(releaseRoot, environment = process.env
|
|
|
15613
15775
|
throw new Error("the native Pi executable is unavailable");
|
|
15614
15776
|
}
|
|
15615
15777
|
const executablePath = await executableFile(executable, "native Pi executable");
|
|
15616
|
-
const nativeRoot =
|
|
15778
|
+
const nativeRoot = dirname6(executablePath);
|
|
15617
15779
|
const manifestPath = await piManifestFile(join6(nativeRoot, "package.json"));
|
|
15618
15780
|
const support = Object.freeze({
|
|
15619
15781
|
launcherPath: join6(releaseRoot, "libexec", "agent", "pi-agent-launcher.js"),
|
|
@@ -15926,6 +16088,7 @@ async function readCredentialFile(path) {
|
|
|
15926
16088
|
|
|
15927
16089
|
// src/internal/installed-bun-host.ts
|
|
15928
16090
|
var AGENT_CLIENT = "JIG_AGENT_CLIENT";
|
|
16091
|
+
var OPENROUTER_BASE_URL = "https://openrouter.ai/api/v1";
|
|
15929
16092
|
async function openPrivateInstalledBunHost(location, environment = process.env) {
|
|
15930
16093
|
const installedBunSupport = await openPrivateInstalledBunSupport(location);
|
|
15931
16094
|
const agent = await tryOpenAgentProvider(installedBunSupport, environment);
|
|
@@ -15946,21 +16109,39 @@ async function tryOpenAgentProvider(installedBunSupport, environment) {
|
|
|
15946
16109
|
return {
|
|
15947
16110
|
agentUnavailableHint: "JIG_AGENT_CLIENT must be codex, claude, or pi; unset it to use the configured API endpoint"
|
|
15948
16111
|
};
|
|
16112
|
+
let selectedEnvironment = environment;
|
|
16113
|
+
let openRouter = false;
|
|
15949
16114
|
if (client === undefined) {
|
|
15950
|
-
const
|
|
16115
|
+
const hasOpenRouter = ["OPENROUTER_API_KEY", "OPENROUTER_MODEL"].some((key) => environment[key] !== undefined);
|
|
16116
|
+
const hasOpenAI = ["OPENAI_API_KEY", "OPENAI_MODEL", "OPENAI_BASE_URL", "OPENAI_API"].some((key) => environment[key] !== undefined);
|
|
16117
|
+
if (hasOpenRouter && hasOpenAI)
|
|
16118
|
+
return {
|
|
16119
|
+
agentUnavailableHint: "choose either OPENROUTER_API_KEY and OPENROUTER_MODEL, or the OPENAI_* endpoint variables; unset the other family before jig review"
|
|
16120
|
+
};
|
|
16121
|
+
openRouter = hasOpenRouter;
|
|
16122
|
+
const required = openRouter ? ["OPENROUTER_API_KEY", "OPENROUTER_MODEL"] : ["OPENAI_API_KEY", "OPENAI_MODEL"];
|
|
16123
|
+
const missing = required.filter((key) => environment[key] === undefined);
|
|
15951
16124
|
if (missing.length > 0)
|
|
15952
16125
|
return {
|
|
15953
|
-
agentUnavailableHint: `export ${missing.join(" and ")} before jig review; Jig reads operator configuration, not project .env files`
|
|
16126
|
+
agentUnavailableHint: !hasOpenRouter && !hasOpenAI ? "export OPENROUTER_API_KEY and OPENROUTER_MODEL, or OPENAI_API_KEY and OPENAI_MODEL, before jig review; Jig reads operator configuration, not project .env files" : `export ${missing.join(" and ")} before jig review; Jig reads operator configuration, not project .env files`
|
|
15954
16127
|
};
|
|
16128
|
+
if (openRouter)
|
|
16129
|
+
selectedEnvironment = Object.freeze({
|
|
16130
|
+
...environment,
|
|
16131
|
+
OPENAI_API_KEY: environment.OPENROUTER_API_KEY,
|
|
16132
|
+
OPENAI_MODEL: environment.OPENROUTER_MODEL,
|
|
16133
|
+
OPENAI_BASE_URL: OPENROUTER_BASE_URL,
|
|
16134
|
+
OPENAI_API: "chat-completions"
|
|
16135
|
+
});
|
|
15955
16136
|
}
|
|
15956
16137
|
try {
|
|
15957
|
-
const agentProvider = client === undefined ? openPrivateOpenAIAgentProvider(installedBunSupport,
|
|
16138
|
+
const agentProvider = client === undefined ? openPrivateOpenAIAgentProvider(installedBunSupport, selectedEnvironment) : client === "codex" ? await openPrivateCodexAgentProvider(installedBunSupport.releaseRoot, selectedEnvironment) : client === "claude" ? await openPrivateClaudeAgentProvider(installedBunSupport.releaseRoot, environment) : client === "pi" ? await openPrivatePiAgentProvider(installedBunSupport.releaseRoot, environment) : (() => {
|
|
15958
16139
|
throw new Error("the native Agent client is unsupported");
|
|
15959
16140
|
})();
|
|
15960
16141
|
return { agentProvider };
|
|
15961
16142
|
} catch (error) {
|
|
15962
16143
|
return {
|
|
15963
|
-
agentUnavailableHint: error instanceof PrivateAgentConfigurationError ? `correct the exported ${error.field} value before jig review` : client === undefined ? "the API Agent could not be opened; check the installed support assets and exported configuration" : `the selected ${client} client could not be opened; check its executable and exported host configuration`
|
|
16144
|
+
agentUnavailableHint: error instanceof PrivateCodexExecutableUnavailableError ? "export CODEX_PATH with the absolute path of this operator's installed codex executable, then retry jig review" : error instanceof PrivateCodexSandboxUnavailableError ? "install Bubblewrap in a fixed system location or export its absolute JIG_BWRAP_PATH, then retry jig review" : error instanceof PrivateCodexLoginUnavailableError ? 'configure Codex with cli_auth_credentials_store="file", run codex login as this OS user, and retry jig review; Jig reads CODEX_HOME/auth.json or ~/.codex/auth.json' : error instanceof PrivateAgentConfigurationError ? `correct the exported ${openRouter ? error.field === "OPENAI_API_KEY" ? "OPENROUTER_API_KEY" : error.field === "OPENAI_MODEL" ? "OPENROUTER_MODEL" : error.field : error.field} value before jig review` : client === undefined ? "the API Agent could not be opened; check the installed support assets and exported configuration" : `the selected ${client} client could not be opened; check its executable and exported host configuration`
|
|
15964
16145
|
};
|
|
15965
16146
|
}
|
|
15966
16147
|
}
|
|
@@ -17688,6 +17869,78 @@ async function validateUtf8File(captured, logicalPath) {
|
|
|
17688
17869
|
}
|
|
17689
17870
|
}
|
|
17690
17871
|
|
|
17872
|
+
// src/internal/private-project-command.ts
|
|
17873
|
+
import { createHash as createHash5 } from "crypto";
|
|
17874
|
+
var PROJECT_COMMAND_CONTRACT_ID = "https://jig.md/contracts/project-command";
|
|
17875
|
+
var PROJECT_COMMAND_CONTRACT_VERSION = "1.0.0";
|
|
17876
|
+
var PROJECT_COMMAND_CONTRACT_DIGEST = "sha256:aed62fe17f01897545f82d7ee91f163a023721431433c8f4f6981b4367c85bcf";
|
|
17877
|
+
var PROJECT_COMMAND_LIMITS = Object.freeze({
|
|
17878
|
+
files: 64,
|
|
17879
|
+
bytes: 262144,
|
|
17880
|
+
streamBytes: 65536,
|
|
17881
|
+
stdinBytes: 16384,
|
|
17882
|
+
args: 32,
|
|
17883
|
+
argumentBytes: 1024,
|
|
17884
|
+
timeoutMs: 1e4
|
|
17885
|
+
});
|
|
17886
|
+
function isProjectCommandContract(value) {
|
|
17887
|
+
return value.id === PROJECT_COMMAND_CONTRACT_ID && value.version === PROJECT_COMMAND_CONTRACT_VERSION && value.digest === PROJECT_COMMAND_CONTRACT_DIGEST;
|
|
17888
|
+
}
|
|
17889
|
+
function assertProjectCommandContract(contract) {
|
|
17890
|
+
const parsed = parseCapabilityContract(canonicalJson(contract.descriptor));
|
|
17891
|
+
if (!isProjectCommandContract({ ...parsed.descriptor, digest: parsed.digest }) || parsed.digest !== contract.digest)
|
|
17892
|
+
throw new TypeError("expected the exact supported Project Command contract");
|
|
17893
|
+
}
|
|
17894
|
+
function parseProjectCommandInput(value, commands) {
|
|
17895
|
+
const input = snapshotPrivateOrdinaryJson(value, "project command input", (message) => new TypeError(message));
|
|
17896
|
+
if (!input || typeof input !== "object" || Array.isArray(input) || Object.keys(input).some((key) => !["command", "files", "args", "stdin"].includes(key)) || typeof input.command !== "string" || !Object.hasOwn(commands, input.command))
|
|
17897
|
+
throw new TypeError("select a command from the admitted Binding commands");
|
|
17898
|
+
if (!input.files || typeof input.files !== "object" || Array.isArray(input.files))
|
|
17899
|
+
throw new TypeError("command files must be an object of UTF-8 source text");
|
|
17900
|
+
const paths = Object.keys(input.files).sort();
|
|
17901
|
+
if (paths.length === 0 || paths.length > PROJECT_COMMAND_LIMITS.files)
|
|
17902
|
+
throw new TypeError("command requires one to 64 candidate files");
|
|
17903
|
+
let bytes = 0;
|
|
17904
|
+
for (const path of paths) {
|
|
17905
|
+
projectCommandPath(path);
|
|
17906
|
+
if (path.split("/").some((part) => ["node_modules", ".git", ".jig"].includes(part)))
|
|
17907
|
+
throw new TypeError("candidate contains a reserved project directory");
|
|
17908
|
+
if (paths.some((other) => path !== other && path.startsWith(`${other}/`)))
|
|
17909
|
+
throw new TypeError("candidate has a file/directory collision");
|
|
17910
|
+
const text = input.files[path];
|
|
17911
|
+
if (typeof text !== "string")
|
|
17912
|
+
throw new TypeError("candidate files must be UTF-8 text");
|
|
17913
|
+
bytes += Buffer.byteLength(text);
|
|
17914
|
+
}
|
|
17915
|
+
if (bytes > PROJECT_COMMAND_LIMITS.bytes)
|
|
17916
|
+
throw new TypeError("candidate exceeds 256 KiB");
|
|
17917
|
+
const args = input.args === undefined ? [] : input.args;
|
|
17918
|
+
if (!Array.isArray(args) || args.length > PROJECT_COMMAND_LIMITS.args || args.some((arg) => typeof arg !== "string" || arg.includes("\x00") || Buffer.byteLength(arg) > PROJECT_COMMAND_LIMITS.argumentBytes))
|
|
17919
|
+
throw new TypeError("command arguments exceed their bounded string profile");
|
|
17920
|
+
const stdin = input.stdin === undefined ? "" : input.stdin;
|
|
17921
|
+
if (typeof stdin !== "string" || Buffer.byteLength(stdin) > PROJECT_COMMAND_LIMITS.stdinBytes)
|
|
17922
|
+
throw new TypeError("command stdin exceeds 16 KiB");
|
|
17923
|
+
const command = commands[input.command];
|
|
17924
|
+
const selected = "run" in command ? [command.run] : command.test;
|
|
17925
|
+
if (selected.some((path) => !Object.hasOwn(input.files, path)))
|
|
17926
|
+
throw new TypeError("candidate omits a reviewed command file");
|
|
17927
|
+
if ("test" in command && args.length !== 0)
|
|
17928
|
+
throw new TypeError("test commands do not accept variable arguments");
|
|
17929
|
+
const invocation = Object.freeze("run" in command ? ["bun", command.run, ...args] : ["bun", "test", ...command.test]);
|
|
17930
|
+
return Object.freeze({
|
|
17931
|
+
input,
|
|
17932
|
+
invocation,
|
|
17933
|
+
candidateDigest: projectCommandCandidateDigest(input.files),
|
|
17934
|
+
stdinDigest: digest(Buffer.from(stdin))
|
|
17935
|
+
});
|
|
17936
|
+
}
|
|
17937
|
+
function projectCommandCandidateDigest(files) {
|
|
17938
|
+
return digest(canonicalJson(files));
|
|
17939
|
+
}
|
|
17940
|
+
function digest(bytes) {
|
|
17941
|
+
return `sha256:${createHash5("sha256").update(bytes).digest("hex")}`;
|
|
17942
|
+
}
|
|
17943
|
+
|
|
17691
17944
|
// src/project/flow-source.ts
|
|
17692
17945
|
import { constants as constants9 } from "fs";
|
|
17693
17946
|
import { lstat as lstat9, open as open5, opendir as opendir2 } from "fs/promises";
|
|
@@ -18331,7 +18584,7 @@ function directoryEntryName2(entry) {
|
|
|
18331
18584
|
}
|
|
18332
18585
|
|
|
18333
18586
|
// src/internal/package-artifact-store.ts
|
|
18334
|
-
import { createHash as
|
|
18587
|
+
import { createHash as createHash6, randomUUID } from "crypto";
|
|
18335
18588
|
import { constants as constants10 } from "fs";
|
|
18336
18589
|
import { link as link2, lstat as lstat10, mkdir as mkdir5, open as open6, opendir as opendir3, unlink as unlink3 } from "fs/promises";
|
|
18337
18590
|
import { tmpdir as tmpdir3 } from "os";
|
|
@@ -18366,26 +18619,26 @@ async function publishCapturedPackage(storeRoot, captured) {
|
|
|
18366
18619
|
}
|
|
18367
18620
|
}
|
|
18368
18621
|
async function publishCapturedPackageExclusive(storeRoot, captured) {
|
|
18369
|
-
const
|
|
18622
|
+
const digest2 = parsePackageDigest(captured.digest);
|
|
18370
18623
|
const artifactBytes = privatePackageArtifactArchiveBytes(captured.files);
|
|
18371
18624
|
if (artifactBytes > PRIVATE_PACKAGE_ARTIFACT_STORE_LIMITS.artifactBytes) {
|
|
18372
18625
|
unavailable("PACKAGE_ARTIFACT_LIMIT", `Package/1 artifact exceeds the fixed ${PRIVATE_PACKAGE_ARTIFACT_STORE_LIMITS.artifactBytes}-byte alpha limit`);
|
|
18373
18626
|
}
|
|
18374
|
-
const location = await openArtifactShard(storeRoot,
|
|
18627
|
+
const location = await openArtifactShard(storeRoot, digest2, true);
|
|
18375
18628
|
const stage = `${location.directoryPath}/.stage-${process.pid}-${randomUUID()}`;
|
|
18376
18629
|
let stageHandle;
|
|
18377
18630
|
let stageExists = false;
|
|
18378
18631
|
let result2;
|
|
18379
18632
|
let failure;
|
|
18380
18633
|
try {
|
|
18381
|
-
const existing = await tryCapturePackageArtifactFile(location.finalPath,
|
|
18634
|
+
const existing = await tryCapturePackageArtifactFile(location.finalPath, digest2, `stored Package/1 ${digest2}`, location.ownerUid);
|
|
18382
18635
|
if (existing !== undefined) {
|
|
18383
18636
|
await existing.dispose();
|
|
18384
18637
|
const observedDigest2 = await digestCapturedPackage(captured);
|
|
18385
|
-
if (observedDigest2 !==
|
|
18386
|
-
invalid("PACKAGE_ARTIFACT_SOURCE_MISMATCH", `captured Package/1 bytes produced ${observedDigest2}, not ${
|
|
18638
|
+
if (observedDigest2 !== digest2) {
|
|
18639
|
+
invalid("PACKAGE_ARTIFACT_SOURCE_MISMATCH", `captured Package/1 bytes produced ${observedDigest2}, not ${digest2}`);
|
|
18387
18640
|
}
|
|
18388
|
-
return packageArtifactRef(
|
|
18641
|
+
return packageArtifactRef(digest2);
|
|
18389
18642
|
}
|
|
18390
18643
|
const retainedBytes = await retainedStoreBytes(storeRoot, location.ownerUid);
|
|
18391
18644
|
if (retainedBytes + artifactBytes > PRIVATE_PACKAGE_ARTIFACT_STORE_LIMITS.storeBytes) {
|
|
@@ -18394,15 +18647,15 @@ async function publishCapturedPackageExclusive(storeRoot, captured) {
|
|
|
18394
18647
|
stageHandle = await open6(stage, constants10.O_WRONLY | constants10.O_CREAT | constants10.O_EXCL | constants10.O_NOFOLLOW, 384);
|
|
18395
18648
|
stageExists = true;
|
|
18396
18649
|
const observedDigest = await writeCapturedArchive(stageHandle, captured);
|
|
18397
|
-
if (observedDigest !==
|
|
18398
|
-
invalid("PACKAGE_ARTIFACT_SOURCE_MISMATCH", `captured Package/1 bytes produced ${observedDigest}, not ${
|
|
18650
|
+
if (observedDigest !== digest2) {
|
|
18651
|
+
invalid("PACKAGE_ARTIFACT_SOURCE_MISMATCH", `captured Package/1 bytes produced ${observedDigest}, not ${digest2}`);
|
|
18399
18652
|
}
|
|
18400
18653
|
await stageHandle.sync();
|
|
18401
18654
|
await stageHandle.chmod(256);
|
|
18402
18655
|
await stageHandle.sync();
|
|
18403
18656
|
await stageHandle.close();
|
|
18404
18657
|
stageHandle = undefined;
|
|
18405
|
-
const staged = await capturePackageArtifactFile(stage,
|
|
18658
|
+
const staged = await capturePackageArtifactFile(stage, digest2, "staged Package/1 artifact", location.ownerUid);
|
|
18406
18659
|
await staged.dispose();
|
|
18407
18660
|
try {
|
|
18408
18661
|
await link2(stage, location.finalPath);
|
|
@@ -18416,9 +18669,9 @@ async function publishCapturedPackageExclusive(storeRoot, captured) {
|
|
|
18416
18669
|
await unlink3(stage);
|
|
18417
18670
|
stageExists = false;
|
|
18418
18671
|
await location.directory.sync();
|
|
18419
|
-
const existing2 = await capturePackageArtifactFile(location.finalPath,
|
|
18672
|
+
const existing2 = await capturePackageArtifactFile(location.finalPath, digest2, `stored Package/1 ${digest2}`, location.ownerUid);
|
|
18420
18673
|
await existing2.dispose();
|
|
18421
|
-
result2 = packageArtifactRef(
|
|
18674
|
+
result2 = packageArtifactRef(digest2);
|
|
18422
18675
|
return result2;
|
|
18423
18676
|
}
|
|
18424
18677
|
await requireSameFile(stage, location.finalPath);
|
|
@@ -18426,7 +18679,7 @@ async function publishCapturedPackageExclusive(storeRoot, captured) {
|
|
|
18426
18679
|
await unlink3(stage);
|
|
18427
18680
|
stageExists = false;
|
|
18428
18681
|
await location.directory.sync();
|
|
18429
|
-
result2 = packageArtifactRef(
|
|
18682
|
+
result2 = packageArtifactRef(digest2);
|
|
18430
18683
|
return result2;
|
|
18431
18684
|
} catch (error) {
|
|
18432
18685
|
failure = isResourceError2(error) ? new CheckError("unavailable", "PACKAGE_ARTIFACT_RESOURCE_EXHAUSTED", `cannot publish Package/1 artifact: ${errorText4(error)}`) : error;
|
|
@@ -18480,15 +18733,15 @@ function privatePackageArtifactArchiveBytes(files) {
|
|
|
18480
18733
|
return bytes;
|
|
18481
18734
|
}
|
|
18482
18735
|
async function captureStoredPackage(storeRoot, reference) {
|
|
18483
|
-
const
|
|
18736
|
+
const digest2 = parsePackageArtifactRef(reference);
|
|
18484
18737
|
let location;
|
|
18485
18738
|
let captured;
|
|
18486
18739
|
try {
|
|
18487
|
-
location = await openArtifactShard(storeRoot,
|
|
18488
|
-
captured = await capturePackageArtifactFile(location.finalPath,
|
|
18740
|
+
location = await openArtifactShard(storeRoot, digest2, false);
|
|
18741
|
+
captured = await capturePackageArtifactFile(location.finalPath, digest2, `stored Package/1 ${digest2}`, location.ownerUid);
|
|
18489
18742
|
} catch (error) {
|
|
18490
18743
|
if (hasCode2(error, "ENOENT")) {
|
|
18491
|
-
unavailable("PACKAGE_ARTIFACT_MISSING", `stored Package/1 ${
|
|
18744
|
+
unavailable("PACKAGE_ARTIFACT_MISSING", `stored Package/1 ${digest2} is missing`);
|
|
18492
18745
|
}
|
|
18493
18746
|
if (isResourceError2(error)) {
|
|
18494
18747
|
unavailable("PACKAGE_ARTIFACT_RESOURCE_EXHAUSTED", `cannot acquire Package/1 artifact: ${errorText4(error)}`);
|
|
@@ -18506,8 +18759,8 @@ async function captureStoredPackage(storeRoot, reference) {
|
|
|
18506
18759
|
}
|
|
18507
18760
|
return captured;
|
|
18508
18761
|
}
|
|
18509
|
-
function packageArtifactRef(
|
|
18510
|
-
return Object.freeze({ kind: ARTIFACT_KIND, digest });
|
|
18762
|
+
function packageArtifactRef(digest2) {
|
|
18763
|
+
return Object.freeze({ kind: ARTIFACT_KIND, digest: digest2 });
|
|
18511
18764
|
}
|
|
18512
18765
|
function normalizePackageArtifactRef(reference) {
|
|
18513
18766
|
return packageArtifactRef(parsePackageArtifactRef(reference));
|
|
@@ -18525,11 +18778,11 @@ function parsePackageArtifactRef(reference) {
|
|
|
18525
18778
|
invalid("PACKAGE_ARTIFACT_REF", `Package/1 artifact reference must contain only kind=${ARTIFACT_KIND} and digest`);
|
|
18526
18779
|
}
|
|
18527
18780
|
const kind = Object.getOwnPropertyDescriptor(reference, "kind");
|
|
18528
|
-
const
|
|
18529
|
-
if (kind === undefined || !("value" in kind) || !kind.enumerable || kind.value !== ARTIFACT_KIND ||
|
|
18781
|
+
const digest2 = Object.getOwnPropertyDescriptor(reference, "digest");
|
|
18782
|
+
if (kind === undefined || !("value" in kind) || !kind.enumerable || kind.value !== ARTIFACT_KIND || digest2 === undefined || !("value" in digest2) || !digest2.enumerable) {
|
|
18530
18783
|
invalid("PACKAGE_ARTIFACT_REF", `Package/1 artifact reference must contain enumerable data fields kind=${ARTIFACT_KIND} and digest`);
|
|
18531
18784
|
}
|
|
18532
|
-
return parsePackageDigest(
|
|
18785
|
+
return parsePackageDigest(digest2.value);
|
|
18533
18786
|
}
|
|
18534
18787
|
function parsePackageDigest(value) {
|
|
18535
18788
|
if (typeof value !== "string" || !DIGEST_PATTERN.test(value)) {
|
|
@@ -18537,8 +18790,8 @@ function parsePackageDigest(value) {
|
|
|
18537
18790
|
}
|
|
18538
18791
|
return value;
|
|
18539
18792
|
}
|
|
18540
|
-
async function openArtifactShard(storeRoot,
|
|
18541
|
-
const hexadecimal = DIGEST_PATTERN.exec(
|
|
18793
|
+
async function openArtifactShard(storeRoot, digest2, create) {
|
|
18794
|
+
const hexadecimal = DIGEST_PATTERN.exec(digest2)[1];
|
|
18542
18795
|
let parent = await openStoreRoot(storeRoot);
|
|
18543
18796
|
try {
|
|
18544
18797
|
for (const segment of ["packages", "v1", "sha256", hexadecimal.slice(0, 2)]) {
|
|
@@ -18709,7 +18962,7 @@ async function capturePackageArtifactFile(path, expectedDigest, sourceLabel, exp
|
|
|
18709
18962
|
}
|
|
18710
18963
|
}
|
|
18711
18964
|
async function parsePackageArchive(handle, information, expectedDigest, snapshot2) {
|
|
18712
|
-
const hash =
|
|
18965
|
+
const hash = createHash6("sha256");
|
|
18713
18966
|
let position = 0;
|
|
18714
18967
|
async function readHashed(length, description) {
|
|
18715
18968
|
const bytes = await readExact(handle, position, length, description);
|
|
@@ -18859,7 +19112,7 @@ async function readExact(handle, offset, length, description) {
|
|
|
18859
19112
|
return result2;
|
|
18860
19113
|
}
|
|
18861
19114
|
async function writeCapturedArchive(destination, captured) {
|
|
18862
|
-
const hash =
|
|
19115
|
+
const hash = createHash6("sha256");
|
|
18863
19116
|
const iterator = encodePackage1(captured.files, (file) => captured.stream(file.path))[Symbol.asyncIterator]();
|
|
18864
19117
|
let finished = false;
|
|
18865
19118
|
let failure;
|
|
@@ -19073,28 +19326,36 @@ function projectSupportedCapabilityUses(inspected, packagePath) {
|
|
|
19073
19326
|
const declarations = Object.entries(inspected.metadata.uses ?? {});
|
|
19074
19327
|
if (declarations.length === 0)
|
|
19075
19328
|
return Object.freeze(Object.create(null));
|
|
19076
|
-
if (declarations.length
|
|
19077
|
-
invalid("PROJECT_FLOW_CAPABILITY_UNSUPPORTED", "
|
|
19329
|
+
if (declarations.length > 2) {
|
|
19330
|
+
invalid("PROJECT_FLOW_CAPABILITY_UNSUPPORTED", "Jig supports one Agent Run and one Project Command capability slot per package", packagePath);
|
|
19078
19331
|
}
|
|
19079
|
-
const
|
|
19080
|
-
|
|
19081
|
-
|
|
19082
|
-
|
|
19083
|
-
|
|
19084
|
-
|
|
19085
|
-
|
|
19086
|
-
|
|
19087
|
-
|
|
19088
|
-
|
|
19089
|
-
|
|
19332
|
+
const output = Object.create(null);
|
|
19333
|
+
const used = new Set;
|
|
19334
|
+
for (const [slot, declaration] of declarations) {
|
|
19335
|
+
if (declaration.contract === undefined) {
|
|
19336
|
+
invalid("PROJECT_FLOW_CAPABILITY_UNSUPPORTED", "Jig supports only the exact Agent Run and Project Command contracts", packagePath, `/uses/${pointerToken(slot)}`);
|
|
19337
|
+
}
|
|
19338
|
+
const reference = inspected.usedContracts.find((candidate) => candidate.slot === slot);
|
|
19339
|
+
if (reference === undefined)
|
|
19340
|
+
throw new Error("inspected capability reference invariant violated");
|
|
19341
|
+
try {
|
|
19342
|
+
if (reference.contract.digest === PROJECT_COMMAND_CONTRACT_DIGEST)
|
|
19343
|
+
assertProjectCommandContract(reference.contract);
|
|
19344
|
+
else
|
|
19345
|
+
assertAgentRunContract(reference.contract);
|
|
19346
|
+
if (used.has(reference.contract.digest))
|
|
19347
|
+
throw new TypeError("a supported capability may be declared only once");
|
|
19348
|
+
used.add(reference.contract.digest);
|
|
19349
|
+
} catch (error) {
|
|
19350
|
+
invalid("PROJECT_FLOW_CAPABILITY_UNSUPPORTED", errorText5(error), packagePath, `/uses/${pointerToken(slot)}`);
|
|
19351
|
+
}
|
|
19352
|
+
output[slot] = Object.freeze({
|
|
19353
|
+
id: reference.contract.descriptor.id,
|
|
19354
|
+
version: reference.contract.descriptor.version,
|
|
19355
|
+
digest: reference.contract.digest
|
|
19356
|
+
});
|
|
19090
19357
|
}
|
|
19091
|
-
return Object.freeze(
|
|
19092
|
-
[slot]: Object.freeze({
|
|
19093
|
-
id: AGENT_RUN_CONTRACT_ID,
|
|
19094
|
-
version: AGENT_RUN_CONTRACT_VERSION,
|
|
19095
|
-
digest: AGENT_RUN_CONTRACT_DIGEST
|
|
19096
|
-
})
|
|
19097
|
-
});
|
|
19358
|
+
return Object.freeze(output);
|
|
19098
19359
|
}
|
|
19099
19360
|
function prepareBindings(values, flowByPath, budget) {
|
|
19100
19361
|
const bindings = values.map((value, index) => {
|
|
@@ -19127,6 +19388,8 @@ function prepareBindings(values, flowByPath, budget) {
|
|
|
19127
19388
|
invalid("PROJECT_BINDING_ENTRYPOINT_REQUIRED", `Binding ${id} selects an instruction-only package without a supported code entrypoint`, declarationPath, "/package");
|
|
19128
19389
|
}
|
|
19129
19390
|
validateSettings(definition.settings, flow.inspected, declarationPath);
|
|
19391
|
+
if (definition.commands !== undefined && !Object.values(flow.value.uses).some(({ digest: digest2 }) => digest2 === PROJECT_COMMAND_CONTRACT_DIGEST))
|
|
19392
|
+
invalid("PROJECT_BINDING_COMMANDS_UNDECLARED", "commands require a Project Command capability declaration", declarationPath, "/commands");
|
|
19130
19393
|
return Object.freeze({ id, declarationPath, definition, flow });
|
|
19131
19394
|
});
|
|
19132
19395
|
bindings.sort((left, right) => compareProjectPaths(left.id, right.id));
|
|
@@ -19141,7 +19404,8 @@ function linkBinding(prepared, flowByPath, bindingById) {
|
|
|
19141
19404
|
declarationPath,
|
|
19142
19405
|
packagePath: definition.package,
|
|
19143
19406
|
settings: definition.settings,
|
|
19144
|
-
slots: linkFlowSlots(prepared, flowByPath, bindingById)
|
|
19407
|
+
slots: linkFlowSlots(prepared, flowByPath, bindingById),
|
|
19408
|
+
...definition.commands === undefined ? {} : { commands: definition.commands }
|
|
19145
19409
|
});
|
|
19146
19410
|
}
|
|
19147
19411
|
function linkFlowSlots(binding, flowByPath, bindingById) {
|
|
@@ -19521,15 +19785,15 @@ function requirePlainRecord(value, label) {
|
|
|
19521
19785
|
}
|
|
19522
19786
|
|
|
19523
19787
|
// src/project/author-evaluator.ts
|
|
19524
|
-
import { createHash as
|
|
19788
|
+
import { createHash as createHash8 } from "crypto";
|
|
19525
19789
|
import { readFile as readFile6 } from "fs/promises";
|
|
19526
19790
|
import { join as join7 } from "path";
|
|
19527
19791
|
|
|
19528
19792
|
// src/project/author-module.ts
|
|
19529
|
-
import { createHash as
|
|
19793
|
+
import { createHash as createHash7 } from "crypto";
|
|
19530
19794
|
import { constants as constants11 } from "fs";
|
|
19531
19795
|
import { lstat as lstat11, open as open7 } from "fs/promises";
|
|
19532
|
-
import { dirname as
|
|
19796
|
+
import { dirname as dirname7, join as joinPath, normalize as normalizePath } from "path/posix";
|
|
19533
19797
|
var MAX_SOURCE_BYTES = 1024 * 1024;
|
|
19534
19798
|
var MAX_CLOSURE_SOURCE_BYTES = 1024 * 1024;
|
|
19535
19799
|
var MAX_CLOSURE_MODULES = 256;
|
|
@@ -19623,7 +19887,7 @@ function createClosure(entries, modulePaths, captured, imports, sourceBytes) {
|
|
|
19623
19887
|
return Object.freeze({
|
|
19624
19888
|
projectPath,
|
|
19625
19889
|
sourceBytes: bytes.byteLength,
|
|
19626
|
-
sourceDigest:
|
|
19890
|
+
sourceDigest: digest2(bytes),
|
|
19627
19891
|
imports: Object.freeze([...imports.get(projectPath) ?? []])
|
|
19628
19892
|
});
|
|
19629
19893
|
});
|
|
@@ -19644,7 +19908,7 @@ function createClosure(entries, modulePaths, captured, imports, sourceBytes) {
|
|
|
19644
19908
|
entries: Object.freeze([...entries]),
|
|
19645
19909
|
modules: Object.freeze(modules),
|
|
19646
19910
|
sourceBytes,
|
|
19647
|
-
closureDigest:
|
|
19911
|
+
closureDigest: digest2(canonicalJson(identity2)),
|
|
19648
19912
|
read(projectPath) {
|
|
19649
19913
|
if (disposed)
|
|
19650
19914
|
unavailable("PROJECT_CAPTURE_CLOSED", "author closure has been disposed", projectPath);
|
|
@@ -19695,7 +19959,7 @@ function resolveAuthorImport(importer, specifier) {
|
|
|
19695
19959
|
if (!(specifier.startsWith("./") || specifier.startsWith("../")) || specifier.includes("\\") || specifier.includes("\x00") || !specifier.endsWith(".ts") || specifier.endsWith(".d.ts")) {
|
|
19696
19960
|
invalid("PROJECT_EVALUATOR_IMPORT", `project-local imports must use an explicit relative .ts path: ${specifier}`, importer);
|
|
19697
19961
|
}
|
|
19698
|
-
const target = normalizePath(joinPath(
|
|
19962
|
+
const target = normalizePath(joinPath(dirname7(importer), specifier));
|
|
19699
19963
|
try {
|
|
19700
19964
|
validateProjectPath(target, "author import target");
|
|
19701
19965
|
if (isProtectedProjectPath(target)) {
|
|
@@ -19732,8 +19996,8 @@ function compareUtf82(left, right) {
|
|
|
19732
19996
|
}
|
|
19733
19997
|
return leftBytes.byteLength - rightBytes.byteLength;
|
|
19734
19998
|
}
|
|
19735
|
-
function
|
|
19736
|
-
return `sha256:${
|
|
19999
|
+
function digest2(bytes) {
|
|
20000
|
+
return `sha256:${createHash7("sha256").update(bytes).digest("hex")}`;
|
|
19737
20001
|
}
|
|
19738
20002
|
async function captureFile(project, projectPath) {
|
|
19739
20003
|
const opened = await openProjectFile(project, projectPath, false);
|
|
@@ -20208,7 +20472,7 @@ async function collectBounded(stream, maximum, terminate) {
|
|
|
20208
20472
|
return output;
|
|
20209
20473
|
}
|
|
20210
20474
|
function digestBytes(bytes) {
|
|
20211
|
-
return `sha256:${
|
|
20475
|
+
return `sha256:${createHash8("sha256").update(bytes).digest("hex")}`;
|
|
20212
20476
|
}
|
|
20213
20477
|
function frozenNumbers(value) {
|
|
20214
20478
|
return Object.freeze(Object.fromEntries(Object.entries(value).sort(([left], [right]) => left < right ? -1 : left > right ? 1 : 0)));
|
|
@@ -20662,8 +20926,8 @@ async function retainAuthorClosure(storeRoot, closure) {
|
|
|
20662
20926
|
};
|
|
20663
20927
|
let captured;
|
|
20664
20928
|
try {
|
|
20665
|
-
const
|
|
20666
|
-
captured = createCapturedPackage("captured author closure", files,
|
|
20929
|
+
const digest3 = await packageDigest(files, (file) => backing.stream(file.path));
|
|
20930
|
+
captured = createCapturedPackage("captured author closure", files, digest3, backing);
|
|
20667
20931
|
const reference = await publishCapturedPackage(storeRoot, captured);
|
|
20668
20932
|
return Object.freeze({
|
|
20669
20933
|
kind: "author-closure/1",
|
|
@@ -20854,6 +21118,7 @@ function buildPrivateActivationRequests(project) {
|
|
|
20854
21118
|
settings: binding.settings,
|
|
20855
21119
|
capabilities: flow.uses,
|
|
20856
21120
|
flowSlots: binding.slots,
|
|
21121
|
+
...binding.commands === undefined ? {} : { commands: binding.commands },
|
|
20857
21122
|
attachments: normalizeRequestAttachments(flow.metadata.attachments ?? {})
|
|
20858
21123
|
}));
|
|
20859
21124
|
}
|
|
@@ -20881,7 +21146,8 @@ function restorePrivateActivationRequest(value) {
|
|
|
20881
21146
|
"settings",
|
|
20882
21147
|
"capabilities",
|
|
20883
21148
|
"flowSlots",
|
|
20884
|
-
"attachments"
|
|
21149
|
+
"attachments",
|
|
21150
|
+
...value !== null && typeof value === "object" && Object.hasOwn(value, "commands") ? ["commands"] : []
|
|
20885
21151
|
], "activation request");
|
|
20886
21152
|
if (root.kind !== "activation-request/4") {
|
|
20887
21153
|
throw new TypeError("activation request kind must be activation-request/4");
|
|
@@ -20924,7 +21190,10 @@ function restorePrivateActivationRequest(value) {
|
|
|
20924
21190
|
settings: snapshotJsonObject2(root.settings, "activation settings"),
|
|
20925
21191
|
capabilities: normalizeRequestCapabilities(root.capabilities),
|
|
20926
21192
|
flowSlots: normalizeRequestFlowSlots(root.flowSlots),
|
|
20927
|
-
attachments: normalizeRequestAttachments(root.attachments)
|
|
21193
|
+
attachments: normalizeRequestAttachments(root.attachments),
|
|
21194
|
+
...root.commands === undefined ? {} : {
|
|
21195
|
+
commands: normalizeProjectCommands(snapshotJsonObject2(root.commands, "activation commands"))
|
|
21196
|
+
}
|
|
20928
21197
|
});
|
|
20929
21198
|
if (root.digest !== request.digest) {
|
|
20930
21199
|
throw new TypeError("activation request digest does not match its canonical content");
|
|
@@ -21000,7 +21269,8 @@ function createRequest(input) {
|
|
|
21000
21269
|
settings: input.settings,
|
|
21001
21270
|
capabilities: input.capabilities,
|
|
21002
21271
|
flowSlots: input.flowSlots,
|
|
21003
|
-
attachments: input.attachments
|
|
21272
|
+
attachments: input.attachments,
|
|
21273
|
+
...input.commands === undefined ? {} : { commands: input.commands }
|
|
21004
21274
|
});
|
|
21005
21275
|
const request = Object.freeze({
|
|
21006
21276
|
...valueWithoutDigest,
|
|
@@ -21034,7 +21304,8 @@ function semanticProject(project) {
|
|
|
21034
21304
|
id: binding.id,
|
|
21035
21305
|
packagePath: binding.packagePath,
|
|
21036
21306
|
settings: binding.settings,
|
|
21037
|
-
slots: binding.slots
|
|
21307
|
+
slots: binding.slots,
|
|
21308
|
+
...binding.commands === undefined ? {} : { commands: binding.commands }
|
|
21038
21309
|
}))
|
|
21039
21310
|
};
|
|
21040
21311
|
}
|
|
@@ -21117,22 +21388,24 @@ function normalizeRequestAttachments(value) {
|
|
|
21117
21388
|
}
|
|
21118
21389
|
function normalizeRequestCapabilities(value) {
|
|
21119
21390
|
const input = snapshotJsonObject2(value, "activation capability uses");
|
|
21120
|
-
if (Object.keys(input).length >
|
|
21121
|
-
throw new TypeError("activation capability uses exceed
|
|
21391
|
+
if (Object.keys(input).length > 2) {
|
|
21392
|
+
throw new TypeError("activation capability uses exceed 2 entries");
|
|
21122
21393
|
}
|
|
21123
21394
|
const output = Object.create(null);
|
|
21124
21395
|
for (const name of Object.keys(input).sort()) {
|
|
21125
21396
|
requireLocalName3(name, "activation capability slot");
|
|
21126
21397
|
const item = exactObject(input[name], ["id", "version", "digest"], `activation capability slot ${name}`);
|
|
21127
|
-
if (item.id !== AGENT_RUN_CONTRACT_ID || item.version !== AGENT_RUN_CONTRACT_VERSION || item.digest !== AGENT_RUN_CONTRACT_DIGEST) {
|
|
21128
|
-
throw new TypeError(`activation capability slot ${name} must select
|
|
21398
|
+
if (!isProjectCommandContract(item) && (item.id !== AGENT_RUN_CONTRACT_ID || item.version !== AGENT_RUN_CONTRACT_VERSION || item.digest !== AGENT_RUN_CONTRACT_DIGEST)) {
|
|
21399
|
+
throw new TypeError(`activation capability slot ${name} must select an exact supported contract`);
|
|
21129
21400
|
}
|
|
21130
21401
|
output[name] = Object.freeze({
|
|
21131
|
-
id:
|
|
21132
|
-
version:
|
|
21133
|
-
digest:
|
|
21402
|
+
id: item.id,
|
|
21403
|
+
version: item.version,
|
|
21404
|
+
digest: item.digest
|
|
21134
21405
|
});
|
|
21135
21406
|
}
|
|
21407
|
+
if (new Set(Object.values(output).map(({ digest: digest3 }) => digest3)).size !== Object.keys(output).length)
|
|
21408
|
+
throw new TypeError("activation capability contracts must be distinct");
|
|
21136
21409
|
return Object.freeze(output);
|
|
21137
21410
|
}
|
|
21138
21411
|
function normalizeRequestFlowSlots(value) {
|
|
@@ -21229,6 +21502,49 @@ function freezeJson(value) {
|
|
|
21229
21502
|
return value;
|
|
21230
21503
|
}
|
|
21231
21504
|
|
|
21505
|
+
// src/internal/root-operation-limits.ts
|
|
21506
|
+
var PRIVATE_FLOW_RESOURCE_CEILINGS = Object.freeze({
|
|
21507
|
+
memoryBytes: 256 * 1024 * 1024,
|
|
21508
|
+
pids: 64,
|
|
21509
|
+
cpuQuotaMicros: 50000,
|
|
21510
|
+
cpuPeriodMicros: 1e5,
|
|
21511
|
+
cleanupTimeoutMs: 5000
|
|
21512
|
+
});
|
|
21513
|
+
var PRIVATE_AGENT_PROVIDER_PIDS = 128;
|
|
21514
|
+
var PRIVATE_ROOT_RESOURCE_POLICY = Object.freeze({
|
|
21515
|
+
siblingFlows: 2,
|
|
21516
|
+
leafEffects: 1,
|
|
21517
|
+
memoryBytes: 1280 * 1024 * 1024,
|
|
21518
|
+
pids: 448,
|
|
21519
|
+
cpuQuotaMicros: 250000,
|
|
21520
|
+
cpuPeriodMicros: 1e5,
|
|
21521
|
+
reservation: "whole-branch-until-cleanup"
|
|
21522
|
+
});
|
|
21523
|
+
function isPrivateChildFlowAllocation(value) {
|
|
21524
|
+
return value !== null && typeof value === "object" && !Array.isArray(value) && value.kind === "private-root-child-owner-allocation/1";
|
|
21525
|
+
}
|
|
21526
|
+
function privateRootBranchReservation(branches) {
|
|
21527
|
+
if (!Number.isSafeInteger(branches) || branches < 0)
|
|
21528
|
+
throw new TypeError("Invalid branch count.");
|
|
21529
|
+
const flow = PRIVATE_FLOW_RESOURCE_CEILINGS;
|
|
21530
|
+
return Object.freeze({
|
|
21531
|
+
memoryBytes: flow.memoryBytes * (1 + branches * 2),
|
|
21532
|
+
pids: flow.pids + branches * (flow.pids + PRIVATE_AGENT_PROVIDER_PIDS),
|
|
21533
|
+
cpuQuotaMicros: flow.cpuQuotaMicros * (1 + branches * 2),
|
|
21534
|
+
cpuPeriodMicros: flow.cpuPeriodMicros
|
|
21535
|
+
});
|
|
21536
|
+
}
|
|
21537
|
+
function canReservePrivateRootOperation(current, proposed) {
|
|
21538
|
+
const allocations = [...current, proposed];
|
|
21539
|
+
const allFlows = allocations.every(isPrivateChildFlowAllocation);
|
|
21540
|
+
if (!allFlows && allocations.length !== 1)
|
|
21541
|
+
return false;
|
|
21542
|
+
if (allocations.length > PRIVATE_ROOT_RESOURCE_POLICY.siblingFlows)
|
|
21543
|
+
return false;
|
|
21544
|
+
const reserved = privateRootBranchReservation(allocations.length);
|
|
21545
|
+
return reserved.memoryBytes <= PRIVATE_ROOT_RESOURCE_POLICY.memoryBytes && reserved.pids <= PRIVATE_ROOT_RESOURCE_POLICY.pids && reserved.cpuQuotaMicros / reserved.cpuPeriodMicros <= PRIVATE_ROOT_RESOURCE_POLICY.cpuQuotaMicros / PRIVATE_ROOT_RESOURCE_POLICY.cpuPeriodMicros;
|
|
21546
|
+
}
|
|
21547
|
+
|
|
21232
21548
|
// src/internal/project-local-lock.ts
|
|
21233
21549
|
var DIGEST6 = /^sha256:[0-9a-f]{64}$/;
|
|
21234
21550
|
var LOCAL_NAME8 = /^[a-z0-9]+(?:-[a-z0-9]+)*$/;
|
|
@@ -21248,7 +21564,8 @@ function createPrivateProjectLocalLock(project) {
|
|
|
21248
21564
|
bindings[binding.id] = Object.freeze({
|
|
21249
21565
|
packagePath: binding.packagePath,
|
|
21250
21566
|
settings: binding.settings,
|
|
21251
|
-
slots: binding.slots
|
|
21567
|
+
slots: binding.slots,
|
|
21568
|
+
...binding.commands === undefined ? {} : { commands: binding.commands }
|
|
21252
21569
|
});
|
|
21253
21570
|
}
|
|
21254
21571
|
const lock = normalizeLock({ packages, bindings });
|
|
@@ -21297,7 +21614,7 @@ function normalizePackages(value) {
|
|
|
21297
21614
|
throw new TypeError(`package ${path} directRun must be boolean`);
|
|
21298
21615
|
}
|
|
21299
21616
|
output[path] = Object.freeze({
|
|
21300
|
-
digest:
|
|
21617
|
+
digest: digest3(item.digest, `package ${path}`),
|
|
21301
21618
|
directRun: item.directRun,
|
|
21302
21619
|
uses: normalizeUses(item.uses, `package ${path}`)
|
|
21303
21620
|
});
|
|
@@ -21307,21 +21624,23 @@ function normalizePackages(value) {
|
|
|
21307
21624
|
function normalizeUses(value, label) {
|
|
21308
21625
|
const input = object2(value, `${label} uses`);
|
|
21309
21626
|
const names = Object.keys(input);
|
|
21310
|
-
if (names.length >
|
|
21311
|
-
throw new TypeError(`${label} uses exceed
|
|
21627
|
+
if (names.length > 2)
|
|
21628
|
+
throw new TypeError(`${label} uses exceed 2 entries`);
|
|
21312
21629
|
const output = Object.create(null);
|
|
21313
21630
|
for (const name of names.sort()) {
|
|
21314
21631
|
localName(name, `${label} capability slot`);
|
|
21315
21632
|
const item = exactObject2(input[name], ["id", "version", "digest"], `${label} capability slot ${name}`);
|
|
21316
|
-
if (item.id !== AGENT_RUN_CONTRACT_ID || item.version !== AGENT_RUN_CONTRACT_VERSION || item.digest !== AGENT_RUN_CONTRACT_DIGEST) {
|
|
21317
|
-
throw new TypeError(`${label} capability slot ${name} must select
|
|
21633
|
+
if (!isProjectCommandContract(item) && (item.id !== AGENT_RUN_CONTRACT_ID || item.version !== AGENT_RUN_CONTRACT_VERSION || item.digest !== AGENT_RUN_CONTRACT_DIGEST)) {
|
|
21634
|
+
throw new TypeError(`${label} capability slot ${name} must select an exact supported contract`);
|
|
21318
21635
|
}
|
|
21319
21636
|
output[name] = Object.freeze({
|
|
21320
|
-
id:
|
|
21321
|
-
version:
|
|
21322
|
-
digest:
|
|
21637
|
+
id: item.id,
|
|
21638
|
+
version: item.version,
|
|
21639
|
+
digest: item.digest
|
|
21323
21640
|
});
|
|
21324
21641
|
}
|
|
21642
|
+
if (new Set(Object.values(output).map(({ digest: digest3 }) => digest3)).size !== names.length)
|
|
21643
|
+
throw new TypeError("lock capability contracts must be distinct");
|
|
21325
21644
|
return Object.freeze(output);
|
|
21326
21645
|
}
|
|
21327
21646
|
function normalizeBindings(value) {
|
|
@@ -21329,13 +21648,19 @@ function normalizeBindings(value) {
|
|
|
21329
21648
|
const output = Object.create(null);
|
|
21330
21649
|
for (const id of Object.keys(input).sort()) {
|
|
21331
21650
|
localName(id, `Binding ${JSON.stringify(id)}`);
|
|
21332
|
-
const item = exactObject2(input[id], [
|
|
21651
|
+
const item = exactObject2(input[id], [
|
|
21652
|
+
"packagePath",
|
|
21653
|
+
"settings",
|
|
21654
|
+
"slots",
|
|
21655
|
+
...Object.hasOwn(object2(input[id], `Binding ${id}`), "commands") ? ["commands"] : []
|
|
21656
|
+
], `Binding ${id}`);
|
|
21333
21657
|
const settings = object2(item.settings, `Binding ${id} settings`);
|
|
21334
21658
|
const slots = normalizeSlots(item.slots, `Binding ${id}`);
|
|
21335
21659
|
output[id] = Object.freeze({
|
|
21336
21660
|
packagePath: projectPath(item.packagePath, `Binding ${id} packagePath`),
|
|
21337
21661
|
settings,
|
|
21338
|
-
slots
|
|
21662
|
+
slots,
|
|
21663
|
+
...item.commands === undefined ? {} : { commands: normalizeProjectCommands(item.commands) }
|
|
21339
21664
|
});
|
|
21340
21665
|
}
|
|
21341
21666
|
return Object.freeze(output);
|
|
@@ -21404,7 +21729,7 @@ function localName(value, label) {
|
|
|
21404
21729
|
}
|
|
21405
21730
|
return value;
|
|
21406
21731
|
}
|
|
21407
|
-
function
|
|
21732
|
+
function digest3(value, label) {
|
|
21408
21733
|
if (typeof value !== "string" || !DIGEST6.test(value)) {
|
|
21409
21734
|
throw new TypeError(`${label} digest must be sha256: followed by 64 lowercase hexadecimal digits`);
|
|
21410
21735
|
}
|
|
@@ -21465,13 +21790,6 @@ var RUNTIME_PREDICATES = Object.freeze([
|
|
|
21465
21790
|
"private-runtime-devices/1"
|
|
21466
21791
|
]);
|
|
21467
21792
|
var authenticRecipes = new WeakSet;
|
|
21468
|
-
var RESOURCE_CEILINGS = Object.freeze({
|
|
21469
|
-
memoryBytes: 256 * 1024 * 1024,
|
|
21470
|
-
pids: 64,
|
|
21471
|
-
cpuQuotaMicros: 50000,
|
|
21472
|
-
cpuPeriodMicros: 1e5,
|
|
21473
|
-
cleanupTimeoutMs: 5000
|
|
21474
|
-
});
|
|
21475
21793
|
async function planPrivateBunDirectRun(input) {
|
|
21476
21794
|
const request = requirePrivateActivationRequest(input.request);
|
|
21477
21795
|
const installedSupport = requirePrivateInstalledBunSupport(input.installedSupport);
|
|
@@ -21487,13 +21805,19 @@ async function planPrivateBunDirectRun(input) {
|
|
|
21487
21805
|
}
|
|
21488
21806
|
}
|
|
21489
21807
|
const capabilityUses = Object.values(request.capabilities);
|
|
21490
|
-
|
|
21808
|
+
const usesAgent = capabilityUses.some(({ digest: digest4 }) => digest4 === AGENT_RUN_CONTRACT_DIGEST);
|
|
21809
|
+
const usesCommand = capabilityUses.some(({ digest: digest4 }) => digest4 === PROJECT_COMMAND_CONTRACT_DIGEST);
|
|
21810
|
+
if (usesAgent && input.agentProvider === undefined) {
|
|
21491
21811
|
unavailable("PROJECT_AGENT_UNAVAILABLE", "the target requires a configured host Agent", `${request.packagePath}/FLOW.md`);
|
|
21492
21812
|
}
|
|
21493
|
-
const agentProvider =
|
|
21494
|
-
if (capabilityUses.some(({ digest:
|
|
21495
|
-
throw new TypeError("private Bun recipe requires
|
|
21813
|
+
const agentProvider = !usesAgent ? undefined : requirePrivateAgentProvider(input.agentProvider);
|
|
21814
|
+
if (capabilityUses.some(({ digest: digest4 }) => ![AGENT_RUN_CONTRACT_DIGEST, PROJECT_COMMAND_CONTRACT_DIGEST].includes(digest4)) || capabilityUses.length > 2 || agentProvider !== undefined && agentProvider.contractDigest !== AGENT_RUN_CONTRACT_DIGEST) {
|
|
21815
|
+
throw new TypeError("private Bun recipe requires exact supported capabilities");
|
|
21496
21816
|
}
|
|
21817
|
+
if (usesCommand && Object.keys(request.commands ?? {}).length === 0)
|
|
21818
|
+
unavailable("PROJECT_COMMAND_UNCONFIGURED", "configure commands in a Binding for this Project Command Flow", `${request.packagePath}/FLOW.md`);
|
|
21819
|
+
if (!usesCommand && request.commands !== undefined)
|
|
21820
|
+
throw new TypeError("command policy requires the Project Command capability");
|
|
21497
21821
|
const adapterDigest = privateDomainDigest("JIG-Private-Bun-Direct-Adapter/1", {
|
|
21498
21822
|
revision: ADAPTER_REVISION,
|
|
21499
21823
|
installedSupportDigest: installedSupport.digest
|
|
@@ -21513,7 +21837,8 @@ async function planPrivateBunDirectRun(input) {
|
|
|
21513
21837
|
});
|
|
21514
21838
|
const authorityDigest = privateDomainDigest("JIG-Private-Bun-Authority/1", {
|
|
21515
21839
|
attachments: request.attachments,
|
|
21516
|
-
capabilities: request.capabilities
|
|
21840
|
+
capabilities: request.capabilities,
|
|
21841
|
+
...request.commands === undefined ? {} : { commands: request.commands }
|
|
21517
21842
|
});
|
|
21518
21843
|
const launchEnvelopeDigest = logicalLaunchDigest(request, executionPackage, installedSupport, support, agentProvider);
|
|
21519
21844
|
const observation = createPrivateActivationRecipeObservation({
|
|
@@ -21551,7 +21876,7 @@ async function planPrivateBunDirectRun(input) {
|
|
|
21551
21876
|
packageDestination: PACKAGE_DESTINATION,
|
|
21552
21877
|
scratch: SCRATCH,
|
|
21553
21878
|
wallClockCeilingMs: PRIVATE_MAX_ROOT_RUN_TIMEOUT_MS,
|
|
21554
|
-
resourceCeilings:
|
|
21879
|
+
resourceCeilings: PRIVATE_FLOW_RESOURCE_CEILINGS,
|
|
21555
21880
|
bunPolicy: BUN_POLICY3,
|
|
21556
21881
|
privateProcessFilesystem: true,
|
|
21557
21882
|
privateRuntimeDevices: true,
|
|
@@ -21577,8 +21902,9 @@ function logicalLaunchDigest(request, executionPackage, installedSupport, mechan
|
|
|
21577
21902
|
backendMechanismDigest: mechanism.digest,
|
|
21578
21903
|
packageDestination: PACKAGE_DESTINATION,
|
|
21579
21904
|
scratch: SCRATCH,
|
|
21580
|
-
resourceCeilings:
|
|
21905
|
+
resourceCeilings: PRIVATE_FLOW_RESOURCE_CEILINGS,
|
|
21581
21906
|
wallClockCeilingMs: PRIVATE_MAX_ROOT_RUN_TIMEOUT_MS,
|
|
21907
|
+
rootResourcePolicy: PRIVATE_ROOT_RESOURCE_POLICY,
|
|
21582
21908
|
environment: Object.freeze({
|
|
21583
21909
|
LD_LIBRARY_PATH: "/jig-runtime/lib"
|
|
21584
21910
|
}),
|
|
@@ -21591,6 +21917,7 @@ function logicalLaunchDigest(request, executionPackage, installedSupport, mechan
|
|
|
21591
21917
|
rootOnly: true
|
|
21592
21918
|
},
|
|
21593
21919
|
capabilities: request.capabilities,
|
|
21920
|
+
...request.commands === undefined ? {} : { commands: request.commands, commandLimits: PROJECT_COMMAND_LIMITS },
|
|
21594
21921
|
...agentProvider === undefined ? {} : { agentProviderDigest: agentProvider.digest }
|
|
21595
21922
|
});
|
|
21596
21923
|
}
|
|
@@ -21970,11 +22297,11 @@ function normalizePlanV2(input, decodedLocks = false) {
|
|
|
21970
22297
|
} else if (observedState === "present") {
|
|
21971
22298
|
const present = exactObject3(observedInput, ["state", "digest", "lock"], "activation plan/2 observed lock");
|
|
21972
22299
|
const lock = normalizeEmbeddedLock(present.lock, "activation plan/2 observed lock value", decodedLocks);
|
|
21973
|
-
const
|
|
21974
|
-
if (
|
|
22300
|
+
const digest4 = requireDigest3(present.digest, "observed lock");
|
|
22301
|
+
if (digest4 !== privateProjectLocalLockDigest(lock)) {
|
|
21975
22302
|
throw new TypeError("activation plan/2 observed lock digest does not match its lock");
|
|
21976
22303
|
}
|
|
21977
|
-
observedLock = Object.freeze({ state: "present", digest:
|
|
22304
|
+
observedLock = Object.freeze({ state: "present", digest: digest4, lock });
|
|
21978
22305
|
} else {
|
|
21979
22306
|
throw new TypeError("activation plan/2 observed lock state must be absent or present");
|
|
21980
22307
|
}
|
|
@@ -22048,7 +22375,7 @@ function normalizeTarget3(input) {
|
|
|
22048
22375
|
if (!isUnavailableCode2(disposition.code)) {
|
|
22049
22376
|
throw new TypeError("target disposition has an invalid unavailable code");
|
|
22050
22377
|
}
|
|
22051
|
-
const evidence = ordinaryArray(disposition.evidenceDigests, MAX_EVIDENCE, "target evidence").map((
|
|
22378
|
+
const evidence = ordinaryArray(disposition.evidenceDigests, MAX_EVIDENCE, "target evidence").map((digest4) => requireDigest3(digest4, "target evidence")).sort();
|
|
22052
22379
|
if (evidence.length === 0)
|
|
22053
22380
|
throw new TypeError("unavailable target requires evidence");
|
|
22054
22381
|
for (let index = 1;index < evidence.length; index += 1) {
|
|
@@ -22079,12 +22406,12 @@ function requireRequestLockProjection(request, lock) {
|
|
|
22079
22406
|
}
|
|
22080
22407
|
if (request.target.kind === "binding") {
|
|
22081
22408
|
const binding = lock.bindings[request.target.id];
|
|
22082
|
-
if (binding === undefined || !sameJson2(binding.settings, request.settings) || !sameJson2(binding.slots, request.flowSlots)) {
|
|
22409
|
+
if (binding === undefined || !sameJson2(binding.settings, request.settings) || !sameJson2(binding.slots, request.flowSlots) || !sameJson2(binding.commands ?? {}, request.commands ?? {})) {
|
|
22083
22410
|
throw new TypeError("activation request Binding configuration does not match its lock projection");
|
|
22084
22411
|
}
|
|
22085
22412
|
return;
|
|
22086
22413
|
}
|
|
22087
|
-
if (Object.keys(request.settings).length !== 0 || Object.keys(request.flowSlots).length !== 0) {
|
|
22414
|
+
if (Object.keys(request.settings).length !== 0 || Object.keys(request.flowSlots).length !== 0 || request.commands !== undefined) {
|
|
22088
22415
|
throw new TypeError("direct Flow activation request must have empty configuration");
|
|
22089
22416
|
}
|
|
22090
22417
|
}
|
|
@@ -22327,7 +22654,7 @@ function normalizePrivateRootRunIdentityInput(value) {
|
|
|
22327
22654
|
inode: unsigned64(project.inode, "root Run project inode")
|
|
22328
22655
|
}),
|
|
22329
22656
|
origin: normalizePrivateRootRunOrigin(root.origin),
|
|
22330
|
-
requestDigest:
|
|
22657
|
+
requestDigest: digest4(root.requestDigest, "root Run identity request"),
|
|
22331
22658
|
coordinatorEpoch: positiveSafeInteger(root.coordinatorEpoch, "root Run identity coordinator epoch")
|
|
22332
22659
|
});
|
|
22333
22660
|
}
|
|
@@ -22398,13 +22725,13 @@ function normalizePrivateRootSpawnIntent(value) {
|
|
|
22398
22725
|
const deadlineUnixMs = nonnegativeSafeInteger(root.deadlineUnixMs, "root Run spawn intent deadline");
|
|
22399
22726
|
return Object.freeze({
|
|
22400
22727
|
kind: "private-root-spawn-intent/1",
|
|
22401
|
-
runId:
|
|
22402
|
-
admissionDigest:
|
|
22728
|
+
runId: digest4(root.runId, "root Run spawn intent run"),
|
|
22729
|
+
admissionDigest: digest4(root.admissionDigest, "root Run spawn intent admission"),
|
|
22403
22730
|
candidateRevision,
|
|
22404
22731
|
coordinatorEpoch,
|
|
22405
|
-
requestDigest:
|
|
22406
|
-
recipeDigest:
|
|
22407
|
-
observationDigest:
|
|
22732
|
+
requestDigest: digest4(root.requestDigest, "root Run spawn intent request"),
|
|
22733
|
+
recipeDigest: digest4(root.recipeDigest, "root Run spawn intent recipe"),
|
|
22734
|
+
observationDigest: digest4(root.observationDigest, "root Run spawn intent observation"),
|
|
22408
22735
|
deadlineUnixMs
|
|
22409
22736
|
});
|
|
22410
22737
|
}
|
|
@@ -22502,7 +22829,7 @@ function exactRecord5(value, keys, label) {
|
|
|
22502
22829
|
}
|
|
22503
22830
|
return value;
|
|
22504
22831
|
}
|
|
22505
|
-
function
|
|
22832
|
+
function digest4(value, label) {
|
|
22506
22833
|
if (typeof value !== "string" || !DIGEST8.test(value)) {
|
|
22507
22834
|
throw new TypeError(`${label} digest is invalid`);
|
|
22508
22835
|
}
|
|
@@ -22551,6 +22878,7 @@ var MAX_STORED_BYTES = 16777216;
|
|
|
22551
22878
|
var MAX_SAFE_REVISION = BigInt(Number.MAX_SAFE_INTEGER);
|
|
22552
22879
|
var DIGEST9 = /^sha256:[0-9a-f]{64}$/;
|
|
22553
22880
|
var WIRE_ID = /^[A-Za-z0-9][A-Za-z0-9._:/-]*$/;
|
|
22881
|
+
var stateTurns = new Map;
|
|
22554
22882
|
var CREATE_CANDIDATES = "CREATE TABLE candidates (revision INTEGER PRIMARY KEY CHECK (revision BETWEEN 1 AND 9007199254740991), candidate_digest TEXT NOT NULL, candidate_bytes BLOB NOT NULL CHECK (length(candidate_bytes) BETWEEN 1 AND 16777216), lock_bytes BLOB NOT NULL CHECK (length(lock_bytes) BETWEEN 1 AND 16777216)) STRICT";
|
|
22555
22883
|
var CREATE_CANDIDATE_HEAD = "CREATE TABLE candidate_head (singleton INTEGER PRIMARY KEY CHECK (singleton = 1), revision INTEGER REFERENCES candidates(revision)) STRICT";
|
|
22556
22884
|
var CREATE_REVIEW_PLANS = "CREATE TABLE review_plans (plan_digest TEXT PRIMARY KEY, candidate_revision INTEGER NOT NULL REFERENCES candidates(revision), plan_bytes BLOB NOT NULL CHECK (length(plan_bytes) BETWEEN 1 AND 16777216)) STRICT";
|
|
@@ -22789,6 +23117,7 @@ async function openPrivateProjectCoordinator(input) {
|
|
|
22789
23117
|
device: owner.root.information.dev,
|
|
22790
23118
|
inode: owner.root.information.ino
|
|
22791
23119
|
}));
|
|
23120
|
+
await owner.finish();
|
|
22792
23121
|
await coordinator.verify();
|
|
22793
23122
|
return coordinator;
|
|
22794
23123
|
} catch (error) {
|
|
@@ -22835,7 +23164,7 @@ async function replacePrivateBunPreparationOwner(input) {
|
|
|
22835
23164
|
const encoded = input.value === null ? null : canonicalJson(input.value);
|
|
22836
23165
|
if (encoded !== null)
|
|
22837
23166
|
requireStoredSize(encoded, "Bun preparation owner");
|
|
22838
|
-
const
|
|
23167
|
+
const digest5 = input.value === null ? null : privateDomainDigest("JIG-Private-Bun-Preparation-Owner/1", input.value);
|
|
22839
23168
|
const owner = await openStateOwner(input.projectRoot, false);
|
|
22840
23169
|
let failure;
|
|
22841
23170
|
try {
|
|
@@ -22845,7 +23174,7 @@ async function replacePrivateBunPreparationOwner(input) {
|
|
|
22845
23174
|
if ((current?.digest ?? null) !== input.expectedDigest) {
|
|
22846
23175
|
invalid("PREPARATION_OWNER_CONFLICT", "Bun preparation cleanup ownership changed");
|
|
22847
23176
|
}
|
|
22848
|
-
const changed = runFinalized(owner.database, "UPDATE coordinator_head SET preparation_owner_digest = ?1, preparation_owner_bytes = ?2 WHERE singleton = 1 AND preparation_owner_digest IS ?3", [
|
|
23177
|
+
const changed = runFinalized(owner.database, "UPDATE coordinator_head SET preparation_owner_digest = ?1, preparation_owner_bytes = ?2 WHERE singleton = 1 AND preparation_owner_digest IS ?3", [digest5, encoded, input.expectedDigest]).changes;
|
|
22849
23178
|
if (changed !== 1)
|
|
22850
23179
|
corrupt("Bun preparation cleanup owner compare-and-set failed");
|
|
22851
23180
|
return readBunPreparationOwner(owner.database);
|
|
@@ -23009,10 +23338,10 @@ async function recordPrivateRootExecutionCheckpoint(input) {
|
|
|
23009
23338
|
}, checkpoint);
|
|
23010
23339
|
const bytes = canonicalJson(envelope);
|
|
23011
23340
|
requireStoredSize(bytes, `root execution ${checkpoint}`);
|
|
23012
|
-
const
|
|
23341
|
+
const digest5 = rootExecutionCheckpointDigest(checkpoint, envelope);
|
|
23013
23342
|
const current = executionFact(before, checkpoint);
|
|
23014
23343
|
if (current !== undefined) {
|
|
23015
|
-
if (current.digest !==
|
|
23344
|
+
if (current.digest !== digest5 || !sameBytes4(checkpointBytes(row, checkpoint), bytes)) {
|
|
23016
23345
|
invalid("RUN_EXECUTION_CHECKPOINT_CONFLICT", `root execution ${checkpoint} checkpoint differs`);
|
|
23017
23346
|
}
|
|
23018
23347
|
return before;
|
|
@@ -23020,7 +23349,7 @@ async function recordPrivateRootExecutionCheckpoint(input) {
|
|
|
23020
23349
|
requireCheckpointAuthority(run, coordinator, checkpoint, envelope.value);
|
|
23021
23350
|
requireCheckpointOrder(before, checkpoint, envelope.value);
|
|
23022
23351
|
const columns = checkpointColumns(checkpoint);
|
|
23023
|
-
const changed = runFinalized(owner.database, `UPDATE root_execution_lifecycles SET ${columns.digest} = ?1, ${columns.bytes} = ?2 WHERE run_id = ?3 AND ${columns.digest} IS NULL`, [
|
|
23352
|
+
const changed = runFinalized(owner.database, `UPDATE root_execution_lifecycles SET ${columns.digest} = ?1, ${columns.bytes} = ?2 WHERE run_id = ?3 AND ${columns.digest} IS NULL`, [digest5, bytes, input.runId]).changes;
|
|
23024
23353
|
if (changed !== 1)
|
|
23025
23354
|
corrupt("root execution checkpoint compare-and-set failed");
|
|
23026
23355
|
return loadRootExecutionLifecycle(owner.database, requireRootExecutionLifecycle(owner.database, input.runId), runRow);
|
|
@@ -23043,7 +23372,7 @@ async function allocatePrivateRootChildOwner(input) {
|
|
|
23043
23372
|
requireWireId(input.parentOperationId, "parent child operation");
|
|
23044
23373
|
const bytes = canonicalJson(input.allocation);
|
|
23045
23374
|
requireStoredSize(bytes, "child owner allocation");
|
|
23046
|
-
const
|
|
23375
|
+
const digest5 = privateDomainDigest("JIG-Private-Root-Child-Owner-Allocation/1", input.allocation);
|
|
23047
23376
|
const owner = await openStateOwner(input.projectRoot, false);
|
|
23048
23377
|
let failure;
|
|
23049
23378
|
try {
|
|
@@ -23060,19 +23389,28 @@ async function allocatePrivateRootChildOwner(input) {
|
|
|
23060
23389
|
const existing = findRootChildOwner(owner.database, input.parentRunId, input.operationId, input.parentOperationId);
|
|
23061
23390
|
if (existing !== null) {
|
|
23062
23391
|
const loaded = loadRootChildOwner(existing);
|
|
23063
|
-
if (loaded.allocation.digest !==
|
|
23392
|
+
if (loaded.allocation.digest !== digest5 || !sameBytes4(existing.allocation_bytes, bytes)) {
|
|
23064
23393
|
invalid("RUN_CHILD_OWNER_CONFLICT", "child operation owner was reused differently");
|
|
23065
23394
|
}
|
|
23066
23395
|
return loaded;
|
|
23067
23396
|
}
|
|
23068
23397
|
requireActiveChildScope(owner.database, input.parentRunId, input.parentOperationId);
|
|
23069
|
-
if (input.parentOperationId !== undefined && (input.allocation === null || typeof input.allocation !== "object" || Array.isArray(input.allocation) ||
|
|
23070
|
-
invalid("RUN_CHILD_OWNER_CONFLICT", "a child Flow may own only
|
|
23398
|
+
if (input.parentOperationId !== undefined && (input.allocation === null || typeof input.allocation !== "object" || Array.isArray(input.allocation) || !["private-root-agent-owner-allocation/1", "private-project-command-owner/1"].includes(String(input.allocation.kind)))) {
|
|
23399
|
+
invalid("RUN_CHILD_OWNER_CONFLICT", "a child Flow may own only an Agent or project-command operation");
|
|
23071
23400
|
}
|
|
23072
|
-
if (
|
|
23073
|
-
|
|
23401
|
+
if (input.parentOperationId === undefined) {
|
|
23402
|
+
const query = statement(owner.database, "SELECT allocation_bytes FROM root_child_owners WHERE parent_run_id = ?1 AND scope_operation_id = ?2");
|
|
23403
|
+
try {
|
|
23404
|
+
const allocations = query.all(input.parentRunId, "").map((row) => decodeJson1(row.allocation_bytes));
|
|
23405
|
+
if (!canReservePrivateRootOperation(allocations, input.allocation))
|
|
23406
|
+
invalid("RUN_CHILD_CAPACITY", "the root operation or aggregate resource budget is occupied");
|
|
23407
|
+
} finally {
|
|
23408
|
+
query.finalize();
|
|
23409
|
+
}
|
|
23410
|
+
} else if (countScopedRootChildOwners(owner.database, input.parentRunId, input.parentOperationId) !== 0n) {
|
|
23411
|
+
invalid("RUN_CHILD_CAPACITY", "the child Flow already has an active effect");
|
|
23074
23412
|
}
|
|
23075
|
-
runFinalized(owner.database, "INSERT INTO root_child_owners(parent_run_id, scope_operation_id, operation_id, allocation_digest, allocation_bytes) VALUES (?1, ?2, ?3, ?4, ?5)", [input.parentRunId, input.parentOperationId ?? "", input.operationId,
|
|
23413
|
+
runFinalized(owner.database, "INSERT INTO root_child_owners(parent_run_id, scope_operation_id, operation_id, allocation_digest, allocation_bytes) VALUES (?1, ?2, ?3, ?4, ?5)", [input.parentRunId, input.parentOperationId ?? "", input.operationId, digest5, bytes]);
|
|
23076
23414
|
return loadRootChildOwner(requireRootChildOwner(owner.database, input.parentRunId, input.operationId, input.parentOperationId));
|
|
23077
23415
|
});
|
|
23078
23416
|
await owner.finish();
|
|
@@ -23094,7 +23432,7 @@ async function recordPrivateRootChildSandbox(input) {
|
|
|
23094
23432
|
requireDigest4(input.allocationDigest, "child allocation");
|
|
23095
23433
|
const bytes = canonicalJson(input.sandbox);
|
|
23096
23434
|
requireStoredSize(bytes, "child sandbox owner");
|
|
23097
|
-
const
|
|
23435
|
+
const digest5 = privateDomainDigest("JIG-Private-Root-Child-Sandbox/1", input.sandbox);
|
|
23098
23436
|
const owner = await openStateOwner(input.projectRoot, false);
|
|
23099
23437
|
let failure;
|
|
23100
23438
|
try {
|
|
@@ -23106,7 +23444,7 @@ async function recordPrivateRootChildSandbox(input) {
|
|
|
23106
23444
|
invalid("RUN_CHILD_OWNER_CONFLICT", "child sandbox names a different allocation");
|
|
23107
23445
|
}
|
|
23108
23446
|
if (row.sandbox_digest !== null) {
|
|
23109
|
-
if (row.sandbox_digest !==
|
|
23447
|
+
if (row.sandbox_digest !== digest5 || !sameBytes4(row.sandbox_bytes, bytes)) {
|
|
23110
23448
|
invalid("RUN_CHILD_OWNER_CONFLICT", "child sandbox owner differs");
|
|
23111
23449
|
}
|
|
23112
23450
|
return loadRootChildOwner(row);
|
|
@@ -23119,7 +23457,7 @@ async function recordPrivateRootChildSandbox(input) {
|
|
|
23119
23457
|
invalid("RUN_OWNER_CHANGED", "only the active parent coordinator may seal child work");
|
|
23120
23458
|
}
|
|
23121
23459
|
requireActiveChildScope(owner.database, input.parentRunId, input.parentOperationId);
|
|
23122
|
-
const changed = runFinalized(owner.database, "UPDATE root_child_owners SET sandbox_digest = ?1, sandbox_bytes = ?2 WHERE parent_run_id = ?3 AND operation_id = ?4 AND scope_operation_id = ?5 AND sandbox_digest IS NULL", [
|
|
23460
|
+
const changed = runFinalized(owner.database, "UPDATE root_child_owners SET sandbox_digest = ?1, sandbox_bytes = ?2 WHERE parent_run_id = ?3 AND operation_id = ?4 AND scope_operation_id = ?5 AND sandbox_digest IS NULL", [digest5, bytes, input.parentRunId, input.operationId, input.parentOperationId ?? ""]).changes;
|
|
23123
23461
|
if (changed !== 1)
|
|
23124
23462
|
corrupt("child sandbox owner compare-and-set failed");
|
|
23125
23463
|
return loadRootChildOwner(requireRootChildOwner(owner.database, input.parentRunId, input.operationId, input.parentOperationId));
|
|
@@ -23144,7 +23482,7 @@ async function recordPrivateRootChildFence(input) {
|
|
|
23144
23482
|
requireDigest4(input.sandboxDigest, "child sandbox");
|
|
23145
23483
|
const bytes = canonicalJson(input.fence);
|
|
23146
23484
|
requireStoredSize(bytes, "child fence");
|
|
23147
|
-
const
|
|
23485
|
+
const digest5 = privateDomainDigest("JIG-Private-Root-Child-Fence/1", input.fence);
|
|
23148
23486
|
const owner = await openStateOwner(input.projectRoot, false);
|
|
23149
23487
|
let failure;
|
|
23150
23488
|
try {
|
|
@@ -23156,12 +23494,12 @@ async function recordPrivateRootChildFence(input) {
|
|
|
23156
23494
|
invalid("RUN_CHILD_OWNER_CONFLICT", "child fence names a different owner");
|
|
23157
23495
|
}
|
|
23158
23496
|
if (row.fence_digest !== null) {
|
|
23159
|
-
if (row.fence_digest !==
|
|
23497
|
+
if (row.fence_digest !== digest5 || !sameBytes4(row.fence_bytes, bytes)) {
|
|
23160
23498
|
invalid("RUN_CHILD_OWNER_CONFLICT", "child fence differs");
|
|
23161
23499
|
}
|
|
23162
23500
|
return loadRootChildOwner(row);
|
|
23163
23501
|
}
|
|
23164
|
-
const changed = runFinalized(owner.database, "UPDATE root_child_owners SET fence_digest = ?1, fence_bytes = ?2 WHERE parent_run_id = ?3 AND operation_id = ?4 AND scope_operation_id = ?5 AND fence_digest IS NULL", [
|
|
23502
|
+
const changed = runFinalized(owner.database, "UPDATE root_child_owners SET fence_digest = ?1, fence_bytes = ?2 WHERE parent_run_id = ?3 AND operation_id = ?4 AND scope_operation_id = ?5 AND fence_digest IS NULL", [digest5, bytes, input.parentRunId, input.operationId, input.parentOperationId ?? ""]).changes;
|
|
23165
23503
|
if (changed !== 1)
|
|
23166
23504
|
corrupt("child fence compare-and-set failed");
|
|
23167
23505
|
return loadRootChildOwner(requireRootChildOwner(owner.database, input.parentRunId, input.operationId, input.parentOperationId));
|
|
@@ -23187,7 +23525,7 @@ async function recordPrivateRootChildCleanup(input) {
|
|
|
23187
23525
|
requireDigest4(input.fenceDigest, "child fence");
|
|
23188
23526
|
const bytes = canonicalJson(input.cleanup);
|
|
23189
23527
|
requireStoredSize(bytes, "child cleanup");
|
|
23190
|
-
const
|
|
23528
|
+
const digest5 = privateDomainDigest("JIG-Private-Root-Child-Cleanup/1", input.cleanup);
|
|
23191
23529
|
const owner = await openStateOwner(input.projectRoot, false);
|
|
23192
23530
|
let failure;
|
|
23193
23531
|
try {
|
|
@@ -23199,12 +23537,12 @@ async function recordPrivateRootChildCleanup(input) {
|
|
|
23199
23537
|
invalid("RUN_CHILD_OWNER_CONFLICT", "child cleanup names different durable evidence");
|
|
23200
23538
|
}
|
|
23201
23539
|
if (row.cleanup_digest !== null) {
|
|
23202
|
-
if (row.cleanup_digest !==
|
|
23540
|
+
if (row.cleanup_digest !== digest5 || !sameBytes4(row.cleanup_bytes, bytes)) {
|
|
23203
23541
|
invalid("RUN_CHILD_OWNER_CONFLICT", "child cleanup differs");
|
|
23204
23542
|
}
|
|
23205
23543
|
return loadRootChildOwner(row);
|
|
23206
23544
|
}
|
|
23207
|
-
const changed = runFinalized(owner.database, "UPDATE root_child_owners SET cleanup_digest = ?1, cleanup_bytes = ?2 WHERE parent_run_id = ?3 AND operation_id = ?4 AND scope_operation_id = ?5 AND cleanup_digest IS NULL", [
|
|
23545
|
+
const changed = runFinalized(owner.database, "UPDATE root_child_owners SET cleanup_digest = ?1, cleanup_bytes = ?2 WHERE parent_run_id = ?3 AND operation_id = ?4 AND scope_operation_id = ?5 AND cleanup_digest IS NULL", [digest5, bytes, input.parentRunId, input.operationId, input.parentOperationId ?? ""]).changes;
|
|
23208
23546
|
if (changed !== 1)
|
|
23209
23547
|
corrupt("child cleanup compare-and-set failed");
|
|
23210
23548
|
return loadRootChildOwner(requireRootChildOwner(owner.database, input.parentRunId, input.operationId, input.parentOperationId));
|
|
@@ -23268,7 +23606,7 @@ async function closePrivateRootChildOwner(input) {
|
|
|
23268
23606
|
await coordinator.verify();
|
|
23269
23607
|
const row = findRootChildOwner(owner.database, input.parentRunId, input.operationId, input.parentOperationId);
|
|
23270
23608
|
if (input.parentOperationId === undefined && countScopedRootChildOwners(owner.database, input.parentRunId, input.operationId) !== 0n) {
|
|
23271
|
-
invalid("RUN_EXECUTION_INCOMPLETE", "child Flow still has an active
|
|
23609
|
+
invalid("RUN_EXECUTION_INCOMPLETE", "child Flow still has an active operation owner");
|
|
23272
23610
|
}
|
|
23273
23611
|
if (row === null)
|
|
23274
23612
|
return;
|
|
@@ -23459,7 +23797,7 @@ function requireActiveChildScope(database, parentRunId, parentOperationId) {
|
|
|
23459
23797
|
}
|
|
23460
23798
|
const allocation = loadRootChildOwner(parent).allocation.value;
|
|
23461
23799
|
if (allocation === null || typeof allocation !== "object" || Array.isArray(allocation) || allocation.kind !== "private-root-child-owner-allocation/1") {
|
|
23462
|
-
invalid("RUN_CHILD_PARENT_INACTIVE", "only a direct child Flow may own
|
|
23800
|
+
invalid("RUN_CHILD_PARENT_INACTIVE", "only a direct child Flow may own a nested operation");
|
|
23463
23801
|
}
|
|
23464
23802
|
}
|
|
23465
23803
|
async function loadPrivateRootRunForCoordinator(input) {
|
|
@@ -23845,20 +24183,20 @@ function loadRootExecutionLifecycle(database, row, run) {
|
|
|
23845
24183
|
return Object.freeze(result2);
|
|
23846
24184
|
}
|
|
23847
24185
|
function loadOptionalExecutionFact(row, checkpoint, allocationDigest) {
|
|
23848
|
-
const
|
|
24186
|
+
const digest5 = checkpointDigest(row, checkpoint);
|
|
23849
24187
|
const bytes = checkpointBytes(row, checkpoint);
|
|
23850
|
-
if (
|
|
24188
|
+
if (digest5 === null !== (bytes === null))
|
|
23851
24189
|
corrupt(`stored root execution ${checkpoint} pair is incomplete`);
|
|
23852
|
-
if (
|
|
24190
|
+
if (digest5 === null || bytes === null)
|
|
23853
24191
|
return {};
|
|
23854
|
-
requireDigest4(
|
|
24192
|
+
requireDigest4(digest5, `stored root execution ${checkpoint}`);
|
|
23855
24193
|
let envelope;
|
|
23856
24194
|
try {
|
|
23857
24195
|
envelope = normalizeRootExecutionCheckpoint(decodeJson1(bytes), checkpoint);
|
|
23858
24196
|
} catch {
|
|
23859
24197
|
corrupt(`stored root execution ${checkpoint} checkpoint is invalid`);
|
|
23860
24198
|
}
|
|
23861
|
-
if (!sameBytes4(bytes, canonicalJson(envelope)) || rootExecutionCheckpointDigest(checkpoint, envelope) !==
|
|
24199
|
+
if (!sameBytes4(bytes, canonicalJson(envelope)) || rootExecutionCheckpointDigest(checkpoint, envelope) !== digest5 || envelope.runId !== row.run_id || envelope.allocationDigest !== allocationDigest) {
|
|
23862
24200
|
corrupt(`stored root execution ${checkpoint} differs from its durable identity`);
|
|
23863
24201
|
}
|
|
23864
24202
|
if (checkpoint === "provisional" || checkpoint === "admitted") {
|
|
@@ -23870,7 +24208,7 @@ function loadOptionalExecutionFact(row, checkpoint, allocationDigest) {
|
|
|
23870
24208
|
}
|
|
23871
24209
|
envelope = Object.freeze({ ...envelope, value: terminal });
|
|
23872
24210
|
}
|
|
23873
|
-
return { [checkpoint]: Object.freeze({ digest:
|
|
24211
|
+
return { [checkpoint]: Object.freeze({ digest: digest5, value: envelope.value }) };
|
|
23874
24212
|
}
|
|
23875
24213
|
function findRootTerminal(database, runId) {
|
|
23876
24214
|
const query = statement(database, "SELECT run_id, terminal_digest, terminal_bytes FROM root_terminals WHERE run_id = ?1");
|
|
@@ -24035,8 +24373,8 @@ function persistRootTerminal(database, runId, terminalValue) {
|
|
|
24035
24373
|
const terminal = normalizePrivateRootTerminal(terminalValue);
|
|
24036
24374
|
const bytes = privateRootTerminalBytes(terminal);
|
|
24037
24375
|
requireStoredSize(bytes, "root Run terminal");
|
|
24038
|
-
const
|
|
24039
|
-
runFinalized(database, "INSERT INTO root_terminals(run_id, terminal_digest, terminal_bytes) VALUES (?1, ?2, ?3)", [runId,
|
|
24376
|
+
const digest5 = privateDomainDigest("JIG-Private-Root-Terminal/1", terminal);
|
|
24377
|
+
runFinalized(database, "INSERT INTO root_terminals(run_id, terminal_digest, terminal_bytes) VALUES (?1, ?2, ?3)", [runId, digest5, bytes]);
|
|
24040
24378
|
}
|
|
24041
24379
|
function normalizeRootExecutionAllocation(value) {
|
|
24042
24380
|
const root = exactJsonObject(value, ["kind", "runId", "spawnIntentDigest", "coordinatorEpoch", "value"], "root execution allocation");
|
|
@@ -24361,6 +24699,7 @@ async function openStateOwner(projectRoot, create) {
|
|
|
24361
24699
|
const root = ownsRoot ? await openPrivateProjectRoot(projectRoot) : requirePrivateProjectRoot(projectRoot);
|
|
24362
24700
|
if (!ownsRoot)
|
|
24363
24701
|
await root.verify();
|
|
24702
|
+
const releaseTurn = await acquireStateTurn(root);
|
|
24364
24703
|
let directory;
|
|
24365
24704
|
let database;
|
|
24366
24705
|
try {
|
|
@@ -24415,6 +24754,7 @@ async function openStateOwner(projectRoot, create) {
|
|
|
24415
24754
|
database.close(true);
|
|
24416
24755
|
databaseClosed = true;
|
|
24417
24756
|
await owner.verify();
|
|
24757
|
+
releaseTurn();
|
|
24418
24758
|
},
|
|
24419
24759
|
async dispose() {
|
|
24420
24760
|
if (disposed)
|
|
@@ -24441,6 +24781,7 @@ async function openStateOwner(projectRoot, create) {
|
|
|
24441
24781
|
failures.push(error);
|
|
24442
24782
|
}
|
|
24443
24783
|
}
|
|
24784
|
+
releaseTurn();
|
|
24444
24785
|
if (failures.length > 0)
|
|
24445
24786
|
throw new AggregateError(failures, "admission state cleanup did not complete");
|
|
24446
24787
|
}
|
|
@@ -24457,11 +24798,31 @@ async function openStateOwner(projectRoot, create) {
|
|
|
24457
24798
|
await root.dispose().catch(() => {
|
|
24458
24799
|
return;
|
|
24459
24800
|
});
|
|
24801
|
+
releaseTurn();
|
|
24460
24802
|
if (isSqliteBusy(error))
|
|
24461
24803
|
busy();
|
|
24462
24804
|
throw error;
|
|
24463
24805
|
}
|
|
24464
24806
|
}
|
|
24807
|
+
async function acquireStateTurn(root) {
|
|
24808
|
+
const key = `${root.information.dev}:${root.information.ino}`;
|
|
24809
|
+
const previous = stateTurns.get(key);
|
|
24810
|
+
let resolve8;
|
|
24811
|
+
const current = new Promise((done) => {
|
|
24812
|
+
resolve8 = done;
|
|
24813
|
+
});
|
|
24814
|
+
stateTurns.set(key, current);
|
|
24815
|
+
await previous;
|
|
24816
|
+
let released = false;
|
|
24817
|
+
return () => {
|
|
24818
|
+
if (released)
|
|
24819
|
+
return;
|
|
24820
|
+
released = true;
|
|
24821
|
+
if (stateTurns.get(key) === current)
|
|
24822
|
+
stateTurns.delete(key);
|
|
24823
|
+
resolve8();
|
|
24824
|
+
};
|
|
24825
|
+
}
|
|
24465
24826
|
async function openCheckedDirectory(path, projectDevice) {
|
|
24466
24827
|
let observed;
|
|
24467
24828
|
try {
|
|
@@ -24752,18 +25113,18 @@ function requireCandidateRow(database, revision) {
|
|
|
24752
25113
|
corrupt(`candidate revision ${revision} is missing or duplicated`);
|
|
24753
25114
|
return rows[0];
|
|
24754
25115
|
}
|
|
24755
|
-
function requirePlanRow(database,
|
|
25116
|
+
function requirePlanRow(database, digest5) {
|
|
24756
25117
|
const query = statement(database, "SELECT plan_digest, candidate_revision, plan_bytes FROM review_plans WHERE plan_digest = ?1");
|
|
24757
25118
|
let rows;
|
|
24758
25119
|
try {
|
|
24759
|
-
rows = query.all(
|
|
25120
|
+
rows = query.all(digest5).map(copiedPlanRow);
|
|
24760
25121
|
} finally {
|
|
24761
25122
|
query.finalize();
|
|
24762
25123
|
}
|
|
24763
25124
|
if (rows.length === 0)
|
|
24764
|
-
unavailable("ADMISSION_PLAN_MISSING", `review plan ${
|
|
25125
|
+
unavailable("ADMISSION_PLAN_MISSING", `review plan ${digest5} does not exist`);
|
|
24765
25126
|
if (rows.length !== 1)
|
|
24766
|
-
corrupt(`review plan ${
|
|
25127
|
+
corrupt(`review plan ${digest5} is duplicated`);
|
|
24767
25128
|
return rows[0];
|
|
24768
25129
|
}
|
|
24769
25130
|
function requireAdmissionRow(database, revision) {
|
|
@@ -24790,16 +25151,16 @@ function findAdmissionByPlan(database, planDigest) {
|
|
|
24790
25151
|
corrupt(`plan ${planDigest} names multiple admissions`);
|
|
24791
25152
|
return rows[0] ?? null;
|
|
24792
25153
|
}
|
|
24793
|
-
function requireAdmissionByDigest(database,
|
|
25154
|
+
function requireAdmissionByDigest(database, digest5) {
|
|
24794
25155
|
const query = statement(database, "SELECT revision, admission_digest, base_generation, plan_digest, admission_bytes FROM admissions WHERE admission_digest = ?1");
|
|
24795
25156
|
let rows;
|
|
24796
25157
|
try {
|
|
24797
|
-
rows = query.all(
|
|
25158
|
+
rows = query.all(digest5).map(copiedAdmissionRow);
|
|
24798
25159
|
} finally {
|
|
24799
25160
|
query.finalize();
|
|
24800
25161
|
}
|
|
24801
25162
|
if (rows.length !== 1)
|
|
24802
|
-
corrupt(`base admission ${
|
|
25163
|
+
corrupt(`base admission ${digest5} is missing or duplicated`);
|
|
24803
25164
|
return rows[0];
|
|
24804
25165
|
}
|
|
24805
25166
|
function copiedCandidateRow(row) {
|
|
@@ -25308,9 +25669,9 @@ async function reacquireCandidateArtifacts(packageStoreRoot, candidate) {
|
|
|
25308
25669
|
...Object.values(candidate.lock.packages).map((entry) => entry.digest),
|
|
25309
25670
|
...candidate.candidate.targets.flatMap((target) => target.disposition.state === "ready" ? [target.disposition.executionPackage.digest] : [])
|
|
25310
25671
|
]);
|
|
25311
|
-
for (const
|
|
25312
|
-
const reference = normalizePackageArtifactRef({ kind: "flow-package/1", digest:
|
|
25313
|
-
captures.set(
|
|
25672
|
+
for (const digest5 of [...digests].sort()) {
|
|
25673
|
+
const reference = normalizePackageArtifactRef({ kind: "flow-package/1", digest: digest5 });
|
|
25674
|
+
captures.set(digest5, await captureStoredPackage(packageStoreRoot, reference));
|
|
25314
25675
|
}
|
|
25315
25676
|
for (const [path, expected] of Object.entries(candidate.lock.packages)) {
|
|
25316
25677
|
const captured = captures.get(expected.digest);
|
|
@@ -25334,10 +25695,10 @@ async function reacquireCandidateArtifacts(packageStoreRoot, candidate) {
|
|
|
25334
25695
|
}
|
|
25335
25696
|
let disposed = false;
|
|
25336
25697
|
return Object.freeze({
|
|
25337
|
-
inspection(
|
|
25338
|
-
const inspected = inspections.get(
|
|
25698
|
+
inspection(digest5) {
|
|
25699
|
+
const inspected = inspections.get(digest5);
|
|
25339
25700
|
if (inspected === undefined)
|
|
25340
|
-
corrupt(`stored package ${
|
|
25701
|
+
corrupt(`stored package ${digest5} has no verified inspection`);
|
|
25341
25702
|
return inspected;
|
|
25342
25703
|
},
|
|
25343
25704
|
async dispose() {
|
|
@@ -26053,8 +26414,8 @@ async function capturedFromPrepared(value) {
|
|
|
26053
26414
|
contents.clear();
|
|
26054
26415
|
}
|
|
26055
26416
|
};
|
|
26056
|
-
const
|
|
26057
|
-
return createCapturedPackage("prepared Bun dependency tree", frozenFiles,
|
|
26417
|
+
const digest5 = await packageDigest(frozenFiles, (file) => backing.stream(file.path));
|
|
26418
|
+
return createCapturedPackage("prepared Bun dependency tree", frozenFiles, digest5, backing);
|
|
26058
26419
|
}
|
|
26059
26420
|
async function* jsonLines(source, maximum) {
|
|
26060
26421
|
let pending = [];
|
|
@@ -26157,6 +26518,7 @@ function projectCandidate(lock, targetValues) {
|
|
|
26157
26518
|
packagePath: request.packagePath,
|
|
26158
26519
|
entrypoint: request.entrypoint,
|
|
26159
26520
|
settings: request.settings,
|
|
26521
|
+
...request.commands === undefined ? {} : { commands: request.commands },
|
|
26160
26522
|
attachments: request.attachments,
|
|
26161
26523
|
...Object.keys(request.attachments).length === 0 ? {} : {
|
|
26162
26524
|
filePolicy: "Root-only captured input; one initially empty bounded output; no live host writes."
|
|
@@ -26630,7 +26992,7 @@ import { lstat as lstat18, mkdir as mkdir11, realpath as realpath13 } from "fs/p
|
|
|
26630
26992
|
import { join as join13 } from "path";
|
|
26631
26993
|
|
|
26632
26994
|
// src/run/session.ts
|
|
26633
|
-
import { createHash as
|
|
26995
|
+
import { createHash as createHash9 } from "crypto";
|
|
26634
26996
|
var ROOT_ID = "host:1";
|
|
26635
26997
|
var MAX_PENDING_COMPONENT_REQUESTS = 64;
|
|
26636
26998
|
var MAX_COMPONENT_REQUEST_IDS = 65536;
|
|
@@ -26899,7 +27261,7 @@ class RunHostSession {
|
|
|
26899
27261
|
this.graceTimer ??= setTimeout(() => this.startTermination(), this.limits.cancellationGraceMs);
|
|
26900
27262
|
return;
|
|
26901
27263
|
}
|
|
26902
|
-
if (request.method !== "flow/
|
|
27264
|
+
if (request.method !== "flow/run-child" && request.method !== "capability/call") {
|
|
26903
27265
|
this.queueResponse(request.id, errorMessage(request.id, -32601, "Method not found"));
|
|
26904
27266
|
return;
|
|
26905
27267
|
}
|
|
@@ -26923,9 +27285,9 @@ class RunHostSession {
|
|
|
26923
27285
|
this.attachOperationWaiter(request.id, prior);
|
|
26924
27286
|
return;
|
|
26925
27287
|
}
|
|
26926
|
-
const dispatch = operation.method === "flow/
|
|
27288
|
+
const dispatch = operation.method === "flow/run-child" ? this.dispatcher?.runChildFlow : this.dispatcher?.callCapability;
|
|
26927
27289
|
if (dispatch === undefined) {
|
|
26928
|
-
const terminal = failedOperation("UNAVAILABLE", operation.method === "
|
|
27290
|
+
const terminal = failedOperation("UNAVAILABLE", operation.method === "capability/call" ? "no effect dispatcher is installed" : "no child Flow dispatcher is installed");
|
|
26929
27291
|
const settled = {
|
|
26930
27292
|
signature: operation.signature,
|
|
26931
27293
|
controller: new AbortController,
|
|
@@ -26943,7 +27305,7 @@ class RunHostSession {
|
|
|
26943
27305
|
};
|
|
26944
27306
|
this.operations.set(operation.operationId, record2);
|
|
26945
27307
|
this.attachOperationWaiter(request.id, record2);
|
|
26946
|
-
const task = (operation.method === "flow/
|
|
27308
|
+
const task = (operation.method === "flow/run-child" ? this.dispatcher.runChildFlow(operation.call, record2.controller.signal).then((terminal) => normalizeFlowOperationTerminal(terminal)) : this.dispatcher.callCapability(operation.call, record2.controller.signal).then((terminal) => normalizeEffectOperationTerminal(terminal))).catch((error) => failedOperation(error instanceof InvalidDispatcherResult ? "INVALID_RESULT" : "EXECUTION_FAILED", error instanceof InvalidDispatcherResult ? "the host dispatcher returned an invalid result" : "the host operation failed")).then((terminal) => this.settleOperation(record2, terminal));
|
|
26947
27309
|
this.own(task);
|
|
26948
27310
|
}
|
|
26949
27311
|
receiveNotification(notification) {
|
|
@@ -27406,7 +27768,7 @@ function parseRunResult(value) {
|
|
|
27406
27768
|
}
|
|
27407
27769
|
function parseOperation(request) {
|
|
27408
27770
|
const params = requireObject3(request.params, `${request.method} params`);
|
|
27409
|
-
if (request.method === "flow/
|
|
27771
|
+
if (request.method === "flow/run-child") {
|
|
27410
27772
|
const keys = Object.hasOwn(params, "intent") ? ["operationId", "slot", "intent", "input"] : ["operationId", "slot", "input"];
|
|
27411
27773
|
requireExactKeys(params, keys);
|
|
27412
27774
|
const operationId2 = requireWireId2(params.operationId);
|
|
@@ -27424,7 +27786,7 @@ function parseOperation(request) {
|
|
|
27424
27786
|
input: params.input
|
|
27425
27787
|
});
|
|
27426
27788
|
return {
|
|
27427
|
-
method: "flow/
|
|
27789
|
+
method: "flow/run-child",
|
|
27428
27790
|
operationId: operationId2,
|
|
27429
27791
|
signature: operationSignature(request.method, params),
|
|
27430
27792
|
call
|
|
@@ -27435,7 +27797,7 @@ function parseOperation(request) {
|
|
|
27435
27797
|
const slot = requireLocalName4(params.slot);
|
|
27436
27798
|
const method = requireLocalName4(params.method);
|
|
27437
27799
|
return {
|
|
27438
|
-
method: "
|
|
27800
|
+
method: "capability/call",
|
|
27439
27801
|
operationId,
|
|
27440
27802
|
signature: operationSignature(request.method, params),
|
|
27441
27803
|
call: Object.freeze({ operationId, slot, method, input: params.input })
|
|
@@ -27448,7 +27810,7 @@ function operationSignature(method, params) {
|
|
|
27448
27810
|
semantic[key] = value;
|
|
27449
27811
|
}
|
|
27450
27812
|
const bytes = canonicalJson({ method, params: semantic });
|
|
27451
|
-
return
|
|
27813
|
+
return createHash9("sha256").update(bytes).digest("hex");
|
|
27452
27814
|
}
|
|
27453
27815
|
function errorMessage(id, code, message) {
|
|
27454
27816
|
return { jsonrpc: "2.0", id, error: { code, message } };
|
|
@@ -27479,7 +27841,11 @@ function normalizeFlowOperationTerminal(value) {
|
|
|
27479
27841
|
if (value.status === "succeeded") {
|
|
27480
27842
|
try {
|
|
27481
27843
|
const result2 = parseRunResult(value.result);
|
|
27482
|
-
return Object.freeze({
|
|
27844
|
+
return Object.freeze({
|
|
27845
|
+
status: "succeeded",
|
|
27846
|
+
method: "flow/run-child",
|
|
27847
|
+
result: result2
|
|
27848
|
+
});
|
|
27483
27849
|
} catch (error) {
|
|
27484
27850
|
throw new InvalidDispatcherResult(`invalid Flow dispatcher result: ${errorText9(error)}`);
|
|
27485
27851
|
}
|
|
@@ -27490,7 +27856,11 @@ function normalizeEffectOperationTerminal(value) {
|
|
|
27490
27856
|
if (value.status === "succeeded") {
|
|
27491
27857
|
try {
|
|
27492
27858
|
const result2 = parseEffectResult(value.result);
|
|
27493
|
-
return Object.freeze({
|
|
27859
|
+
return Object.freeze({
|
|
27860
|
+
status: "succeeded",
|
|
27861
|
+
method: "capability/call",
|
|
27862
|
+
result: result2
|
|
27863
|
+
});
|
|
27494
27864
|
} catch (error) {
|
|
27495
27865
|
throw new InvalidDispatcherResult(`invalid effect dispatcher result: ${errorText9(error)}`);
|
|
27496
27866
|
}
|
|
@@ -27586,7 +27956,7 @@ import {
|
|
|
27586
27956
|
rmdir as rmdir3,
|
|
27587
27957
|
unlink as unlink5
|
|
27588
27958
|
} from "fs/promises";
|
|
27589
|
-
import { dirname as
|
|
27959
|
+
import { dirname as dirname8, isAbsolute as isAbsolute2, join as join10, resolve as resolve8 } from "path";
|
|
27590
27960
|
import { types as utilTypes8 } from "util";
|
|
27591
27961
|
var ALLOCATION_KIND = "private-package-materialization-allocation/1";
|
|
27592
27962
|
var LEASE_KIND = "private-package-materialization-lease/1";
|
|
@@ -28419,6 +28789,9 @@ function invalidResult(terminal, message, details) {
|
|
|
28419
28789
|
import { lstat as lstat17, mkdir as mkdir10, realpath as realpath12 } from "fs/promises";
|
|
28420
28790
|
import { join as join12 } from "path";
|
|
28421
28791
|
|
|
28792
|
+
// src/internal/root-project-command-controller.ts
|
|
28793
|
+
import { closeSync as closeSync3 } from "fs";
|
|
28794
|
+
|
|
28422
28795
|
// src/internal/root-agent-run-controller.ts
|
|
28423
28796
|
import { lstat as lstat16, mkdir as mkdir9, realpath as realpath11 } from "fs/promises";
|
|
28424
28797
|
import { join as join11 } from "path";
|
|
@@ -49319,20 +49692,20 @@ function getName(value, options) {
|
|
|
49319
49692
|
const name = "name" in value ? value.name : undefined;
|
|
49320
49693
|
const explicitName = name && String(name) || "filename" in value && value.filename && String(value.filename);
|
|
49321
49694
|
if (explicitName) {
|
|
49322
|
-
return options?.stripFilename === false ? normalizeFilenamePath(explicitName) :
|
|
49695
|
+
return options?.stripFilename === false ? normalizeFilenamePath(explicitName) : basename2(explicitName);
|
|
49323
49696
|
}
|
|
49324
49697
|
const url2 = "url" in value && value.url && String(value.url);
|
|
49325
49698
|
if (url2) {
|
|
49326
49699
|
try {
|
|
49327
|
-
return
|
|
49700
|
+
return basename2(new URL(url2).pathname);
|
|
49328
49701
|
} catch {
|
|
49329
|
-
return
|
|
49702
|
+
return basename2(url2);
|
|
49330
49703
|
}
|
|
49331
49704
|
}
|
|
49332
49705
|
const path = "path" in value && value.path && String(value.path);
|
|
49333
|
-
return path ?
|
|
49706
|
+
return path ? basename2(path) : undefined;
|
|
49334
49707
|
}
|
|
49335
|
-
function
|
|
49708
|
+
function basename2(value) {
|
|
49336
49709
|
return value.split(/[\\/]/).pop() || undefined;
|
|
49337
49710
|
}
|
|
49338
49711
|
function normalizeFilenamePath(value) {
|
|
@@ -49513,7 +49886,7 @@ function getStreamingFileName(value, options) {
|
|
|
49513
49886
|
if (typeof name !== "string" || !name) {
|
|
49514
49887
|
throw new TypeError("Streaming upload file name must be a non-empty string");
|
|
49515
49888
|
}
|
|
49516
|
-
return options.stripFilenames === false ? normalizeFilenamePath(name) :
|
|
49889
|
+
return options.stripFilenames === false ? normalizeFilenamePath(name) : basename2(name) ?? "unknown_file";
|
|
49517
49890
|
}
|
|
49518
49891
|
return getName(value, { stripFilename: options.stripFilenames }) ?? "unknown_file";
|
|
49519
49892
|
}
|
|
@@ -59869,7 +60242,6 @@ var SANDBOX_KIND = "private-root-agent-sandbox/1";
|
|
|
59869
60242
|
var CLEANUP_KIND = "private-root-agent-cleanup/1";
|
|
59870
60243
|
var CANCELLATION_GRACE_MS = 1000;
|
|
59871
60244
|
var PROVIDER_STDERR_BYTES = 64 * 1024;
|
|
59872
|
-
var AGENT_PROVIDER_MINIMUM_PIDS = 128;
|
|
59873
60245
|
var PROVIDER_INSTRUCTION_BYTES = 1048576;
|
|
59874
60246
|
var DIGEST11 = /^sha256:[0-9a-f]{64}$/;
|
|
59875
60247
|
var decoder10 = new TextDecoder("utf-8", { fatal: true, ignoreBOM: true });
|
|
@@ -60234,7 +60606,7 @@ function backendPlan(recipe, provider, deadlineUnixMs, identity2) {
|
|
|
60234
60606
|
runId: `agent-${identity2.slice(0, 42)}`,
|
|
60235
60607
|
limits: Object.freeze({
|
|
60236
60608
|
...recipe.resourceCeilings,
|
|
60237
|
-
pids:
|
|
60609
|
+
pids: PRIVATE_AGENT_PROVIDER_PIDS,
|
|
60238
60610
|
deadlineUnixMs,
|
|
60239
60611
|
cancellationGraceMs: CANCELLATION_GRACE_MS
|
|
60240
60612
|
}),
|
|
@@ -60494,7 +60866,7 @@ async function requireAllocationMatchesParent(input, lifecycle, allocation) {
|
|
|
60494
60866
|
...rootInput,
|
|
60495
60867
|
...parentFlow === null ? {} : { parentFlow }
|
|
60496
60868
|
});
|
|
60497
|
-
if (allocation.parentRunId !== input.parent.run.runId || allocation.coordinatorEpoch !== input.parent.run.coordinatorEpoch || allocation.operationId !== lifecycle.operationId || allocation.parentRequestDigest !== target.request.digest || allocation.effectiveDeadlineUnixMs > input.parent.intent.deadlineUnixMs || Object.values(target.request.capabilities).
|
|
60869
|
+
if (allocation.parentRunId !== input.parent.run.runId || allocation.coordinatorEpoch !== input.parent.run.coordinatorEpoch || allocation.operationId !== lifecycle.operationId || allocation.parentRequestDigest !== target.request.digest || allocation.effectiveDeadlineUnixMs > input.parent.intent.deadlineUnixMs || !Object.values(target.request.capabilities).some(({ digest: digest5 }) => digest5 === AGENT_RUN_CONTRACT_DIGEST)) {
|
|
60498
60870
|
throw new Error("durable Agent allocation differs from its admitted parent or provider");
|
|
60499
60871
|
}
|
|
60500
60872
|
if (parentFlow !== null) {
|
|
@@ -60633,6 +61005,326 @@ function hasCode6(error49, code) {
|
|
|
60633
61005
|
class AgentInstructionLimitError extends Error {
|
|
60634
61006
|
}
|
|
60635
61007
|
|
|
61008
|
+
// src/internal/root-project-command-controller.ts
|
|
61009
|
+
var KIND = "private-project-command-owner/1";
|
|
61010
|
+
var ROOT = "/jig-input/project";
|
|
61011
|
+
async function executePrivateProjectCommand(input) {
|
|
61012
|
+
const target = requireParentTarget(input);
|
|
61013
|
+
const capability = target.request.capabilities[input.call.slot];
|
|
61014
|
+
if (capability === undefined || !isProjectCommandContract(capability) || input.call.method !== "run")
|
|
61015
|
+
return failed2("UNAVAILABLE", "the requested slot has no admitted Project Command run method");
|
|
61016
|
+
if (input.signal.aborted)
|
|
61017
|
+
return failed2("CANCELLED", "the project command was cancelled");
|
|
61018
|
+
let prepared;
|
|
61019
|
+
try {
|
|
61020
|
+
prepared = parseProjectCommandInput(input.call.input, target.request.commands ?? {});
|
|
61021
|
+
} catch {
|
|
61022
|
+
return failed2("INVALID_INPUT", "select a reviewed command and supply bounded candidate files, arguments, and stdin");
|
|
61023
|
+
}
|
|
61024
|
+
let recipe;
|
|
61025
|
+
try {
|
|
61026
|
+
if (target.disposition.state !== "ready")
|
|
61027
|
+
throw new Error("target unavailable");
|
|
61028
|
+
recipe = await planPrivateDirectRun({
|
|
61029
|
+
...input,
|
|
61030
|
+
request: target.request,
|
|
61031
|
+
executionPackage: target.disposition.executionPackage
|
|
61032
|
+
});
|
|
61033
|
+
if (recipe.digest !== target.disposition.recipeDigest || recipe.observation.digest !== target.disposition.observationDigest)
|
|
61034
|
+
throw new Error("command parent recipe changed");
|
|
61035
|
+
await revalidatePrivateInstalledBunSupport(input.installedSupport);
|
|
61036
|
+
} catch {
|
|
61037
|
+
return failed2("UNAVAILABLE", "the admitted project-command runtime cannot be reproduced");
|
|
61038
|
+
}
|
|
61039
|
+
const deadlineUnixMs = Math.min(input.parentDeadlineUnixMs, input.parent.intent.deadlineUnixMs, Date.now() + PROJECT_COMMAND_LIMITS.timeoutMs);
|
|
61040
|
+
if (deadlineUnixMs <= Date.now())
|
|
61041
|
+
return failed2("DEADLINE_EXCEEDED", "the command deadline elapsed before dispatch");
|
|
61042
|
+
if (input.parentFlow !== undefined)
|
|
61043
|
+
await requireParentFlowOwner(input, input.parentFlow, deadlineUnixMs);
|
|
61044
|
+
const rows = (await owners(input)).filter((row) => row.parentOperationId === input.parentFlow?.operationId);
|
|
61045
|
+
const prior = rows.find((row) => row.operationId === input.call.operationId);
|
|
61046
|
+
if (prior !== undefined) {
|
|
61047
|
+
if (!isCommandOwner(prior))
|
|
61048
|
+
throw new Error("command identity names a different operation");
|
|
61049
|
+
await releaseCommand(input, prior);
|
|
61050
|
+
return failed2("UNCERTAIN", "a prior command dispatch was fenced without a proved result");
|
|
61051
|
+
}
|
|
61052
|
+
if (rows.length !== 0)
|
|
61053
|
+
return failed2("RESOURCE_EXHAUSTED", "the parent already has an active operation");
|
|
61054
|
+
const identity2 = commandIdentity(input.parent.run.runId, input.call.operationId, input.parentFlow?.operationId);
|
|
61055
|
+
const ownerAllocation = await planPrivateLinuxOwnerStateAllocation({
|
|
61056
|
+
parent: await protectedOwnerRoot(input.projectRoot),
|
|
61057
|
+
name: `x-${identity2.slice(0, 62)}`
|
|
61058
|
+
});
|
|
61059
|
+
const allocation = {
|
|
61060
|
+
kind: KIND,
|
|
61061
|
+
parentRunId: input.parent.run.runId,
|
|
61062
|
+
coordinatorEpoch: input.parent.run.coordinatorEpoch,
|
|
61063
|
+
operationId: input.call.operationId,
|
|
61064
|
+
parentRequestDigest: target.request.digest,
|
|
61065
|
+
parentFlow: input.parentFlow ?? null,
|
|
61066
|
+
deadlineUnixMs,
|
|
61067
|
+
ownerAllocation,
|
|
61068
|
+
requestDigest: privateDomainDigest("JIG-Project-Command-Request/1", prepared)
|
|
61069
|
+
};
|
|
61070
|
+
const key = operationKey(input, input.call.operationId, input.parentFlow?.operationId);
|
|
61071
|
+
let lifecycle;
|
|
61072
|
+
try {
|
|
61073
|
+
lifecycle = await allocatePrivateRootChildOwner({
|
|
61074
|
+
...key,
|
|
61075
|
+
allocation
|
|
61076
|
+
});
|
|
61077
|
+
} catch (error49) {
|
|
61078
|
+
const cancelled = await cancelPrivateLinuxOwnerStateAllocation(ownerAllocation);
|
|
61079
|
+
await releasePrivateLinuxOwnerState(ownerAllocation, cancelled);
|
|
61080
|
+
if (error49 instanceof CheckError && error49.code === "RUN_CHILD_CAPACITY")
|
|
61081
|
+
return failed2("RESOURCE_EXHAUSTED", "the parent already has an active operation");
|
|
61082
|
+
throw error49;
|
|
61083
|
+
}
|
|
61084
|
+
const files = [];
|
|
61085
|
+
let attempted = false;
|
|
61086
|
+
try {
|
|
61087
|
+
for (const [path2, source] of Object.entries(prepared.input.files)) {
|
|
61088
|
+
const bytes = Buffer.from(source);
|
|
61089
|
+
files.push({
|
|
61090
|
+
fd: privateSealedBytes(bytes),
|
|
61091
|
+
destination: `${ROOT}/${path2}`,
|
|
61092
|
+
bytes: bytes.length,
|
|
61093
|
+
digest: sha256(bytes)
|
|
61094
|
+
});
|
|
61095
|
+
}
|
|
61096
|
+
const sealed = await input.backend.seal(commandPlan(recipe, prepared, files, identity2, deadlineUnixMs), ownerAllocation);
|
|
61097
|
+
lifecycle = await recordPrivateRootChildSandbox({
|
|
61098
|
+
...key,
|
|
61099
|
+
allocationDigest: lifecycle.allocation.digest,
|
|
61100
|
+
sandbox: sealed.identity
|
|
61101
|
+
});
|
|
61102
|
+
attempted = true;
|
|
61103
|
+
const component = await sealed.admit(input.signal);
|
|
61104
|
+
const observed = await collectCommand(component, prepared.input.stdin ?? "");
|
|
61105
|
+
await releaseCommand(input, lifecycle, observed.fence);
|
|
61106
|
+
const reason = observed.fence.stopReason;
|
|
61107
|
+
if (!["payload_exit", "cancelled", "deadline"].includes(reason))
|
|
61108
|
+
return failed2("UNCERTAIN", "the command was fenced without a proved command terminal");
|
|
61109
|
+
const value = Object.freeze({
|
|
61110
|
+
candidateDigest: prepared.candidateDigest,
|
|
61111
|
+
command: prepared.input.command,
|
|
61112
|
+
invocation: prepared.invocation,
|
|
61113
|
+
stdinDigest: prepared.stdinDigest,
|
|
61114
|
+
stdout: observed.stdout,
|
|
61115
|
+
stderr: observed.stderr,
|
|
61116
|
+
exitCode: observed.fence.exitCode,
|
|
61117
|
+
signal: observed.fence.signal,
|
|
61118
|
+
stopReason: reason === "payload_exit" ? "exited" : reason,
|
|
61119
|
+
cleanup: "complete"
|
|
61120
|
+
});
|
|
61121
|
+
const details = { command: value };
|
|
61122
|
+
if (input.signal.aborted || reason === "cancelled")
|
|
61123
|
+
return failed2("CANCELLED", "the project command was cancelled", details);
|
|
61124
|
+
if (reason === "deadline")
|
|
61125
|
+
return failed2("DEADLINE_EXCEEDED", "the project command exceeded its deadline", details);
|
|
61126
|
+
return { status: "succeeded", result: { value } };
|
|
61127
|
+
} catch (error49) {
|
|
61128
|
+
try {
|
|
61129
|
+
const row = (await owners(input)).find((row2) => row2.operationId === input.call.operationId && row2.parentOperationId === input.parentFlow?.operationId);
|
|
61130
|
+
if (row !== undefined)
|
|
61131
|
+
await releaseCommand(input, row);
|
|
61132
|
+
} catch (cleanupError) {
|
|
61133
|
+
if (attempted && cleanupError instanceof PrivateLinuxFenceUnconfirmedError)
|
|
61134
|
+
return failed2("UNCERTAIN", "command dispatch may have occurred but fencing is unconfirmed");
|
|
61135
|
+
throw new AggregateError([error49, cleanupError], "project command execution and cleanup failed");
|
|
61136
|
+
}
|
|
61137
|
+
if (input.signal.aborted)
|
|
61138
|
+
return failed2("CANCELLED", "the project command was cancelled");
|
|
61139
|
+
if (Date.now() >= deadlineUnixMs)
|
|
61140
|
+
return failed2("DEADLINE_EXCEEDED", "the project command deadline elapsed");
|
|
61141
|
+
return failed2(attempted ? "UNCERTAIN" : "EXECUTION_FAILED", attempted ? "command dispatch may have occurred but no result was proved" : "project command setup failed before dispatch");
|
|
61142
|
+
} finally {
|
|
61143
|
+
for (const file2 of files)
|
|
61144
|
+
closeSync3(file2.fd);
|
|
61145
|
+
}
|
|
61146
|
+
}
|
|
61147
|
+
function commandPlan(recipe, prepared, files, identity2, deadlineUnixMs) {
|
|
61148
|
+
const policy = recipe.request.commands[prepared.input.command];
|
|
61149
|
+
const args = "run" in policy ? [
|
|
61150
|
+
...recipe.bunPolicy,
|
|
61151
|
+
"--cwd",
|
|
61152
|
+
ROOT,
|
|
61153
|
+
`${ROOT}/${policy.run}`,
|
|
61154
|
+
...prepared.input.args ?? []
|
|
61155
|
+
] : [
|
|
61156
|
+
"test",
|
|
61157
|
+
...recipe.bunPolicy,
|
|
61158
|
+
"--cwd",
|
|
61159
|
+
ROOT,
|
|
61160
|
+
...policy.test.map((path2) => `${ROOT}/${path2}`)
|
|
61161
|
+
];
|
|
61162
|
+
return {
|
|
61163
|
+
runId: `command-${identity2.slice(0, 40)}`,
|
|
61164
|
+
limits: { ...recipe.resourceCeilings, deadlineUnixMs, cancellationGraceMs: 1000 },
|
|
61165
|
+
readOnlyMounts: recipe.installedSupport.runtimeMounts,
|
|
61166
|
+
capturedInputs: files,
|
|
61167
|
+
inputDirectories: [ROOT],
|
|
61168
|
+
command: [recipe.sandboxExecutablePath, ...args],
|
|
61169
|
+
network: "isolated"
|
|
61170
|
+
};
|
|
61171
|
+
}
|
|
61172
|
+
async function collectProjectCommandStream(source) {
|
|
61173
|
+
const chunks = [];
|
|
61174
|
+
let retained = 0;
|
|
61175
|
+
let truncated = false;
|
|
61176
|
+
for await (const chunk of source) {
|
|
61177
|
+
const keep = Math.min(chunk.length, PROJECT_COMMAND_LIMITS.streamBytes - retained);
|
|
61178
|
+
if (keep > 0) {
|
|
61179
|
+
chunks.push(Uint8Array.from(chunk.subarray(0, keep)));
|
|
61180
|
+
retained += keep;
|
|
61181
|
+
}
|
|
61182
|
+
if (keep < chunk.length)
|
|
61183
|
+
truncated = true;
|
|
61184
|
+
}
|
|
61185
|
+
return Object.freeze({ text: new TextDecoder().decode(Buffer.concat(chunks)), truncated });
|
|
61186
|
+
}
|
|
61187
|
+
async function collectCommand(component, stdin) {
|
|
61188
|
+
for (const promise2 of [component.completion, component.evidence, component.terminationReason])
|
|
61189
|
+
promise2.catch(() => {
|
|
61190
|
+
return;
|
|
61191
|
+
});
|
|
61192
|
+
const stdout = collectProjectCommandStream(component.stdout);
|
|
61193
|
+
const stderr = collectProjectCommandStream(component.stderr);
|
|
61194
|
+
const send2 = (async () => {
|
|
61195
|
+
try {
|
|
61196
|
+
if (stdin.length > 0)
|
|
61197
|
+
await component.write(Buffer.from(stdin));
|
|
61198
|
+
} catch (error49) {
|
|
61199
|
+
if (!(error49 instanceof Error && ("code" in error49) && error49.code === "EPIPE"))
|
|
61200
|
+
throw error49;
|
|
61201
|
+
}
|
|
61202
|
+
await component.closeInput();
|
|
61203
|
+
})();
|
|
61204
|
+
try {
|
|
61205
|
+
const [out, err, fence] = await Promise.all([stdout, stderr, component.enforcement, send2]);
|
|
61206
|
+
return { stdout: out, stderr: err, fence };
|
|
61207
|
+
} catch (error49) {
|
|
61208
|
+
await component.terminate().catch(() => {
|
|
61209
|
+
return;
|
|
61210
|
+
});
|
|
61211
|
+
await Promise.allSettled([stdout, stderr, send2, component.enforcement]);
|
|
61212
|
+
throw error49;
|
|
61213
|
+
}
|
|
61214
|
+
}
|
|
61215
|
+
async function recoverPrivateProjectCommandOwners(input) {
|
|
61216
|
+
for (const owner of await owners(input)) {
|
|
61217
|
+
if (isCommandOwner(owner) && (input.parentFlow === undefined || owner.parentOperationId === input.parentFlow.operationId))
|
|
61218
|
+
await releaseCommand(input, owner);
|
|
61219
|
+
}
|
|
61220
|
+
}
|
|
61221
|
+
function isCommandOwner(row) {
|
|
61222
|
+
const value = row.allocation.value;
|
|
61223
|
+
return value !== null && typeof value === "object" && !Array.isArray(value) && value.kind === KIND;
|
|
61224
|
+
}
|
|
61225
|
+
async function releaseCommand(input, row, knownFence) {
|
|
61226
|
+
let lifecycle = row;
|
|
61227
|
+
const allocation = parseAllocation3(row);
|
|
61228
|
+
const parentFlow = allocation.parentFlow;
|
|
61229
|
+
const { parentFlow: _requestedParentFlow, ...rootInput } = input;
|
|
61230
|
+
const context = { ...rootInput, ...parentFlow === null ? {} : { parentFlow } };
|
|
61231
|
+
const target = requireParentTarget(context);
|
|
61232
|
+
const identity2 = commandIdentity(lifecycle.parentRunId, lifecycle.operationId, lifecycle.parentOperationId);
|
|
61233
|
+
if (allocation.parentRunId !== input.parent.run.runId || allocation.coordinatorEpoch !== input.parent.run.coordinatorEpoch || allocation.parentRequestDigest !== target.request.digest || allocation.deadlineUnixMs > input.parent.intent.deadlineUnixMs || !Object.values(target.request.capabilities).some(isProjectCommandContract) || allocation.ownerAllocation.parent !== await protectedOwnerRoot(input.projectRoot) || allocation.ownerAllocation.name !== `x-${identity2.slice(0, 62)}` || input.parentFlow !== undefined && input.parentFlow.operationId !== parentFlow?.operationId)
|
|
61234
|
+
throw new Error("command owner differs from its admitted parent");
|
|
61235
|
+
if (parentFlow !== null)
|
|
61236
|
+
await requireParentFlowOwner(context, parentFlow, allocation.deadlineUnixMs);
|
|
61237
|
+
const key = operationKey(input, lifecycle.operationId, lifecycle.parentOperationId);
|
|
61238
|
+
if (lifecycle.sandbox === undefined) {
|
|
61239
|
+
if (lifecycle.fence !== undefined || lifecycle.cleanup !== undefined)
|
|
61240
|
+
throw new Error("command fence precedes sandbox");
|
|
61241
|
+
const cancelled = await cancelPrivateLinuxOwnerStateAllocation(allocation.ownerAllocation);
|
|
61242
|
+
await releasePrivateLinuxOwnerState(allocation.ownerAllocation, cancelled);
|
|
61243
|
+
} else {
|
|
61244
|
+
const owner = normalizePrivateLinuxSealedOwnerIdentity(lifecycle.sandbox.value);
|
|
61245
|
+
if (owner.ownerStateAllocationDigest !== allocation.ownerAllocation.digest || owner.runId !== `command-${identity2.slice(0, 40)}` || owner.deadlineUnixMs !== allocation.deadlineUnixMs)
|
|
61246
|
+
throw new Error("command sandbox differs from its allocation");
|
|
61247
|
+
const fence = lifecycle.fence === undefined ? knownFence ?? await input.backend.recoverFence(owner) : normalizePrivateLinuxConfirmedEnforcementReceipt(lifecycle.fence.value);
|
|
61248
|
+
normalizePrivateLinuxPreparedOwnerIdentity({
|
|
61249
|
+
kind: "private-linux-prepared-owner/1",
|
|
61250
|
+
digest: fence.ownerDigest,
|
|
61251
|
+
owner
|
|
61252
|
+
});
|
|
61253
|
+
if (lifecycle.fence === undefined)
|
|
61254
|
+
lifecycle = await recordPrivateRootChildFence({
|
|
61255
|
+
...key,
|
|
61256
|
+
allocationDigest: lifecycle.allocation.digest,
|
|
61257
|
+
sandboxDigest: lifecycle.sandbox.digest,
|
|
61258
|
+
fence
|
|
61259
|
+
});
|
|
61260
|
+
const released = await releasePrivateLinuxOwnerState(owner, fence);
|
|
61261
|
+
if (lifecycle.cleanup === undefined)
|
|
61262
|
+
lifecycle = await recordPrivateRootChildCleanup({
|
|
61263
|
+
...key,
|
|
61264
|
+
allocationDigest: lifecycle.allocation.digest,
|
|
61265
|
+
sandboxDigest: lifecycle.sandbox.digest,
|
|
61266
|
+
fenceDigest: lifecycle.fence.digest,
|
|
61267
|
+
cleanup: released
|
|
61268
|
+
});
|
|
61269
|
+
else if (normalizePrivateLinuxOwnerStateReleaseReceipt(lifecycle.cleanup.value).digest !== released.digest)
|
|
61270
|
+
throw new Error("command cleanup receipt changed");
|
|
61271
|
+
}
|
|
61272
|
+
await closePrivateRootChildOwner({
|
|
61273
|
+
...key,
|
|
61274
|
+
allocationDigest: lifecycle.allocation.digest,
|
|
61275
|
+
sandboxDigest: lifecycle.sandbox?.digest ?? null,
|
|
61276
|
+
fenceDigest: lifecycle.fence?.digest ?? null,
|
|
61277
|
+
cleanupDigest: lifecycle.cleanup?.digest ?? null
|
|
61278
|
+
});
|
|
61279
|
+
}
|
|
61280
|
+
function parseAllocation3(row) {
|
|
61281
|
+
const value = snapshotPrivateOrdinaryJson(row.allocation.value, "command allocation", (message) => new TypeError(message));
|
|
61282
|
+
const fields = [
|
|
61283
|
+
"kind",
|
|
61284
|
+
"parentRunId",
|
|
61285
|
+
"coordinatorEpoch",
|
|
61286
|
+
"operationId",
|
|
61287
|
+
"parentRequestDigest",
|
|
61288
|
+
"parentFlow",
|
|
61289
|
+
"requestDigest",
|
|
61290
|
+
"deadlineUnixMs",
|
|
61291
|
+
"ownerAllocation"
|
|
61292
|
+
];
|
|
61293
|
+
if (!value || Array.isArray(value) || Object.keys(value).length !== fields.length || fields.some((field) => !Object.hasOwn(value, field)) || value.kind !== KIND || value.parentRunId !== row.parentRunId || value.operationId !== row.operationId || typeof value.coordinatorEpoch !== "number" || !Number.isSafeInteger(value.coordinatorEpoch) || value.coordinatorEpoch < 1 || typeof value.deadlineUnixMs !== "number" || !Number.isSafeInteger(value.deadlineUnixMs) || value.deadlineUnixMs < 0 || typeof value.parentRequestDigest !== "string" || !/^sha256:[0-9a-f]{64}$/.test(value.parentRequestDigest) || typeof value.requestDigest !== "string" || !/^sha256:[0-9a-f]{64}$/.test(value.requestDigest))
|
|
61294
|
+
throw new TypeError("invalid command owner allocation");
|
|
61295
|
+
return {
|
|
61296
|
+
...value,
|
|
61297
|
+
parentFlow: normalizeParentFlow(value.parentFlow, row.parentOperationId),
|
|
61298
|
+
ownerAllocation: normalizePrivateLinuxOwnerStateAllocationIdentity(value.ownerAllocation)
|
|
61299
|
+
};
|
|
61300
|
+
}
|
|
61301
|
+
function operationKey(input, operationId, parentOperationId) {
|
|
61302
|
+
return {
|
|
61303
|
+
coordinator: input.coordinator,
|
|
61304
|
+
projectRoot: input.projectRoot,
|
|
61305
|
+
parentRunId: input.parent.run.runId,
|
|
61306
|
+
operationId,
|
|
61307
|
+
...parentOperationId === undefined ? {} : { parentOperationId }
|
|
61308
|
+
};
|
|
61309
|
+
}
|
|
61310
|
+
function owners(input) {
|
|
61311
|
+
return listPrivateRootChildOwners({
|
|
61312
|
+
coordinator: input.coordinator,
|
|
61313
|
+
projectRoot: input.projectRoot,
|
|
61314
|
+
parentRunId: input.parent.run.runId
|
|
61315
|
+
});
|
|
61316
|
+
}
|
|
61317
|
+
function commandIdentity(parentRunId, operationId, parentOperationId) {
|
|
61318
|
+
return privateDomainDigest("JIG-Project-Command-Owner/1", {
|
|
61319
|
+
parentRunId,
|
|
61320
|
+
operationId,
|
|
61321
|
+
parentOperationId: parentOperationId ?? null
|
|
61322
|
+
}).slice(7);
|
|
61323
|
+
}
|
|
61324
|
+
function failed2(code, message, details) {
|
|
61325
|
+
return { status: "failed", code, message, ...details === undefined ? {} : { details } };
|
|
61326
|
+
}
|
|
61327
|
+
|
|
60636
61328
|
// src/internal/root-flow-call-controller.ts
|
|
60637
61329
|
var ALLOCATION_KIND3 = "private-root-child-owner-allocation/1";
|
|
60638
61330
|
var SANDBOX_KIND2 = "private-root-child-sandbox/1";
|
|
@@ -60641,13 +61333,13 @@ var CANCELLATION_GRACE_MS2 = 1000;
|
|
|
60641
61333
|
async function executePrivateRootFlowCall(input) {
|
|
60642
61334
|
const selected = selectChild(input.parent, input.call.slot);
|
|
60643
61335
|
if (selected === undefined) {
|
|
60644
|
-
return
|
|
61336
|
+
return failed3("UNAVAILABLE", "the requested slot has no admitted child Flow");
|
|
60645
61337
|
}
|
|
60646
61338
|
if (selected.disposition.state !== "ready") {
|
|
60647
|
-
return
|
|
61339
|
+
return failed3("UNAVAILABLE", "the admitted child Flow is unavailable on this host");
|
|
60648
61340
|
}
|
|
60649
61341
|
if (input.signal.aborted)
|
|
60650
|
-
return
|
|
61342
|
+
return failed3("CANCELLED", "the child Flow call was cancelled");
|
|
60651
61343
|
const invalidInput = await validateChildInput(input.packageStoreRoot, selected.request.package, input.call.input);
|
|
60652
61344
|
if (invalidInput !== undefined)
|
|
60653
61345
|
return invalidInput;
|
|
@@ -60661,14 +61353,14 @@ async function executePrivateRootFlowCall(input) {
|
|
|
60661
61353
|
agentProvider: input.agentProvider
|
|
60662
61354
|
});
|
|
60663
61355
|
} catch {
|
|
60664
|
-
return
|
|
61356
|
+
return failed3("UNAVAILABLE", "the admitted child recipe cannot be reproduced");
|
|
60665
61357
|
}
|
|
60666
61358
|
if (recipe.digest !== selected.disposition.recipeDigest || recipe.observation.digest !== selected.disposition.observationDigest) {
|
|
60667
|
-
return
|
|
61359
|
+
return failed3("UNAVAILABLE", "the admitted child recipe cannot be reproduced");
|
|
60668
61360
|
}
|
|
60669
61361
|
const effectiveDeadlineUnixMs = Math.min(input.parentDeadlineUnixMs, input.parent.intent.deadlineUnixMs, Date.now() + recipe.wallClockCeilingMs);
|
|
60670
61362
|
if (Date.now() >= effectiveDeadlineUnixMs) {
|
|
60671
|
-
return
|
|
61363
|
+
return failed3("DEADLINE_EXCEEDED", "the child Flow deadline elapsed before dispatch");
|
|
60672
61364
|
}
|
|
60673
61365
|
const existing = (await listPrivateRootChildOwners({
|
|
60674
61366
|
coordinator: input.coordinator,
|
|
@@ -60677,7 +61369,7 @@ async function executePrivateRootFlowCall(input) {
|
|
|
60677
61369
|
})).find(({ operationId, parentOperationId }) => parentOperationId === undefined && operationId === input.call.operationId);
|
|
60678
61370
|
if (existing !== undefined) {
|
|
60679
61371
|
await recoverOne(input, existing);
|
|
60680
|
-
return
|
|
61372
|
+
return failed3("UNCERTAIN", "a prior child dispatch was fenced without a proved result");
|
|
60681
61373
|
}
|
|
60682
61374
|
const roots = await protectedWorkRoots(input.projectRoot);
|
|
60683
61375
|
const identity2 = childIdentity(input.parent.run.runId, input.call.operationId);
|
|
@@ -60714,7 +61406,7 @@ async function executePrivateRootFlowCall(input) {
|
|
|
60714
61406
|
});
|
|
60715
61407
|
} catch (error49) {
|
|
60716
61408
|
if (error49 instanceof CheckError && error49.code === "RUN_CHILD_CAPACITY") {
|
|
60717
|
-
return
|
|
61409
|
+
return failed3("RESOURCE_EXHAUSTED", "the parent Run already has an active child operation");
|
|
60718
61410
|
}
|
|
60719
61411
|
throw error49;
|
|
60720
61412
|
}
|
|
@@ -60758,25 +61450,25 @@ async function executePrivateRootFlowCall(input) {
|
|
|
60758
61450
|
await recoverOne(input, active);
|
|
60759
61451
|
} catch (cleanupError) {
|
|
60760
61452
|
if (attemptedDispatch && cleanupError instanceof PrivateLinuxFenceUnconfirmedError) {
|
|
60761
|
-
return
|
|
61453
|
+
return failed3("UNCERTAIN", "child dispatch may have occurred but its fence is not yet confirmed");
|
|
60762
61454
|
}
|
|
60763
61455
|
throw new AggregateError([error49, cleanupError], "child Flow execution and cleanup failed");
|
|
60764
61456
|
}
|
|
60765
61457
|
if (input.signal.aborted)
|
|
60766
|
-
return
|
|
61458
|
+
return failed3("CANCELLED", "the child Flow call was cancelled");
|
|
60767
61459
|
if (Date.now() >= effectiveDeadlineUnixMs) {
|
|
60768
|
-
return
|
|
61460
|
+
return failed3("DEADLINE_EXCEEDED", "the child Flow deadline elapsed");
|
|
60769
61461
|
}
|
|
60770
|
-
return attemptedDispatch ?
|
|
61462
|
+
return attemptedDispatch ? failed3("UNCERTAIN", "child dispatch may have occurred but no result was proved") : failed3("EXECUTION_FAILED", "child Flow execution failed before dispatch");
|
|
60771
61463
|
}
|
|
60772
61464
|
}
|
|
60773
61465
|
async function recoverPrivateRootFlowCallOwners(input) {
|
|
60774
|
-
const
|
|
61466
|
+
const owners2 = await listPrivateRootChildOwners({
|
|
60775
61467
|
coordinator: input.coordinator,
|
|
60776
61468
|
projectRoot: input.projectRoot,
|
|
60777
61469
|
parentRunId: input.parent.run.runId
|
|
60778
61470
|
});
|
|
60779
|
-
for (const owner of
|
|
61471
|
+
for (const owner of owners2) {
|
|
60780
61472
|
if (isPrivateRootFlowCallOwner(owner))
|
|
60781
61473
|
await recoverOne(input, owner);
|
|
60782
61474
|
}
|
|
@@ -60804,14 +61496,25 @@ function specialistDispatcher(input, selected, parentDeadlineUnixMs) {
|
|
|
60804
61496
|
return;
|
|
60805
61497
|
let active = false;
|
|
60806
61498
|
return {
|
|
60807
|
-
async
|
|
60808
|
-
if (input.agentProvider === undefined) {
|
|
60809
|
-
return failed2("UNAVAILABLE", "the admitted Agent provider is unavailable");
|
|
60810
|
-
}
|
|
61499
|
+
async callCapability(call, signal) {
|
|
60811
61500
|
if (active)
|
|
60812
|
-
return
|
|
61501
|
+
return failed3("RESOURCE_EXHAUSTED", "the specialist already has an active operation");
|
|
60813
61502
|
active = true;
|
|
60814
61503
|
try {
|
|
61504
|
+
if (selected.request.capabilities[call.slot]?.digest === PROJECT_COMMAND_CONTRACT_DIGEST)
|
|
61505
|
+
return await executePrivateProjectCommand({
|
|
61506
|
+
...input,
|
|
61507
|
+
parentFlow: {
|
|
61508
|
+
operationId: input.call.operationId,
|
|
61509
|
+
target: selected.request.target,
|
|
61510
|
+
requestDigest: selected.request.digest
|
|
61511
|
+
},
|
|
61512
|
+
call,
|
|
61513
|
+
parentDeadlineUnixMs,
|
|
61514
|
+
signal
|
|
61515
|
+
});
|
|
61516
|
+
if (input.agentProvider === undefined)
|
|
61517
|
+
return failed3("UNAVAILABLE", "the admitted Agent provider is unavailable");
|
|
60815
61518
|
return await executePrivateRootAgentRun({
|
|
60816
61519
|
...input,
|
|
60817
61520
|
agentProvider: input.agentProvider,
|
|
@@ -60839,7 +61542,7 @@ async function validateChildInput(store, reference, value) {
|
|
|
60839
61542
|
} catch (error49) {
|
|
60840
61543
|
if (!(error49 instanceof SchemaDiagnostic))
|
|
60841
61544
|
throw error49;
|
|
60842
|
-
return
|
|
61545
|
+
return failed3("INVALID_INPUT", "child Flow input does not satisfy its declared schema");
|
|
60843
61546
|
}
|
|
60844
61547
|
return;
|
|
60845
61548
|
} finally {
|
|
@@ -60860,9 +61563,9 @@ async function admitOperationResult(store, reference, provisional) {
|
|
|
60860
61563
|
return Object.freeze({ status: "succeeded", result: admitted.result });
|
|
60861
61564
|
}
|
|
60862
61565
|
if (admitted.code === "PROTOCOL_ERROR" || admitted.code === "CHANNEL_LOST") {
|
|
60863
|
-
return
|
|
61566
|
+
return failed3("EXECUTION_FAILED", "the child Flow execution channel failed");
|
|
60864
61567
|
}
|
|
60865
|
-
return
|
|
61568
|
+
return failed3(admitted.code, admitted.message, admitted.details);
|
|
60866
61569
|
}
|
|
60867
61570
|
async function materializeChild(store, recipe, allocation) {
|
|
60868
61571
|
const captured = await captureStoredPackage(store, recipe.executionPackage);
|
|
@@ -60902,7 +61605,7 @@ function backendPlan2(recipe, packageRoot, identity2, deadlineUnixMs) {
|
|
|
60902
61605
|
}
|
|
60903
61606
|
async function releaseKnownChild(input, lifecycleValue, lease, fence) {
|
|
60904
61607
|
let lifecycle = lifecycleValue;
|
|
60905
|
-
const selected = await requireAllocationMatchesParent2(input, lifecycle,
|
|
61608
|
+
const selected = await requireAllocationMatchesParent2(input, lifecycle, parseAllocation4(lifecycle));
|
|
60906
61609
|
const sandbox = parseSandbox2(lifecycle);
|
|
60907
61610
|
lifecycle = await recordPrivateRootChildFence({
|
|
60908
61611
|
coordinator: input.coordinator,
|
|
@@ -60921,6 +61624,14 @@ async function releaseKnownChild(input, lifecycleValue, lease, fence) {
|
|
|
60921
61624
|
requestDigest: selected.request.digest
|
|
60922
61625
|
}
|
|
60923
61626
|
});
|
|
61627
|
+
await recoverPrivateProjectCommandOwners({
|
|
61628
|
+
...input,
|
|
61629
|
+
parentFlow: {
|
|
61630
|
+
operationId: lifecycle.operationId,
|
|
61631
|
+
target: selected.request.target,
|
|
61632
|
+
requestDigest: selected.request.digest
|
|
61633
|
+
}
|
|
61634
|
+
});
|
|
60924
61635
|
await disposePrivatePackageMaterializationLease(lease.identity.allocation.parent.path, lease.identity);
|
|
60925
61636
|
const ownerRelease = await releasePrivateLinuxOwnerState(sandbox.owner, fence);
|
|
60926
61637
|
const cleanup = childCleanup(ownerRelease);
|
|
@@ -60946,7 +61657,7 @@ async function releaseKnownChild(input, lifecycleValue, lease, fence) {
|
|
|
60946
61657
|
});
|
|
60947
61658
|
}
|
|
60948
61659
|
async function recoverOne(input, lifecycle) {
|
|
60949
|
-
const allocation =
|
|
61660
|
+
const allocation = parseAllocation4(lifecycle);
|
|
60950
61661
|
const selected = await requireAllocationMatchesParent2(input, lifecycle, allocation);
|
|
60951
61662
|
if (lifecycle.sandbox === undefined) {
|
|
60952
61663
|
const cancelled = await cancelPrivateLinuxOwnerStateAllocation(allocation.ownerAllocation);
|
|
@@ -60976,6 +61687,14 @@ async function recoverOne(input, lifecycle) {
|
|
|
60976
61687
|
requestDigest: selected.request.digest
|
|
60977
61688
|
}
|
|
60978
61689
|
});
|
|
61690
|
+
await recoverPrivateProjectCommandOwners({
|
|
61691
|
+
...input,
|
|
61692
|
+
parentFlow: {
|
|
61693
|
+
operationId: lifecycle.operationId,
|
|
61694
|
+
target: selected.request.target,
|
|
61695
|
+
requestDigest: selected.request.digest
|
|
61696
|
+
}
|
|
61697
|
+
});
|
|
60979
61698
|
const recovered = await recoverPrivatePackageMaterializationAllocation(allocation.packageAllocation.parent.path, allocation.packageAllocation);
|
|
60980
61699
|
if (recovered.state === "complete")
|
|
60981
61700
|
await recovered.lease.dispose();
|
|
@@ -61019,7 +61738,7 @@ async function findLifecycle2(input, operationId) {
|
|
|
61019
61738
|
parentRunId: input.parent.run.runId
|
|
61020
61739
|
})).find((item) => item.parentOperationId === undefined && item.operationId === operationId);
|
|
61021
61740
|
}
|
|
61022
|
-
function
|
|
61741
|
+
function parseAllocation4(lifecycle) {
|
|
61023
61742
|
const value = exactObject5(lifecycle.allocation.value, [
|
|
61024
61743
|
"kind",
|
|
61025
61744
|
"parentRunId",
|
|
@@ -61119,9 +61838,9 @@ function childIdentity(parentRunId, operationId) {
|
|
|
61119
61838
|
async function protectedWorkRoots(projectRoot) {
|
|
61120
61839
|
const state2 = await realpath12(join12(projectRoot, ".jig"));
|
|
61121
61840
|
const materializations = join12(state2, "private-root-materializations");
|
|
61122
|
-
const
|
|
61123
|
-
await Promise.all([ensureProtectedDirectory(materializations), ensureProtectedDirectory(
|
|
61124
|
-
return Object.freeze({ materializations, owners });
|
|
61841
|
+
const owners2 = join12(state2, "private-root-linux-owners");
|
|
61842
|
+
await Promise.all([ensureProtectedDirectory(materializations), ensureProtectedDirectory(owners2)]);
|
|
61843
|
+
return Object.freeze({ materializations, owners: owners2 });
|
|
61125
61844
|
}
|
|
61126
61845
|
async function ensureProtectedDirectory(path2) {
|
|
61127
61846
|
await mkdir10(path2, { mode: 448 }).catch((error49) => {
|
|
@@ -61148,7 +61867,7 @@ function startupSignal(signal) {
|
|
|
61148
61867
|
}
|
|
61149
61868
|
});
|
|
61150
61869
|
}
|
|
61151
|
-
function
|
|
61870
|
+
function failed3(code, message, details) {
|
|
61152
61871
|
return Object.freeze({
|
|
61153
61872
|
status: "failed",
|
|
61154
61873
|
code,
|
|
@@ -61660,9 +62379,9 @@ async function reacquire(input) {
|
|
|
61660
62379
|
async function protectedWorkRoots2(projectRoot) {
|
|
61661
62380
|
const state2 = await realpath13(join13(projectRoot, ".jig"));
|
|
61662
62381
|
const materializations = join13(state2, "private-root-materializations");
|
|
61663
|
-
const
|
|
61664
|
-
await Promise.all([ensureProtectedDirectory2(materializations), ensureProtectedDirectory2(
|
|
61665
|
-
return Object.freeze({ materializations, owners });
|
|
62382
|
+
const owners2 = join13(state2, "private-root-linux-owners");
|
|
62383
|
+
await Promise.all([ensureProtectedDirectory2(materializations), ensureProtectedDirectory2(owners2)]);
|
|
62384
|
+
return Object.freeze({ materializations, owners: owners2 });
|
|
61666
62385
|
}
|
|
61667
62386
|
async function ensureProtectedDirectory2(path2) {
|
|
61668
62387
|
await mkdir11(path2, { mode: 448 }).catch((error49) => {
|
|
@@ -61692,9 +62411,9 @@ function parsePlan(value) {
|
|
|
61692
62411
|
}
|
|
61693
62412
|
return Object.freeze({
|
|
61694
62413
|
kind: PLAN_KIND,
|
|
61695
|
-
requestDigest:
|
|
61696
|
-
recipeDigest:
|
|
61697
|
-
observationDigest:
|
|
62414
|
+
requestDigest: digest5(record3.requestDigest, "direct root request"),
|
|
62415
|
+
recipeDigest: digest5(record3.recipeDigest, "direct root recipe"),
|
|
62416
|
+
observationDigest: digest5(record3.observationDigest, "direct root observation"),
|
|
61698
62417
|
activationStartedUnixMs: record3.activationStartedUnixMs,
|
|
61699
62418
|
effectiveDeadlineUnixMs: record3.effectiveDeadlineUnixMs,
|
|
61700
62419
|
cancellationGraceMs: record3.cancellationGraceMs,
|
|
@@ -61747,7 +62466,7 @@ function exactRecord7(value, keys, label) {
|
|
|
61747
62466
|
}
|
|
61748
62467
|
return value;
|
|
61749
62468
|
}
|
|
61750
|
-
function
|
|
62469
|
+
function digest5(value, label) {
|
|
61751
62470
|
if (typeof value !== "string" || !/^sha256:[0-9a-f]{64}$/.test(value)) {
|
|
61752
62471
|
throw new TypeError(`${label} digest is invalid`);
|
|
61753
62472
|
}
|
|
@@ -61826,37 +62545,52 @@ function operationInput(input, parent) {
|
|
|
61826
62545
|
async function recoverPrivateRootOperationOwners(input) {
|
|
61827
62546
|
await recoverPrivateRootFlowCallOwners(input);
|
|
61828
62547
|
await recoverPrivateRootAgentRunOwners(input);
|
|
62548
|
+
await recoverPrivateProjectCommandOwners(input);
|
|
61829
62549
|
}
|
|
61830
62550
|
function operationDispatcher(input, parent, parentDeadlineUnixMs) {
|
|
61831
62551
|
const target = findPrivateActivationCandidateTargetV5(parent.candidate, parent.run.target);
|
|
61832
62552
|
if (target === undefined)
|
|
61833
62553
|
return;
|
|
61834
62554
|
const hasFlows = Object.keys(target.request.flowSlots).length !== 0;
|
|
61835
|
-
const
|
|
61836
|
-
if (!hasFlows && !
|
|
62555
|
+
const hasEffects = Object.keys(target.request.capabilities).length !== 0;
|
|
62556
|
+
if (!hasFlows && !hasEffects)
|
|
61837
62557
|
return;
|
|
61838
|
-
let
|
|
61839
|
-
|
|
61840
|
-
|
|
62558
|
+
let activeFlows = 0;
|
|
62559
|
+
let activeEffect = false;
|
|
62560
|
+
const enter = async (kind, run, unavailable2) => {
|
|
62561
|
+
if (activeEffect || (kind === "effect" ? activeFlows !== 0 : activeFlows >= PRIVATE_ROOT_RESOURCE_POLICY.siblingFlows))
|
|
61841
62562
|
return unavailable2;
|
|
61842
|
-
|
|
62563
|
+
if (kind === "flow")
|
|
62564
|
+
activeFlows++;
|
|
62565
|
+
else
|
|
62566
|
+
activeEffect = true;
|
|
61843
62567
|
try {
|
|
61844
62568
|
return await run();
|
|
61845
62569
|
} finally {
|
|
61846
|
-
|
|
62570
|
+
if (kind === "flow")
|
|
62571
|
+
activeFlows--;
|
|
62572
|
+
else
|
|
62573
|
+
activeEffect = false;
|
|
61847
62574
|
}
|
|
61848
62575
|
};
|
|
61849
62576
|
return Object.freeze({
|
|
61850
62577
|
...hasFlows ? {
|
|
61851
|
-
|
|
62578
|
+
runChildFlow: async (call, signal) => enter("flow", () => executePrivateRootFlowCall({
|
|
61852
62579
|
...operationInput(input, parent),
|
|
61853
62580
|
call,
|
|
61854
62581
|
parentDeadlineUnixMs,
|
|
61855
62582
|
signal
|
|
61856
62583
|
}), operationBusy())
|
|
61857
62584
|
} : {},
|
|
61858
|
-
...
|
|
61859
|
-
|
|
62585
|
+
...hasEffects ? {
|
|
62586
|
+
callCapability: async (call, signal) => {
|
|
62587
|
+
if (target.request.capabilities[call.slot]?.digest === PROJECT_COMMAND_CONTRACT_DIGEST)
|
|
62588
|
+
return enter("effect", () => executePrivateProjectCommand({
|
|
62589
|
+
...operationInput(input, parent),
|
|
62590
|
+
call,
|
|
62591
|
+
parentDeadlineUnixMs,
|
|
62592
|
+
signal
|
|
62593
|
+
}), operationBusy());
|
|
61860
62594
|
if (input.agentProvider === undefined) {
|
|
61861
62595
|
return Object.freeze({
|
|
61862
62596
|
status: "failed",
|
|
@@ -61864,7 +62598,7 @@ function operationDispatcher(input, parent, parentDeadlineUnixMs) {
|
|
|
61864
62598
|
message: "the admitted Agent provider is unavailable"
|
|
61865
62599
|
});
|
|
61866
62600
|
}
|
|
61867
|
-
return enter(() => executePrivateRootAgentRun({
|
|
62601
|
+
return enter("effect", () => executePrivateRootAgentRun({
|
|
61868
62602
|
...operationInput(input, parent),
|
|
61869
62603
|
agentProvider: input.agentProvider,
|
|
61870
62604
|
call,
|
|
@@ -61879,7 +62613,7 @@ function operationBusy() {
|
|
|
61879
62613
|
return Object.freeze({
|
|
61880
62614
|
status: "failed",
|
|
61881
62615
|
code: "RESOURCE_EXHAUSTED",
|
|
61882
|
-
message: "the
|
|
62616
|
+
message: "the root permits two sibling Flows or one exclusive effect; wait for owned work to settle"
|
|
61883
62617
|
});
|
|
61884
62618
|
}
|
|
61885
62619
|
function terminal(run) {
|
|
@@ -62381,7 +63115,7 @@ function scopePrivatePackagePlanningError(error49, packagePath) {
|
|
|
62381
63115
|
return new CheckError(error49.kind, error49.code, error49.message, `${packagePath}/${relativePath}`, error49.pointer);
|
|
62382
63116
|
}
|
|
62383
63117
|
function isUnavailableDiagnosticCode(code) {
|
|
62384
|
-
return code === "PACKAGE_BUN_SOURCE_UNSUPPORTED" || code === "PACKAGE_BUN_PREPARATION_FAILED" || code === "PROJECT_AGENT_UNAVAILABLE";
|
|
63118
|
+
return code === "PACKAGE_BUN_SOURCE_UNSUPPORTED" || code === "PACKAGE_BUN_PREPARATION_FAILED" || code === "PROJECT_AGENT_UNAVAILABLE" || code === "PROJECT_COMMAND_UNCONFIGURED";
|
|
62385
63119
|
}
|
|
62386
63120
|
function isCandidateDiagnosticCode(code) {
|
|
62387
63121
|
return code.startsWith("CAPABILITY_") || code.startsWith("METADATA_") || code.startsWith("SCHEMA_") || code.startsWith("PACKAGE_BUN_") || code.startsWith("PROJECT_BINDING_") || code.startsWith("PROJECT_DECLARATION_") || code.startsWith("PROJECT_EVALUATION_") || code.startsWith("PROJECT_EVALUATOR_") || code.startsWith("PROJECT_MEMBER_") || code.startsWith("PROJECT_SOURCE_") || [
|
|
@@ -62421,7 +63155,7 @@ function hasCode9(error49, code) {
|
|
|
62421
63155
|
// src/installed-cli.ts
|
|
62422
63156
|
var BUN_POLICY5 = Object.freeze(["--no-env-file", "--no-install", "--config=/dev/null"]);
|
|
62423
63157
|
var installedCliPath = await realpath14(fileURLToPath2(import.meta.url));
|
|
62424
|
-
var releaseRoot =
|
|
63158
|
+
var releaseRoot = dirname9(dirname9(installedCliPath));
|
|
62425
63159
|
var executablePath = await realpath14(process.execPath);
|
|
62426
63160
|
if (process.argv[0] !== executablePath || process.argv[1] !== installedCliPath || await realpath14("/proc/self/exe") !== executablePath || process.execArgv.length !== BUN_POLICY5.length || process.execArgv.some((value, index) => value !== BUN_POLICY5[index])) {
|
|
62427
63161
|
throw new Error("the installed Jig command has an invalid startup posture");
|