@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.
@@ -2986,7 +2986,7 @@ var require_compile = __commonJS({
2986
2986
  const schOrFunc = root.refs[ref];
2987
2987
  if (schOrFunc)
2988
2988
  return schOrFunc;
2989
- let _sch = resolve9.call(this, root, ref);
2989
+ let _sch = resolve8.call(this, root, ref);
2990
2990
  if (_sch === void 0) {
2991
2991
  const schema = (_a = root.localRefs) === null || _a === void 0 ? void 0 : _a[ref];
2992
2992
  const { schemaId } = this.opts;
@@ -3013,7 +3013,7 @@ var require_compile = __commonJS({
3013
3013
  function sameSchemaEnv(s1, s2) {
3014
3014
  return s1.schema === s2.schema && s1.root === s2.root && s1.baseId === s2.baseId;
3015
3015
  }
3016
- function resolve9(root, ref) {
3016
+ function resolve8(root, ref) {
3017
3017
  let sch;
3018
3018
  while (typeof (sch = this.refs[ref]) == "string")
3019
3019
  ref = sch;
@@ -3838,7 +3838,7 @@ var require_fast_uri = __commonJS({
3838
3838
  }
3839
3839
  return uri;
3840
3840
  }
3841
- function resolve9(baseURI, relativeURI, options) {
3841
+ function resolve8(baseURI, relativeURI, options) {
3842
3842
  const schemelessOptions = options ? Object.assign({ scheme: "null" }, options) : { scheme: "null" };
3843
3843
  const {
3844
3844
  parsed: baseParsed,
@@ -4200,7 +4200,7 @@ var require_fast_uri = __commonJS({
4200
4200
  var fastUri = {
4201
4201
  SCHEMES,
4202
4202
  normalize,
4203
- resolve: resolve9,
4203
+ resolve: resolve8,
4204
4204
  resolveComponent,
4205
4205
  equal,
4206
4206
  serialize,
@@ -14779,16 +14779,15 @@ var require_dist = __commonJS({
14779
14779
 
14780
14780
  // plugins/kxm/src/vnext-runtime.ts
14781
14781
  import { createHash as createHash6 } from "node:crypto";
14782
- import { existsSync as existsSync5, readdirSync as readdirSync3, readFileSync as readFileSync4 } from "node:fs";
14783
- import { join as join5 } from "node:path";
14782
+ import { existsSync as existsSync6, readdirSync as readdirSync3, readFileSync as readFileSync4 } from "node:fs";
14783
+ import { join as join6 } from "node:path";
14784
14784
 
14785
14785
  // plugins/kxm/src/vnext-config.ts
14786
14786
  var import__ = __toESM(require__(), 1);
14787
14787
  import { spawnSync as spawnSync2 } from "node:child_process";
14788
14788
  import { createHash as createHash2 } from "node:crypto";
14789
- import { existsSync as existsSync2, lstatSync, readFileSync, readdirSync, realpathSync } from "node:fs";
14790
- import { basename, dirname, extname, isAbsolute, join, relative, resolve, sep } from "node:path";
14791
- import { fileURLToPath } from "node:url";
14789
+ import { existsSync as existsSync3, lstatSync, readFileSync, readdirSync, realpathSync } from "node:fs";
14790
+ import { basename, dirname as dirname2, extname, isAbsolute, join as join2, relative, resolve, sep } from "node:path";
14792
14791
 
14793
14792
  // plugins/kxm/src/restricted-yaml.mjs
14794
14793
  var import_yaml = __toESM(require_dist(), 1);
@@ -15114,9 +15113,28 @@ function resolveVnextTemplateBaseline(value) {
15114
15113
  return void 0;
15115
15114
  }
15116
15115
 
15116
+ // plugins/kxm/src/repo-root.ts
15117
+ import { existsSync } from "node:fs";
15118
+ import { dirname, join } from "node:path";
15119
+ import { fileURLToPath } from "node:url";
15120
+ var ROOT_MARKERS = ["scripts/kxm-hub.mjs", "scripts/kxm.mjs"];
15121
+ var MAX_WALK_DEPTH = 10;
15122
+ function findKxmRepoRoot(fromUrl = import.meta.url) {
15123
+ let dir = dirname(fileURLToPath(fromUrl));
15124
+ for (let depth = 0; depth < MAX_WALK_DEPTH; depth += 1) {
15125
+ if (ROOT_MARKERS.some((marker) => existsSync(join(dir, marker)))) return dir;
15126
+ const parent = dirname(dir);
15127
+ if (parent === dir) break;
15128
+ dir = parent;
15129
+ }
15130
+ throw new Error(
15131
+ `kxm: cannot locate the KXM repo root from ${fileURLToPath(fromUrl)} (walked ${MAX_WALK_DEPTH} levels looking for ${ROOT_MARKERS[0]})`
15132
+ );
15133
+ }
15134
+
15117
15135
  // plugins/kxm/src/vnext-harness.ts
15118
15136
  import { spawnSync } from "node:child_process";
15119
- import { existsSync } from "node:fs";
15137
+ import { existsSync as existsSync2 } from "node:fs";
15120
15138
  import { win32 as win32Path } from "node:path";
15121
15139
 
15122
15140
  // plugins/kxm/src/vnext-oneshot-process.ts
@@ -15142,7 +15160,7 @@ function defaultSpawn(command, args, options) {
15142
15160
  if (options.signal?.aborted) {
15143
15161
  return Promise.resolve({ stdout: "", stderr: "", code: null, started: false, observedChildExit: false, error: new Error("process_aborted") });
15144
15162
  }
15145
- return new Promise((resolve9) => {
15163
+ return new Promise((resolve8) => {
15146
15164
  const stdout = [];
15147
15165
  const stderr = [];
15148
15166
  let outputBytes = 0;
@@ -15173,7 +15191,7 @@ function defaultSpawn(command, args, options) {
15173
15191
  const started = Boolean(child?.pid);
15174
15192
  if (started && !observedChildExit) error ??= new Error("process_exit_unobserved");
15175
15193
  const unverifiedDescendants = stopping || started && !observedChildExit;
15176
- resolve9({
15194
+ resolve8({
15177
15195
  stdout: Buffer.concat(stdout).toString("utf8"),
15178
15196
  stderr: Buffer.concat(stderr).toString("utf8"),
15179
15197
  code,
@@ -15665,7 +15683,7 @@ function findWinNpmInnerExe(cliId, options = {}) {
15665
15683
  if ((options.platform ?? process.platform) !== "win32") return void 0;
15666
15684
  const segments = WIN_NPM_INNER_EXE[cliId];
15667
15685
  if (!segments) return void 0;
15668
- const exists = options.existsSync ?? existsSync;
15686
+ const exists = options.existsSync ?? existsSync2;
15669
15687
  const pathEnv = options.pathEnv ?? process.env.PATH ?? "";
15670
15688
  for (const dir of pathEnv.split(";").filter(Boolean)) {
15671
15689
  if (!exists(win32Path.join(dir, `${cliId}.cmd`))) continue;
@@ -16348,8 +16366,10 @@ var VnextConfigError = class extends Error {
16348
16366
  this.issues = sorted;
16349
16367
  }
16350
16368
  };
16351
- var PACKAGE_ROOT = resolve(dirname(fileURLToPath(import.meta.url)), "../../..");
16352
- var DEFAULT_SCHEMA_DIR = join(PACKAGE_ROOT, "schemas", "vnext");
16369
+ function defaultVnextSchemaDir() {
16370
+ return join2(findKxmRepoRoot(import.meta.url), "schemas", "vnext");
16371
+ }
16372
+ var DEFAULT_SCHEMA_DIR = defaultVnextSchemaDir();
16353
16373
  var RESOURCE_SCHEMA = Object.freeze({
16354
16374
  project: { identity: "kxm.project.v1", file: "project.schema.json" },
16355
16375
  repository: { identity: "kxm.repository.v1", file: "repository.schema.json" },
@@ -16414,10 +16434,10 @@ var VnextSchemaRegistry = class {
16414
16434
  constructor(schemasDir = DEFAULT_SCHEMA_DIR) {
16415
16435
  this.schemasDir = resolve(schemasDir);
16416
16436
  this.ajv = new import__.Ajv2020({ allErrors: true, strict: true, strictRequired: false });
16417
- const common = readJsonObject(join(this.schemasDir, "common.schema.json"));
16437
+ const common = readJsonObject(join2(this.schemasDir, "common.schema.json"));
16418
16438
  this.ajv.addSchema(common);
16419
16439
  for (const definition of Object.values(RESOURCE_SCHEMA)) {
16420
- this.ajv.addSchema(readJsonObject(join(this.schemasDir, definition.file)));
16440
+ this.ajv.addSchema(readJsonObject(join2(this.schemasDir, definition.file)));
16421
16441
  }
16422
16442
  const localBindingsFile = "local-repository-bindings.schema.json";
16423
16443
  const templateProvenanceFile = "template-provenance.schema.json";
@@ -16427,14 +16447,14 @@ var VnextSchemaRegistry = class {
16427
16447
  const migrationReceiptFile = "migration-receipt.schema.json";
16428
16448
  const permissionDiffFile = "permission-diff.schema.json";
16429
16449
  const runEventFile = "run-event.schema.json";
16430
- this.ajv.addSchema(readJsonObject(join(this.schemasDir, localBindingsFile)));
16431
- this.ajv.addSchema(readJsonObject(join(this.schemasDir, templateProvenanceFile)));
16432
- this.ajv.addSchema(readJsonObject(join(this.schemasDir, initOperationFile)));
16433
- this.ajv.addSchema(readJsonObject(join(this.schemasDir, migrationPlanFile)));
16434
- this.ajv.addSchema(readJsonObject(join(this.schemasDir, migrationDecisionFile)));
16435
- this.ajv.addSchema(readJsonObject(join(this.schemasDir, migrationReceiptFile)));
16436
- this.ajv.addSchema(readJsonObject(join(this.schemasDir, permissionDiffFile)));
16437
- this.ajv.addSchema(readJsonObject(join(this.schemasDir, runEventFile)));
16450
+ this.ajv.addSchema(readJsonObject(join2(this.schemasDir, localBindingsFile)));
16451
+ this.ajv.addSchema(readJsonObject(join2(this.schemasDir, templateProvenanceFile)));
16452
+ this.ajv.addSchema(readJsonObject(join2(this.schemasDir, initOperationFile)));
16453
+ this.ajv.addSchema(readJsonObject(join2(this.schemasDir, migrationPlanFile)));
16454
+ this.ajv.addSchema(readJsonObject(join2(this.schemasDir, migrationDecisionFile)));
16455
+ this.ajv.addSchema(readJsonObject(join2(this.schemasDir, migrationReceiptFile)));
16456
+ this.ajv.addSchema(readJsonObject(join2(this.schemasDir, permissionDiffFile)));
16457
+ this.ajv.addSchema(readJsonObject(join2(this.schemasDir, runEventFile)));
16438
16458
  for (const [kind, definition] of Object.entries(RESOURCE_SCHEMA)) {
16439
16459
  const validator = this.ajv.getSchema(`https://schemas.kxm.dev/vnext/${definition.file}`);
16440
16460
  if (!validator) throw new Error(`schema did not compile: ${definition.file}`);
@@ -16541,15 +16561,15 @@ function containedHostPath(root, candidate) {
16541
16561
  function portableBindingIssue(root, pathHint, repositoryId) {
16542
16562
  let current = root;
16543
16563
  for (const segment of pathHint === "." ? [] : pathHint.split("/")) {
16544
- current = join(current, segment);
16545
- if (!existsSync2(current)) break;
16564
+ current = join2(current, segment);
16565
+ if (!existsSync3(current)) break;
16546
16566
  const stat = lstatSync(current);
16547
16567
  if (stat.isSymbolicLink()) {
16548
16568
  return issue2("path", "repository_binding_path_link", ".kxm/project.yaml", `portable pathHint for ${repositoryId} traverses a symbolic link or junction`);
16549
16569
  }
16550
16570
  }
16551
16571
  const binding = resolve(root, ...pathHint.split("/"));
16552
- if (existsSync2(binding)) {
16572
+ if (existsSync3(binding)) {
16553
16573
  const realRoot = canonicalHostPath(root);
16554
16574
  const realBinding = canonicalHostPath(binding);
16555
16575
  if (!containedHostPath(realRoot, realBinding)) {
@@ -16587,9 +16607,9 @@ function readResource(registry, root, file, logicalPath, kind, id, containmentRo
16587
16607
  }
16588
16608
  if (stat.isSymbolicLink()) fail2("path", "resource_symlink", label, "configuration resources must not be symbolic links");
16589
16609
  const boundary = resolve(containmentRoot);
16590
- let parent = dirname(file);
16610
+ let parent = dirname2(file);
16591
16611
  while (parent !== boundary) {
16592
- if (parent === dirname(parent)) fail2("path", "resource_outside_project", label, "resource escapes the project root");
16612
+ if (parent === dirname2(parent)) fail2("path", "resource_outside_project", label, "resource escapes the project root");
16593
16613
  let parentStat;
16594
16614
  try {
16595
16615
  parentStat = lstatSync(parent);
@@ -16597,7 +16617,7 @@ function readResource(registry, root, file, logicalPath, kind, id, containmentRo
16597
16617
  fail2("discovery", "resource_parent_missing", label, "resource parent does not exist");
16598
16618
  }
16599
16619
  if (parentStat.isSymbolicLink()) fail2("path", "resource_parent_symlink", label, "configuration resource parents must not be symbolic links");
16600
- parent = dirname(parent);
16620
+ parent = dirname2(parent);
16601
16621
  }
16602
16622
  if (!stat.isFile()) fail2("path", "resource_not_file", label, "configuration resource must be a regular file");
16603
16623
  const value = parseRestrictedYaml2(readFileSync(file), label);
@@ -16606,22 +16626,22 @@ function readResource(registry, root, file, logicalPath, kind, id, containmentRo
16606
16626
  return { kind, ...id === void 0 ? {} : { id }, file, logicalPath, value };
16607
16627
  }
16608
16628
  function readTemplateProvenance(registry, root) {
16609
- const file = join(root, ".kxm", "template-provenance.yaml");
16610
- if (!existsSync2(file)) return void 0;
16629
+ const file = join2(root, ".kxm", "template-provenance.yaml");
16630
+ if (!existsSync3(file)) return void 0;
16611
16631
  const label = ".kxm/template-provenance.yaml";
16612
16632
  const stat = lstatSync(file);
16613
16633
  if (stat.isSymbolicLink() || !stat.isFile()) {
16614
16634
  fail2("path", "resource_not_file", label, "template provenance must be a regular file, not a link or directory");
16615
16635
  }
16616
- const configRoot = join(root, ".kxm");
16617
- let parent = dirname(file);
16636
+ const configRoot = join2(root, ".kxm");
16637
+ let parent = dirname2(file);
16618
16638
  while (parent !== root) {
16619
16639
  const parentStat = lstatSync(parent);
16620
16640
  if (parentStat.isSymbolicLink() || !parentStat.isDirectory()) {
16621
16641
  fail2("path", "resource_parent_symlink", label, "template provenance parents must be regular directories");
16622
16642
  }
16623
16643
  if (parent === configRoot) break;
16624
- parent = dirname(parent);
16644
+ parent = dirname2(parent);
16625
16645
  }
16626
16646
  const value = parseRestrictedYaml2(readFileSync(file), label);
16627
16647
  const issues = registry.validateTemplateProvenance(value, label);
@@ -16654,7 +16674,7 @@ function readTemplateProvenance(registry, root) {
16654
16674
  }
16655
16675
  function listNamedResources(registry, root, directory, logicalDirectory, kind) {
16656
16676
  const resources = /* @__PURE__ */ new Map();
16657
- if (!existsSync2(directory)) return resources;
16677
+ if (!existsSync3(directory)) return resources;
16658
16678
  const stat = lstatSync(directory);
16659
16679
  if (stat.isSymbolicLink() || !stat.isDirectory()) {
16660
16680
  fail2("path", "resource_directory_invalid", displayPath(root, directory), "resource directory must be a regular directory");
@@ -16663,27 +16683,27 @@ function listNamedResources(registry, root, directory, logicalDirectory, kind) {
16663
16683
  const entries = readdirSync(directory, { withFileTypes: true }).sort((left, right) => compareCodeUnits3(left.name, right.name));
16664
16684
  for (const entry of entries) {
16665
16685
  if (entry.isDirectory()) {
16666
- issues.push(issue2("path", "nested_resource_directory", displayPath(root, join(directory, entry.name)), "nested resource directories are not allowed"));
16686
+ issues.push(issue2("path", "nested_resource_directory", displayPath(root, join2(directory, entry.name)), "nested resource directories are not allowed"));
16667
16687
  continue;
16668
16688
  }
16669
16689
  if (!entry.name.toLowerCase().endsWith(".yaml") && !entry.name.toLowerCase().endsWith(".yml")) continue;
16670
16690
  if (!entry.isFile() || extname(entry.name) !== ".yaml") {
16671
- issues.push(issue2("path", "resource_filename_invalid", displayPath(root, join(directory, entry.name)), "resource must be a regular file with the exact .yaml extension"));
16691
+ issues.push(issue2("path", "resource_filename_invalid", displayPath(root, join2(directory, entry.name)), "resource must be a regular file with the exact .yaml extension"));
16672
16692
  continue;
16673
16693
  }
16674
16694
  const id = basename(entry.name, ".yaml");
16675
16695
  if (kind === "model" && id === "inventory") continue;
16676
16696
  if (!resourceIdentifier(id)) {
16677
- issues.push(issue2("path", "resource_id_invalid", displayPath(root, join(directory, entry.name)), `filename-derived identity ${id} is invalid or platform-reserved`));
16697
+ issues.push(issue2("path", "resource_id_invalid", displayPath(root, join2(directory, entry.name)), `filename-derived identity ${id} is invalid or platform-reserved`));
16678
16698
  continue;
16679
16699
  }
16680
16700
  const collision = [...resources.keys()].find((candidate) => candidate.toLocaleLowerCase("en-US") === id.toLocaleLowerCase("en-US"));
16681
16701
  if (collision) {
16682
- issues.push(issue2("path", "resource_id_collision", displayPath(root, join(directory, entry.name)), `${id} case-folds to existing ${collision}`));
16702
+ issues.push(issue2("path", "resource_id_collision", displayPath(root, join2(directory, entry.name)), `${id} case-folds to existing ${collision}`));
16683
16703
  continue;
16684
16704
  }
16685
16705
  try {
16686
- const resource = readResource(registry, root, join(directory, entry.name), `${logicalDirectory}/${id}.yaml`, kind, id);
16706
+ const resource = readResource(registry, root, join2(directory, entry.name), `${logicalDirectory}/${id}.yaml`, kind, id);
16687
16707
  resources.set(id, resource);
16688
16708
  } catch (error) {
16689
16709
  if (error instanceof VnextConfigError) issues.push(...error.issues);
@@ -16975,8 +16995,8 @@ function validateWorkflow(workflow, agents, models, repositories, gates, issues)
16975
16995
  const writable = Object.values(objectValue(step.repositories) ?? {}).filter((access) => access === "write").length;
16976
16996
  if (maxWriteRepositories > writable) issues.push(issue2("semantic", "write_repository_bound_invalid", file, `${stepId} maxWriteRepositories exceeds writable repository scope`));
16977
16997
  }
16978
- const join17 = objectValue(step.join);
16979
- const minimumPassed = join17 && typeof join17.minimumPassed === "number" ? join17.minimumPassed : void 0;
16998
+ const join18 = objectValue(step.join);
16999
+ const minimumPassed = join18 && typeof join18.minimumPassed === "number" ? join18.minimumPassed : void 0;
16980
17000
  if (minimumPassed !== void 0 && minimumPassed > maximum) issues.push(issue2("semantic", "join_impossible", file, `${stepId} minimumPassed exceeds assignment maximum`));
16981
17001
  const distinctBy = names(assignment?.distinctBy);
16982
17002
  if (distinctBy.length > 0) {
@@ -17190,9 +17210,9 @@ function validateBundle(project, repositories, agents, models, workflows, enviro
17190
17210
  if (!workflows.has(defaultWorkflow)) issues.push(issue2("reference", "default_workflow_unknown", project.logicalPath, `default workflow ${defaultWorkflow} does not exist`));
17191
17211
  for (const workflow of workflows.values()) validateWorkflow(workflow, agents, models, repositoryIds, gates, issues);
17192
17212
  if (projectRoot) {
17193
- const writerRolePath = join(projectRoot, ".kxm", "roles", "writer.yaml");
17213
+ const writerRolePath = join2(projectRoot, ".kxm", "roles", "writer.yaml");
17194
17214
  const implementerAgent = agents.get("implementer") ?? agents.get("writer");
17195
- if (existsSync2(writerRolePath) && implementerAgent) {
17215
+ if (existsSync3(writerRolePath) && implementerAgent) {
17196
17216
  try {
17197
17217
  const rawRole = parseRestrictedYaml2(readFileSync(writerRolePath, "utf8"));
17198
17218
  const roleObj = objectValue(rawRole);
@@ -17241,7 +17261,7 @@ function gitEnvironment() {
17241
17261
  }
17242
17262
  function discoverGitRoot(start = process.cwd()) {
17243
17263
  let current = resolve(start);
17244
- if (existsSync2(current) && !lstatSync(current).isDirectory()) current = dirname(current);
17264
+ if (existsSync3(current) && !lstatSync(current).isDirectory()) current = dirname2(current);
17245
17265
  const result = spawnSync2("git", ["-C", current, "rev-parse", "--show-toplevel"], {
17246
17266
  encoding: "utf8",
17247
17267
  env: gitEnvironment(),
@@ -17250,7 +17270,7 @@ function discoverGitRoot(start = process.cwd()) {
17250
17270
  });
17251
17271
  if (result.status !== 0 || result.error || !result.stdout.trim()) return void 0;
17252
17272
  const root = resolve(result.stdout.trim());
17253
- return existsSync2(root) && lstatSync(root).isDirectory() ? root : void 0;
17273
+ return existsSync3(root) && lstatSync(root).isDirectory() ? root : void 0;
17254
17274
  }
17255
17275
  function assertNoRegisteredGates(options) {
17256
17276
  if ("registeredGates" in options) {
@@ -17267,7 +17287,7 @@ function loadVnextProject(projectRoot, options = {}) {
17267
17287
  migrationReceipt = receiptCheck.receipt;
17268
17288
  }
17269
17289
  const registry = new VnextSchemaRegistry(options.schemasDir);
17270
- const project = readResource(registry, root, join(root, ".kxm", "project.yaml"), ".kxm/project.yaml", "project");
17290
+ const project = readResource(registry, root, join2(root, ".kxm", "project.yaml"), ".kxm/project.yaml", "project");
17271
17291
  const earlyIssues = [];
17272
17292
  validatePortablePaths(project, earlyIssues);
17273
17293
  const templateProvenance = readTemplateProvenance(registry, root);
@@ -17289,16 +17309,16 @@ function loadVnextProject(projectRoot, options = {}) {
17289
17309
  }
17290
17310
  }
17291
17311
  if (earlyIssues.length > 0) throw new VnextConfigError(earlyIssues);
17292
- const agents = listNamedResources(registry, root, join(root, ".kxm", "agents"), ".kxm/agents", "agent");
17293
- const models = listNamedResources(registry, root, join(root, ".kxm", "models"), ".kxm/models", "model");
17294
- const workflows = listNamedResources(registry, root, join(root, ".kxm", "workflows"), ".kxm/workflows", "workflow");
17295
- const gatePath = join(root, ".kxm", "gates.yaml");
17296
- const gateRegistry = existsSync2(gatePath) ? readResource(registry, root, gatePath, ".kxm/gates.yaml", "gate-registry") : void 0;
17312
+ const agents = listNamedResources(registry, root, join2(root, ".kxm", "agents"), ".kxm/agents", "agent");
17313
+ const models = listNamedResources(registry, root, join2(root, ".kxm", "models"), ".kxm/models", "model");
17314
+ const workflows = listNamedResources(registry, root, join2(root, ".kxm", "workflows"), ".kxm/workflows", "workflow");
17315
+ const gatePath = join2(root, ".kxm", "gates.yaml");
17316
+ const gateRegistry = existsSync3(gatePath) ? readResource(registry, root, gatePath, ".kxm/gates.yaml", "gate-registry") : void 0;
17297
17317
  const environments = [];
17298
17318
  const repositories = /* @__PURE__ */ new Map();
17299
17319
  const loadIssues = [];
17300
- const projectEnvironment = join(root, ".kxm", "project", "env.yaml");
17301
- if (existsSync2(projectEnvironment)) {
17320
+ const projectEnvironment = join2(root, ".kxm", "project", "env.yaml");
17321
+ if (existsSync3(projectEnvironment)) {
17302
17322
  try {
17303
17323
  environments.push(readResource(registry, root, projectEnvironment, ".kxm/project/env.yaml", "environment"));
17304
17324
  } catch (error) {
@@ -17340,7 +17360,7 @@ function loadVnextProject(projectRoot, options = {}) {
17340
17360
  if (required) loadIssues.push(issue2("discovery", "repository_binding_missing", ".kxm/project.yaml", `required repository ${repositoryId} has no portable pathHint or host-local binding`));
17341
17361
  continue;
17342
17362
  }
17343
- if (!existsSync2(binding)) {
17363
+ if (!existsSync3(binding)) {
17344
17364
  if (required || hasLocalBinding) loadIssues.push(issue2("discovery", "repository_binding_unavailable", ".kxm/project.yaml", `${hasLocalBinding ? "explicit" : "required"} repository binding ${repositoryId} is unavailable`));
17345
17365
  continue;
17346
17366
  }
@@ -17363,9 +17383,9 @@ function loadVnextProject(projectRoot, options = {}) {
17363
17383
  continue;
17364
17384
  }
17365
17385
  seenBindings.set(foldedBinding, repositoryId);
17366
- const repositoryFile = join(binding, ".kxm", "repo", "repo.yaml");
17386
+ const repositoryFile = join2(binding, ".kxm", "repo", "repo.yaml");
17367
17387
  let definitionValidated = false;
17368
- if (existsSync2(repositoryFile)) {
17388
+ if (existsSync3(repositoryFile)) {
17369
17389
  try {
17370
17390
  const resource = readResource(registry, root, repositoryFile, `.kxm/repositories/${repositoryId}/repo.yaml`, "repository", repositoryId, binding);
17371
17391
  if (resource.value.repositoryId !== repositoryId) {
@@ -17381,8 +17401,8 @@ function loadVnextProject(projectRoot, options = {}) {
17381
17401
  } else if (required || hasLocalBinding) {
17382
17402
  loadIssues.push(issue2("discovery", "repository_definition_missing", `.kxm/repositories/${repositoryId}/repo.yaml`, `${hasLocalBinding ? "explicit" : "required"} repository ${repositoryId} has no repo.yaml`));
17383
17403
  }
17384
- const environmentFile = join(binding, ".kxm", "repo", "env.yaml");
17385
- if (existsSync2(environmentFile)) {
17404
+ const environmentFile = join2(binding, ".kxm", "repo", "env.yaml");
17405
+ if (existsSync3(environmentFile)) {
17386
17406
  if (!definitionValidated) {
17387
17407
  loadIssues.push(issue2("reference", "repository_environment_without_definition", `.kxm/repositories/${repositoryId}/env.yaml`, `repository ${repositoryId} environment requires a validated matching repo.yaml`));
17388
17408
  } else {
@@ -17419,14 +17439,14 @@ var LEGACY_CONFIG_FILES = [".kxm/config/agents.json", ".kxm/config/gates.json"];
17419
17439
  function legacyConfigFilesAt(root) {
17420
17440
  const files = [];
17421
17441
  for (const component of [".kxm", ".kxm/config"]) {
17422
- const absolute = join(root, ...component.split("/"));
17423
- if (existsSync2(absolute) && lstatSync(absolute).isSymbolicLink()) return [component];
17442
+ const absolute = join2(root, ...component.split("/"));
17443
+ if (existsSync3(absolute) && lstatSync(absolute).isSymbolicLink()) return [component];
17424
17444
  }
17425
17445
  for (const candidate of LEGACY_CONFIG_FILES) {
17426
- if (existsSync2(join(root, ...candidate.split("/")))) files.push(candidate);
17446
+ if (existsSync3(join2(root, ...candidate.split("/")))) files.push(candidate);
17427
17447
  }
17428
- const workflowsDir = join(root, ".kxm", "config", "workflows");
17429
- if (existsSync2(workflowsDir)) {
17448
+ const workflowsDir = join2(root, ".kxm", "config", "workflows");
17449
+ if (existsSync3(workflowsDir)) {
17430
17450
  const stat = lstatSync(workflowsDir);
17431
17451
  if (stat.isSymbolicLink()) {
17432
17452
  files.push(".kxm/config/workflows");
@@ -17441,8 +17461,8 @@ function legacyConfigFilesAt(root) {
17441
17461
  return files;
17442
17462
  }
17443
17463
  function hashFileRecord(root, relativePath) {
17444
- const absolute = join(root, ...relativePath.split("/"));
17445
- if (!existsSync2(absolute)) return void 0;
17464
+ const absolute = join2(root, ...relativePath.split("/"));
17465
+ if (!existsSync3(absolute)) return void 0;
17446
17466
  const bytes = readFileSync(absolute);
17447
17467
  return {
17448
17468
  path: relativePath,
@@ -17455,9 +17475,9 @@ function migrationReceiptSelfHash(receipt) {
17455
17475
  return `sha256:${createHash2("sha256").update(vnextCanonicalJson(unsigned), "utf8").digest("hex")}`;
17456
17476
  }
17457
17477
  function readVnextMigrationReceipt(root, options = {}) {
17458
- const receiptPath = join(root, ...VNEXT_MIGRATION_RECEIPT_PATH.split("/"));
17478
+ const receiptPath = join2(root, ...VNEXT_MIGRATION_RECEIPT_PATH.split("/"));
17459
17479
  const legacyFiles = legacyConfigFilesAt(root);
17460
- if (!existsSync2(receiptPath)) {
17480
+ if (!existsSync3(receiptPath)) {
17461
17481
  return {
17462
17482
  issues: legacyFiles.map((file) => issue2("semantic", "legacy_vnext_conflict", file, "legacy and vNext configuration cannot coexist before an accepted migration receipt"))
17463
17483
  };
@@ -17503,8 +17523,8 @@ function readVnextMigrationReceipt(root, options = {}) {
17503
17523
 
17504
17524
  // plugins/kxm/src/vnext-runtime-store.ts
17505
17525
  import { createHash as createHash4, randomUUID } from "node:crypto";
17506
- import { existsSync as existsSync4, lstatSync as lstatSync3, mkdirSync as mkdirSync2, readFileSync as readFileSync3, realpathSync as realpathSync2, writeFileSync as writeFileSync2 } from "node:fs";
17507
- import { dirname as dirname4, join as join4, resolve as resolve4 } from "node:path";
17526
+ import { existsSync as existsSync5, lstatSync as lstatSync3, mkdirSync as mkdirSync2, readFileSync as readFileSync3, realpathSync as realpathSync2, writeFileSync as writeFileSync2 } from "node:fs";
17527
+ import { dirname as dirname5, join as join5, resolve as resolve4 } from "node:path";
17508
17528
 
17509
17529
  // plugins/kxm/src/vnext-bindings.ts
17510
17530
  import { homedir } from "node:os";
@@ -17549,7 +17569,7 @@ var DatabaseSync = class {
17549
17569
  };
17550
17570
 
17551
17571
  // plugins/kxm/src/vnext-bindings.ts
17552
- import { dirname as dirname2, isAbsolute as isAbsolute2, join as join2, parse, relative as relative2, resolve as resolve2, sep as sep2 } from "node:path";
17572
+ import { dirname as dirname3, isAbsolute as isAbsolute2, join as join3, parse, relative as relative2, resolve as resolve2, sep as sep2 } from "node:path";
17553
17573
  var MAX_BINDING_RECORD_BYTES = 256 * 1024;
17554
17574
  var BINDING_LABEL = "Runtime-local repository bindings";
17555
17575
  function bindingIssue(phase, code, message) {
@@ -17569,12 +17589,12 @@ function vnextUserStateRoot(options = {}) {
17569
17589
  }
17570
17590
  if (platform === "win32") {
17571
17591
  const localAppData = env.LOCALAPPDATA?.trim();
17572
- const base2 = localAppData && isAbsolute2(localAppData) ? localAppData : join2(home, "AppData", "Local");
17592
+ const base2 = localAppData && isAbsolute2(localAppData) ? localAppData : join3(home, "AppData", "Local");
17573
17593
  return resolve2(base2, "KXM");
17574
17594
  }
17575
17595
  if (platform === "darwin") return resolve2(home, "Library", "Application Support", "KXM");
17576
17596
  const xdgState = env.XDG_STATE_HOME?.trim();
17577
- const base = xdgState && isAbsolute2(xdgState) ? xdgState : join2(home, ".local", "state");
17597
+ const base = xdgState && isAbsolute2(xdgState) ? xdgState : join3(home, ".local", "state");
17578
17598
  return resolve2(base, "kxm");
17579
17599
  }
17580
17600
 
@@ -17583,7 +17603,7 @@ import { createHash as createHash3, randomBytes } from "node:crypto";
17583
17603
  import {
17584
17604
  chmodSync,
17585
17605
  copyFileSync,
17586
- existsSync as existsSync3,
17606
+ existsSync as existsSync4,
17587
17607
  lstatSync as lstatSync2,
17588
17608
  mkdirSync,
17589
17609
  readdirSync as readdirSync2,
@@ -17591,14 +17611,14 @@ import {
17591
17611
  unlinkSync,
17592
17612
  writeFileSync
17593
17613
  } from "node:fs";
17594
- import { basename as basename2, dirname as dirname3, join as join3, resolve as resolve3 } from "node:path";
17614
+ import { basename as basename2, dirname as dirname4, join as join4, resolve as resolve3 } from "node:path";
17595
17615
  function databaseError(code, file, message) {
17596
17616
  const issue3 = { phase: "semantic", code, file, message };
17597
17617
  return new VnextConfigError([issue3]);
17598
17618
  }
17599
17619
  function checkedParent(path, description) {
17600
- const parent = dirname3(path);
17601
- if (!existsSync3(parent)) mkdirSync(parent, { recursive: true, mode: 448 });
17620
+ const parent = dirname4(path);
17621
+ if (!existsSync4(parent)) mkdirSync(parent, { recursive: true, mode: 448 });
17602
17622
  const stat = lstatSync2(parent, { throwIfNoEntry: false });
17603
17623
  if (!stat || stat.isSymbolicLink() || !stat.isDirectory()) {
17604
17624
  throw databaseError("runtime_path_invalid", description, `${description} parent must be a regular directory, not a link`);
@@ -17772,7 +17792,7 @@ function backupDatabaseFile(sourcePath, targetPath, storeId) {
17772
17792
  throw databaseError("runtime_path_invalid", resolvedSource, `source database ${resolvedSource} must be a regular file, not a link or directory`);
17773
17793
  }
17774
17794
  checkedParent(resolvedTarget, "backup target");
17775
- if (existsSync3(resolvedTarget)) {
17795
+ if (existsSync4(resolvedTarget)) {
17776
17796
  unlinkSync(resolvedTarget);
17777
17797
  }
17778
17798
  const sourceDb = new DatabaseSync(resolvedSource);
@@ -17850,7 +17870,7 @@ function restoreDatabaseFile(backupPath, targetPath, storeId, expectedSchemaVers
17850
17870
  }
17851
17871
  checkedParent(resolvedTarget, "restore target");
17852
17872
  for (const file of [resolvedTarget, `${resolvedTarget}-wal`, `${resolvedTarget}-shm`]) {
17853
- if (existsSync3(file)) {
17873
+ if (existsSync4(file)) {
17854
17874
  try {
17855
17875
  unlinkSync(file);
17856
17876
  } catch {
@@ -17882,27 +17902,27 @@ function restoreDatabaseFile(backupPath, targetPath, storeId, expectedSchemaVers
17882
17902
  function discoverProjectStores(projectRoot, options = {}) {
17883
17903
  const root = resolve3(projectRoot);
17884
17904
  const stores = [];
17885
- const hubPath = options.hubDataPath ? resolve3(options.hubDataPath) : join3(root, ".kxm", "state", "kxm.db");
17886
- if (existsSync3(hubPath)) {
17905
+ const hubPath = options.hubDataPath ? resolve3(options.hubDataPath) : join4(root, ".kxm", "state", "kxm.db");
17906
+ if (existsSync4(hubPath)) {
17887
17907
  stores.push({ storeId: "hub-store", sourcePath: hubPath, maxSupportedVersion: 3 });
17888
17908
  }
17889
- const registryPath = join3(root, ".kxm", "runtime", "registry.db");
17890
- if (existsSync3(registryPath)) {
17909
+ const registryPath = join4(root, ".kxm", "runtime", "registry.db");
17910
+ if (existsSync4(registryPath)) {
17891
17911
  stores.push({ storeId: "registry", sourcePath: registryPath, maxSupportedVersion: 1 });
17892
17912
  }
17893
- const bindingsPath = join3(root, ".kxm", "runtime", "bindings.db");
17894
- if (existsSync3(bindingsPath)) {
17913
+ const bindingsPath = join4(root, ".kxm", "runtime", "bindings.db");
17914
+ if (existsSync4(bindingsPath)) {
17895
17915
  stores.push({ storeId: "binding-store", sourcePath: bindingsPath, maxSupportedVersion: 1 });
17896
17916
  }
17897
- const eventsDir = join3(root, ".kxm", "runtime", "events");
17898
- if (existsSync3(eventsDir)) {
17917
+ const eventsDir = join4(root, ".kxm", "runtime", "events");
17918
+ if (existsSync4(eventsDir)) {
17899
17919
  const entries = readdirSync2(eventsDir, { withFileTypes: true });
17900
17920
  for (const entry of entries) {
17901
17921
  if (entry.isFile() && entry.name.endsWith(".db")) {
17902
17922
  const key = entry.name.replace(/\.db$/, "");
17903
17923
  stores.push({
17904
17924
  storeId: `events:${key}`,
17905
- sourcePath: join3(eventsDir, entry.name),
17925
+ sourcePath: join4(eventsDir, entry.name),
17906
17926
  maxSupportedVersion: 3
17907
17927
  });
17908
17928
  }
@@ -17921,8 +17941,8 @@ function createBackup(options = {}) {
17921
17941
  const now = /* @__PURE__ */ new Date();
17922
17942
  const timestamp = now.toISOString().replace(/[:.]/g, "-");
17923
17943
  const backupId = `bk_${randomBytes(8).toString("hex")}`;
17924
- const outDir = options.outDir ? resolve3(options.outDir) : join3(projectRoot, ".kxm", "backups", `backup-${timestamp}`);
17925
- if (!existsSync3(outDir)) {
17944
+ const outDir = options.outDir ? resolve3(options.outDir) : join4(projectRoot, ".kxm", "backups", `backup-${timestamp}`);
17945
+ if (!existsSync4(outDir)) {
17926
17946
  mkdirSync(outDir, { recursive: true, mode: 448 });
17927
17947
  }
17928
17948
  const backedUpStores = [];
@@ -17934,7 +17954,7 @@ function createBackup(options = {}) {
17934
17954
  filename = `${sanitizedId}-${filename}`;
17935
17955
  }
17936
17956
  usedFilenames.add(filename);
17937
- const targetFile = join3(outDir, filename);
17957
+ const targetFile = join4(outDir, filename);
17938
17958
  const record2 = backupDatabaseFile(store.sourcePath, targetFile, store.storeId);
17939
17959
  backedUpStores.push(record2);
17940
17960
  }
@@ -17949,7 +17969,7 @@ function createBackup(options = {}) {
17949
17969
  const manifestSha256 = `sha256:${createHash3("sha256").update(manifestJson, "utf8").digest("hex")}`;
17950
17970
  manifest.manifestSha256 = manifestSha256;
17951
17971
  const finalJson = JSON.stringify(manifest, null, 2) + "\n";
17952
- const manifestPath = join3(outDir, "manifest.json");
17972
+ const manifestPath = join4(outDir, "manifest.json");
17953
17973
  writeFileSync(manifestPath, finalJson, "utf8");
17954
17974
  return { manifest, outDir };
17955
17975
  }
@@ -17960,12 +17980,12 @@ function restoreBackup(manifestPathOrDir, options = {}) {
17960
17980
  throw databaseError("runtime_path_invalid", manifestPath, `manifest path ${manifestPath} does not exist`);
17961
17981
  }
17962
17982
  if (stat.isDirectory()) {
17963
- manifestPath = join3(manifestPath, "manifest.json");
17983
+ manifestPath = join4(manifestPath, "manifest.json");
17964
17984
  }
17965
- if (!existsSync3(manifestPath)) {
17985
+ if (!existsSync4(manifestPath)) {
17966
17986
  throw databaseError("runtime_path_invalid", manifestPath, `backup manifest ${manifestPath} not found`);
17967
17987
  }
17968
- const manifestDir = dirname3(manifestPath);
17988
+ const manifestDir = dirname4(manifestPath);
17969
17989
  const rawText = readFileSync2(manifestPath, "utf8");
17970
17990
  let manifest;
17971
17991
  try {
@@ -17978,8 +17998,8 @@ function restoreBackup(manifestPathOrDir, options = {}) {
17978
17998
  }
17979
17999
  const restoredStores = [];
17980
18000
  for (const store of manifest.stores) {
17981
- const backupFilePath = join3(manifestDir, store.backupFile);
17982
- if (!existsSync3(backupFilePath)) {
18001
+ const backupFilePath = join4(manifestDir, store.backupFile);
18002
+ if (!existsSync4(backupFilePath)) {
17983
18003
  throw databaseError("restore_file_missing", backupFilePath, `backup file ${store.backupFile} missing from ${manifestDir}`);
17984
18004
  }
17985
18005
  const actualSha256 = fileSha256(backupFilePath);
@@ -17997,7 +18017,7 @@ function restoreBackup(manifestPathOrDir, options = {}) {
17997
18017
  let targetPath = store.sourcePath;
17998
18018
  if (options.projectRoot && manifest.projectRoot && targetPath.startsWith(manifest.projectRoot)) {
17999
18019
  const rel = targetPath.slice(manifest.projectRoot.length).replace(/^[\\/]+/, "");
18000
- targetPath = join3(resolve3(options.projectRoot), rel);
18020
+ targetPath = join4(resolve3(options.projectRoot), rel);
18001
18021
  }
18002
18022
  const result = restoreDatabaseFile(
18003
18023
  backupFilePath,
@@ -18018,12 +18038,12 @@ function restoreBackup(manifestPathOrDir, options = {}) {
18018
18038
  // plugins/kxm/src/vnext-runtime-store.ts
18019
18039
  function vnextRuntimePaths(options = {}) {
18020
18040
  const stateRoot = options.stateRoot ? resolve4(options.stateRoot) : vnextUserStateRoot({ ...options.env ? { env: options.env } : {}, ...options.homeDir ? { homeDir: options.homeDir } : {} });
18021
- const runtimeDir = join4(stateRoot, "runtime");
18041
+ const runtimeDir = join5(stateRoot, "runtime");
18022
18042
  return {
18023
18043
  stateRoot,
18024
18044
  runtimeDir,
18025
- registryDb: join4(runtimeDir, "registry.db"),
18026
- projectsDir: join4(runtimeDir, "projects")
18045
+ registryDb: join5(runtimeDir, "registry.db"),
18046
+ projectsDir: join5(runtimeDir, "projects")
18027
18047
  };
18028
18048
  }
18029
18049
  function runtimeIssue(phase, code, file, message) {
@@ -18486,7 +18506,7 @@ var VnextRunEventStore = class {
18486
18506
  }
18487
18507
  readRunPrompts() {
18488
18508
  const sidecar = this.runPromptSidecarPath();
18489
- if (!existsSync4(sidecar)) return {};
18509
+ if (!existsSync5(sidecar)) return {};
18490
18510
  try {
18491
18511
  const parsed = JSON.parse(readFileSync3(sidecar, "utf8"));
18492
18512
  if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) return {};
@@ -20504,7 +20524,7 @@ function compileStep(step, index, stepIndex, requirePlanHash, sink) {
20504
20524
  const maxAttempts = compileCountField(step.maxAttempts, 1, `${id}.maxAttempts`, id, sink);
20505
20525
  const timeoutMs = compileOptionalDuration(step.timeoutMs, `${id}.timeoutMs`, id, sink);
20506
20526
  const assignments = compileAssignments(step, id, agent, sink);
20507
- const join17 = compileJoin(step, id, sink);
20527
+ const join18 = compileJoin(step, id, sink);
20508
20528
  const requiredEvidence = compileEvidence(step, id, sink);
20509
20529
  const transitions = compileTransitions(step, id, index, stepIndex, sink);
20510
20530
  const outcomes = Object.keys(transitions).sort(compareCodeUnits4);
@@ -20532,7 +20552,7 @@ function compileStep(step, index, stepIndex, requirePlanHash, sink) {
20532
20552
  transitions: orderedTransitions,
20533
20553
  requiresPlanHash: requirePlanHash.includes(id),
20534
20554
  assignments,
20535
- join: join17
20555
+ join: join18
20536
20556
  };
20537
20557
  if (kind === "agent" || kind === "moa") {
20538
20558
  if (!agent) return void 0;
@@ -20582,15 +20602,15 @@ function compileAssignments(step, stepId, primaryAgentId, sink) {
20582
20602
  };
20583
20603
  }
20584
20604
  function compileJoin(step, stepId, sink) {
20585
- const join17 = objectValue2(step.join);
20586
- if (!join17) return { strategy: "all" };
20587
- const declared = stringValue2(join17.strategy);
20605
+ const join18 = objectValue2(step.join);
20606
+ if (!join18) return { strategy: "all" };
20607
+ const declared = stringValue2(join18.strategy);
20588
20608
  const strategy = declared && JOIN_STRATEGIES.has(declared) ? declared : "all";
20589
- const minimumPassed = compileOptionalCount(join17.minimumPassed, `${stepId}.join.minimumPassed`, stepId, sink);
20609
+ const minimumPassed = compileOptionalCount(join18.minimumPassed, `${stepId}.join.minimumPassed`, stepId, sink);
20590
20610
  const compiled = {
20591
20611
  strategy,
20592
20612
  ...minimumPassed !== void 0 ? { minimumPassed } : {},
20593
- ...typeof join17.cancelRemaining === "boolean" ? { cancelRemaining: join17.cancelRemaining } : {}
20613
+ ...typeof join18.cancelRemaining === "boolean" ? { cancelRemaining: join18.cancelRemaining } : {}
20594
20614
  };
20595
20615
  return compiled;
20596
20616
  }
@@ -21911,12 +21931,12 @@ function enqueueVnextScheduledRun(storePath, runId, configRevision, bound, start
21911
21931
  if (owner.admitted.has(runId) || owner.queue.some((item) => item.runId === runId)) {
21912
21932
  return Promise.reject(runtimeError("run_busy", runId, `run ${runId} is already admitted or queued`));
21913
21933
  }
21914
- return new Promise((resolve9, reject) => {
21934
+ return new Promise((resolve8, reject) => {
21915
21935
  owner.queue.push({
21916
21936
  runId,
21917
21937
  configRevision,
21918
21938
  bound,
21919
- start: (token) => start(token).then(resolve9, reject),
21939
+ start: (token) => start(token).then(resolve8, reject),
21920
21940
  fail: (error) => reject(error)
21921
21941
  });
21922
21942
  pump(storePath, owner);
@@ -21977,11 +21997,11 @@ function vnextToolPolicyRevision(bundle) {
21977
21997
  return sha256Of(vnextCanonicalJson({ policies, gateRegistry: bundle.gateRegistry?.value ?? null }));
21978
21998
  }
21979
21999
  function collectMemoryFiles(dir, baseDir, ignoreSubdirs = /* @__PURE__ */ new Set()) {
21980
- if (!existsSync5(dir)) return [];
22000
+ if (!existsSync6(dir)) return [];
21981
22001
  const entries = readdirSync3(dir, { withFileTypes: true });
21982
22002
  const results = [];
21983
22003
  for (const entry of entries) {
21984
- const fullPath = join5(dir, entry.name);
22004
+ const fullPath = join6(dir, entry.name);
21985
22005
  if (entry.isDirectory()) {
21986
22006
  if (ignoreSubdirs.has(entry.name)) continue;
21987
22007
  results.push(...collectMemoryFiles(fullPath, baseDir, ignoreSubdirs));
@@ -21994,15 +22014,15 @@ function collectMemoryFiles(dir, baseDir, ignoreSubdirs = /* @__PURE__ */ new Se
21994
22014
  }
21995
22015
  function computeVnextMemoryRevision(bundle, options = {}) {
21996
22016
  const hash = createHash6("sha256");
21997
- const memoryDir = options.memoryDir ?? join5(bundle.projectRoot, ".kxm", "memory");
22017
+ const memoryDir = options.memoryDir ?? join6(bundle.projectRoot, ".kxm", "memory");
21998
22018
  const memoryFiles = collectMemoryFiles(memoryDir, memoryDir, /* @__PURE__ */ new Set(["candidates"])).sort((left, right) => compareCodeUnits5(left.relPath, right.relPath));
21999
22019
  for (const file of memoryFiles) {
22000
22020
  hash.update(`memory:${file.relPath}\0`, "utf8");
22001
22021
  hash.update(readFileSync4(file.fullPath));
22002
22022
  hash.update("\0", "utf8");
22003
22023
  }
22004
- const skillsDir = options.skillsDir ?? join5(bundle.projectRoot, ".kxm", "skills");
22005
- const promotedSkillsDir = join5(skillsDir, "promoted");
22024
+ const skillsDir = options.skillsDir ?? join6(bundle.projectRoot, ".kxm", "skills");
22025
+ const promotedSkillsDir = join6(skillsDir, "promoted");
22006
22026
  const skillFiles = collectMemoryFiles(promotedSkillsDir, promotedSkillsDir).sort((left, right) => compareCodeUnits5(left.relPath, right.relPath));
22007
22027
  for (const file of skillFiles) {
22008
22028
  hash.update(`skill:${file.relPath}\0`, "utf8");
@@ -22086,7 +22106,7 @@ function openVnextRuntimeContext(projectRoot, options) {
22086
22106
  configRevision: bundle.configRevision,
22087
22107
  now: options.now ?? (/* @__PURE__ */ new Date()).toISOString()
22088
22108
  });
22089
- const eventStore = new VnextRunEventStore(join5(paths.projectsDir, registration.projectKey, "run-events.db"));
22109
+ const eventStore = new VnextRunEventStore(join6(paths.projectsDir, registration.projectKey, "run-events.db"));
22090
22110
  registerVnextRuntimeHandle(eventStore.path);
22091
22111
  return {
22092
22112
  registry,
@@ -22416,18 +22436,17 @@ function assertVnextConfigError(error) {
22416
22436
  // plugins/kxm/src/vnext-runtime-supervisor.ts
22417
22437
  import { spawn as spawn3 } from "node:child_process";
22418
22438
  import { createHash as createHash12, createHmac, randomBytes as randomBytes3, timingSafeEqual as timingSafeEqual2 } from "node:crypto";
22419
- import { chmodSync as chmodSync2, existsSync as existsSync9, lstatSync as lstatSync5, mkdirSync as mkdirSync4, readFileSync as readFileSync8, renameSync, rmSync, writeFileSync as writeFileSync4 } from "node:fs";
22439
+ import { chmodSync as chmodSync2, existsSync as existsSync10, lstatSync as lstatSync5, mkdirSync as mkdirSync4, readFileSync as readFileSync8, renameSync, rmSync, writeFileSync as writeFileSync4 } from "node:fs";
22420
22440
  import { createServer } from "node:http";
22421
- import { dirname as dirname5, isAbsolute as isAbsolute4, join as join12, resolve as resolve6 } from "node:path";
22422
- import { fileURLToPath as fileURLToPath2 } from "node:url";
22441
+ import { dirname as dirname6, isAbsolute as isAbsolute4, join as join13 } from "node:path";
22423
22442
 
22424
22443
  // plugins/kxm/src/vnext-oneshot-producer.ts
22425
- import { join as join11 } from "node:path";
22444
+ import { join as join12 } from "node:path";
22426
22445
 
22427
22446
  // plugins/kxm/src/vnext-oneshot-evidence.ts
22428
22447
  import { createHash as createHash7, randomUUID as randomUUID3 } from "node:crypto";
22429
22448
  import { lstat, mkdir, open, rename } from "node:fs/promises";
22430
- import { join as join6 } from "node:path";
22449
+ import { join as join7 } from "node:path";
22431
22450
  var ONESHOT_EVIDENCE_SCHEMA = "kxm.oneshot-evidence.v2";
22432
22451
  var RETIRED_ONESHOT_EVIDENCE_SCHEMAS = /* @__PURE__ */ new Set(["kxm.oneshot-evidence.v1"]);
22433
22452
  var TEXT_LIMIT = 4 * 1024 * 1024;
@@ -22457,7 +22476,7 @@ async function beginOneShotEvidence(root, intent, sensitive) {
22457
22476
  throw new Error("oneshot_evidence_root_not_private");
22458
22477
  }
22459
22478
  const id = `evd_${randomUUID3().replaceAll("-", "")}`;
22460
- const dir = join6(root, id);
22479
+ const dir = join7(root, id);
22461
22480
  await mkdir(dir, { mode: 448 });
22462
22481
  const secrets = [...new Set(sensitive.filter((value) => value.length >= 8))].sort((a, b) => b.length - a.length);
22463
22482
  const redact = (value) => {
@@ -22477,7 +22496,7 @@ async function beginOneShotEvidence(root, intent, sensitive) {
22477
22496
  const bytes = JSON.stringify(value);
22478
22497
  if (Buffer.byteLength(bytes) > RECORD_LIMIT) throw new Error("oneshot_evidence_record_limit");
22479
22498
  parseOneShotEvidenceRecord(bytes);
22480
- const target = join6(dir, name);
22499
+ const target = join7(dir, name);
22481
22500
  const partial = `${target}.partial`;
22482
22501
  const file = await open(partial, "wx", 384);
22483
22502
  try {
@@ -22544,8 +22563,8 @@ async function beginOneShotEvidence(root, intent, sensitive) {
22544
22563
  // plugins/kxm/src/prices.ts
22545
22564
  var import_yaml3 = __toESM(require_dist(), 1);
22546
22565
  import { createHash as createHash8 } from "node:crypto";
22547
- import { existsSync as existsSync6, readFileSync as readFileSync5, statSync } from "node:fs";
22548
- import { join as join7 } from "node:path";
22566
+ import { existsSync as existsSync7, readFileSync as readFileSync5, statSync } from "node:fs";
22567
+ import { join as join8 } from "node:path";
22549
22568
 
22550
22569
  // plugins/kxm/src/price-calc.ts
22551
22570
  var PRICES_SCHEMA = "kxm.prices.v1";
@@ -22697,8 +22716,8 @@ function parsePriceCatalog(text) {
22697
22716
  return catalog;
22698
22717
  }
22699
22718
  function loadPriceCatalog(rootOrPath) {
22700
- 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;
22701
- if (!candidatePath || !existsSync6(candidatePath)) {
22719
+ 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;
22720
+ if (!candidatePath || !existsSync7(candidatePath)) {
22702
22721
  return void 0;
22703
22722
  }
22704
22723
  const content = readFileSync5(candidatePath, "utf8");
@@ -22720,28 +22739,28 @@ function loadPriceCatalogForEstimate(options) {
22720
22739
  // plugins/kxm/src/vnext-engine.ts
22721
22740
  var import_yaml5 = __toESM(require_dist(), 1);
22722
22741
  import { createHash as createHash11, randomBytes as randomBytes2, timingSafeEqual } from "node:crypto";
22723
- import { existsSync as existsSync8, readFileSync as readFileSync7 } from "node:fs";
22724
- import { join as join10 } from "node:path";
22742
+ import { existsSync as existsSync9, readFileSync as readFileSync7 } from "node:fs";
22743
+ import { join as join11 } from "node:path";
22725
22744
 
22726
22745
  // plugins/kxm/src/producers.ts
22727
22746
  var import_yaml4 = __toESM(require_dist(), 1);
22728
- import { existsSync as existsSync7, readFileSync as readFileSync6, mkdirSync as mkdirSync3, writeFileSync as writeFileSync3, readdirSync as readdirSync4 } from "node:fs";
22729
- import { join as join8 } from "node:path";
22747
+ import { existsSync as existsSync8, readFileSync as readFileSync6, mkdirSync as mkdirSync3, writeFileSync as writeFileSync3, readdirSync as readdirSync4 } from "node:fs";
22748
+ import { join as join9 } from "node:path";
22730
22749
  var empty = () => ({ schema: "kxm.producers.v1", updatedAt: (/* @__PURE__ */ new Date()).toISOString(), promoted: [], demoted: [], enabled: [], disabled: [], roles: {} });
22731
22750
  function loadProducerPolicy(root) {
22732
- const path = join8(root, ".kxm", "producers.yaml");
22733
- if (!existsSync7(path)) return empty();
22751
+ const path = join9(root, ".kxm", "producers.yaml");
22752
+ if (!existsSync8(path)) return empty();
22734
22753
  const value = (0, import_yaml4.parse)(readFileSync6(path, "utf8"));
22735
22754
  if (value?.schema !== "kxm.producers.v1" || !Array.isArray(value.promoted) || !Array.isArray(value.demoted)) throw new Error("invalid .kxm/producers.yaml");
22736
22755
  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")])) : {} };
22737
22756
  }
22738
22757
  function listRoleBindings(root) {
22739
- const dir = join8(root, ".kxm", "roles");
22758
+ const dir = join9(root, ".kxm", "roles");
22740
22759
  const result = {};
22741
- if (!existsSync7(dir)) return result;
22760
+ if (!existsSync8(dir)) return result;
22742
22761
  for (const file of readdirSync4(dir).filter((name) => name.endsWith(".yaml"))) {
22743
22762
  const role = file.slice(0, -5);
22744
- const value = (0, import_yaml4.parse)(readFileSync6(join8(dir, file), "utf8"));
22763
+ const value = (0, import_yaml4.parse)(readFileSync6(join9(dir, file), "utf8"));
22745
22764
  result[role] = (value.roster ?? []).map((entry) => entry.model).filter((model) => typeof model === "string");
22746
22765
  }
22747
22766
  return result;
@@ -23012,7 +23031,7 @@ function pruneContextPacket(packet, tokenBudget) {
23012
23031
  }
23013
23032
 
23014
23033
  // plugins/kxm/src/vnext-engine-artifacts.ts
23015
- import { join as join9 } from "node:path";
23034
+ import { join as join10 } from "node:path";
23016
23035
 
23017
23036
  // plugins/kxm/src/artifacts-exist.ts
23018
23037
  import { lstatSync as lstatSync4, realpathSync as realpathSync3, statSync as statSync2 } from "node:fs";
@@ -23059,14 +23078,14 @@ function verifyArtifactExists(rootInput, pathInput) {
23059
23078
  // plugins/kxm/src/vnext-engine-artifacts.ts
23060
23079
  var vnextArtifactsGateSeams = {};
23061
23080
  function evaluateArtifactsGate(context, definition) {
23062
- const root = join9(context.projectRoot, ".kxm", "assets");
23081
+ const root = join10(context.projectRoot, ".kxm", "assets");
23063
23082
  const startedAt = (/* @__PURE__ */ new Date()).toISOString();
23064
23083
  const startTime = process.hrtime.bigint();
23065
23084
  let checkedCount = 0;
23066
23085
  let failedCount = 0;
23067
23086
  for (const [index, path] of definition.paths.entries()) {
23068
23087
  checkedCount += 1;
23069
- const result = verifyArtifactExists(root, join9(root, path));
23088
+ const result = verifyArtifactExists(root, join10(root, path));
23070
23089
  if (!result.ok) failedCount += 1;
23071
23090
  vnextArtifactsGateSeams.afterPathChecked?.({ path, index, checkedCount, failedCount });
23072
23091
  }
@@ -23222,8 +23241,8 @@ var CommandObserver = class {
23222
23241
  this.requestStop("error", "lost-close");
23223
23242
  }
23224
23243
  run() {
23225
- return new Promise((resolve9) => {
23226
- this.resolveOutcome = resolve9;
23244
+ return new Promise((resolve8) => {
23245
+ this.resolveOutcome = resolve8;
23227
23246
  try {
23228
23247
  this.start();
23229
23248
  } catch (error) {
@@ -24424,8 +24443,8 @@ var VnextRunScheduler = class _VnextRunScheduler {
24424
24443
  resolve: (_value) => void 0,
24425
24444
  reject: (_error) => void 0
24426
24445
  };
24427
- const settled = new Promise((resolve9, reject) => {
24428
- pending.resolve = resolve9;
24446
+ const settled = new Promise((resolve8, reject) => {
24447
+ pending.resolve = resolve8;
24429
24448
  pending.reject = reject;
24430
24449
  });
24431
24450
  void settled.then(void 0, () => void 0);
@@ -24760,8 +24779,8 @@ function unreconciledPanelAttemptId(state) {
24760
24779
  }
24761
24780
  function resolveProducerRoute(projectRoot, step, agentId) {
24762
24781
  let agentModel;
24763
- const agentFile = join10(projectRoot, ".kxm", "agents", `${agentId}.yaml`);
24764
- if (existsSync8(agentFile)) {
24782
+ const agentFile = join11(projectRoot, ".kxm", "agents", `${agentId}.yaml`);
24783
+ if (existsSync9(agentFile)) {
24765
24784
  try {
24766
24785
  const parsed = (0, import_yaml5.parse)(readFileSync7(agentFile, "utf8"));
24767
24786
  if (typeof parsed?.model === "string") {
@@ -26344,7 +26363,7 @@ Return a final JSON object with an "outcome" field chosen from ${JSON.stringify(
26344
26363
  }
26345
26364
  const spawnFn = options.spawnProcess ?? defaultSpawn;
26346
26365
  const cwd = options.projectRoot ?? process.cwd();
26347
- const evidence = await beginOneShotEvidence(options.evidenceRoot ?? join11(vnextUserStateRoot(), "runtime", "oneshot-evidence"), {
26366
+ const evidence = await beginOneShotEvidence(options.evidenceRoot ?? join12(vnextUserStateRoot(), "runtime", "oneshot-evidence"), {
26348
26367
  runId: request.runId,
26349
26368
  stepId: request.stepId,
26350
26369
  attemptId: request.attemptId,
@@ -26488,13 +26507,12 @@ Return a final JSON object with an "outcome" field chosen from ${JSON.stringify(
26488
26507
  }
26489
26508
 
26490
26509
  // plugins/kxm/src/vnext-runtime-supervisor.ts
26491
- var repoRoot = resolve6(fileURLToPath2(new URL("../../../", import.meta.url)));
26492
26510
  function vnextSupervisorTokenFile(paths) {
26493
- return join12(paths.runtimeDir, "supervisor.token");
26511
+ return join13(paths.runtimeDir, "supervisor.token");
26494
26512
  }
26495
26513
  function publishVnextSupervisorToken(paths, token) {
26496
26514
  const file = vnextSupervisorTokenFile(paths);
26497
- mkdirSync4(dirname5(file), { recursive: true, mode: 448 });
26515
+ mkdirSync4(dirname6(file), { recursive: true, mode: 448 });
26498
26516
  const temp = `${file}.${process.pid}.tmp`;
26499
26517
  writeFileSync4(temp, `${token}
26500
26518
  `, { encoding: "utf8", mode: 384 });
@@ -26532,11 +26550,11 @@ function processAlive(pid) {
26532
26550
  var HEARTBEAT_STALE_MS = 15e3;
26533
26551
  var SUPERVISOR_ERROR_MAX_AGE_MS = 3e4;
26534
26552
  function supervisorErrorFile(paths) {
26535
- return join12(paths.runtimeDir, "supervisor.error");
26553
+ return join13(paths.runtimeDir, "supervisor.error");
26536
26554
  }
26537
26555
  function clearSupervisorError(paths) {
26538
26556
  const file = supervisorErrorFile(paths);
26539
- if (existsSync9(file)) rmSync(file, { force: true });
26557
+ if (existsSync10(file)) rmSync(file, { force: true });
26540
26558
  }
26541
26559
  function recordSupervisorError(paths, message) {
26542
26560
  try {
@@ -26559,7 +26577,7 @@ function readRecentSupervisorError(paths) {
26559
26577
  }
26560
26578
  }
26561
26579
  function vnextSupervisorStatus(paths) {
26562
- if (!existsSync9(paths.registryDb)) return { running: false };
26580
+ if (!existsSync10(paths.registryDb)) return { running: false };
26563
26581
  const registry = new VnextRuntimeRegistry(paths.registryDb);
26564
26582
  try {
26565
26583
  const record2 = registry.supervisor();
@@ -26620,7 +26638,7 @@ async function ensureVnextSupervisor(options = {}) {
26620
26638
  throw runtimeError("runtime_supervisor_unreachable", paths.registryDb, `runtime supervisor pid ${status.pid} is registered as running but cannot be probed`);
26621
26639
  }
26622
26640
  clearSupervisorError(paths);
26623
- const scriptPath = join12(repoRoot, "scripts", "kxm-runtime-supervisor.mjs");
26641
+ const scriptPath = join13(findKxmRepoRoot(import.meta.url), "scripts", "kxm-runtime-supervisor.mjs");
26624
26642
  const spawnImpl = options.spawnImpl ?? ((script, env) => {
26625
26643
  const child = spawn3(process.execPath, [script], {
26626
26644
  detached: true,
@@ -26705,8 +26723,8 @@ async function waitForDriveSessions(settled, graceMs) {
26705
26723
  try {
26706
26724
  await Promise.race([
26707
26725
  Promise.allSettled(settled),
26708
- new Promise((resolve9) => {
26709
- timeout = setTimeout(resolve9, graceMs);
26726
+ new Promise((resolve8) => {
26727
+ timeout = setTimeout(resolve8, graceMs);
26710
26728
  timeout.unref?.();
26711
26729
  })
26712
26730
  ]);
@@ -27073,7 +27091,7 @@ async function vnextRuntimeRequest(handle, method, path, body) {
27073
27091
 
27074
27092
  // plugins/kxm/src/vnext-pi-producer.ts
27075
27093
  import { spawn as spawn4 } from "node:child_process";
27076
- import { join as join13 } from "node:path";
27094
+ import { join as join14 } from "node:path";
27077
27095
  import { StringDecoder } from "node:string_decoder";
27078
27096
  function formatPiSessionKey(params) {
27079
27097
  if (params.agentId === "coordinator") {
@@ -27272,8 +27290,8 @@ var PiSession = class {
27272
27290
  }
27273
27291
  const id = `cmd_${++this.commandCounter}`;
27274
27292
  const payload = { ...command, id };
27275
- return new Promise((resolve9, reject) => {
27276
- this.pendingCommands.set(id, { resolve: resolve9, reject });
27293
+ return new Promise((resolve8, reject) => {
27294
+ this.pendingCommands.set(id, { resolve: resolve8, reject });
27277
27295
  try {
27278
27296
  this.process.stdin.write(JSON.stringify(payload) + "\n");
27279
27297
  } catch (err) {
@@ -27294,7 +27312,7 @@ var PiSession = class {
27294
27312
  return { outcome, text: "aborted", usage: {} };
27295
27313
  }
27296
27314
  this.status = "busy";
27297
- return new Promise((resolve9, reject) => {
27315
+ return new Promise((resolve8, reject) => {
27298
27316
  let signalCleanup;
27299
27317
  if (signal) {
27300
27318
  const onAbort = () => {
@@ -27308,7 +27326,7 @@ var PiSession = class {
27308
27326
  signalCleanup = () => signal.removeEventListener("abort", onAbort);
27309
27327
  }
27310
27328
  this.activePrompt = {
27311
- resolve: resolve9,
27329
+ resolve: resolve8,
27312
27330
  reject,
27313
27331
  allowedOutcomes,
27314
27332
  text: "",
@@ -27425,7 +27443,7 @@ function createVnextPiProducer(options = {}) {
27425
27443
  const args = ["--mode", "rpc", "--name", displayName];
27426
27444
  if (options.sessionDir) {
27427
27445
  const safeDirName = key.replace(/[^a-zA-Z0-9_-]/g, "_");
27428
- args.push("--session-dir", join13(options.sessionDir, request.runId, safeDirName));
27446
+ args.push("--session-dir", join14(options.sessionDir, request.runId, safeDirName));
27429
27447
  }
27430
27448
  if (model) {
27431
27449
  args.push("--model", model);
@@ -27553,8 +27571,8 @@ function createVnextPiProducer(options = {}) {
27553
27571
  }
27554
27572
 
27555
27573
  // plugins/kxm/src/logger.ts
27556
- import { appendFileSync, existsSync as existsSync10, mkdirSync as mkdirSync5, renameSync as renameSync2, statSync as statSync3, unlinkSync as unlinkSync2 } from "node:fs";
27557
- import { dirname as dirname6 } from "node:path";
27574
+ import { appendFileSync, existsSync as existsSync11, mkdirSync as mkdirSync5, renameSync as renameSync2, statSync as statSync3, unlinkSync as unlinkSync2 } from "node:fs";
27575
+ import { dirname as dirname7 } from "node:path";
27558
27576
 
27559
27577
  // plugins/kxm/src/redact.ts
27560
27578
  var SECRET_PATTERNS = [
@@ -27617,7 +27635,7 @@ function redactLogValue(val, key) {
27617
27635
  function rotateLogFiles(filePath, maxFiles) {
27618
27636
  for (let i = maxFiles; i >= 1; i--) {
27619
27637
  const current = `${filePath}.${i}`;
27620
- if (existsSync10(current)) {
27638
+ if (existsSync11(current)) {
27621
27639
  if (i >= maxFiles) {
27622
27640
  try {
27623
27641
  unlinkSync2(current);
@@ -27631,7 +27649,7 @@ function rotateLogFiles(filePath, maxFiles) {
27631
27649
  }
27632
27650
  }
27633
27651
  }
27634
- if (existsSync10(filePath)) {
27652
+ if (existsSync11(filePath)) {
27635
27653
  try {
27636
27654
  renameSync2(filePath, `${filePath}.1`);
27637
27655
  } catch {
@@ -27648,7 +27666,7 @@ function createLogger(options) {
27648
27666
  const shouldStdout = options.stdout ?? !isDaemon;
27649
27667
  const correlationDefaults = options.correlation ?? {};
27650
27668
  let currentSize = 0;
27651
- if (filePath && existsSync10(filePath)) {
27669
+ if (filePath && existsSync11(filePath)) {
27652
27670
  try {
27653
27671
  currentSize = statSync3(filePath).size;
27654
27672
  } catch {
@@ -27686,7 +27704,7 @@ function createLogger(options) {
27686
27704
  currentSize = 0;
27687
27705
  }
27688
27706
  try {
27689
- mkdirSync5(dirname6(filePath), { recursive: true });
27707
+ mkdirSync5(dirname7(filePath), { recursive: true });
27690
27708
  appendFileSync(filePath, line, { encoding: "utf8", mode: 384 });
27691
27709
  currentSize += lineBytes;
27692
27710
  } catch {
@@ -27729,8 +27747,8 @@ function createLogger(options) {
27729
27747
 
27730
27748
  // plugins/kxm/src/improve.ts
27731
27749
  import { createHash as createHash13 } from "node:crypto";
27732
- import { existsSync as existsSync11, mkdirSync as mkdirSync6, writeFileSync as writeFileSync5 } from "node:fs";
27733
- import { join as join14, relative as relative4, resolve as resolve7 } from "node:path";
27750
+ import { existsSync as existsSync12, mkdirSync as mkdirSync6, writeFileSync as writeFileSync5 } from "node:fs";
27751
+ import { join as join15, relative as relative4, resolve as resolve6 } from "node:path";
27734
27752
 
27735
27753
  // plugins/kxm/src/protocol.ts
27736
27754
  var DEFAULT_MESSAGE_TTL_MS = 24 * 60 * 6e4;
@@ -27913,8 +27931,8 @@ function groupRoutingRecords(records, options = {}) {
27913
27931
  });
27914
27932
  }
27915
27933
  function buildImprovementReport(records, options = {}) {
27916
- const projectRoot = options.projectRoot ? resolve7(options.projectRoot) : process.cwd();
27917
- const candidatesDir = options.candidatesDir ? resolve7(options.candidatesDir) : join14(projectRoot, ".kxm", "candidates");
27934
+ const projectRoot = options.projectRoot ? resolve6(options.projectRoot) : process.cwd();
27935
+ const candidatesDir = options.candidatesDir ? resolve6(options.candidatesDir) : join15(projectRoot, ".kxm", "candidates");
27918
27936
  const groups = groupRoutingRecords(records, options);
27919
27937
  const candidates = [];
27920
27938
  for (const group of groups) {
@@ -27926,7 +27944,7 @@ function buildImprovementReport(records, options = {}) {
27926
27944
  group.workflowHash
27927
27945
  );
27928
27946
  const diffFileName = `${group.candidateId}.diff`;
27929
- const diffFilePath = join14(candidatesDir, diffFileName);
27947
+ const diffFilePath = join15(candidatesDir, diffFileName);
27930
27948
  const relDiffPath = relative4(projectRoot, diffFilePath).replace(/\\/g, "/");
27931
27949
  const candidate = {
27932
27950
  schema: CANDIDATE_SCHEMA,
@@ -27948,11 +27966,11 @@ function buildImprovementReport(records, options = {}) {
27948
27966
  createdAt: nowIso()
27949
27967
  };
27950
27968
  if (!options.dryRun) {
27951
- if (!existsSync11(candidatesDir)) {
27969
+ if (!existsSync12(candidatesDir)) {
27952
27970
  mkdirSync6(candidatesDir, { recursive: true });
27953
27971
  }
27954
27972
  writeFileSync5(diffFilePath, diff, "utf8");
27955
- const jsonFilePath = join14(candidatesDir, `${group.candidateId}.json`);
27973
+ const jsonFilePath = join15(candidatesDir, `${group.candidateId}.json`);
27956
27974
  writeFileSync5(jsonFilePath, JSON.stringify(candidate, null, 2) + "\n", "utf8");
27957
27975
  }
27958
27976
  candidates.push(candidate);
@@ -27968,7 +27986,7 @@ function buildImprovementReport(records, options = {}) {
27968
27986
  }
27969
27987
  function writeImprovementReport(improvementsDir, report, dryRun = false) {
27970
27988
  const stamp = report.createdAt.replace(/[:.]/g, "-");
27971
- const path = join14(improvementsDir, `${stamp}.json`);
27989
+ const path = join15(improvementsDir, `${stamp}.json`);
27972
27990
  if (!dryRun) {
27973
27991
  mkdirSync6(improvementsDir, { recursive: true });
27974
27992
  writeFileSync5(path, `${JSON.stringify(report, null, 2)}
@@ -28472,8 +28490,8 @@ Instructions for Operator:
28472
28490
 
28473
28491
  // plugins/kxm/src/modes.ts
28474
28492
  var import_yaml6 = __toESM(require_dist(), 1);
28475
- import { existsSync as existsSync12, readFileSync as readFileSync10 } from "node:fs";
28476
- import { join as join15 } from "node:path";
28493
+ import { existsSync as existsSync13, readFileSync as readFileSync10 } from "node:fs";
28494
+ import { join as join16 } from "node:path";
28477
28495
  var DEFAULT_MODES_CONFIG = Object.freeze({
28478
28496
  schema: "kxm.modes.v1",
28479
28497
  majorModes: {
@@ -28536,8 +28554,8 @@ function loadModesConfig(projectRoot) {
28536
28554
  if (!projectRoot) {
28537
28555
  return DEFAULT_MODES_CONFIG;
28538
28556
  }
28539
- const modesPath = join15(projectRoot, ".kxm", "modes.yaml");
28540
- if (!existsSync12(modesPath)) {
28557
+ const modesPath = join16(projectRoot, ".kxm", "modes.yaml");
28558
+ if (!existsSync13(modesPath)) {
28541
28559
  return DEFAULT_MODES_CONFIG;
28542
28560
  }
28543
28561
  try {
@@ -28627,9 +28645,9 @@ function calculatePromptFootprint(resolved, projectRoot = process.cwd(), catalog
28627
28645
  estimatedTokens: estimateTokens(baseSystemPromptChars)
28628
28646
  });
28629
28647
  for (const relPath of resolved.contextFiles) {
28630
- const fullPath = join15(projectRoot, relPath);
28648
+ const fullPath = join16(projectRoot, relPath);
28631
28649
  let chars = 0;
28632
- if (existsSync12(fullPath)) {
28650
+ if (existsSync13(fullPath)) {
28633
28651
  try {
28634
28652
  chars = readFileSync10(fullPath, "utf8").length;
28635
28653
  } catch {
@@ -28763,9 +28781,9 @@ ${divider}
28763
28781
 
28764
28782
  // plugins/kxm/src/ssh-remote.ts
28765
28783
  import { spawnSync as spawnSync3 } from "node:child_process";
28766
- import { existsSync as existsSync13, mkdirSync as mkdirSync7, readFileSync as readFileSync11, readdirSync as readdirSync5, rmSync as rmSync2, statSync as statSync4 } from "node:fs";
28784
+ import { existsSync as existsSync14, mkdirSync as mkdirSync7, readFileSync as readFileSync11, readdirSync as readdirSync5, rmSync as rmSync2, statSync as statSync4 } from "node:fs";
28767
28785
  import { homedir as homedir2 } from "node:os";
28768
- import { join as join16, resolve as resolve8 } from "node:path";
28786
+ import { join as join17, resolve as resolve7 } from "node:path";
28769
28787
  var MAX_SSH_OUTPUT_BYTES = 50 * 1024;
28770
28788
  var MAX_SSH_OUTPUT_LINES = 2e3;
28771
28789
  var DEFAULT_SOCKET_DIR = ".kxm/run/ssh-sockets";
@@ -28791,8 +28809,8 @@ function truncateSshOutput(raw) {
28791
28809
  return { text, truncated };
28792
28810
  }
28793
28811
  function parseSshConfig(configPath) {
28794
- const targetPath = configPath ?? join16(homedir2(), ".ssh", "config");
28795
- if (!existsSync13(targetPath)) {
28812
+ const targetPath = configPath ?? join17(homedir2(), ".ssh", "config");
28813
+ if (!existsSync14(targetPath)) {
28796
28814
  return [];
28797
28815
  }
28798
28816
  try {
@@ -28873,15 +28891,15 @@ function resolveSshHostG(host, execFn = spawnSync3) {
28873
28891
  }
28874
28892
  }
28875
28893
  function ensureSocketDir(socketDir = DEFAULT_SOCKET_DIR) {
28876
- const resolved = resolve8(socketDir);
28877
- if (!existsSync13(resolved)) {
28894
+ const resolved = resolve7(socketDir);
28895
+ if (!existsSync14(resolved)) {
28878
28896
  mkdirSync7(resolved, { recursive: true, mode: 448 });
28879
28897
  }
28880
28898
  return resolved;
28881
28899
  }
28882
28900
  function buildSshArgs(options) {
28883
28901
  const socketDir = ensureSocketDir(options.socketDir ?? DEFAULT_SOCKET_DIR);
28884
- const controlPath = join16(socketDir, "%C");
28902
+ const controlPath = join17(socketDir, "%C");
28885
28903
  const persist2 = options.controlPersist ?? DEFAULT_CONTROL_PERSIST;
28886
28904
  const args = [
28887
28905
  "-o",
@@ -28906,7 +28924,7 @@ function buildSshArgs(options) {
28906
28924
  }
28907
28925
  function checkControlSocket(host, socketDir = DEFAULT_SOCKET_DIR, execFn = spawnSync3) {
28908
28926
  const resolvedDir = ensureSocketDir(socketDir);
28909
- const controlPath = join16(resolvedDir, "%C");
28927
+ const controlPath = join17(resolvedDir, "%C");
28910
28928
  try {
28911
28929
  const result = execFn("ssh", ["-O", "check", "-o", `ControlPath=${controlPath}`, host], {
28912
28930
  encoding: "utf-8"
@@ -28918,7 +28936,7 @@ function checkControlSocket(host, socketDir = DEFAULT_SOCKET_DIR, execFn = spawn
28918
28936
  }
28919
28937
  function closeControlSocket(host, socketDir = DEFAULT_SOCKET_DIR, execFn = spawnSync3) {
28920
28938
  const resolvedDir = ensureSocketDir(socketDir);
28921
- const controlPath = join16(resolvedDir, "%C");
28939
+ const controlPath = join17(resolvedDir, "%C");
28922
28940
  try {
28923
28941
  const result = execFn("ssh", ["-O", "stop", "-o", `ControlPath=${controlPath}`, host], {
28924
28942
  encoding: "utf-8"
@@ -28934,7 +28952,7 @@ function pruneSocketDir(socketDir = DEFAULT_SOCKET_DIR) {
28934
28952
  try {
28935
28953
  const entries = readdirSync5(resolvedDir);
28936
28954
  for (const entry of entries) {
28937
- const fullPath = join16(resolvedDir, entry);
28955
+ const fullPath = join17(resolvedDir, entry);
28938
28956
  try {
28939
28957
  const stat = statSync4(fullPath);
28940
28958
  if (stat.isSocket()) {