@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.
@@ -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 dirname10 } from "path";
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 { closeSync as closeSync2 } from "fs";
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.13",
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
- const libc = posix.join(dirname(realpathSync("/lib64/ld-linux-x86-64.so.2")), "libc.so.6");
9887
- const { symbols } = ffi.dlopen(libc, {
9888
- syscall: { args: ["i64", "i32", "ptr", "ptr", "u64"], returns: "i32" },
9889
- memfd_create: { args: ["ptr", "u32"], returns: "i32" },
9890
- fcntl: { args: ["i32", "i32", "i32"], returns: "i32" },
9891
- renameat2: { args: ["i32", "ptr", "i32", "ptr", "u32"], returns: "i32" },
9892
- __errno_location: { args: [], returns: "ptr" }
9893
- });
9894
- native = { ffi, symbols };
9895
- return native;
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 TypeError("file mount identity is unavailable");
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 TypeError("file mount identity changed");
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(nextMessage(messages, closed), this.#options.startupTimeoutMs, "rootless preparation"), "prepared");
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(nextMessage(messages, closed), this.#options.startupTimeoutMs, "rootless readiness"), "ready");
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 nextMessage(iterator, closed) {
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
- iterator.next().then((next) => {
11909
- if (next.done)
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 nextMessage(iterator, closed);
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
- const parent = privateOpenFileRoot(dirname3(path));
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
- throw new CliDiagnostic("JIG_RUN_INPUT_INVALID", error instanceof PrivateFileInputError ? error.message : "--input requires bounded JSON/1 in a regular file; check the path, links, size, and contents", 1);
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 closeSync3, fstatSync as fstatSync2, lstatSync, mkdirSync, opendirSync as opendirSync2 } from "fs";
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 as basename2, dirname as dirname4, resolve as resolve4 } from "path";
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 = dirname4(destination), leaf = privateFilePath(basename2(destination));
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
- closeSync3(parent);
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
- closeSync3(fd);
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(dirname4(destination), { recursive: true, mode: 448 });
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
- closeSync3(this.#parent);
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
- closeSync3(current);
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
- closeSync3(current);
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
- closeSync3(current);
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 dirname5, join as join3 } from "path";
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(dirname5(await resolvePrivateLinuxHostLoader()), "librt.so.1"), "Claude runtime library")
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
- const credential = await projectPrivateCodexSubscriptionCredential(join4(sourceHome, "auth.json"));
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 nativeBubblewrapFor(executablePath) {
15035
- const path = await exactFile2(join4(executablePath, "..", "..", "codex-resources", "bwrap"), "Codex native Bubblewrap");
15036
- if (((await lstat4(path)).mode & 73) === 0) {
15037
- throw new Error("Codex native Bubblewrap is invalid");
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 dirname6, join as join5 } from "path";
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 = dirname6(loaderPath);
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 dirname7, join as join6, resolve as resolve5 } from "path";
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 = dirname7(executablePath);
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 missing = ["OPENAI_API_KEY", "OPENAI_MODEL"].filter((key) => environment[key] === undefined);
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, environment) : client === "codex" ? await openPrivateCodexAgentProvider(installedBunSupport.releaseRoot, environment) : client === "claude" ? await openPrivateClaudeAgentProvider(installedBunSupport.releaseRoot, environment) : client === "pi" ? await openPrivatePiAgentProvider(installedBunSupport.releaseRoot, environment) : (() => {
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 createHash5, randomUUID } from "crypto";
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 digest = parsePackageDigest(captured.digest);
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, digest, true);
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, digest, `stored Package/1 ${digest}`, location.ownerUid);
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 !== digest) {
18386
- invalid("PACKAGE_ARTIFACT_SOURCE_MISMATCH", `captured Package/1 bytes produced ${observedDigest2}, not ${digest}`);
18638
+ if (observedDigest2 !== digest2) {
18639
+ invalid("PACKAGE_ARTIFACT_SOURCE_MISMATCH", `captured Package/1 bytes produced ${observedDigest2}, not ${digest2}`);
18387
18640
  }
18388
- return packageArtifactRef(digest);
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 !== digest) {
18398
- invalid("PACKAGE_ARTIFACT_SOURCE_MISMATCH", `captured Package/1 bytes produced ${observedDigest}, not ${digest}`);
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, digest, "staged Package/1 artifact", location.ownerUid);
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, digest, `stored Package/1 ${digest}`, location.ownerUid);
18672
+ const existing2 = await capturePackageArtifactFile(location.finalPath, digest2, `stored Package/1 ${digest2}`, location.ownerUid);
18420
18673
  await existing2.dispose();
