@kontextmind/kxm 0.7.20 → 0.7.22

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.
@@ -2987,7 +2987,7 @@ var require_compile = __commonJS({
2987
2987
  const schOrFunc = root.refs[ref];
2988
2988
  if (schOrFunc)
2989
2989
  return schOrFunc;
2990
- let _sch = resolve7.call(this, root, ref);
2990
+ let _sch = resolve6.call(this, root, ref);
2991
2991
  if (_sch === void 0) {
2992
2992
  const schema = (_a = root.localRefs) === null || _a === void 0 ? void 0 : _a[ref];
2993
2993
  const { schemaId } = this.opts;
@@ -3014,7 +3014,7 @@ var require_compile = __commonJS({
3014
3014
  function sameSchemaEnv(s1, s2) {
3015
3015
  return s1.schema === s2.schema && s1.root === s2.root && s1.baseId === s2.baseId;
3016
3016
  }
3017
- function resolve7(root, ref) {
3017
+ function resolve6(root, ref) {
3018
3018
  let sch;
3019
3019
  while (typeof (sch = this.refs[ref]) == "string")
3020
3020
  ref = sch;
@@ -3839,7 +3839,7 @@ var require_fast_uri = __commonJS({
3839
3839
  }
3840
3840
  return uri;
3841
3841
  }
3842
- function resolve7(baseURI, relativeURI, options) {
3842
+ function resolve6(baseURI, relativeURI, options) {
3843
3843
  const schemelessOptions = options ? Object.assign({ scheme: "null" }, options) : { scheme: "null" };
3844
3844
  const {
3845
3845
  parsed: baseParsed,
@@ -4201,7 +4201,7 @@ var require_fast_uri = __commonJS({
4201
4201
  var fastUri = {
4202
4202
  SCHEMES,
4203
4203
  normalize,
4204
- resolve: resolve7,
4204
+ resolve: resolve6,
4205
4205
  resolveComponent,
4206
4206
  equal,
4207
4207
  serialize,
@@ -14781,18 +14781,35 @@ var require_dist = __commonJS({
14781
14781
  // plugins/kxm/src/vnext-runtime-supervisor.ts
14782
14782
  import { spawn as spawn3 } from "node:child_process";
14783
14783
  import { createHash as createHash11, createHmac, randomBytes as randomBytes2, timingSafeEqual as timingSafeEqual2 } from "node:crypto";
14784
- import { chmodSync as chmodSync2, existsSync as existsSync9, lstatSync as lstatSync5, mkdirSync as mkdirSync4, readFileSync as readFileSync8, renameSync, rmSync, writeFileSync as writeFileSync4 } from "node:fs";
14784
+ import { chmodSync as chmodSync2, existsSync as existsSync10, lstatSync as lstatSync5, mkdirSync as mkdirSync4, readFileSync as readFileSync8, renameSync, rmSync, writeFileSync as writeFileSync4 } from "node:fs";
14785
14785
  import { createServer } from "node:http";
14786
- import { dirname as dirname5, isAbsolute as isAbsolute4, join as join12, resolve as resolve6 } from "node:path";
14787
- import { fileURLToPath as fileURLToPath2 } from "node:url";
14786
+ import { dirname as dirname6, isAbsolute as isAbsolute4, join as join13 } from "node:path";
14787
+
14788
+ // plugins/kxm/src/repo-root.ts
14789
+ import { existsSync } from "node:fs";
14790
+ import { dirname, join } from "node:path";
14791
+ import { fileURLToPath } from "node:url";
14792
+ var ROOT_MARKERS = ["scripts/kxm-hub.mjs", "scripts/kxm.mjs"];
14793
+ var MAX_WALK_DEPTH = 10;
14794
+ function findKxmRepoRoot(fromUrl = import.meta.url) {
14795
+ let dir = dirname(fileURLToPath(fromUrl));
14796
+ for (let depth = 0; depth < MAX_WALK_DEPTH; depth += 1) {
14797
+ if (ROOT_MARKERS.some((marker) => existsSync(join(dir, marker)))) return dir;
14798
+ const parent = dirname(dir);
14799
+ if (parent === dir) break;
14800
+ dir = parent;
14801
+ }
14802
+ throw new Error(
14803
+ `kxm: cannot locate the KXM repo root from ${fileURLToPath(fromUrl)} (walked ${MAX_WALK_DEPTH} levels looking for ${ROOT_MARKERS[0]})`
14804
+ );
14805
+ }
14788
14806
 
14789
14807
  // plugins/kxm/src/vnext-config.ts
14790
14808
  var import__ = __toESM(require__(), 1);
14791
14809
  import { spawnSync as spawnSync2 } from "node:child_process";
14792
14810
  import { createHash as createHash2 } from "node:crypto";
14793
- import { existsSync as existsSync2, lstatSync, readFileSync, readdirSync, realpathSync } from "node:fs";
14794
- import { basename, dirname, extname, isAbsolute, join, relative, resolve, sep } from "node:path";
14795
- import { fileURLToPath } from "node:url";
14811
+ import { existsSync as existsSync3, lstatSync, readFileSync, readdirSync, realpathSync } from "node:fs";
14812
+ import { basename, dirname as dirname2, extname, isAbsolute, join as join2, relative, resolve, sep } from "node:path";
14796
14813
 
14797
14814
  // plugins/kxm/src/restricted-yaml.mjs
14798
14815
  var import_yaml = __toESM(require_dist(), 1);
@@ -15120,7 +15137,7 @@ function resolveVnextTemplateBaseline(value) {
15120
15137
 
15121
15138
  // plugins/kxm/src/vnext-harness.ts
15122
15139
  import { spawnSync } from "node:child_process";
15123
- import { existsSync } from "node:fs";
15140
+ import { existsSync as existsSync2 } from "node:fs";
15124
15141
  import { win32 as win32Path } from "node:path";
15125
15142
 
15126
15143
  // plugins/kxm/src/vnext-oneshot-process.ts
@@ -15146,7 +15163,7 @@ function defaultSpawn(command, args, options) {
15146
15163
  if (options.signal?.aborted) {
15147
15164
  return Promise.resolve({ stdout: "", stderr: "", code: null, started: false, observedChildExit: false, error: new Error("process_aborted") });
15148
15165
  }
15149
- return new Promise((resolve7) => {
15166
+ return new Promise((resolve6) => {
15150
15167
  const stdout = [];
15151
15168
  const stderr = [];
15152
15169
  let outputBytes = 0;
@@ -15177,7 +15194,7 @@ function defaultSpawn(command, args, options) {
15177
15194
  const started = Boolean(child?.pid);
15178
15195
  if (started && !observedChildExit) error ??= new Error("process_exit_unobserved");
15179
15196
  const unverifiedDescendants = stopping || started && !observedChildExit;
15180
- resolve7({
15197
+ resolve6({
15181
15198
  stdout: Buffer.concat(stdout).toString("utf8"),
15182
15199
  stderr: Buffer.concat(stderr).toString("utf8"),
15183
15200
  code,
@@ -15669,7 +15686,7 @@ function findWinNpmInnerExe(cliId, options = {}) {
15669
15686
  if ((options.platform ?? process.platform) !== "win32") return void 0;
15670
15687
  const segments = WIN_NPM_INNER_EXE[cliId];
15671
15688
  if (!segments) return void 0;
15672
- const exists = options.existsSync ?? existsSync;
15689
+ const exists = options.existsSync ?? existsSync2;
15673
15690
  const pathEnv = options.pathEnv ?? process.env.PATH ?? "";
15674
15691
  for (const dir of pathEnv.split(";").filter(Boolean)) {
15675
15692
  if (!exists(win32Path.join(dir, `${cliId}.cmd`))) continue;
@@ -16179,8 +16196,10 @@ var VnextConfigError = class extends Error {
16179
16196
  this.issues = sorted;
16180
16197
  }
16181
16198
  };
16182
- var PACKAGE_ROOT = resolve(dirname(fileURLToPath(import.meta.url)), "../../..");
16183
- var DEFAULT_SCHEMA_DIR = join(PACKAGE_ROOT, "schemas", "vnext");
16199
+ function defaultVnextSchemaDir() {
16200
+ return join2(findKxmRepoRoot(import.meta.url), "schemas", "vnext");
16201
+ }
16202
+ var DEFAULT_SCHEMA_DIR = defaultVnextSchemaDir();
16184
16203
  var RESOURCE_SCHEMA = Object.freeze({
16185
16204
  project: { identity: "kxm.project.v1", file: "project.schema.json" },
16186
16205
  repository: { identity: "kxm.repository.v1", file: "repository.schema.json" },
@@ -16245,10 +16264,10 @@ var VnextSchemaRegistry = class {
16245
16264
  constructor(schemasDir = DEFAULT_SCHEMA_DIR) {
16246
16265
  this.schemasDir = resolve(schemasDir);
16247
16266
  this.ajv = new import__.Ajv2020({ allErrors: true, strict: true, strictRequired: false });
16248
- const common = readJsonObject(join(this.schemasDir, "common.schema.json"));
16267
+ const common = readJsonObject(join2(this.schemasDir, "common.schema.json"));
16249
16268
  this.ajv.addSchema(common);
16250
16269
  for (const definition of Object.values(RESOURCE_SCHEMA)) {
16251
- this.ajv.addSchema(readJsonObject(join(this.schemasDir, definition.file)));
16270
+ this.ajv.addSchema(readJsonObject(join2(this.schemasDir, definition.file)));
16252
16271
  }
16253
16272
  const localBindingsFile = "local-repository-bindings.schema.json";
16254
16273
  const templateProvenanceFile = "template-provenance.schema.json";
@@ -16258,14 +16277,14 @@ var VnextSchemaRegistry = class {
16258
16277
  const migrationReceiptFile = "migration-receipt.schema.json";
16259
16278
  const permissionDiffFile = "permission-diff.schema.json";
16260
16279
  const runEventFile = "run-event.schema.json";
16261
- this.ajv.addSchema(readJsonObject(join(this.schemasDir, localBindingsFile)));
16262
- this.ajv.addSchema(readJsonObject(join(this.schemasDir, templateProvenanceFile)));
16263
- this.ajv.addSchema(readJsonObject(join(this.schemasDir, initOperationFile)));
16264
- this.ajv.addSchema(readJsonObject(join(this.schemasDir, migrationPlanFile)));
16265
- this.ajv.addSchema(readJsonObject(join(this.schemasDir, migrationDecisionFile)));
16266
- this.ajv.addSchema(readJsonObject(join(this.schemasDir, migrationReceiptFile)));
16267
- this.ajv.addSchema(readJsonObject(join(this.schemasDir, permissionDiffFile)));
16268
- this.ajv.addSchema(readJsonObject(join(this.schemasDir, runEventFile)));
16280
+ this.ajv.addSchema(readJsonObject(join2(this.schemasDir, localBindingsFile)));
16281
+ this.ajv.addSchema(readJsonObject(join2(this.schemasDir, templateProvenanceFile)));
16282
+ this.ajv.addSchema(readJsonObject(join2(this.schemasDir, initOperationFile)));
16283
+ this.ajv.addSchema(readJsonObject(join2(this.schemasDir, migrationPlanFile)));
16284
+ this.ajv.addSchema(readJsonObject(join2(this.schemasDir, migrationDecisionFile)));
16285
+ this.ajv.addSchema(readJsonObject(join2(this.schemasDir, migrationReceiptFile)));
16286
+ this.ajv.addSchema(readJsonObject(join2(this.schemasDir, permissionDiffFile)));
16287
+ this.ajv.addSchema(readJsonObject(join2(this.schemasDir, runEventFile)));
16269
16288
  for (const [kind, definition] of Object.entries(RESOURCE_SCHEMA)) {
16270
16289
  const validator = this.ajv.getSchema(`https://schemas.kxm.dev/vnext/${definition.file}`);
16271
16290
  if (!validator) throw new Error(`schema did not compile: ${definition.file}`);
@@ -16372,15 +16391,15 @@ function containedHostPath(root, candidate) {
16372
16391
  function portableBindingIssue(root, pathHint, repositoryId) {
16373
16392
  let current = root;
16374
16393
  for (const segment of pathHint === "." ? [] : pathHint.split("/")) {
16375
- current = join(current, segment);
16376
- if (!existsSync2(current)) break;
16394
+ current = join2(current, segment);
16395
+ if (!existsSync3(current)) break;
16377
16396
  const stat = lstatSync(current);
16378
16397
  if (stat.isSymbolicLink()) {
16379
16398
  return issue2("path", "repository_binding_path_link", ".kxm/project.yaml", `portable pathHint for ${repositoryId} traverses a symbolic link or junction`);
16380
16399
  }
16381
16400
  }
16382
16401
  const binding = resolve(root, ...pathHint.split("/"));
16383
- if (existsSync2(binding)) {
16402
+ if (existsSync3(binding)) {
16384
16403
  const realRoot = canonicalHostPath(root);
16385
16404
  const realBinding = canonicalHostPath(binding);
16386
16405
  if (!containedHostPath(realRoot, realBinding)) {
@@ -16418,9 +16437,9 @@ function readResource(registry, root, file, logicalPath, kind, id, containmentRo
16418
16437
  }
16419
16438
  if (stat.isSymbolicLink()) fail2("path", "resource_symlink", label, "configuration resources must not be symbolic links");
16420
16439
  const boundary = resolve(containmentRoot);
16421
- let parent = dirname(file);
16440
+ let parent = dirname2(file);
16422
16441
  while (parent !== boundary) {
16423
- if (parent === dirname(parent)) fail2("path", "resource_outside_project", label, "resource escapes the project root");
16442
+ if (parent === dirname2(parent)) fail2("path", "resource_outside_project", label, "resource escapes the project root");
16424
16443
  let parentStat;
16425
16444
  try {
16426
16445
  parentStat = lstatSync(parent);
@@ -16428,7 +16447,7 @@ function readResource(registry, root, file, logicalPath, kind, id, containmentRo
16428
16447
  fail2("discovery", "resource_parent_missing", label, "resource parent does not exist");
16429
16448
  }
16430
16449
  if (parentStat.isSymbolicLink()) fail2("path", "resource_parent_symlink", label, "configuration resource parents must not be symbolic links");
16431
- parent = dirname(parent);
16450
+ parent = dirname2(parent);
16432
16451
  }
16433
16452
  if (!stat.isFile()) fail2("path", "resource_not_file", label, "configuration resource must be a regular file");
16434
16453
  const value = parseRestrictedYaml2(readFileSync(file), label);
@@ -16437,22 +16456,22 @@ function readResource(registry, root, file, logicalPath, kind, id, containmentRo
16437
16456
  return { kind, ...id === void 0 ? {} : { id }, file, logicalPath, value };
16438
16457
  }
16439
16458
  function readTemplateProvenance(registry, root) {
16440
- const file = join(root, ".kxm", "template-provenance.yaml");
16441
- if (!existsSync2(file)) return void 0;
16459
+ const file = join2(root, ".kxm", "template-provenance.yaml");
16460
+ if (!existsSync3(file)) return void 0;
16442
16461
  const label = ".kxm/template-provenance.yaml";
16443
16462
  const stat = lstatSync(file);
16444
16463
  if (stat.isSymbolicLink() || !stat.isFile()) {
16445
16464
  fail2("path", "resource_not_file", label, "template provenance must be a regular file, not a link or directory");
16446
16465
  }
16447
- const configRoot = join(root, ".kxm");
16448
- let parent = dirname(file);
16466
+ const configRoot = join2(root, ".kxm");
16467
+ let parent = dirname2(file);
16449
16468
  while (parent !== root) {
16450
16469
  const parentStat = lstatSync(parent);
16451
16470
  if (parentStat.isSymbolicLink() || !parentStat.isDirectory()) {
16452
16471
  fail2("path", "resource_parent_symlink", label, "template provenance parents must be regular directories");
16453
16472
  }
16454
16473
  if (parent === configRoot) break;
16455
- parent = dirname(parent);
16474
+ parent = dirname2(parent);
16456
16475
  }
16457
16476
  const value = parseRestrictedYaml2(readFileSync(file), label);
16458
16477
  const issues = registry.validateTemplateProvenance(value, label);
@@ -16485,7 +16504,7 @@ function readTemplateProvenance(registry, root) {
16485
16504
  }
16486
16505
  function listNamedResources(registry, root, directory, logicalDirectory, kind) {
16487
16506
  const resources = /* @__PURE__ */ new Map();
16488
- if (!existsSync2(directory)) return resources;
16507
+ if (!existsSync3(directory)) return resources;
16489
16508
  const stat = lstatSync(directory);
16490
16509
  if (stat.isSymbolicLink() || !stat.isDirectory()) {
16491
16510
  fail2("path", "resource_directory_invalid", displayPath(root, directory), "resource directory must be a regular directory");
@@ -16494,27 +16513,27 @@ function listNamedResources(registry, root, directory, logicalDirectory, kind) {
16494
16513
  const entries = readdirSync(directory, { withFileTypes: true }).sort((left, right) => compareCodeUnits3(left.name, right.name));
16495
16514
  for (const entry of entries) {
16496
16515
  if (entry.isDirectory()) {
16497
- issues.push(issue2("path", "nested_resource_directory", displayPath(root, join(directory, entry.name)), "nested resource directories are not allowed"));
16516
+ issues.push(issue2("path", "nested_resource_directory", displayPath(root, join2(directory, entry.name)), "nested resource directories are not allowed"));
16498
16517
  continue;
16499
16518
  }
16500
16519
  if (!entry.name.toLowerCase().endsWith(".yaml") && !entry.name.toLowerCase().endsWith(".yml")) continue;
16501
16520
  if (!entry.isFile() || extname(entry.name) !== ".yaml") {
16502
- issues.push(issue2("path", "resource_filename_invalid", displayPath(root, join(directory, entry.name)), "resource must be a regular file with the exact .yaml extension"));
16521
+ issues.push(issue2("path", "resource_filename_invalid", displayPath(root, join2(directory, entry.name)), "resource must be a regular file with the exact .yaml extension"));
16503
16522
  continue;
16504
16523
  }
16505
16524
  const id = basename(entry.name, ".yaml");
16506
16525
  if (kind === "model" && id === "inventory") continue;
16507
16526
  if (!resourceIdentifier(id)) {
16508
- issues.push(issue2("path", "resource_id_invalid", displayPath(root, join(directory, entry.name)), `filename-derived identity ${id} is invalid or platform-reserved`));
16527
+ issues.push(issue2("path", "resource_id_invalid", displayPath(root, join2(directory, entry.name)), `filename-derived identity ${id} is invalid or platform-reserved`));
16509
16528
  continue;
16510
16529
  }
16511
16530
  const collision = [...resources.keys()].find((candidate) => candidate.toLocaleLowerCase("en-US") === id.toLocaleLowerCase("en-US"));
16512
16531
  if (collision) {
16513
- issues.push(issue2("path", "resource_id_collision", displayPath(root, join(directory, entry.name)), `${id} case-folds to existing ${collision}`));
16532
+ issues.push(issue2("path", "resource_id_collision", displayPath(root, join2(directory, entry.name)), `${id} case-folds to existing ${collision}`));
16514
16533
  continue;
16515
16534
  }
16516
16535
  try {
16517
- const resource = readResource(registry, root, join(directory, entry.name), `${logicalDirectory}/${id}.yaml`, kind, id);
16536
+ const resource = readResource(registry, root, join2(directory, entry.name), `${logicalDirectory}/${id}.yaml`, kind, id);
16518
16537
  resources.set(id, resource);
16519
16538
  } catch (error) {
16520
16539
  if (error instanceof VnextConfigError) issues.push(...error.issues);
@@ -16806,8 +16825,8 @@ function validateWorkflow(workflow, agents, models, repositories, gates, issues)
16806
16825
  const writable = Object.values(objectValue(step.repositories) ?? {}).filter((access) => access === "write").length;
16807
16826
  if (maxWriteRepositories > writable) issues.push(issue2("semantic", "write_repository_bound_invalid", file, `${stepId} maxWriteRepositories exceeds writable repository scope`));
16808
16827
  }
16809
- const join13 = objectValue(step.join);
16810
- const minimumPassed = join13 && typeof join13.minimumPassed === "number" ? join13.minimumPassed : void 0;
16828
+ const join14 = objectValue(step.join);
16829
+ const minimumPassed = join14 && typeof join14.minimumPassed === "number" ? join14.minimumPassed : void 0;
16811
16830
  if (minimumPassed !== void 0 && minimumPassed > maximum) issues.push(issue2("semantic", "join_impossible", file, `${stepId} minimumPassed exceeds assignment maximum`));
16812
16831
  const distinctBy = names(assignment?.distinctBy);
16813
16832
  if (distinctBy.length > 0) {
@@ -17021,9 +17040,9 @@ function validateBundle(project, repositories, agents, models, workflows, enviro
17021
17040
  if (!workflows.has(defaultWorkflow)) issues.push(issue2("reference", "default_workflow_unknown", project.logicalPath, `default workflow ${defaultWorkflow} does not exist`));
17022
17041
  for (const workflow of workflows.values()) validateWorkflow(workflow, agents, models, repositoryIds, gates, issues);
17023
17042
  if (projectRoot) {
17024
- const writerRolePath = join(projectRoot, ".kxm", "roles", "writer.yaml");
17043
+ const writerRolePath = join2(projectRoot, ".kxm", "roles", "writer.yaml");
17025
17044
  const implementerAgent = agents.get("implementer") ?? agents.get("writer");
17026
- if (existsSync2(writerRolePath) && implementerAgent) {
17045
+ if (existsSync3(writerRolePath) && implementerAgent) {
17027
17046
  try {
17028
17047
  const rawRole = parseRestrictedYaml2(readFileSync(writerRolePath, "utf8"));
17029
17048
  const roleObj = objectValue(rawRole);
@@ -17072,7 +17091,7 @@ function gitEnvironment() {
17072
17091
  }
17073
17092
  function discoverGitRoot(start = process.cwd()) {
17074
17093
  let current = resolve(start);
17075
- if (existsSync2(current) && !lstatSync(current).isDirectory()) current = dirname(current);
17094
+ if (existsSync3(current) && !lstatSync(current).isDirectory()) current = dirname2(current);
17076
17095
  const result = spawnSync2("git", ["-C", current, "rev-parse", "--show-toplevel"], {
17077
17096
  encoding: "utf8",
17078
17097
  env: gitEnvironment(),
@@ -17081,7 +17100,7 @@ function discoverGitRoot(start = process.cwd()) {
17081
17100
  });
17082
17101
  if (result.status !== 0 || result.error || !result.stdout.trim()) return void 0;
17083
17102
  const root = resolve(result.stdout.trim());
17084
- return existsSync2(root) && lstatSync(root).isDirectory() ? root : void 0;
17103
+ return existsSync3(root) && lstatSync(root).isDirectory() ? root : void 0;
17085
17104
  }
17086
17105
  function assertNoRegisteredGates(options) {
17087
17106
  if ("registeredGates" in options) {
@@ -17098,7 +17117,7 @@ function loadVnextProject(projectRoot, options = {}) {
17098
17117
  migrationReceipt = receiptCheck.receipt;
17099
17118
  }
17100
17119
  const registry = new VnextSchemaRegistry(options.schemasDir);
17101
- const project = readResource(registry, root, join(root, ".kxm", "project.yaml"), ".kxm/project.yaml", "project");
17120
+ const project = readResource(registry, root, join2(root, ".kxm", "project.yaml"), ".kxm/project.yaml", "project");
17102
17121
  const earlyIssues = [];
17103
17122
  validatePortablePaths(project, earlyIssues);
17104
17123
  const templateProvenance = readTemplateProvenance(registry, root);
@@ -17120,16 +17139,16 @@ function loadVnextProject(projectRoot, options = {}) {
17120
17139
  }
17121
17140
  }
17122
17141
  if (earlyIssues.length > 0) throw new VnextConfigError(earlyIssues);
17123
- const agents = listNamedResources(registry, root, join(root, ".kxm", "agents"), ".kxm/agents", "agent");
17124
- const models = listNamedResources(registry, root, join(root, ".kxm", "models"), ".kxm/models", "model");
17125
- const workflows = listNamedResources(registry, root, join(root, ".kxm", "workflows"), ".kxm/workflows", "workflow");
17126
- const gatePath = join(root, ".kxm", "gates.yaml");
17127
- const gateRegistry = existsSync2(gatePath) ? readResource(registry, root, gatePath, ".kxm/gates.yaml", "gate-registry") : void 0;
17142
+ const agents = listNamedResources(registry, root, join2(root, ".kxm", "agents"), ".kxm/agents", "agent");
17143
+ const models = listNamedResources(registry, root, join2(root, ".kxm", "models"), ".kxm/models", "model");
17144
+ const workflows = listNamedResources(registry, root, join2(root, ".kxm", "workflows"), ".kxm/workflows", "workflow");
17145
+ const gatePath = join2(root, ".kxm", "gates.yaml");
17146
+ const gateRegistry = existsSync3(gatePath) ? readResource(registry, root, gatePath, ".kxm/gates.yaml", "gate-registry") : void 0;
17128
17147
  const environments = [];
17129
17148
  const repositories = /* @__PURE__ */ new Map();
17130
17149
  const loadIssues = [];
17131
- const projectEnvironment = join(root, ".kxm", "project", "env.yaml");
17132
- if (existsSync2(projectEnvironment)) {
17150
+ const projectEnvironment = join2(root, ".kxm", "project", "env.yaml");
17151
+ if (existsSync3(projectEnvironment)) {
17133
17152
  try {
17134
17153
  environments.push(readResource(registry, root, projectEnvironment, ".kxm/project/env.yaml", "environment"));
17135
17154
  } catch (error) {
@@ -17171,7 +17190,7 @@ function loadVnextProject(projectRoot, options = {}) {
17171
17190
  if (required) loadIssues.push(issue2("discovery", "repository_binding_missing", ".kxm/project.yaml", `required repository ${repositoryId} has no portable pathHint or host-local binding`));
17172
17191
  continue;
17173
17192
  }
17174
- if (!existsSync2(binding)) {
17193
+ if (!existsSync3(binding)) {
17175
17194
  if (required || hasLocalBinding) loadIssues.push(issue2("discovery", "repository_binding_unavailable", ".kxm/project.yaml", `${hasLocalBinding ? "explicit" : "required"} repository binding ${repositoryId} is unavailable`));
17176
17195
  continue;
17177
17196
  }
@@ -17194,9 +17213,9 @@ function loadVnextProject(projectRoot, options = {}) {
17194
17213
  continue;
17195
17214
  }
17196
17215
  seenBindings.set(foldedBinding, repositoryId);
17197
- const repositoryFile = join(binding, ".kxm", "repo", "repo.yaml");
17216
+ const repositoryFile = join2(binding, ".kxm", "repo", "repo.yaml");
17198
17217
  let definitionValidated = false;
17199
- if (existsSync2(repositoryFile)) {
17218
+ if (existsSync3(repositoryFile)) {
17200
17219
  try {
17201
17220
  const resource = readResource(registry, root, repositoryFile, `.kxm/repositories/${repositoryId}/repo.yaml`, "repository", repositoryId, binding);
17202
17221
  if (resource.value.repositoryId !== repositoryId) {
@@ -17212,8 +17231,8 @@ function loadVnextProject(projectRoot, options = {}) {
17212
17231
  } else if (required || hasLocalBinding) {
17213
17232
  loadIssues.push(issue2("discovery", "repository_definition_missing", `.kxm/repositories/${repositoryId}/repo.yaml`, `${hasLocalBinding ? "explicit" : "required"} repository ${repositoryId} has no repo.yaml`));
17214
17233
  }
17215
- const environmentFile = join(binding, ".kxm", "repo", "env.yaml");
17216
- if (existsSync2(environmentFile)) {
17234
+ const environmentFile = join2(binding, ".kxm", "repo", "env.yaml");
17235
+ if (existsSync3(environmentFile)) {
17217
17236
  if (!definitionValidated) {
17218
17237
  loadIssues.push(issue2("reference", "repository_environment_without_definition", `.kxm/repositories/${repositoryId}/env.yaml`, `repository ${repositoryId} environment requires a validated matching repo.yaml`));
17219
17238
  } else {
@@ -17250,14 +17269,14 @@ var LEGACY_CONFIG_FILES = [".kxm/config/agents.json", ".kxm/config/gates.json"];
17250
17269
  function legacyConfigFilesAt(root) {
17251
17270
  const files = [];
17252
17271
  for (const component of [".kxm", ".kxm/config"]) {
17253
- const absolute = join(root, ...component.split("/"));
17254
- if (existsSync2(absolute) && lstatSync(absolute).isSymbolicLink()) return [component];
17272
+ const absolute = join2(root, ...component.split("/"));
17273
+ if (existsSync3(absolute) && lstatSync(absolute).isSymbolicLink()) return [component];
17255
17274
  }
17256
17275
  for (const candidate of LEGACY_CONFIG_FILES) {
17257
- if (existsSync2(join(root, ...candidate.split("/")))) files.push(candidate);
17276
+ if (existsSync3(join2(root, ...candidate.split("/")))) files.push(candidate);
17258
17277
  }
17259
- const workflowsDir = join(root, ".kxm", "config", "workflows");
17260
- if (existsSync2(workflowsDir)) {
17278
+ const workflowsDir = join2(root, ".kxm", "config", "workflows");
17279
+ if (existsSync3(workflowsDir)) {
17261
17280
  const stat = lstatSync(workflowsDir);
17262
17281
  if (stat.isSymbolicLink()) {
17263
17282
  files.push(".kxm/config/workflows");
@@ -17272,8 +17291,8 @@ function legacyConfigFilesAt(root) {
17272
17291
  return files;
17273
17292
  }
17274
17293
  function hashFileRecord(root, relativePath) {
17275
- const absolute = join(root, ...relativePath.split("/"));
17276
- if (!existsSync2(absolute)) return void 0;
17294
+ const absolute = join2(root, ...relativePath.split("/"));
17295
+ if (!existsSync3(absolute)) return void 0;
17277
17296
  const bytes = readFileSync(absolute);
17278
17297
  return {
17279
17298
  path: relativePath,
@@ -17286,9 +17305,9 @@ function migrationReceiptSelfHash(receipt) {
17286
17305
  return `sha256:${createHash2("sha256").update(vnextCanonicalJson(unsigned), "utf8").digest("hex")}`;
17287
17306
  }
17288
17307
  function readVnextMigrationReceipt(root, options = {}) {
17289
- const receiptPath = join(root, ...VNEXT_MIGRATION_RECEIPT_PATH.split("/"));
17308
+ const receiptPath = join2(root, ...VNEXT_MIGRATION_RECEIPT_PATH.split("/"));
17290
17309
  const legacyFiles = legacyConfigFilesAt(root);
17291
- if (!existsSync2(receiptPath)) {
17310
+ if (!existsSync3(receiptPath)) {
17292
17311
  return {
17293
17312
  issues: legacyFiles.map((file) => issue2("semantic", "legacy_vnext_conflict", file, "legacy and vNext configuration cannot coexist before an accepted migration receipt"))
17294
17313
  };
@@ -17334,8 +17353,8 @@ function readVnextMigrationReceipt(root, options = {}) {
17334
17353
 
17335
17354
  // plugins/kxm/src/vnext-runtime-store.ts
17336
17355
  import { createHash as createHash3, randomUUID } from "node:crypto";
17337
- import { existsSync as existsSync4, lstatSync as lstatSync3, mkdirSync as mkdirSync2, readFileSync as readFileSync3, realpathSync as realpathSync2, writeFileSync as writeFileSync2 } from "node:fs";
17338
- import { dirname as dirname4, join as join4, resolve as resolve4 } from "node:path";
17356
+ import { existsSync as existsSync5, lstatSync as lstatSync3, mkdirSync as mkdirSync2, readFileSync as readFileSync3, realpathSync as realpathSync2, writeFileSync as writeFileSync2 } from "node:fs";
17357
+ import { dirname as dirname5, join as join5, resolve as resolve4 } from "node:path";
17339
17358
 
17340
17359
  // plugins/kxm/src/vnext-bindings.ts
17341
17360
  import { homedir } from "node:os";
@@ -17380,7 +17399,7 @@ var DatabaseSync = class {
17380
17399
  };
17381
17400
 
17382
17401
  // plugins/kxm/src/vnext-bindings.ts
17383
- import { dirname as dirname2, isAbsolute as isAbsolute2, join as join2, parse, relative as relative2, resolve as resolve2, sep as sep2 } from "node:path";
17402
+ import { dirname as dirname3, isAbsolute as isAbsolute2, join as join3, parse, relative as relative2, resolve as resolve2, sep as sep2 } from "node:path";
17384
17403
  var MAX_BINDING_RECORD_BYTES = 256 * 1024;
17385
17404
  var BINDING_LABEL = "Runtime-local repository bindings";
17386
17405
  function bindingIssue(phase, code, message) {
@@ -17400,12 +17419,12 @@ function vnextUserStateRoot(options = {}) {
17400
17419
  }
17401
17420
  if (platform === "win32") {
17402
17421
  const localAppData = env.LOCALAPPDATA?.trim();
17403
- const base2 = localAppData && isAbsolute2(localAppData) ? localAppData : join2(home, "AppData", "Local");
17422
+ const base2 = localAppData && isAbsolute2(localAppData) ? localAppData : join3(home, "AppData", "Local");
17404
17423
  return resolve2(base2, "KXM");
17405
17424
  }
17406
17425
  if (platform === "darwin") return resolve2(home, "Library", "Application Support", "KXM");
17407
17426
  const xdgState = env.XDG_STATE_HOME?.trim();
17408
- const base = xdgState && isAbsolute2(xdgState) ? xdgState : join2(home, ".local", "state");
17427
+ const base = xdgState && isAbsolute2(xdgState) ? xdgState : join3(home, ".local", "state");
17409
17428
  return resolve2(base, "kxm");
17410
17429
  }
17411
17430
 
@@ -17413,7 +17432,7 @@ function vnextUserStateRoot(options = {}) {
17413
17432
  import {
17414
17433
  chmodSync,
17415
17434
  copyFileSync,
17416
- existsSync as existsSync3,
17435
+ existsSync as existsSync4,
17417
17436
  lstatSync as lstatSync2,
17418
17437
  mkdirSync,
17419
17438
  readdirSync as readdirSync2,
@@ -17421,14 +17440,14 @@ import {
17421
17440
  unlinkSync,
17422
17441
  writeFileSync
17423
17442
  } from "node:fs";
17424
- import { basename as basename2, dirname as dirname3, join as join3, resolve as resolve3 } from "node:path";
17443
+ import { basename as basename2, dirname as dirname4, join as join4, resolve as resolve3 } from "node:path";
17425
17444
  function databaseError(code, file, message) {
17426
17445
  const issue3 = { phase: "semantic", code, file, message };
17427
17446
  return new VnextConfigError([issue3]);
17428
17447
  }
17429
17448
  function checkedParent(path, description) {
17430
- const parent = dirname3(path);
17431
- if (!existsSync3(parent)) mkdirSync(parent, { recursive: true, mode: 448 });
17449
+ const parent = dirname4(path);
17450
+ if (!existsSync4(parent)) mkdirSync(parent, { recursive: true, mode: 448 });
17432
17451
  const stat = lstatSync2(parent, { throwIfNoEntry: false });
17433
17452
  if (!stat || stat.isSymbolicLink() || !stat.isDirectory()) {
17434
17453
  throw databaseError("runtime_path_invalid", description, `${description} parent must be a regular directory, not a link`);
@@ -17582,12 +17601,12 @@ function withDatabaseTransaction(database, work, mode = "IMMEDIATE") {
17582
17601
  // plugins/kxm/src/vnext-runtime-store.ts
17583
17602
  function vnextRuntimePaths(options = {}) {
17584
17603
  const stateRoot = options.stateRoot ? resolve4(options.stateRoot) : vnextUserStateRoot({ ...options.env ? { env: options.env } : {}, ...options.homeDir ? { homeDir: options.homeDir } : {} });
17585
- const runtimeDir = join4(stateRoot, "runtime");
17604
+ const runtimeDir = join5(stateRoot, "runtime");
17586
17605
  return {
17587
17606
  stateRoot,
17588
17607
  runtimeDir,
17589
- registryDb: join4(runtimeDir, "registry.db"),
17590
- projectsDir: join4(runtimeDir, "projects")
17608
+ registryDb: join5(runtimeDir, "registry.db"),
17609
+ projectsDir: join5(runtimeDir, "projects")
17591
17610
  };
17592
17611
  }
17593
17612
  function runtimeIssue(phase, code, file, message) {
@@ -18049,7 +18068,7 @@ var VnextRunEventStore = class {
18049
18068
  }
18050
18069
  readRunPrompts() {
18051
18070
  const sidecar = this.runPromptSidecarPath();
18052
- if (!existsSync4(sidecar)) return {};
18071
+ if (!existsSync5(sidecar)) return {};
18053
18072
  try {
18054
18073
  const parsed = JSON.parse(readFileSync3(sidecar, "utf8"));
18055
18074
  if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) return {};
@@ -18772,8 +18791,8 @@ function capabilityFromRow(row) {
18772
18791
 
18773
18792
  // plugins/kxm/src/vnext-runtime.ts
18774
18793
  import { createHash as createHash5 } from "node:crypto";
18775
- import { existsSync as existsSync5, readdirSync as readdirSync3, readFileSync as readFileSync4 } from "node:fs";
18776
- import { join as join5 } from "node:path";
18794
+ import { existsSync as existsSync6, readdirSync as readdirSync3, readFileSync as readFileSync4 } from "node:fs";
18795
+ import { join as join6 } from "node:path";
18777
18796
 
18778
18797
  // plugins/kxm/src/vnext-engine-fold.ts
18779
18798
  var VNEXT_RUN_STATE_SCHEMA = "kxm.run-state.v2";
@@ -20072,7 +20091,7 @@ function compileStep(step, index, stepIndex, requirePlanHash, sink) {
20072
20091
  const maxAttempts = compileCountField(step.maxAttempts, 1, `${id}.maxAttempts`, id, sink);
20073
20092
  const timeoutMs = compileOptionalDuration(step.timeoutMs, `${id}.timeoutMs`, id, sink);
20074
20093
  const assignments = compileAssignments(step, id, agent, sink);
20075
- const join13 = compileJoin(step, id, sink);
20094
+ const join14 = compileJoin(step, id, sink);
20076
20095
  const requiredEvidence = compileEvidence(step, id, sink);
20077
20096
  const transitions = compileTransitions(step, id, index, stepIndex, sink);
20078
20097
  const outcomes = Object.keys(transitions).sort(compareCodeUnits4);
@@ -20100,7 +20119,7 @@ function compileStep(step, index, stepIndex, requirePlanHash, sink) {
20100
20119
  transitions: orderedTransitions,
20101
20120
  requiresPlanHash: requirePlanHash.includes(id),
20102
20121
  assignments,
20103
- join: join13
20122
+ join: join14
20104
20123
  };
20105
20124
  if (kind === "agent" || kind === "moa") {
20106
20125
  if (!agent) return void 0;
@@ -20150,15 +20169,15 @@ function compileAssignments(step, stepId, primaryAgentId, sink) {
20150
20169
  };
20151
20170
  }
20152
20171
  function compileJoin(step, stepId, sink) {
20153
- const join13 = objectValue2(step.join);
20154
- if (!join13) return { strategy: "all" };
20155
- const declared = stringValue2(join13.strategy);
20172
+ const join14 = objectValue2(step.join);
20173
+ if (!join14) return { strategy: "all" };
20174
+ const declared = stringValue2(join14.strategy);
20156
20175
  const strategy = declared && JOIN_STRATEGIES.has(declared) ? declared : "all";
20157
- const minimumPassed = compileOptionalCount(join13.minimumPassed, `${stepId}.join.minimumPassed`, stepId, sink);
20176
+ const minimumPassed = compileOptionalCount(join14.minimumPassed, `${stepId}.join.minimumPassed`, stepId, sink);
20158
20177
  const compiled = {
20159
20178
  strategy,
20160
20179
  ...minimumPassed !== void 0 ? { minimumPassed } : {},
20161
- ...typeof join13.cancelRemaining === "boolean" ? { cancelRemaining: join13.cancelRemaining } : {}
20180
+ ...typeof join14.cancelRemaining === "boolean" ? { cancelRemaining: join14.cancelRemaining } : {}
20162
20181
  };
20163
20182
  return compiled;
20164
20183
  }
@@ -21479,12 +21498,12 @@ function enqueueVnextScheduledRun(storePath, runId, configRevision, bound, start
21479
21498
  if (owner.admitted.has(runId) || owner.queue.some((item) => item.runId === runId)) {
21480
21499
  return Promise.reject(runtimeError("run_busy", runId, `run ${runId} is already admitted or queued`));
21481
21500
  }
21482
- return new Promise((resolve7, reject) => {
21501
+ return new Promise((resolve6, reject) => {
21483
21502
  owner.queue.push({
21484
21503
  runId,
21485
21504
  configRevision,
21486
21505
  bound,
21487
- start: (token) => start(token).then(resolve7, reject),
21506
+ start: (token) => start(token).then(resolve6, reject),
21488
21507
  fail: (error) => reject(error)
21489
21508
  });
21490
21509
  pump(storePath, owner);
@@ -21545,11 +21564,11 @@ function vnextToolPolicyRevision(bundle) {
21545
21564
  return sha256Of(vnextCanonicalJson({ policies, gateRegistry: bundle.gateRegistry?.value ?? null }));
21546
21565
  }
21547
21566
  function collectMemoryFiles(dir, baseDir, ignoreSubdirs = /* @__PURE__ */ new Set()) {
21548
- if (!existsSync5(dir)) return [];
21567
+ if (!existsSync6(dir)) return [];
21549
21568
  const entries = readdirSync3(dir, { withFileTypes: true });
21550
21569
  const results = [];
21551
21570
  for (const entry of entries) {
21552
- const fullPath = join5(dir, entry.name);
21571
+ const fullPath = join6(dir, entry.name);
21553
21572
  if (entry.isDirectory()) {
21554
21573
  if (ignoreSubdirs.has(entry.name)) continue;
21555
21574
  results.push(...collectMemoryFiles(fullPath, baseDir, ignoreSubdirs));
@@ -21562,15 +21581,15 @@ function collectMemoryFiles(dir, baseDir, ignoreSubdirs = /* @__PURE__ */ new Se
21562
21581
  }
21563
21582
  function computeVnextMemoryRevision(bundle, options = {}) {
21564
21583
  const hash = createHash5("sha256");
21565
- const memoryDir = options.memoryDir ?? join5(bundle.projectRoot, ".kxm", "memory");
21584
+ const memoryDir = options.memoryDir ?? join6(bundle.projectRoot, ".kxm", "memory");
21566
21585
  const memoryFiles = collectMemoryFiles(memoryDir, memoryDir, /* @__PURE__ */ new Set(["candidates"])).sort((left, right) => compareCodeUnits5(left.relPath, right.relPath));
21567
21586
  for (const file of memoryFiles) {
21568
21587
  hash.update(`memory:${file.relPath}\0`, "utf8");
21569
21588
  hash.update(readFileSync4(file.fullPath));
21570
21589
  hash.update("\0", "utf8");
21571
21590
  }
21572
- const skillsDir = options.skillsDir ?? join5(bundle.projectRoot, ".kxm", "skills");
21573
- const promotedSkillsDir = join5(skillsDir, "promoted");
21591
+ const skillsDir = options.skillsDir ?? join6(bundle.projectRoot, ".kxm", "skills");
21592
+ const promotedSkillsDir = join6(skillsDir, "promoted");
21574
21593
  const skillFiles = collectMemoryFiles(promotedSkillsDir, promotedSkillsDir).sort((left, right) => compareCodeUnits5(left.relPath, right.relPath));
21575
21594
  for (const file of skillFiles) {
21576
21595
  hash.update(`skill:${file.relPath}\0`, "utf8");
@@ -21646,7 +21665,7 @@ function openVnextRuntimeContext(projectRoot, options) {
21646
21665
  configRevision: bundle.configRevision,
21647
21666
  now: options.now ?? (/* @__PURE__ */ new Date()).toISOString()
21648
21667
  });
21649
- const eventStore = new VnextRunEventStore(join5(paths.projectsDir, registration.projectKey, "run-events.db"));
21668
+ const eventStore = new VnextRunEventStore(join6(paths.projectsDir, registration.projectKey, "run-events.db"));
21650
21669
  registerVnextRuntimeHandle(eventStore.path);
21651
21670
  return {
21652
21671
  registry,
@@ -21961,12 +21980,12 @@ function cancelVnextRun(context, runId, options = {}) {
21961
21980
  }
21962
21981
 
21963
21982
  // plugins/kxm/src/vnext-oneshot-producer.ts
21964
- import { join as join11 } from "node:path";
21983
+ import { join as join12 } from "node:path";
21965
21984
 
21966
21985
  // plugins/kxm/src/vnext-oneshot-evidence.ts
21967
21986
  import { createHash as createHash6, randomUUID as randomUUID3 } from "node:crypto";
21968
21987
  import { lstat, mkdir, open, rename } from "node:fs/promises";
21969
- import { join as join6 } from "node:path";
21988
+ import { join as join7 } from "node:path";
21970
21989
  var ONESHOT_EVIDENCE_SCHEMA = "kxm.oneshot-evidence.v2";
21971
21990
  var RETIRED_ONESHOT_EVIDENCE_SCHEMAS = /* @__PURE__ */ new Set(["kxm.oneshot-evidence.v1"]);
21972
21991
  var TEXT_LIMIT = 4 * 1024 * 1024;
@@ -21996,7 +22015,7 @@ async function beginOneShotEvidence(root, intent, sensitive) {
21996
22015
  throw new Error("oneshot_evidence_root_not_private");
21997
22016
  }
21998
22017
  const id = `evd_${randomUUID3().replaceAll("-", "")}`;
21999
- const dir = join6(root, id);
22018
+ const dir = join7(root, id);
22000
22019
  await mkdir(dir, { mode: 448 });
22001
22020
  const secrets = [...new Set(sensitive.filter((value) => value.length >= 8))].sort((a, b) => b.length - a.length);
22002
22021
  const redact = (value) => {
@@ -22016,7 +22035,7 @@ async function beginOneShotEvidence(root, intent, sensitive) {
22016
22035
  const bytes = JSON.stringify(value);
22017
22036
  if (Buffer.byteLength(bytes) > RECORD_LIMIT) throw new Error("oneshot_evidence_record_limit");
22018
22037
  parseOneShotEvidenceRecord(bytes);
22019
- const target = join6(dir, name);
22038
+ const target = join7(dir, name);
22020
22039
  const partial = `${target}.partial`;
22021
22040
  const file = await open(partial, "wx", 384);
22022
22041
  try {
@@ -22083,8 +22102,8 @@ async function beginOneShotEvidence(root, intent, sensitive) {
22083
22102
  // plugins/kxm/src/prices.ts
22084
22103
  var import_yaml3 = __toESM(require_dist(), 1);
22085
22104
  import { createHash as createHash7 } from "node:crypto";
22086
- import { existsSync as existsSync6, readFileSync as readFileSync5, statSync } from "node:fs";
22087
- import { join as join7 } from "node:path";
22105
+ import { existsSync as existsSync7, readFileSync as readFileSync5, statSync } from "node:fs";
22106
+ import { join as join8 } from "node:path";
22088
22107
 
22089
22108
  // plugins/kxm/src/price-calc.ts
22090
22109
  var PRICES_SCHEMA = "kxm.prices.v1";
@@ -22236,8 +22255,8 @@ function parsePriceCatalog(text) {
22236
22255
  return catalog;
22237
22256
  }
22238
22257
  function loadPriceCatalog(rootOrPath) {
22239
- const candidatePath = existsSync6(join7(rootOrPath, ".kxm", "prices.yaml")) ? join7(rootOrPath, ".kxm", "prices.yaml") : existsSync6(join7(rootOrPath, "prices.yaml")) ? join7(rootOrPath, "prices.yaml") : existsSync6(rootOrPath) && statSync(rootOrPath).isFile() ? rootOrPath : void 0;
22240
- if (!candidatePath || !existsSync6(candidatePath)) {
22258
+ const candidatePath = existsSync7(join8(rootOrPath, ".kxm", "prices.yaml")) ? join8(rootOrPath, ".kxm", "prices.yaml") : existsSync7(join8(rootOrPath, "prices.yaml")) ? join8(rootOrPath, "prices.yaml") : existsSync7(rootOrPath) && statSync(rootOrPath).isFile() ? rootOrPath : void 0;
22259
+ if (!candidatePath || !existsSync7(candidatePath)) {
22241
22260
  return void 0;
22242
22261
  }
22243
22262
  const content = readFileSync5(candidatePath, "utf8");
@@ -22247,28 +22266,28 @@ function loadPriceCatalog(rootOrPath) {
22247
22266
  // plugins/kxm/src/vnext-engine.ts
22248
22267
  var import_yaml5 = __toESM(require_dist(), 1);
22249
22268
  import { createHash as createHash10, randomBytes, timingSafeEqual } from "node:crypto";
22250
- import { existsSync as existsSync8, readFileSync as readFileSync7 } from "node:fs";
22251
- import { join as join10 } from "node:path";
22269
+ import { existsSync as existsSync9, readFileSync as readFileSync7 } from "node:fs";
22270
+ import { join as join11 } from "node:path";
22252
22271
 
22253
22272
  // plugins/kxm/src/producers.ts
22254
22273
  var import_yaml4 = __toESM(require_dist(), 1);
22255
- import { existsSync as existsSync7, readFileSync as readFileSync6, mkdirSync as mkdirSync3, writeFileSync as writeFileSync3, readdirSync as readdirSync4 } from "node:fs";
22256
- import { join as join8 } from "node:path";
22274
+ import { existsSync as existsSync8, readFileSync as readFileSync6, mkdirSync as mkdirSync3, writeFileSync as writeFileSync3, readdirSync as readdirSync4 } from "node:fs";
22275
+ import { join as join9 } from "node:path";
22257
22276
  var empty = () => ({ schema: "kxm.producers.v1", updatedAt: (/* @__PURE__ */ new Date()).toISOString(), promoted: [], demoted: [], enabled: [], disabled: [], roles: {} });
22258
22277
  function loadProducerPolicy(root) {
22259
- const path = join8(root, ".kxm", "producers.yaml");
22260
- if (!existsSync7(path)) return empty();
22278
+ const path = join9(root, ".kxm", "producers.yaml");
22279
+ if (!existsSync8(path)) return empty();
22261
22280
  const value = (0, import_yaml4.parse)(readFileSync6(path, "utf8"));
22262
22281
  if (value?.schema !== "kxm.producers.v1" || !Array.isArray(value.promoted) || !Array.isArray(value.demoted)) throw new Error("invalid .kxm/producers.yaml");
22263
22282
  return { schema: "kxm.producers.v1", updatedAt: typeof value.updatedAt === "string" ? value.updatedAt : (/* @__PURE__ */ new Date()).toISOString(), promoted: value.promoted.filter((x) => typeof x === "string"), demoted: value.demoted.filter((x) => typeof x === "string"), enabled: Array.isArray(value.enabled) ? value.enabled.filter((x) => typeof x === "string") : [], disabled: Array.isArray(value.disabled) ? value.disabled.filter((x) => typeof x === "string") : [], roles: value.roles && typeof value.roles === "object" ? Object.fromEntries(Object.entries(value.roles).filter(([, v]) => Array.isArray(v)).map(([k, v]) => [k, v.filter((x) => typeof x === "string")])) : {} };
22264
22283
  }
22265
22284
  function listRoleBindings(root) {
22266
- const dir = join8(root, ".kxm", "roles");
22285
+ const dir = join9(root, ".kxm", "roles");
22267
22286
  const result = {};
22268
- if (!existsSync7(dir)) return result;
22287
+ if (!existsSync8(dir)) return result;
22269
22288
  for (const file of readdirSync4(dir).filter((name) => name.endsWith(".yaml"))) {
22270
22289
  const role = file.slice(0, -5);
22271
- const value = (0, import_yaml4.parse)(readFileSync6(join8(dir, file), "utf8"));
22290
+ const value = (0, import_yaml4.parse)(readFileSync6(join9(dir, file), "utf8"));
22272
22291
  result[role] = (value.roster ?? []).map((entry) => entry.model).filter((model) => typeof model === "string");
22273
22292
  }
22274
22293
  return result;
@@ -22539,7 +22558,7 @@ function pruneContextPacket(packet, tokenBudget) {
22539
22558
  }
22540
22559
 
22541
22560
  // plugins/kxm/src/vnext-engine-artifacts.ts
22542
- import { join as join9 } from "node:path";
22561
+ import { join as join10 } from "node:path";
22543
22562
 
22544
22563
  // plugins/kxm/src/artifacts-exist.ts
22545
22564
  import { lstatSync as lstatSync4, realpathSync as realpathSync3, statSync as statSync2 } from "node:fs";
@@ -22586,14 +22605,14 @@ function verifyArtifactExists(rootInput, pathInput) {
22586
22605
  // plugins/kxm/src/vnext-engine-artifacts.ts
22587
22606
  var vnextArtifactsGateSeams = {};
22588
22607
  function evaluateArtifactsGate(context, definition) {
22589
- const root = join9(context.projectRoot, ".kxm", "assets");
22608
+ const root = join10(context.projectRoot, ".kxm", "assets");
22590
22609
  const startedAt = (/* @__PURE__ */ new Date()).toISOString();
22591
22610
  const startTime = process.hrtime.bigint();
22592
22611
  let checkedCount = 0;
22593
22612
  let failedCount = 0;
22594
22613
  for (const [index, path] of definition.paths.entries()) {
22595
22614
  checkedCount += 1;
22596
- const result = verifyArtifactExists(root, join9(root, path));
22615
+ const result = verifyArtifactExists(root, join10(root, path));
22597
22616
  if (!result.ok) failedCount += 1;
22598
22617
  vnextArtifactsGateSeams.afterPathChecked?.({ path, index, checkedCount, failedCount });
22599
22618
  }
@@ -22738,8 +22757,8 @@ var CommandObserver = class {
22738
22757
  this.requestStop("error", "lost-close");
22739
22758
  }
22740
22759
  run() {
22741
- return new Promise((resolve7) => {
22742
- this.resolveOutcome = resolve7;
22760
+ return new Promise((resolve6) => {
22761
+ this.resolveOutcome = resolve6;
22743
22762
  try {
22744
22763
  this.start();
22745
22764
  } catch (error) {
@@ -23940,8 +23959,8 @@ var VnextRunScheduler = class _VnextRunScheduler {
23940
23959
  resolve: (_value) => void 0,
23941
23960
  reject: (_error) => void 0
23942
23961
  };
23943
- const settled = new Promise((resolve7, reject) => {
23944
- pending.resolve = resolve7;
23962
+ const settled = new Promise((resolve6, reject) => {
23963
+ pending.resolve = resolve6;
23945
23964
  pending.reject = reject;
23946
23965
  });
23947
23966
  void settled.then(void 0, () => void 0);
@@ -24276,8 +24295,8 @@ function unreconciledPanelAttemptId(state) {
24276
24295
  }
24277
24296
  function resolveProducerRoute(projectRoot, step, agentId) {
24278
24297
  let agentModel;
24279
- const agentFile = join10(projectRoot, ".kxm", "agents", `${agentId}.yaml`);
24280
- if (existsSync8(agentFile)) {
24298
+ const agentFile = join11(projectRoot, ".kxm", "agents", `${agentId}.yaml`);
24299
+ if (existsSync9(agentFile)) {
24281
24300
  try {
24282
24301
  const parsed = (0, import_yaml5.parse)(readFileSync7(agentFile, "utf8"));
24283
24302
  if (typeof parsed?.model === "string") {
@@ -25860,7 +25879,7 @@ Return a final JSON object with an "outcome" field chosen from ${JSON.stringify(
25860
25879
  }
25861
25880
  const spawnFn = options.spawnProcess ?? defaultSpawn;
25862
25881
  const cwd = options.projectRoot ?? process.cwd();
25863
- const evidence = await beginOneShotEvidence(options.evidenceRoot ?? join11(vnextUserStateRoot(), "runtime", "oneshot-evidence"), {
25882
+ const evidence = await beginOneShotEvidence(options.evidenceRoot ?? join12(vnextUserStateRoot(), "runtime", "oneshot-evidence"), {
25864
25883
  runId: request.runId,
25865
25884
  stepId: request.stepId,
25866
25885
  attemptId: request.attemptId,
@@ -26004,13 +26023,12 @@ Return a final JSON object with an "outcome" field chosen from ${JSON.stringify(
26004
26023
  }
26005
26024
 
26006
26025
  // plugins/kxm/src/vnext-runtime-supervisor.ts
26007
- var repoRoot = resolve6(fileURLToPath2(new URL("../../../", import.meta.url)));
26008
26026
  function vnextSupervisorTokenFile(paths) {
26009
- return join12(paths.runtimeDir, "supervisor.token");
26027
+ return join13(paths.runtimeDir, "supervisor.token");
26010
26028
  }
26011
26029
  function publishVnextSupervisorToken(paths, token) {
26012
26030
  const file = vnextSupervisorTokenFile(paths);
26013
- mkdirSync4(dirname5(file), { recursive: true, mode: 448 });
26031
+ mkdirSync4(dirname6(file), { recursive: true, mode: 448 });
26014
26032
  const temp = `${file}.${process.pid}.tmp`;
26015
26033
  writeFileSync4(temp, `${token}
26016
26034
  `, { encoding: "utf8", mode: 384 });
@@ -26048,11 +26066,11 @@ function processAlive(pid) {
26048
26066
  var HEARTBEAT_STALE_MS = 15e3;
26049
26067
  var SUPERVISOR_ERROR_MAX_AGE_MS = 3e4;
26050
26068
  function supervisorErrorFile(paths) {
26051
- return join12(paths.runtimeDir, "supervisor.error");
26069
+ return join13(paths.runtimeDir, "supervisor.error");
26052
26070
  }
26053
26071
  function clearSupervisorError(paths) {
26054
26072
  const file = supervisorErrorFile(paths);
26055
- if (existsSync9(file)) rmSync(file, { force: true });
26073
+ if (existsSync10(file)) rmSync(file, { force: true });
26056
26074
  }
26057
26075
  function recordSupervisorError(paths, message) {
26058
26076
  try {
@@ -26075,7 +26093,7 @@ function readRecentSupervisorError(paths) {
26075
26093
  }
26076
26094
  }
26077
26095
  function vnextSupervisorStatus(paths) {
26078
- if (!existsSync9(paths.registryDb)) return { running: false };
26096
+ if (!existsSync10(paths.registryDb)) return { running: false };
26079
26097
  const registry = new VnextRuntimeRegistry(paths.registryDb);
26080
26098
  try {
26081
26099
  const record2 = registry.supervisor();
@@ -26136,7 +26154,7 @@ async function ensureVnextSupervisor(options = {}) {
26136
26154
  throw runtimeError("runtime_supervisor_unreachable", paths.registryDb, `runtime supervisor pid ${status.pid} is registered as running but cannot be probed`);
26137
26155
  }
26138
26156
  clearSupervisorError(paths);
26139
- const scriptPath = join12(repoRoot, "scripts", "kxm-runtime-supervisor.mjs");
26157
+ const scriptPath = join13(findKxmRepoRoot(import.meta.url), "scripts", "kxm-runtime-supervisor.mjs");
26140
26158
  const spawnImpl = options.spawnImpl ?? ((script, env) => {
26141
26159
  const child = spawn3(process.execPath, [script], {
26142
26160
  detached: true,
@@ -26221,8 +26239,8 @@ async function waitForDriveSessions(settled, graceMs) {
26221
26239
  try {
26222
26240
  await Promise.race([
26223
26241
  Promise.allSettled(settled),
26224
- new Promise((resolve7) => {
26225
- timeout = setTimeout(resolve7, graceMs);
26242
+ new Promise((resolve6) => {
26243
+ timeout = setTimeout(resolve6, graceMs);
26226
26244
  timeout.unref?.();
26227
26245
  })
26228
26246
  ]);