18421
- result2 = packageArtifactRef(digest);
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(digest);
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 digest = parsePackageArtifactRef(reference);
18736
+ const digest2 = parsePackageArtifactRef(reference);
18484
18737
  let location;
18485
18738
  let captured;
18486
18739
  try {
18487
- location = await openArtifactShard(storeRoot, digest, false);
18488
- captured = await capturePackageArtifactFile(location.finalPath, digest, `stored Package/1 ${digest}`, location.ownerUid);
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 ${digest} is missing`);
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(digest) {
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 digest = Object.getOwnPropertyDescriptor(reference, "digest");
18529
- if (kind === undefined || !("value" in kind) || !kind.enumerable || kind.value !== ARTIFACT_KIND || digest === undefined || !("value" in digest) || !digest.enumerable) {
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(digest.value);
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, digest, create) {
18541
- const hexadecimal = DIGEST_PATTERN.exec(digest)[1];
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 = createHash5("sha256");
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 = createHash5("sha256");
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 !== 1) {
19077
- invalid("PROJECT_FLOW_CAPABILITY_UNSUPPORTED", "the direct alpha supports at most one Agent Run capability slot per package", packagePath);
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 [slot, declaration] = declarations[0];
19080
- if (declaration.contract === undefined) {
19081
- invalid("PROJECT_FLOW_CAPABILITY_UNSUPPORTED", "the direct alpha supports only the exact Agent Run capability contract", packagePath, `/uses/${pointerToken(slot)}`);
19082
- }
19083
- const reference = inspected.usedContracts.find((candidate) => candidate.slot === slot);
19084
- if (reference === undefined)
19085
- throw new Error("inspected capability reference invariant violated");
19086
- try {
19087
- assertAgentRunContract(reference.contract);
19088
- } catch (error) {
19089
- invalid("PROJECT_FLOW_CAPABILITY_UNSUPPORTED", errorText5(error), packagePath, `/uses/${pointerToken(slot)}`);
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 createHash7 } from "crypto";
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 createHash6 } from "crypto";
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 dirname8, join as joinPath, normalize as normalizePath } from "path/posix";
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: digest(bytes),
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: digest(canonicalJson(identity2)),
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(dirname8(importer), specifier));
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 digest(bytes) {
19736
- return `sha256:${createHash6("sha256").update(bytes).digest("hex")}`;
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:${createHash7("sha256").update(bytes).digest("hex")}`;
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 digest2 = await packageDigest(files, (file) => backing.stream(file.path));
20666
- captured = createCapturedPackage("captured author closure", files, digest2, backing);
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 > 1) {
21121
- throw new TypeError("activation capability uses exceed 1 entry");
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 the exact Agent Run contract`);
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: AGENT_RUN_CONTRACT_ID,
21132
- version: AGENT_RUN_CONTRACT_VERSION,
21133
- digest: AGENT_RUN_CONTRACT_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: digest2(item.digest, `package ${path}`),
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 > 1)
21311
- throw new TypeError(`${label} uses exceed 1 entry`);
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 the exact Agent Run contract`);
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: AGENT_RUN_CONTRACT_ID,
21321
- version: AGENT_RUN_CONTRACT_VERSION,
21322
- digest: AGENT_RUN_CONTRACT_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], ["packagePath", "settings", "slots"], `Binding ${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 digest2(value, label) {
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
- if (capabilityUses.length > 0 && input.agentProvider === undefined) {
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 = capabilityUses.length === 0 ? undefined : requirePrivateAgentProvider(input.agentProvider);
21494
- if (capabilityUses.some(({ digest: digest3 }) => digest3 !== AGENT_RUN_CONTRACT_DIGEST) || capabilityUses.length > 1 || agentProvider !== undefined && agentProvider.contractDigest !== AGENT_RUN_CONTRACT_DIGEST) {
21495
- throw new TypeError("private Bun recipe requires the exact supported Agent capability");
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: RESOURCE_CEILINGS,
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: RESOURCE_CEILINGS,
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 digest3 = requireDigest3(present.digest, "observed lock");
21974
- if (digest3 !== privateProjectLocalLockDigest(lock)) {
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: digest3, lock });
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((digest3) => requireDigest3(digest3, "target evidence")).sort();
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: digest3(root.requestDigest, "root Run identity request"),
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: digest3(root.runId, "root Run spawn intent run"),
22402
- admissionDigest: digest3(root.admissionDigest, "root Run spawn intent admission"),
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: digest3(root.requestDigest, "root Run spawn intent request"),
22406
- recipeDigest: digest3(root.recipeDigest, "root Run spawn intent recipe"),
22407
- observationDigest: digest3(root.observationDigest, "root Run spawn intent observation"),
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 digest3(value, label) {
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 digest4 = input.value === null ? null : privateDomainDigest("JIG-Private-Bun-Preparation-Owner/1", input.value);
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", [digest4, encoded, input.expectedDigest]).changes;
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 digest4 = rootExecutionCheckpointDigest(checkpoint, envelope);
23341
+ const digest5 = rootExecutionCheckpointDigest(checkpoint, envelope);
23013
23342
  const current = executionFact(before, checkpoint);
23014
23343
  if (current !== undefined) {
23015
- if (current.digest !== digest4 || !sameBytes4(checkpointBytes(row, checkpoint), bytes)) {
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`, [digest4, bytes, input.runId]).changes;
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 digest4 = privateDomainDigest("JIG-Private-Root-Child-Owner-Allocation/1", input.allocation);
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 !== digest4 || !sameBytes4(existing.allocation_bytes, bytes)) {
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) || input.allocation.kind !== "private-root-agent-owner-allocation/1")) {
23070
- invalid("RUN_CHILD_OWNER_CONFLICT", "a child Flow may own only one Agent operation");
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 (countScopedRootChildOwners(owner.database, input.parentRunId, input.parentOperationId) !== 0n) {
23073
- invalid("RUN_CHILD_CAPACITY", "the parent Run already has an active child operation");
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, digest4, bytes]);
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 digest4 = privateDomainDigest("JIG-Private-Root-Child-Sandbox/1", input.sandbox);
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 !== digest4 || !sameBytes4(row.sandbox_bytes, bytes)) {
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", [digest4, bytes, input.parentRunId, input.operationId, input.parentOperationId ?? ""]).changes;
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 digest4 = privateDomainDigest("JIG-Private-Root-Child-Fence/1", input.fence);
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 !== digest4 || !sameBytes4(row.fence_bytes, bytes)) {
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", [digest4, bytes, input.parentRunId, input.operationId, input.parentOperationId ?? ""]).changes;
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 digest4 = privateDomainDigest("JIG-Private-Root-Child-Cleanup/1", input.cleanup);
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 !== digest4 || !sameBytes4(row.cleanup_bytes, bytes)) {
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", [digest4, bytes, input.parentRunId, input.operationId, input.parentOperationId ?? ""]).changes;
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 Agent owner");
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 an Agent");
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 digest4 = checkpointDigest(row, checkpoint);
24186
+ const digest5 = checkpointDigest(row, checkpoint);
23849
24187
  const bytes = checkpointBytes(row, checkpoint);
23850
- if (digest4 === null !== (bytes === null))
24188
+ if (digest5 === null !== (bytes === null))
23851
24189
  corrupt(`stored root execution ${checkpoint} pair is incomplete`);
23852
- if (digest4 === null || bytes === null)
24190
+ if (digest5 === null || bytes === null)
23853
24191
  return {};
23854
- requireDigest4(digest4, `stored root execution ${checkpoint}`);
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) !== digest4 || envelope.runId !== row.run_id || envelope.allocationDigest !== allocationDigest) {
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: digest4, value: envelope.value }) };
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 digest4 = privateDomainDigest("JIG-Private-Root-Terminal/1", terminal);
24039
- runFinalized(database, "INSERT INTO root_terminals(run_id, terminal_digest, terminal_bytes) VALUES (?1, ?2, ?3)", [runId, digest4, bytes]);
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, digest4) {
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(digest4).map(copiedPlanRow);
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 ${digest4} does not exist`);
25125
+ unavailable("ADMISSION_PLAN_MISSING", `review plan ${digest5} does not exist`);
24765
25126
  if (rows.length !== 1)
24766
- corrupt(`review plan ${digest4} is duplicated`);
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, digest4) {
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(digest4).map(copiedAdmissionRow);
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 ${digest4} is missing or duplicated`);
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 digest4 of [...digests].sort()) {
25312
- const reference = normalizePackageArtifactRef({ kind: "flow-package/1", digest: digest4 });
25313
- captures.set(digest4, await captureStoredPackage(packageStoreRoot, reference));
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(digest4) {
25338
- const inspected = inspections.get(digest4);
25698
+ inspection(digest5) {
25699
+ const inspected = inspections.get(digest5);
25339
25700
  if (inspected === undefined)
25340
- corrupt(`stored package ${digest4} has no verified inspection`);
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 digest4 = await packageDigest(frozenFiles, (file) => backing.stream(file.path));
26057
- return createCapturedPackage("prepared Bun dependency tree", frozenFiles, digest4, backing);
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 createHash8 } from "crypto";
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/call" && request.method !== "effect/call") {
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/call" ? this.dispatcher?.callFlow : this.dispatcher?.callEffect;
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 === "effect/call" ? "no effect dispatcher is installed" : "no child Flow dispatcher is installed");
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/call" ? this.dispatcher.callFlow(operation.call, record2.controller.signal).then((terminal) => normalizeFlowOperationTerminal(terminal)) : this.dispatcher.callEffect(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));
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/call") {
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/call",
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: "effect/call",
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 createHash8("sha256").update(bytes).digest("hex");
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({ status: "succeeded", method: "flow/call", result: result2 });
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({ status: "succeeded", method: "effect/call", result: result2 });
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 dirname9, isAbsolute as isAbsolute2, join as join10, resolve as resolve8 } from "path";
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) : basename3(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 basename3(new URL(url2).pathname);
49700
+ return basename2(new URL(url2).pathname);
49328
49701
  } catch {
49329
- return basename3(url2);
49702
+ return basename2(url2);
49330
49703
  }
49331
49704
  }
49332
49705
  const path = "path" in value && value.path && String(value.path);
49333
- return path ? basename3(path) : undefined;
49706
+ return path ? basename2(path) : undefined;
49334
49707
  }
49335
- function basename3(value) {
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) : basename3(name) ?? "unknown_file";
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: Math.max(recipe.resourceCeilings.pids, AGENT_PROVIDER_MINIMUM_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).length !== 1 || Object.values(target.request.capabilities)[0]?.digest !== AGENT_RUN_CONTRACT_DIGEST) {
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 failed2("UNAVAILABLE", "the requested slot has no admitted child Flow");
61336
+ return failed3("UNAVAILABLE", "the requested slot has no admitted child Flow");
60645
61337
  }
60646
61338
  if (selected.disposition.state !== "ready") {
60647
- return failed2("UNAVAILABLE", "the admitted child Flow is unavailable on this host");
61339
+ return failed3("UNAVAILABLE", "the admitted child Flow is unavailable on this host");
60648
61340
  }
60649
61341
  if (input.signal.aborted)
60650
- return failed2("CANCELLED", "the child Flow call was cancelled");
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 failed2("UNAVAILABLE", "the admitted child recipe cannot be reproduced");
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 failed2("UNAVAILABLE", "the admitted child recipe cannot be reproduced");
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 failed2("DEADLINE_EXCEEDED", "the child Flow deadline elapsed before dispatch");
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 failed2("UNCERTAIN", "a prior child dispatch was fenced without a proved result");
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 failed2("RESOURCE_EXHAUSTED", "the parent Run already has an active child operation");
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 failed2("UNCERTAIN", "child dispatch may have occurred but its fence is not yet confirmed");
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 failed2("CANCELLED", "the child Flow call was cancelled");
61458
+ return failed3("CANCELLED", "the child Flow call was cancelled");
60767
61459
  if (Date.now() >= effectiveDeadlineUnixMs) {
60768
- return failed2("DEADLINE_EXCEEDED", "the child Flow deadline elapsed");
61460
+ return failed3("DEADLINE_EXCEEDED", "the child Flow deadline elapsed");
60769
61461
  }
60770
- return attemptedDispatch ? failed2("UNCERTAIN", "child dispatch may have occurred but no result was proved") : failed2("EXECUTION_FAILED", "child Flow execution failed before dispatch");
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 owners = await listPrivateRootChildOwners({
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 owners) {
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 callEffect(call, signal) {
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 failed2("RESOURCE_EXHAUSTED", "the specialist already has an active Agent operation");
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 failed2("INVALID_INPUT", "child Flow input does not satisfy its declared schema");
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 failed2("EXECUTION_FAILED", "the child Flow execution channel failed");
61566
+ return failed3("EXECUTION_FAILED", "the child Flow execution channel failed");
60864
61567
  }
60865
- return failed2(admitted.code, admitted.message, admitted.details);
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, parseAllocation3(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 = parseAllocation3(lifecycle);
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 parseAllocation3(lifecycle) {
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 owners = join12(state2, "private-root-linux-owners");
61123
- await Promise.all([ensureProtectedDirectory(materializations), ensureProtectedDirectory(owners)]);
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 failed2(code, message, details) {
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 owners = join13(state2, "private-root-linux-owners");
61664
- await Promise.all([ensureProtectedDirectory2(materializations), ensureProtectedDirectory2(owners)]);
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: digest4(record3.requestDigest, "direct root request"),
61696
- recipeDigest: digest4(record3.recipeDigest, "direct root recipe"),
61697
- observationDigest: digest4(record3.observationDigest, "direct root observation"),
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 digest4(value, label) {
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 hasAgent = Object.keys(target.request.capabilities).length !== 0;
61836
- if (!hasFlows && !hasAgent)
62555
+ const hasEffects = Object.keys(target.request.capabilities).length !== 0;
62556
+ if (!hasFlows && !hasEffects)
61837
62557
  return;
61838
- let active = false;
61839
- const enter = async (run, unavailable2) => {
61840
- if (active)
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
- active = true;
62563
+ if (kind === "flow")
62564
+ activeFlows++;
62565
+ else
62566
+ activeEffect = true;
61843
62567
  try {
61844
62568
  return await run();
61845
62569
  } finally {
61846
- active = false;
62570
+ if (kind === "flow")
62571
+ activeFlows--;
62572
+ else
62573
+ activeEffect = false;
61847
62574
  }
61848
62575
  };
61849
62576
  return Object.freeze({
61850
62577
  ...hasFlows ? {
61851
- callFlow: async (call, signal) => enter(() => executePrivateRootFlowCall({
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
- ...hasAgent ? {
61859
- callEffect: async (call, signal) => {
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 parent Run already has an active child operation"
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 = dirname10(dirname10(installedCliPath));
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");