@kontextmind/kxm 0.7.17 → 0.7.19

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.
Files changed (38) hide show
  1. package/.claude-plugin/marketplace.json +1 -1
  2. package/docs/configuration.md +17 -1
  3. package/docs/getting-started.md +4 -1
  4. package/docs/kxm-handbook.md +6 -2
  5. package/package.json +8 -6
  6. package/plugins/kxm/.claude-plugin/plugin.json +1 -1
  7. package/plugins/kxm/dist/cli.js +484 -458
  8. package/plugins/kxm/dist/core.js +3 -2
  9. package/plugins/kxm/dist/extension.js +28841 -5273
  10. package/plugins/kxm/dist/mcp-server.js +21 -10
  11. package/plugins/kxm/dist/runtime.js +43 -39
  12. package/plugins/kxm/dist/server.js +43 -39
  13. package/plugins/kxm/dist/vnext-runtime-supervisor.js +40 -37
  14. package/plugins/kxm/package.json +4 -1
  15. package/plugins/kxm/src/cli/hub.ts +3 -2
  16. package/plugins/kxm/src/cli.ts +3 -2
  17. package/plugins/kxm/src/config.ts +20 -0
  18. package/plugins/kxm/src/extension.ts +46 -3
  19. package/plugins/kxm/src/hub-autostart.ts +214 -0
  20. package/plugins/kxm/src/mcp-server.ts +3 -3
  21. package/plugins/kxm/src/project-name.ts +20 -0
  22. package/plugins/kxm/src/providers/claude-bridge/LICENSE +21 -0
  23. package/plugins/kxm/src/providers/claude-bridge/README.md +18 -0
  24. package/plugins/kxm/src/providers/claude-bridge/config.ts +53 -0
  25. package/plugins/kxm/src/providers/claude-bridge/convert.ts +180 -0
  26. package/plugins/kxm/src/providers/claude-bridge/index.ts +28 -0
  27. package/plugins/kxm/src/providers/claude-bridge/mcp-server.ts +59 -0
  28. package/plugins/kxm/src/providers/claude-bridge/models.ts +166 -0
  29. package/plugins/kxm/src/providers/claude-bridge/pi-compat.ts +215 -0
  30. package/plugins/kxm/src/providers/claude-bridge/prompt-stream.ts +89 -0
  31. package/plugins/kxm/src/providers/claude-bridge/provider.ts +286 -0
  32. package/plugins/kxm/src/providers/claude-bridge/query-state.ts +72 -0
  33. package/plugins/kxm/src/providers/claude-bridge/redact.ts +26 -0
  34. package/plugins/kxm/src/providers/claude-bridge/register.ts +124 -0
  35. package/plugins/kxm/src/providers/claude-bridge/stream.ts +390 -0
  36. package/plugins/kxm/src/providers/claude-bridge/tools.ts +140 -0
  37. package/plugins/kxm/src/redact.ts +3 -2
  38. package/scripts/build-runtime.mjs +5 -1
@@ -8072,36 +8072,38 @@ var require_Alias = __commonJS({
8072
8072
  if (node.anchor === this.source)
8073
8073
  found = node;
8074
8074
  }
8075
+ if (found && ctx) {
8076
+ const { anchors: anchors2, doc: doc2, maxAliasCount } = ctx;
8077
+ let data = anchors2.get(found);
8078
+ if (!data) {
8079
+ toJS.toJS(found, null, ctx);
8080
+ data = anchors2.get(found);
8081
+ }
8082
+ if (data?.res === void 0) {
8083
+ const msg = "This should not happen: Alias anchor was not resolved?";
8084
+ throw new ReferenceError(msg);
8085
+ }
8086
+ if (maxAliasCount >= 0) {
8087
+ data.count += 1;
8088
+ if (data.aliasCount === 0)
8089
+ data.aliasCount = getAliasCount(doc2, found, anchors2);
8090
+ if (data.count * data.aliasCount > maxAliasCount) {
8091
+ const msg = "Excessive alias count indicates a resource exhaustion attack";
8092
+ throw new ReferenceError(msg);
8093
+ }
8094
+ }
8095
+ }
8075
8096
  return found;
8076
8097
  }
8077
8098
  toJSON(_arg, ctx) {
8078
8099
  if (!ctx)
8079
8100
  return { source: this.source };
8080
- const { anchors: anchors2, doc, maxAliasCount } = ctx;
8081
- const source = this.resolve(doc, ctx);
8101
+ const source = this.resolve(ctx.doc, ctx);
8082
8102
  if (!source) {
8083
8103
  const msg = `Unresolved alias (the anchor must be set before the alias): ${this.source}`;
8084
8104
  throw new ReferenceError(msg);
8085
8105
  }
8086
- let data = anchors2.get(source);
8087
- if (!data) {
8088
- toJS.toJS(source, null, ctx);
8089
- data = anchors2.get(source);
8090
- }
8091
- if (data?.res === void 0) {
8092
- const msg = "This should not happen: Alias anchor was not resolved?";
8093
- throw new ReferenceError(msg);
8094
- }
8095
- if (maxAliasCount >= 0) {
8096
- data.count += 1;
8097
- if (data.aliasCount === 0)
8098
- data.aliasCount = getAliasCount(doc, source, anchors2);
8099
- if (data.count * data.aliasCount > maxAliasCount) {
8100
- const msg = "Excessive alias count indicates a resource exhaustion attack";
8101
- throw new ReferenceError(msg);
8102
- }
8103
- }
8104
- return data.res;
8106
+ return ctx.anchors.get(source).res;
8105
8107
  }
8106
8108
  toString(ctx, _onComment, _onChompKeep) {
8107
8109
  const src = `*${this.source}`;
@@ -12103,37 +12105,38 @@ var require_resolve_flow_scalar = __commonJS({
12103
12105
  }
12104
12106
  if (badChar)
12105
12107
  onError(0, "BAD_SCALAR_START", `Plain value cannot start with ${badChar}`);
12106
- return foldLines(source);
12108
+ return unfoldLines(source);
12107
12109
  }
12108
12110
  function singleQuotedValue(source, onError) {
12109
12111
  if (source[source.length - 1] !== "'" || source.length === 1)
12110
12112
  onError(source.length, "MISSING_CHAR", "Missing closing 'quote");
12111
- return foldLines(source.slice(1, -1)).replace(/''/g, "'");
12113
+ return unfoldLines(source.slice(1, -1)).replace(/''/g, "'");
12112
12114
  }
12113
- function foldLines(source) {
12114
- let first, line;
12115
+ function unfoldLines(source) {
12116
+ const line = /(.*?)\r?\n/sy;
12117
+ let match = line.exec(source);
12118
+ if (!match)
12119
+ return source;
12120
+ let trimEnd, trimBoth;
12115
12121
  try {
12116
- first = new RegExp("(.*?)(?<![ ])[ ]*\r?\n", "sy");
12117
- line = new RegExp("[ ]*(.*?)(?:(?<![ ])[ ]*)?\r?\n", "sy");
12122
+ trimEnd = new RegExp("(?<![ ])[ ]+$");
12123
+ trimBoth = new RegExp("^[ ]+|(?<![ ])[ ]+$", "g");
12118
12124
  } catch {
12119
- first = /(.*?)[ \t]*\r?\n/sy;
12120
- line = /[ \t]*(.*?)[ \t]*\r?\n/sy;
12125
+ trimEnd = /[ \t]+$/;
12126
+ trimBoth = /^[ \t]+|[ \t]+$/g;
12121
12127
  }
12122
- let match = first.exec(source);
12123
- if (!match)
12124
- return source;
12125
- let res = match[1];
12128
+ let res = match[1].replace(trimEnd, "");
12126
12129
  let sep4 = " ";
12127
- let pos = first.lastIndex;
12128
- line.lastIndex = pos;
12130
+ let pos = line.lastIndex;
12129
12131
  while (match = line.exec(source)) {
12130
- if (match[1] === "") {
12132
+ const lm = match[1].replace(trimBoth, "");
12133
+ if (lm === "") {
12131
12134
  if (sep4 === "\n")
12132
12135
  res += sep4;
12133
12136
  else
12134
12137
  sep4 = "\n";
12135
12138
  } else {
12136
- res += sep4 + match[1];
12139
+ res += sep4 + lm;
12137
12140
  sep4 = " ";
12138
12141
  }
12139
12142
  pos = line.lastIndex;
@@ -14776,7 +14779,7 @@ var require_dist = __commonJS({
14776
14779
  });
14777
14780
 
14778
14781
  // plugins/kxm/src/cli.ts
14779
- import { basename as basename10, resolve as resolve30 } from "node:path";
14782
+ import { resolve as resolve30 } from "node:path";
14780
14783
  import { fileURLToPath as fileURLToPath8 } from "node:url";
14781
14784
 
14782
14785
  // node_modules/commander/lib/error.js
@@ -19568,11 +19571,25 @@ var HubClient = class {
19568
19571
  }
19569
19572
  };
19570
19573
 
19574
+ // plugins/kxm/src/project-name.ts
19575
+ import { readFileSync as readFileSync2 } from "node:fs";
19576
+ import { basename, join as join2 } from "node:path";
19577
+ function defaultProjectName(cwd, env = process.env) {
19578
+ const fromEnv = env.KXM_PROJECT?.trim();
19579
+ if (fromEnv) return fromEnv;
19580
+ try {
19581
+ const pkg = JSON.parse(readFileSync2(join2(cwd, "package.json"), "utf8"));
19582
+ if (typeof pkg.name === "string" && pkg.name.trim().length > 0) return pkg.name.trim();
19583
+ } catch {
19584
+ }
19585
+ return basename(cwd);
19586
+ }
19587
+
19571
19588
  // plugins/kxm/src/commands.ts
19572
19589
  import { createHash as createHash4, randomUUID as randomUUID2, timingSafeEqual } from "node:crypto";
19573
- import { chmodSync, existsSync as existsSync2, mkdirSync as mkdirSync2, readFileSync as readFileSync2, unlinkSync, writeFileSync as writeFileSync2 } from "node:fs";
19590
+ import { chmodSync, existsSync as existsSync2, mkdirSync as mkdirSync2, readFileSync as readFileSync3, unlinkSync, writeFileSync as writeFileSync2 } from "node:fs";
19574
19591
  import { homedir } from "node:os";
19575
- import { dirname, join as join2, resolve } from "node:path";
19592
+ import { dirname, join as join3, resolve } from "node:path";
19576
19593
  function requiredString(value, name) {
19577
19594
  if (typeof value !== "string" || value.trim() === "") throw new Error(`${name} is required`);
19578
19595
  return value.trim();
@@ -20321,10 +20338,10 @@ function parseSessionToken(token) {
20321
20338
  }
20322
20339
  function resolveUserConfigDirectory(overrideDir) {
20323
20340
  if (overrideDir) return resolve(overrideDir);
20324
- return resolve(process.env.KXM_USER_CONFIG_DIR?.trim() || join2(homedir(), ".config", "kxm"));
20341
+ return resolve(process.env.KXM_USER_CONFIG_DIR?.trim() || join3(homedir(), ".config", "kxm"));
20325
20342
  }
20326
20343
  function sessionTokenPath(userConfigDir) {
20327
- return join2(resolveUserConfigDirectory(userConfigDir), "session.token");
20344
+ return join3(resolveUserConfigDirectory(userConfigDir), "session.token");
20328
20345
  }
20329
20346
  function persistSessionTokenToDisk(token, options) {
20330
20347
  const filePath = sessionTokenPath(options?.userConfigDir);
@@ -20343,7 +20360,7 @@ function readSessionTokenFromDisk(options) {
20343
20360
  const filePath = sessionTokenPath(options?.userConfigDir);
20344
20361
  if (!existsSync2(filePath)) return void 0;
20345
20362
  try {
20346
- const token = readFileSync2(filePath, "utf8").trim();
20363
+ const token = readFileSync3(filePath, "utf8").trim();
20347
20364
  if (!token) return void 0;
20348
20365
  const payload = parseSessionToken(token);
20349
20366
  if (!payload) return void 0;
@@ -20456,7 +20473,7 @@ function enforceToolPolicy(commandName, env = process.env, options) {
20456
20473
  if (existsSync2(tokenFile)) {
20457
20474
  let tokenRaw;
20458
20475
  try {
20459
- tokenRaw = readFileSync2(tokenFile, "utf8").trim();
20476
+ tokenRaw = readFileSync3(tokenFile, "utf8").trim();
20460
20477
  } catch {
20461
20478
  return { allowed: false, error: "session_token_invalid", detail: "Session token file on disk could not be read" };
20462
20479
  }
@@ -20480,8 +20497,8 @@ function enforceToolPolicy(commandName, env = process.env, options) {
20480
20497
  var import__ = __toESM(require__(), 1);
20481
20498
  import { spawnSync as spawnSync2 } from "node:child_process";
20482
20499
  import { createHash as createHash6 } from "node:crypto";
20483
- import { existsSync as existsSync4, lstatSync, readFileSync as readFileSync3, readdirSync, realpathSync } from "node:fs";
20484
- import { basename, dirname as dirname2, extname, isAbsolute, join as join3, relative, resolve as resolve2, sep } from "node:path";
20500
+ import { existsSync as existsSync4, lstatSync, readFileSync as readFileSync4, readdirSync, realpathSync } from "node:fs";
20501
+ import { basename as basename2, dirname as dirname2, extname, isAbsolute, join as join4, relative, resolve as resolve2, sep } from "node:path";
20485
20502
  import { fileURLToPath } from "node:url";
20486
20503
 
20487
20504
  // plugins/kxm/src/restricted-yaml.mjs
@@ -21877,7 +21894,7 @@ var VnextConfigError = class extends Error {
21877
21894
  }
21878
21895
  };
21879
21896
  var PACKAGE_ROOT = resolve2(dirname2(fileURLToPath(import.meta.url)), "../../..");
21880
- var DEFAULT_SCHEMA_DIR = join3(PACKAGE_ROOT, "schemas", "vnext");
21897
+ var DEFAULT_SCHEMA_DIR = join4(PACKAGE_ROOT, "schemas", "vnext");
21881
21898
  var RESOURCE_SCHEMA = Object.freeze({
21882
21899
  project: { identity: "kxm.project.v1", file: "project.schema.json" },
21883
21900
  repository: { identity: "kxm.repository.v1", file: "repository.schema.json" },
@@ -21923,7 +21940,7 @@ function parseRestrictedYaml2(input, label = "<yaml>", limits = VNEXT_YAML_LIMIT
21923
21940
  }
21924
21941
  }
21925
21942
  function readJsonObject(file) {
21926
- const parsed = JSON.parse(readFileSync3(file, "utf8"));
21943
+ const parsed = JSON.parse(readFileSync4(file, "utf8"));
21927
21944
  if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) throw new Error(`${file} is not a JSON object`);
21928
21945
  return parsed;
21929
21946
  }
@@ -21942,10 +21959,10 @@ var VnextSchemaRegistry = class {
21942
21959
  constructor(schemasDir = DEFAULT_SCHEMA_DIR) {
21943
21960
  this.schemasDir = resolve2(schemasDir);
21944
21961
  this.ajv = new import__.Ajv2020({ allErrors: true, strict: true, strictRequired: false });
21945
- const common = readJsonObject(join3(this.schemasDir, "common.schema.json"));
21962
+ const common = readJsonObject(join4(this.schemasDir, "common.schema.json"));
21946
21963
  this.ajv.addSchema(common);
21947
21964
  for (const definition of Object.values(RESOURCE_SCHEMA)) {
21948
- this.ajv.addSchema(readJsonObject(join3(this.schemasDir, definition.file)));
21965
+ this.ajv.addSchema(readJsonObject(join4(this.schemasDir, definition.file)));
21949
21966
  }
21950
21967
  const localBindingsFile = "local-repository-bindings.schema.json";
21951
21968
  const templateProvenanceFile = "template-provenance.schema.json";
@@ -21955,14 +21972,14 @@ var VnextSchemaRegistry = class {
21955
21972
  const migrationReceiptFile = "migration-receipt.schema.json";
21956
21973
  const permissionDiffFile = "permission-diff.schema.json";
21957
21974
  const runEventFile = "run-event.schema.json";
21958
- this.ajv.addSchema(readJsonObject(join3(this.schemasDir, localBindingsFile)));
21959
- this.ajv.addSchema(readJsonObject(join3(this.schemasDir, templateProvenanceFile)));
21960
- this.ajv.addSchema(readJsonObject(join3(this.schemasDir, initOperationFile)));
21961
- this.ajv.addSchema(readJsonObject(join3(this.schemasDir, migrationPlanFile)));
21962
- this.ajv.addSchema(readJsonObject(join3(this.schemasDir, migrationDecisionFile)));
21963
- this.ajv.addSchema(readJsonObject(join3(this.schemasDir, migrationReceiptFile)));
21964
- this.ajv.addSchema(readJsonObject(join3(this.schemasDir, permissionDiffFile)));
21965
- this.ajv.addSchema(readJsonObject(join3(this.schemasDir, runEventFile)));
21975
+ this.ajv.addSchema(readJsonObject(join4(this.schemasDir, localBindingsFile)));
21976
+ this.ajv.addSchema(readJsonObject(join4(this.schemasDir, templateProvenanceFile)));
21977
+ this.ajv.addSchema(readJsonObject(join4(this.schemasDir, initOperationFile)));
21978
+ this.ajv.addSchema(readJsonObject(join4(this.schemasDir, migrationPlanFile)));
21979
+ this.ajv.addSchema(readJsonObject(join4(this.schemasDir, migrationDecisionFile)));
21980
+ this.ajv.addSchema(readJsonObject(join4(this.schemasDir, migrationReceiptFile)));
21981
+ this.ajv.addSchema(readJsonObject(join4(this.schemasDir, permissionDiffFile)));
21982
+ this.ajv.addSchema(readJsonObject(join4(this.schemasDir, runEventFile)));
21966
21983
  for (const [kind, definition] of Object.entries(RESOURCE_SCHEMA)) {
21967
21984
  const validator = this.ajv.getSchema(`https://schemas.kxm.dev/vnext/${definition.file}`);
21968
21985
  if (!validator) throw new Error(`schema did not compile: ${definition.file}`);
@@ -22057,7 +22074,7 @@ function containedHostPath(root, candidate) {
22057
22074
  function portableBindingIssue(root, pathHint, repositoryId) {
22058
22075
  let current = root;
22059
22076
  for (const segment of pathHint === "." ? [] : pathHint.split("/")) {
22060
- current = join3(current, segment);
22077
+ current = join4(current, segment);
22061
22078
  if (!existsSync4(current)) break;
22062
22079
  const stat = lstatSync(current);
22063
22080
  if (stat.isSymbolicLink()) {
@@ -22116,20 +22133,20 @@ function readResource(registry, root, file, logicalPath, kind, id, containmentRo
22116
22133
  parent = dirname2(parent);
22117
22134
  }
22118
22135
  if (!stat.isFile()) fail2("path", "resource_not_file", label, "configuration resource must be a regular file");
22119
- const value = parseRestrictedYaml2(readFileSync3(file), label);
22136
+ const value = parseRestrictedYaml2(readFileSync4(file), label);
22120
22137
  const issues = registry.validate(kind, value, label);
22121
22138
  if (issues.length > 0) throw new VnextConfigError(issues);
22122
22139
  return { kind, ...id === void 0 ? {} : { id }, file, logicalPath, value };
22123
22140
  }
22124
22141
  function readTemplateProvenance(registry, root) {
22125
- const file = join3(root, ".kxm", "template-provenance.yaml");
22142
+ const file = join4(root, ".kxm", "template-provenance.yaml");
22126
22143
  if (!existsSync4(file)) return void 0;
22127
22144
  const label = ".kxm/template-provenance.yaml";
22128
22145
  const stat = lstatSync(file);
22129
22146
  if (stat.isSymbolicLink() || !stat.isFile()) {
22130
22147
  fail2("path", "resource_not_file", label, "template provenance must be a regular file, not a link or directory");
22131
22148
  }
22132
- const configRoot = join3(root, ".kxm");
22149
+ const configRoot = join4(root, ".kxm");
22133
22150
  let parent = dirname2(file);
22134
22151
  while (parent !== root) {
22135
22152
  const parentStat = lstatSync(parent);
@@ -22139,7 +22156,7 @@ function readTemplateProvenance(registry, root) {
22139
22156
  if (parent === configRoot) break;
22140
22157
  parent = dirname2(parent);
22141
22158
  }
22142
- const value = parseRestrictedYaml2(readFileSync3(file), label);
22159
+ const value = parseRestrictedYaml2(readFileSync4(file), label);
22143
22160
  const issues = registry.validateTemplateProvenance(value, label);
22144
22161
  if (issues.length > 0) throw new VnextConfigError(issues);
22145
22162
  if (!resolveVnextTemplateBaseline(value)) {
@@ -22179,27 +22196,27 @@ function listNamedResources(registry, root, directory, logicalDirectory, kind) {
22179
22196
  const entries = readdirSync(directory, { withFileTypes: true }).sort((left, right) => compareCodeUnits3(left.name, right.name));
22180
22197
  for (const entry of entries) {
22181
22198
  if (entry.isDirectory()) {
22182
- issues.push(issue2("path", "nested_resource_directory", displayPath(root, join3(directory, entry.name)), "nested resource directories are not allowed"));
22199
+ issues.push(issue2("path", "nested_resource_directory", displayPath(root, join4(directory, entry.name)), "nested resource directories are not allowed"));
22183
22200
  continue;
22184
22201
  }
22185
22202
  if (!entry.name.toLowerCase().endsWith(".yaml") && !entry.name.toLowerCase().endsWith(".yml")) continue;
22186
22203
  if (!entry.isFile() || extname(entry.name) !== ".yaml") {
22187
- issues.push(issue2("path", "resource_filename_invalid", displayPath(root, join3(directory, entry.name)), "resource must be a regular file with the exact .yaml extension"));
22204
+ issues.push(issue2("path", "resource_filename_invalid", displayPath(root, join4(directory, entry.name)), "resource must be a regular file with the exact .yaml extension"));
22188
22205
  continue;
22189
22206
  }
22190
- const id = basename(entry.name, ".yaml");
22207
+ const id = basename2(entry.name, ".yaml");
22191
22208
  if (kind === "model" && id === "inventory") continue;
22192
22209
  if (!resourceIdentifier(id)) {
22193
- issues.push(issue2("path", "resource_id_invalid", displayPath(root, join3(directory, entry.name)), `filename-derived identity ${id} is invalid or platform-reserved`));
22210
+ issues.push(issue2("path", "resource_id_invalid", displayPath(root, join4(directory, entry.name)), `filename-derived identity ${id} is invalid or platform-reserved`));
22194
22211
  continue;
22195
22212
  }
22196
22213
  const collision = [...resources.keys()].find((candidate) => candidate.toLocaleLowerCase("en-US") === id.toLocaleLowerCase("en-US"));
22197
22214
  if (collision) {
22198
- issues.push(issue2("path", "resource_id_collision", displayPath(root, join3(directory, entry.name)), `${id} case-folds to existing ${collision}`));
22215
+ issues.push(issue2("path", "resource_id_collision", displayPath(root, join4(directory, entry.name)), `${id} case-folds to existing ${collision}`));
22199
22216
  continue;
22200
22217
  }
22201
22218
  try {
22202
- const resource = readResource(registry, root, join3(directory, entry.name), `${logicalDirectory}/${id}.yaml`, kind, id);
22219
+ const resource = readResource(registry, root, join4(directory, entry.name), `${logicalDirectory}/${id}.yaml`, kind, id);
22203
22220
  resources.set(id, resource);
22204
22221
  } catch (error) {
22205
22222
  if (error instanceof VnextConfigError) issues.push(...error.issues);
@@ -22520,8 +22537,8 @@ function validateWorkflow(workflow, agents, models, repositories, gates, issues)
22520
22537
  const writable = Object.values(objectValue(step.repositories) ?? {}).filter((access) => access === "write").length;
22521
22538
  if (maxWriteRepositories > writable) issues.push(issue2("semantic", "write_repository_bound_invalid", file, `${stepId} maxWriteRepositories exceeds writable repository scope`));
22522
22539
  }
22523
- const join47 = objectValue(step.join);
22524
- const minimumPassed = join47 && typeof join47.minimumPassed === "number" ? join47.minimumPassed : void 0;
22540
+ const join48 = objectValue(step.join);
22541
+ const minimumPassed = join48 && typeof join48.minimumPassed === "number" ? join48.minimumPassed : void 0;
22525
22542
  if (minimumPassed !== void 0 && minimumPassed > maximum) issues.push(issue2("semantic", "join_impossible", file, `${stepId} minimumPassed exceeds assignment maximum`));
22526
22543
  const distinctBy = names(assignment?.distinctBy);
22527
22544
  if (distinctBy.length > 0) {
@@ -22735,11 +22752,11 @@ function validateBundle(project, repositories, agents, models, workflows, enviro
22735
22752
  if (!workflows.has(defaultWorkflow)) issues.push(issue2("reference", "default_workflow_unknown", project.logicalPath, `default workflow ${defaultWorkflow} does not exist`));
22736
22753
  for (const workflow of workflows.values()) validateWorkflow(workflow, agents, models, repositoryIds, gates, issues);
22737
22754
  if (projectRoot) {
22738
- const writerRolePath = join3(projectRoot, ".kxm", "roles", "writer.yaml");
22755
+ const writerRolePath = join4(projectRoot, ".kxm", "roles", "writer.yaml");
22739
22756
  const implementerAgent = agents.get("implementer") ?? agents.get("writer");
22740
22757
  if (existsSync4(writerRolePath) && implementerAgent) {
22741
22758
  try {
22742
- const rawRole = parseRestrictedYaml2(readFileSync3(writerRolePath, "utf8"));
22759
+ const rawRole = parseRestrictedYaml2(readFileSync4(writerRolePath, "utf8"));
22743
22760
  const roleObj = objectValue(rawRole);
22744
22761
  const rosterEntries = valuesOf(roleObj ?? {}, "roster").map((candidate) => objectValue(candidate)).filter((entry) => Boolean(entry));
22745
22762
  const enabledRosterModels = rosterEntries.filter((entry) => entry.enabled !== false).map((entry) => stringValue(entry.model)).filter((m2) => Boolean(m2));
@@ -22799,7 +22816,7 @@ function discoverGitRoot(start = process.cwd()) {
22799
22816
  }
22800
22817
  function discoverVnextProjectRoot(start = process.cwd()) {
22801
22818
  const gitRoot = discoverGitRoot(start);
22802
- return gitRoot && existsSync4(join3(gitRoot, ".kxm", "project.yaml")) ? gitRoot : void 0;
22819
+ return gitRoot && existsSync4(join4(gitRoot, ".kxm", "project.yaml")) ? gitRoot : void 0;
22803
22820
  }
22804
22821
  function assertNoRegisteredGates(options) {
22805
22822
  if ("registeredGates" in options) {
@@ -22816,7 +22833,7 @@ function loadVnextProject(projectRoot, options = {}) {
22816
22833
  migrationReceipt = receiptCheck.receipt;
22817
22834
  }
22818
22835
  const registry = new VnextSchemaRegistry(options.schemasDir);
22819
- const project = readResource(registry, root, join3(root, ".kxm", "project.yaml"), ".kxm/project.yaml", "project");
22836
+ const project = readResource(registry, root, join4(root, ".kxm", "project.yaml"), ".kxm/project.yaml", "project");
22820
22837
  const earlyIssues = [];
22821
22838
  validatePortablePaths(project, earlyIssues);
22822
22839
  const templateProvenance = readTemplateProvenance(registry, root);
@@ -22838,15 +22855,15 @@ function loadVnextProject(projectRoot, options = {}) {
22838
22855
  }
22839
22856
  }
22840
22857
  if (earlyIssues.length > 0) throw new VnextConfigError(earlyIssues);
22841
- const agents = listNamedResources(registry, root, join3(root, ".kxm", "agents"), ".kxm/agents", "agent");
22842
- const models = listNamedResources(registry, root, join3(root, ".kxm", "models"), ".kxm/models", "model");
22843
- const workflows = listNamedResources(registry, root, join3(root, ".kxm", "workflows"), ".kxm/workflows", "workflow");
22844
- const gatePath = join3(root, ".kxm", "gates.yaml");
22858
+ const agents = listNamedResources(registry, root, join4(root, ".kxm", "agents"), ".kxm/agents", "agent");
22859
+ const models = listNamedResources(registry, root, join4(root, ".kxm", "models"), ".kxm/models", "model");
22860
+ const workflows = listNamedResources(registry, root, join4(root, ".kxm", "workflows"), ".kxm/workflows", "workflow");
22861
+ const gatePath = join4(root, ".kxm", "gates.yaml");
22845
22862
  const gateRegistry = existsSync4(gatePath) ? readResource(registry, root, gatePath, ".kxm/gates.yaml", "gate-registry") : void 0;
22846
22863
  const environments = [];
22847
22864
  const repositories = /* @__PURE__ */ new Map();
22848
22865
  const loadIssues = [];
22849
- const projectEnvironment = join3(root, ".kxm", "project", "env.yaml");
22866
+ const projectEnvironment = join4(root, ".kxm", "project", "env.yaml");
22850
22867
  if (existsSync4(projectEnvironment)) {
22851
22868
  try {
22852
22869
  environments.push(readResource(registry, root, projectEnvironment, ".kxm/project/env.yaml", "environment"));
@@ -22912,7 +22929,7 @@ function loadVnextProject(projectRoot, options = {}) {
22912
22929
  continue;
22913
22930
  }
22914
22931
  seenBindings.set(foldedBinding, repositoryId);
22915
- const repositoryFile = join3(binding, ".kxm", "repo", "repo.yaml");
22932
+ const repositoryFile = join4(binding, ".kxm", "repo", "repo.yaml");
22916
22933
  let definitionValidated = false;
22917
22934
  if (existsSync4(repositoryFile)) {
22918
22935
  try {
@@ -22930,7 +22947,7 @@ function loadVnextProject(projectRoot, options = {}) {
22930
22947
  } else if (required || hasLocalBinding) {
22931
22948
  loadIssues.push(issue2("discovery", "repository_definition_missing", `.kxm/repositories/${repositoryId}/repo.yaml`, `${hasLocalBinding ? "explicit" : "required"} repository ${repositoryId} has no repo.yaml`));
22932
22949
  }
22933
- const environmentFile = join3(binding, ".kxm", "repo", "env.yaml");
22950
+ const environmentFile = join4(binding, ".kxm", "repo", "env.yaml");
22934
22951
  if (existsSync4(environmentFile)) {
22935
22952
  if (!definitionValidated) {
22936
22953
  loadIssues.push(issue2("reference", "repository_environment_without_definition", `.kxm/repositories/${repositoryId}/env.yaml`, `repository ${repositoryId} environment requires a validated matching repo.yaml`));
@@ -23009,20 +23026,20 @@ function legacyInputsAt(root) {
23009
23026
  ".kxm/config/workflows",
23010
23027
  ".kxm/state/kxm.db"
23011
23028
  ];
23012
- return candidates.filter((candidate) => existsSync4(join3(root, ...candidate.split("/"))));
23029
+ return candidates.filter((candidate) => existsSync4(join4(root, ...candidate.split("/"))));
23013
23030
  }
23014
23031
  var VNEXT_MIGRATION_RECEIPT_PATH = ".kxm/migration-receipt.yaml";
23015
23032
  var LEGACY_CONFIG_FILES = [".kxm/config/agents.json", ".kxm/config/gates.json"];
23016
23033
  function legacyConfigFilesAt(root) {
23017
23034
  const files = [];
23018
23035
  for (const component of [".kxm", ".kxm/config"]) {
23019
- const absolute = join3(root, ...component.split("/"));
23036
+ const absolute = join4(root, ...component.split("/"));
23020
23037
  if (existsSync4(absolute) && lstatSync(absolute).isSymbolicLink()) return [component];
23021
23038
  }
23022
23039
  for (const candidate of LEGACY_CONFIG_FILES) {
23023
- if (existsSync4(join3(root, ...candidate.split("/")))) files.push(candidate);
23040
+ if (existsSync4(join4(root, ...candidate.split("/")))) files.push(candidate);
23024
23041
  }
23025
- const workflowsDir = join3(root, ".kxm", "config", "workflows");
23042
+ const workflowsDir = join4(root, ".kxm", "config", "workflows");
23026
23043
  if (existsSync4(workflowsDir)) {
23027
23044
  const stat = lstatSync(workflowsDir);
23028
23045
  if (stat.isSymbolicLink()) {
@@ -23038,9 +23055,9 @@ function legacyConfigFilesAt(root) {
23038
23055
  return files;
23039
23056
  }
23040
23057
  function hashFileRecord(root, relativePath) {
23041
- const absolute = join3(root, ...relativePath.split("/"));
23058
+ const absolute = join4(root, ...relativePath.split("/"));
23042
23059
  if (!existsSync4(absolute)) return void 0;
23043
- const bytes = readFileSync3(absolute);
23060
+ const bytes = readFileSync4(absolute);
23044
23061
  return {
23045
23062
  path: relativePath,
23046
23063
  sha256: `sha256:${createHash6("sha256").update(bytes).digest("hex")}`,
@@ -23052,7 +23069,7 @@ function migrationReceiptSelfHash(receipt) {
23052
23069
  return `sha256:${createHash6("sha256").update(vnextCanonicalJson(unsigned), "utf8").digest("hex")}`;
23053
23070
  }
23054
23071
  function readVnextMigrationReceipt(root, options = {}) {
23055
- const receiptPath = join3(root, ...VNEXT_MIGRATION_RECEIPT_PATH.split("/"));
23072
+ const receiptPath = join4(root, ...VNEXT_MIGRATION_RECEIPT_PATH.split("/"));
23056
23073
  const legacyFiles = legacyConfigFilesAt(root);
23057
23074
  if (!existsSync4(receiptPath)) {
23058
23075
  return {
@@ -23065,7 +23082,7 @@ function readVnextMigrationReceipt(root, options = {}) {
23065
23082
  }
23066
23083
  let receipt;
23067
23084
  try {
23068
- receipt = parseRestrictedYaml2(readFileSync3(receiptPath), VNEXT_MIGRATION_RECEIPT_PATH);
23085
+ receipt = parseRestrictedYaml2(readFileSync4(receiptPath), VNEXT_MIGRATION_RECEIPT_PATH);
23069
23086
  } catch (error) {
23070
23087
  if (error instanceof VnextConfigError) return { issues: [...error.issues] };
23071
23088
  throw error;
@@ -23126,7 +23143,7 @@ function planVnextInitialization(start = process.cwd(), options = {}) {
23126
23143
  }
23127
23144
  const gitRoot = discoverGitRoot(inspectedFrom);
23128
23145
  const candidateRoot = gitRoot ?? inspectedFrom;
23129
- if (existsSync4(join3(candidateRoot, ".kxm"))) {
23146
+ if (existsSync4(join4(candidateRoot, ".kxm"))) {
23130
23147
  return {
23131
23148
  mode: "repair",
23132
23149
  inspectedFrom,
@@ -23142,14 +23159,14 @@ function planVnextInitialization(start = process.cwd(), options = {}) {
23142
23159
  // plugins/kxm/src/vnext-runtime-supervisor.ts
23143
23160
  import { spawn as spawn2 } from "node:child_process";
23144
23161
  import { createHash as createHash11, createHmac, randomBytes as randomBytes2, timingSafeEqual as timingSafeEqual2 } from "node:crypto";
23145
- import { chmodSync as chmodSync4, existsSync as existsSync10, lstatSync as lstatSync6, mkdirSync as mkdirSync7, readFileSync as readFileSync9, renameSync as renameSync2, rmSync as rmSync2, writeFileSync as writeFileSync7 } from "node:fs";
23146
- import { dirname as dirname6, isAbsolute as isAbsolute4, join as join9, resolve as resolve7 } from "node:path";
23162
+ import { chmodSync as chmodSync4, existsSync as existsSync10, lstatSync as lstatSync6, mkdirSync as mkdirSync7, readFileSync as readFileSync10, renameSync as renameSync2, rmSync as rmSync2, writeFileSync as writeFileSync7 } from "node:fs";
23163
+ import { dirname as dirname6, isAbsolute as isAbsolute4, join as join10, resolve as resolve7 } from "node:path";
23147
23164
  import { fileURLToPath as fileURLToPath2 } from "node:url";
23148
23165
 
23149
23166
  // plugins/kxm/src/vnext-runtime-store.ts
23150
23167
  import { createHash as createHash9, randomUUID as randomUUID4 } from "node:crypto";
23151
- import { existsSync as existsSync7, lstatSync as lstatSync4, mkdirSync as mkdirSync5, readFileSync as readFileSync6, realpathSync as realpathSync3, writeFileSync as writeFileSync5 } from "node:fs";
23152
- import { dirname as dirname5, join as join6, resolve as resolve5 } from "node:path";
23168
+ import { existsSync as existsSync7, lstatSync as lstatSync4, mkdirSync as mkdirSync5, readFileSync as readFileSync7, realpathSync as realpathSync3, writeFileSync as writeFileSync5 } from "node:fs";
23169
+ import { dirname as dirname5, join as join7, resolve as resolve5 } from "node:path";
23153
23170
 
23154
23171
  // plugins/kxm/src/vnext-bindings.ts
23155
23172
  import { spawnSync as spawnSync3 } from "node:child_process";
@@ -23162,7 +23179,7 @@ import {
23162
23179
  lstatSync as lstatSync2,
23163
23180
  mkdirSync as mkdirSync3,
23164
23181
  openSync,
23165
- readFileSync as readFileSync4,
23182
+ readFileSync as readFileSync5,
23166
23183
  realpathSync as realpathSync2,
23167
23184
  renameSync,
23168
23185
  rmSync,
@@ -23210,7 +23227,7 @@ var DatabaseSync = class {
23210
23227
  };
23211
23228
 
23212
23229
  // plugins/kxm/src/vnext-bindings.ts
23213
- import { dirname as dirname3, isAbsolute as isAbsolute2, join as join4, parse, relative as relative2, resolve as resolve3, sep as sep2 } from "node:path";
23230
+ import { dirname as dirname3, isAbsolute as isAbsolute2, join as join5, parse, relative as relative2, resolve as resolve3, sep as sep2 } from "node:path";
23214
23231
  var MAX_BINDING_RECORD_BYTES = 256 * 1024;
23215
23232
  var BINDING_LABEL = "Runtime-local repository bindings";
23216
23233
  var activeLocks = /* @__PURE__ */ new WeakSet();
@@ -23244,12 +23261,12 @@ function vnextUserStateRoot(options = {}) {
23244
23261
  }
23245
23262
  if (platform === "win32") {
23246
23263
  const localAppData = env.LOCALAPPDATA?.trim();
23247
- const base2 = localAppData && isAbsolute2(localAppData) ? localAppData : join4(home, "AppData", "Local");
23264
+ const base2 = localAppData && isAbsolute2(localAppData) ? localAppData : join5(home, "AppData", "Local");
23248
23265
  return resolve3(base2, "KXM");
23249
23266
  }
23250
23267
  if (platform === "darwin") return resolve3(home, "Library", "Application Support", "KXM");
23251
23268
  const xdgState = env.XDG_STATE_HOME?.trim();
23252
- const base = xdgState && isAbsolute2(xdgState) ? xdgState : join4(home, ".local", "state");
23269
+ const base = xdgState && isAbsolute2(xdgState) ? xdgState : join5(home, ".local", "state");
23253
23270
  return resolve3(base, "kxm");
23254
23271
  }
23255
23272
  function projectBindingKey(projectRoot, platform = process.platform) {
@@ -23259,7 +23276,7 @@ function projectBindingKey(projectRoot, platform = process.platform) {
23259
23276
  }
23260
23277
  function vnextLocalBindingFile(projectRoot, options = {}) {
23261
23278
  const stateRoot = vnextUserStateRoot(options);
23262
- return join4(stateRoot, "projects", projectBindingKey(projectRoot, options.platform), "repository-bindings.json");
23279
+ return join5(stateRoot, "projects", projectBindingKey(projectRoot, options.platform), "repository-bindings.json");
23263
23280
  }
23264
23281
  function checkedDirectory(path4, description) {
23265
23282
  if (!existsSync5(path4)) return false;
@@ -23270,7 +23287,7 @@ function checkedDirectory(path4, description) {
23270
23287
  return true;
23271
23288
  }
23272
23289
  function existingBindingDirectory(file, stateRoot) {
23273
- const projects = join4(stateRoot, "projects");
23290
+ const projects = join5(stateRoot, "projects");
23274
23291
  const project = dirname3(file);
23275
23292
  if (!checkedDirectory(stateRoot, "local state root")) return false;
23276
23293
  if (!checkedDirectory(projects, "local projects directory")) return false;
@@ -23305,7 +23322,7 @@ function readVnextLocalBindings(projectRoot, options = {}) {
23305
23322
  if (stat.size > MAX_BINDING_RECORD_BYTES) {
23306
23323
  bindingError("parse", "local_binding_file_too_large", `binding record exceeds ${MAX_BINDING_RECORD_BYTES} bytes`);
23307
23324
  }
23308
- const parsed = parseRestrictedYaml2(readFileSync4(file), BINDING_LABEL);
23325
+ const parsed = parseRestrictedYaml2(readFileSync5(file), BINDING_LABEL);
23309
23326
  return asRecord2(parsed, file, root, options.schemasDir);
23310
23327
  }
23311
23328
  function normalizedRecord(projectRoot, projectId, repositories, schemasDir) {
@@ -23373,7 +23390,7 @@ function ensureBindingDirectory(file, stateRoot) {
23373
23390
  ensureDurableDirectory(stateRoot, "local state root");
23374
23391
  checkedDirectory(stateRoot, "local state root");
23375
23392
  syncDirectory(stateRoot);
23376
- const projects = join4(stateRoot, "projects");
23393
+ const projects = join5(stateRoot, "projects");
23377
23394
  createDirectoryIfMissing(projects);
23378
23395
  checkedDirectory(projects, "local projects directory");
23379
23396
  const project = dirname3(file);
@@ -23386,7 +23403,7 @@ function assertNoLinkedDirectoryComponents(path4, description) {
23386
23403
  let current = filesystemRoot;
23387
23404
  const remainder = relative2(filesystemRoot, absolute);
23388
23405
  for (const segment of remainder.split(sep2).filter(Boolean)) {
23389
- current = join4(current, segment);
23406
+ current = join5(current, segment);
23390
23407
  const stat = lstatSync2(current);
23391
23408
  if (stat.isSymbolicLink() || !stat.isDirectory()) {
23392
23409
  bindingError("path", "project_operation_lock_parent_invalid", `${description} contains a linked or non-directory component`);
@@ -23413,7 +23430,7 @@ function projectOperationLockFile(projectRoot) {
23413
23430
  if (gitStat.isSymbolicLink() || !gitStat.isDirectory()) {
23414
23431
  bindingError("path", "project_operation_lock_parent_invalid", "authoritative Git metadata must resolve to a regular directory");
23415
23432
  }
23416
- const lockDirectory = join4(gitDirectory, "kxm");
23433
+ const lockDirectory = join5(gitDirectory, "kxm");
23417
23434
  if (existsSync5(lockDirectory)) {
23418
23435
  const stat = lstatSync2(lockDirectory);
23419
23436
  if (stat.isSymbolicLink() || !stat.isDirectory()) {
@@ -23423,7 +23440,7 @@ function projectOperationLockFile(projectRoot) {
23423
23440
  mkdirSync3(lockDirectory, { mode: 448 });
23424
23441
  syncDirectory(gitDirectory);
23425
23442
  }
23426
- return join4(lockDirectory, "project-operation-lock.sqlite");
23443
+ return join5(lockDirectory, "project-operation-lock.sqlite");
23427
23444
  }
23428
23445
  function withVnextLocalBindingLock(projectRoot, options, callback) {
23429
23446
  const root = resolve3(projectRoot);
@@ -23482,7 +23499,7 @@ function writeVnextLocalBindings(projectRoot, projectId, repositories, options =
23482
23499
  const { file, record } = planned;
23483
23500
  if (!planned.written) return planned;
23484
23501
  ensureBindingDirectory(file, vnextUserStateRoot(options));
23485
- const temporary = join4(dirname3(file), `.repository-bindings-${process.pid}-${randomUUID3()}.tmp`);
23502
+ const temporary = join5(dirname3(file), `.repository-bindings-${process.pid}-${randomUUID3()}.tmp`);
23486
23503
  let descriptor;
23487
23504
  try {
23488
23505
  descriptor = openSync(temporary, "wx", 384);
@@ -23513,11 +23530,11 @@ import {
23513
23530
  lstatSync as lstatSync3,
23514
23531
  mkdirSync as mkdirSync4,
23515
23532
  readdirSync as readdirSync2,
23516
- readFileSync as readFileSync5,
23533
+ readFileSync as readFileSync6,
23517
23534
  unlinkSync as unlinkSync2,
23518
23535
  writeFileSync as writeFileSync4
23519
23536
  } from "node:fs";
23520
- import { basename as basename2, dirname as dirname4, join as join5, resolve as resolve4 } from "node:path";
23537
+ import { basename as basename3, dirname as dirname4, join as join6, resolve as resolve4 } from "node:path";
23521
23538
  function databaseError(code, file, message) {
23522
23539
  const issue3 = { phase: "semantic", code, file, message };
23523
23540
  return new VnextConfigError([issue3]);
@@ -23666,7 +23683,7 @@ function checkIntegrity(database) {
23666
23683
  return rows.length === 1 && rows[0]?.integrity_check === "ok";
23667
23684
  }
23668
23685
  function fileSha256(filePath) {
23669
- const bytes = readFileSync5(filePath);
23686
+ const bytes = readFileSync6(filePath);
23670
23687
  return `sha256:${createHash8("sha256").update(bytes).digest("hex")}`;
23671
23688
  }
23672
23689
  function backupDatabaseFile(sourcePath, targetPath, storeId) {
@@ -23713,7 +23730,7 @@ function backupDatabaseFile(sourcePath, targetPath, storeId) {
23713
23730
  return {
23714
23731
  storeId,
23715
23732
  sourcePath: resolvedSource,
23716
- backupFile: basename2(resolvedTarget),
23733
+ backupFile: basename3(resolvedTarget),
23717
23734
  schemaVersion,
23718
23735
  sha256,
23719
23736
  bytes,
@@ -23779,7 +23796,7 @@ function restoreDatabaseFile(backupPath, targetPath, storeId, expectedSchemaVers
23779
23796
  return {
23780
23797
  storeId,
23781
23798
  sourcePath: resolvedTarget,
23782
- backupFile: basename2(resolvedBackup),
23799
+ backupFile: basename3(resolvedBackup),
23783
23800
  schemaVersion,
23784
23801
  integrity: "ok"
23785
23802
  };
@@ -23787,19 +23804,19 @@ function restoreDatabaseFile(backupPath, targetPath, storeId, expectedSchemaVers
23787
23804
  function discoverProjectStores(projectRoot, options = {}) {
23788
23805
  const root = resolve4(projectRoot);
23789
23806
  const stores = [];
23790
- const hubPath = options.hubDataPath ? resolve4(options.hubDataPath) : join5(root, ".kxm", "state", "kxm.db");
23807
+ const hubPath = options.hubDataPath ? resolve4(options.hubDataPath) : join6(root, ".kxm", "state", "kxm.db");
23791
23808
  if (existsSync6(hubPath)) {
23792
23809
  stores.push({ storeId: "hub-store", sourcePath: hubPath, maxSupportedVersion: 3 });
23793
23810
  }
23794
- const registryPath = join5(root, ".kxm", "runtime", "registry.db");
23811
+ const registryPath = join6(root, ".kxm", "runtime", "registry.db");
23795
23812
  if (existsSync6(registryPath)) {
23796
23813
  stores.push({ storeId: "registry", sourcePath: registryPath, maxSupportedVersion: 1 });
23797
23814
  }
23798
- const bindingsPath = join5(root, ".kxm", "runtime", "bindings.db");
23815
+ const bindingsPath = join6(root, ".kxm", "runtime", "bindings.db");
23799
23816
  if (existsSync6(bindingsPath)) {
23800
23817
  stores.push({ storeId: "binding-store", sourcePath: bindingsPath, maxSupportedVersion: 1 });
23801
23818
  }
23802
- const eventsDir = join5(root, ".kxm", "runtime", "events");
23819
+ const eventsDir = join6(root, ".kxm", "runtime", "events");
23803
23820
  if (existsSync6(eventsDir)) {
23804
23821
  const entries = readdirSync2(eventsDir, { withFileTypes: true });
23805
23822
  for (const entry of entries) {
@@ -23807,7 +23824,7 @@ function discoverProjectStores(projectRoot, options = {}) {
23807
23824
  const key = entry.name.replace(/\.db$/, "");
23808
23825
  stores.push({
23809
23826
  storeId: `events:${key}`,
23810
- sourcePath: join5(eventsDir, entry.name),
23827
+ sourcePath: join6(eventsDir, entry.name),
23811
23828
  maxSupportedVersion: 3
23812
23829
  });
23813
23830
  }
@@ -23826,20 +23843,20 @@ function createBackup(options = {}) {
23826
23843
  const now = /* @__PURE__ */ new Date();
23827
23844
  const timestamp = now.toISOString().replace(/[:.]/g, "-");
23828
23845
  const backupId = `bk_${randomBytes(8).toString("hex")}`;
23829
- const outDir = options.outDir ? resolve4(options.outDir) : join5(projectRoot, ".kxm", "backups", `backup-${timestamp}`);
23846
+ const outDir = options.outDir ? resolve4(options.outDir) : join6(projectRoot, ".kxm", "backups", `backup-${timestamp}`);
23830
23847
  if (!existsSync6(outDir)) {
23831
23848
  mkdirSync4(outDir, { recursive: true, mode: 448 });
23832
23849
  }
23833
23850
  const backedUpStores = [];
23834
23851
  const usedFilenames = /* @__PURE__ */ new Set();
23835
23852
  for (const store of stores) {
23836
- let filename = basename2(store.sourcePath);
23853
+ let filename = basename3(store.sourcePath);
23837
23854
  if (usedFilenames.has(filename)) {
23838
23855
  const sanitizedId = store.storeId.replace(/[^a-zA-Z0-9_.-]/g, "_");
23839
23856
  filename = `${sanitizedId}-${filename}`;
23840
23857
  }
23841
23858
  usedFilenames.add(filename);
23842
- const targetFile2 = join5(outDir, filename);
23859
+ const targetFile2 = join6(outDir, filename);
23843
23860
  const record = backupDatabaseFile(store.sourcePath, targetFile2, store.storeId);
23844
23861
  backedUpStores.push(record);
23845
23862
  }
@@ -23854,7 +23871,7 @@ function createBackup(options = {}) {
23854
23871
  const manifestSha256 = `sha256:${createHash8("sha256").update(manifestJson, "utf8").digest("hex")}`;
23855
23872
  manifest.manifestSha256 = manifestSha256;
23856
23873
  const finalJson = JSON.stringify(manifest, null, 2) + "\n";
23857
- const manifestPath = join5(outDir, "manifest.json");
23874
+ const manifestPath = join6(outDir, "manifest.json");
23858
23875
  writeFileSync4(manifestPath, finalJson, "utf8");
23859
23876
  return { manifest, outDir };
23860
23877
  }
@@ -23865,13 +23882,13 @@ function restoreBackup(manifestPathOrDir, options = {}) {
23865
23882
  throw databaseError("runtime_path_invalid", manifestPath, `manifest path ${manifestPath} does not exist`);
23866
23883
  }
23867
23884
  if (stat.isDirectory()) {
23868
- manifestPath = join5(manifestPath, "manifest.json");
23885
+ manifestPath = join6(manifestPath, "manifest.json");
23869
23886
  }
23870
23887
  if (!existsSync6(manifestPath)) {
23871
23888
  throw databaseError("runtime_path_invalid", manifestPath, `backup manifest ${manifestPath} not found`);
23872
23889
  }
23873
23890
  const manifestDir = dirname4(manifestPath);
23874
- const rawText = readFileSync5(manifestPath, "utf8");
23891
+ const rawText = readFileSync6(manifestPath, "utf8");
23875
23892
  let manifest;
23876
23893
  try {
23877
23894
  manifest = JSON.parse(rawText);
@@ -23883,7 +23900,7 @@ function restoreBackup(manifestPathOrDir, options = {}) {
23883
23900
  }
23884
23901
  const restoredStores = [];
23885
23902
  for (const store of manifest.stores) {
23886
- const backupFilePath = join5(manifestDir, store.backupFile);
23903
+ const backupFilePath = join6(manifestDir, store.backupFile);
23887
23904
  if (!existsSync6(backupFilePath)) {
23888
23905
  throw databaseError("restore_file_missing", backupFilePath, `backup file ${store.backupFile} missing from ${manifestDir}`);
23889
23906
  }
@@ -23902,7 +23919,7 @@ function restoreBackup(manifestPathOrDir, options = {}) {
23902
23919
  let targetPath = store.sourcePath;
23903
23920
  if (options.projectRoot && manifest.projectRoot && targetPath.startsWith(manifest.projectRoot)) {
23904
23921
  const rel = targetPath.slice(manifest.projectRoot.length).replace(/^[\\/]+/, "");
23905
- targetPath = join5(resolve4(options.projectRoot), rel);
23922
+ targetPath = join6(resolve4(options.projectRoot), rel);
23906
23923
  }
23907
23924
  const result = restoreDatabaseFile(
23908
23925
  backupFilePath,
@@ -23923,12 +23940,12 @@ function restoreBackup(manifestPathOrDir, options = {}) {
23923
23940
  // plugins/kxm/src/vnext-runtime-store.ts
23924
23941
  function vnextRuntimePaths(options = {}) {
23925
23942
  const stateRoot = options.stateRoot ? resolve5(options.stateRoot) : vnextUserStateRoot({ ...options.env ? { env: options.env } : {}, ...options.homeDir ? { homeDir: options.homeDir } : {} });
23926
- const runtimeDir = join6(stateRoot, "runtime");
23943
+ const runtimeDir = join7(stateRoot, "runtime");
23927
23944
  return {
23928
23945
  stateRoot,
23929
23946
  runtimeDir,
23930
- registryDb: join6(runtimeDir, "registry.db"),
23931
- projectsDir: join6(runtimeDir, "projects")
23947
+ registryDb: join7(runtimeDir, "registry.db"),
23948
+ projectsDir: join7(runtimeDir, "projects")
23932
23949
  };
23933
23950
  }
23934
23951
  function runtimeIssue(phase, code, file, message) {
@@ -24287,7 +24304,7 @@ function compileStep(step, index, stepIndex, requirePlanHash, sink) {
24287
24304
  const maxAttempts = compileCountField(step.maxAttempts, 1, `${id}.maxAttempts`, id, sink);
24288
24305
  const timeoutMs = compileOptionalDuration(step.timeoutMs, `${id}.timeoutMs`, id, sink);
24289
24306
  const assignments = compileAssignments(step, id, agent, sink);
24290
- const join47 = compileJoin(step, id, sink);
24307
+ const join48 = compileJoin(step, id, sink);
24291
24308
  const requiredEvidence = compileEvidence(step, id, sink);
24292
24309
  const transitions = compileTransitions(step, id, index, stepIndex, sink);
24293
24310
  const outcomes = Object.keys(transitions).sort(compareCodeUnits4);
@@ -24315,7 +24332,7 @@ function compileStep(step, index, stepIndex, requirePlanHash, sink) {
24315
24332
  transitions: orderedTransitions,
24316
24333
  requiresPlanHash: requirePlanHash.includes(id),
24317
24334
  assignments,
24318
- join: join47
24335
+ join: join48
24319
24336
  };
24320
24337
  if (kind === "agent" || kind === "moa") {
24321
24338
  if (!agent) return void 0;
@@ -24365,15 +24382,15 @@ function compileAssignments(step, stepId, primaryAgentId, sink) {
24365
24382
  };
24366
24383
  }
24367
24384
  function compileJoin(step, stepId, sink) {
24368
- const join47 = objectValue2(step.join);
24369
- if (!join47) return { strategy: "all" };
24370
- const declared = stringValue2(join47.strategy);
24385
+ const join48 = objectValue2(step.join);
24386
+ if (!join48) return { strategy: "all" };
24387
+ const declared = stringValue2(join48.strategy);
24371
24388
  const strategy = declared && JOIN_STRATEGIES.has(declared) ? declared : "all";
24372
- const minimumPassed = compileOptionalCount(join47.minimumPassed, `${stepId}.join.minimumPassed`, stepId, sink);
24389
+ const minimumPassed = compileOptionalCount(join48.minimumPassed, `${stepId}.join.minimumPassed`, stepId, sink);
24373
24390
  const compiled = {
24374
24391
  strategy,
24375
24392
  ...minimumPassed !== void 0 ? { minimumPassed } : {},
24376
- ...typeof join47.cancelRemaining === "boolean" ? { cancelRemaining: join47.cancelRemaining } : {}
24393
+ ...typeof join48.cancelRemaining === "boolean" ? { cancelRemaining: join48.cancelRemaining } : {}
24377
24394
  };
24378
24395
  return compiled;
24379
24396
  }
@@ -24653,8 +24670,8 @@ var RECORD_LIMIT = 16 * 1024 * 1024;
24653
24670
  // plugins/kxm/src/prices.ts
24654
24671
  var import_yaml3 = __toESM(require_dist(), 1);
24655
24672
  import { createHash as createHash10 } from "node:crypto";
24656
- import { existsSync as existsSync8, readFileSync as readFileSync7, statSync } from "node:fs";
24657
- import { join as join7 } from "node:path";
24673
+ import { existsSync as existsSync8, readFileSync as readFileSync8, statSync } from "node:fs";
24674
+ import { join as join8 } from "node:path";
24658
24675
 
24659
24676
  // plugins/kxm/src/price-calc.ts
24660
24677
  var PRICES_SCHEMA = "kxm.prices.v1";
@@ -24806,11 +24823,11 @@ function parsePriceCatalog(text) {
24806
24823
  return catalog;
24807
24824
  }
24808
24825
  function loadPriceCatalog(rootOrPath) {
24809
- const candidatePath = existsSync8(join7(rootOrPath, ".kxm", "prices.yaml")) ? join7(rootOrPath, ".kxm", "prices.yaml") : existsSync8(join7(rootOrPath, "prices.yaml")) ? join7(rootOrPath, "prices.yaml") : existsSync8(rootOrPath) && statSync(rootOrPath).isFile() ? rootOrPath : void 0;
24826
+ const candidatePath = existsSync8(join8(rootOrPath, ".kxm", "prices.yaml")) ? join8(rootOrPath, ".kxm", "prices.yaml") : existsSync8(join8(rootOrPath, "prices.yaml")) ? join8(rootOrPath, "prices.yaml") : existsSync8(rootOrPath) && statSync(rootOrPath).isFile() ? rootOrPath : void 0;
24810
24827
  if (!candidatePath || !existsSync8(candidatePath)) {
24811
24828
  return void 0;
24812
24829
  }
24813
- const content = readFileSync7(candidatePath, "utf8");
24830
+ const content = readFileSync8(candidatePath, "utf8");
24814
24831
  return parsePriceCatalog(content);
24815
24832
  }
24816
24833
  function loadPriceCatalogForEstimate(options) {
@@ -24831,13 +24848,13 @@ var import_yaml5 = __toESM(require_dist(), 1);
24831
24848
 
24832
24849
  // plugins/kxm/src/producers.ts
24833
24850
  var import_yaml4 = __toESM(require_dist(), 1);
24834
- import { existsSync as existsSync9, readFileSync as readFileSync8, mkdirSync as mkdirSync6, writeFileSync as writeFileSync6, readdirSync as readdirSync3 } from "node:fs";
24835
- import { join as join8 } from "node:path";
24851
+ import { existsSync as existsSync9, readFileSync as readFileSync9, mkdirSync as mkdirSync6, writeFileSync as writeFileSync6, readdirSync as readdirSync3 } from "node:fs";
24852
+ import { join as join9 } from "node:path";
24836
24853
  var empty = () => ({ schema: "kxm.producers.v1", updatedAt: (/* @__PURE__ */ new Date()).toISOString(), promoted: [], demoted: [], enabled: [], disabled: [], roles: {} });
24837
24854
  function loadProducerPolicy(root) {
24838
- const path4 = join8(root, ".kxm", "producers.yaml");
24855
+ const path4 = join9(root, ".kxm", "producers.yaml");
24839
24856
  if (!existsSync9(path4)) return empty();
24840
- const value = (0, import_yaml4.parse)(readFileSync8(path4, "utf8"));
24857
+ const value = (0, import_yaml4.parse)(readFileSync9(path4, "utf8"));
24841
24858
  if (value?.schema !== "kxm.producers.v1" || !Array.isArray(value.promoted) || !Array.isArray(value.demoted)) throw new Error("invalid .kxm/producers.yaml");
24842
24859
  return { schema: "kxm.producers.v1", updatedAt: typeof value.updatedAt === "string" ? value.updatedAt : (/* @__PURE__ */ new Date()).toISOString(), promoted: value.promoted.filter((x2) => typeof x2 === "string"), demoted: value.demoted.filter((x2) => typeof x2 === "string"), enabled: Array.isArray(value.enabled) ? value.enabled.filter((x2) => typeof x2 === "string") : [], disabled: Array.isArray(value.disabled) ? value.disabled.filter((x2) => typeof x2 === "string") : [], roles: value.roles && typeof value.roles === "object" ? Object.fromEntries(Object.entries(value.roles).filter(([, v2]) => Array.isArray(v2)).map(([k, v2]) => [k, v2.filter((x2) => typeof x2 === "string")])) : {} };
24843
24860
  }
@@ -24847,8 +24864,8 @@ function updateProducer(root, model, status) {
24847
24864
  policy.demoted = policy.demoted.filter((x2) => x2 !== model);
24848
24865
  policy[status].push(model);
24849
24866
  policy.updatedAt = (/* @__PURE__ */ new Date()).toISOString();
24850
- mkdirSync6(join8(root, ".kxm"), { recursive: true });
24851
- writeFileSync6(join8(root, ".kxm", "producers.yaml"), (0, import_yaml4.stringify)(policy), "utf8");
24867
+ mkdirSync6(join9(root, ".kxm"), { recursive: true });
24868
+ writeFileSync6(join9(root, ".kxm", "producers.yaml"), (0, import_yaml4.stringify)(policy), "utf8");
24852
24869
  return policy;
24853
24870
  }
24854
24871
  function setModelState(root, model, state, role, removeRole2 = false) {
@@ -24858,10 +24875,10 @@ function setModelState(root, model, state, role, removeRole2 = false) {
24858
24875
  policy[state].push(model);
24859
24876
  if (role) {
24860
24877
  if (!/^[a-z][a-z0-9_-]{0,63}$/i.test(role)) throw new Error("invalid role id");
24861
- const rolePath = join8(root, ".kxm", "roles", `${role}.yaml`);
24878
+ const rolePath = join9(root, ".kxm", "roles", `${role}.yaml`);
24862
24879
  let roleFile = {};
24863
24880
  if (existsSync9(rolePath)) {
24864
- const parsed = (0, import_yaml4.parse)(readFileSync8(rolePath, "utf8"));
24881
+ const parsed = (0, import_yaml4.parse)(readFileSync9(rolePath, "utf8"));
24865
24882
  if (parsed && typeof parsed === "object" && !Array.isArray(parsed)) roleFile = parsed;
24866
24883
  }
24867
24884
  const roster = Array.isArray(roleFile.roster) ? roleFile.roster.filter((entry) => Boolean(entry) && typeof entry === "object" && !Array.isArray(entry)) : [];
@@ -24872,29 +24889,29 @@ function setModelState(root, model, state, role, removeRole2 = false) {
24872
24889
  roleFile.schema ??= "kxm.role.v1";
24873
24890
  roleFile.id ??= role;
24874
24891
  roleFile.roster = roster;
24875
- mkdirSync6(join8(root, ".kxm", "roles"), { recursive: true });
24892
+ mkdirSync6(join9(root, ".kxm", "roles"), { recursive: true });
24876
24893
  writeFileSync6(rolePath, (0, import_yaml4.stringify)(roleFile), "utf8");
24877
24894
  }
24878
24895
  policy.updatedAt = (/* @__PURE__ */ new Date()).toISOString();
24879
- mkdirSync6(join8(root, ".kxm"), { recursive: true });
24880
- writeFileSync6(join8(root, ".kxm", "producers.yaml"), (0, import_yaml4.stringify)(policy), "utf8");
24896
+ mkdirSync6(join9(root, ".kxm"), { recursive: true });
24897
+ writeFileSync6(join9(root, ".kxm", "producers.yaml"), (0, import_yaml4.stringify)(policy), "utf8");
24881
24898
  return policy;
24882
24899
  }
24883
24900
  function listRoleBindings(root) {
24884
- const dir = join8(root, ".kxm", "roles");
24901
+ const dir = join9(root, ".kxm", "roles");
24885
24902
  const result = {};
24886
24903
  if (!existsSync9(dir)) return result;
24887
24904
  for (const file of readdirSync3(dir).filter((name) => name.endsWith(".yaml"))) {
24888
24905
  const role = file.slice(0, -5);
24889
- const value = (0, import_yaml4.parse)(readFileSync8(join8(dir, file), "utf8"));
24906
+ const value = (0, import_yaml4.parse)(readFileSync9(join9(dir, file), "utf8"));
24890
24907
  result[role] = (value.roster ?? []).map((entry) => entry.model).filter((model) => typeof model === "string");
24891
24908
  }
24892
24909
  return result;
24893
24910
  }
24894
24911
  function listInventoryModels(root) {
24895
- const path4 = join8(root, ".kxm", "models", "inventory.yaml");
24912
+ const path4 = join9(root, ".kxm", "models", "inventory.yaml");
24896
24913
  if (!existsSync9(path4)) return [];
24897
- const value = (0, import_yaml4.parse)(readFileSync8(path4, "utf8"));
24914
+ const value = (0, import_yaml4.parse)(readFileSync9(path4, "utf8"));
24898
24915
  return (value.models ?? []).map((m2) => m2.id).filter((id) => typeof id === "string");
24899
24916
  }
24900
24917
 
@@ -25528,7 +25545,7 @@ function formatRoutingReport(report2, options = {}) {
25528
25545
  // plugins/kxm/src/vnext-runtime-supervisor.ts
25529
25546
  var repoRoot = resolve7(fileURLToPath2(new URL("../../../", import.meta.url)));
25530
25547
  function vnextSupervisorTokenFile(paths) {
25531
- return join9(paths.runtimeDir, "supervisor.token");
25548
+ return join10(paths.runtimeDir, "supervisor.token");
25532
25549
  }
25533
25550
  function readVnextSupervisorToken(paths) {
25534
25551
  const file = vnextSupervisorTokenFile(paths);
@@ -25537,7 +25554,7 @@ function readVnextSupervisorToken(paths) {
25537
25554
  if (stat.isSymbolicLink() || !stat.isFile()) {
25538
25555
  throw runtimeError("runtime_path_invalid", file, "supervisor token file must be a regular file, not a link");
25539
25556
  }
25540
- const token = readFileSync9(file, "utf8").trim();
25557
+ const token = readFileSync10(file, "utf8").trim();
25541
25558
  return token.length >= 32 ? token : void 0;
25542
25559
  }
25543
25560
  function processAlive(pid) {
@@ -25551,7 +25568,7 @@ function processAlive(pid) {
25551
25568
  var HEARTBEAT_STALE_MS = 15e3;
25552
25569
  var SUPERVISOR_ERROR_MAX_AGE_MS = 3e4;
25553
25570
  function supervisorErrorFile(paths) {
25554
- return join9(paths.runtimeDir, "supervisor.error");
25571
+ return join10(paths.runtimeDir, "supervisor.error");
25555
25572
  }
25556
25573
  function clearSupervisorError(paths) {
25557
25574
  const file = supervisorErrorFile(paths);
@@ -25564,7 +25581,7 @@ function readRecentSupervisorError(paths) {
25564
25581
  const ageMs = Date.now() - stat.mtimeMs;
25565
25582
  if (ageMs > SUPERVISOR_ERROR_MAX_AGE_MS) return void 0;
25566
25583
  try {
25567
- return readFileSync9(file, "utf8").trim();
25584
+ return readFileSync10(file, "utf8").trim();
25568
25585
  } catch {
25569
25586
  return void 0;
25570
25587
  }
@@ -25631,7 +25648,7 @@ async function ensureVnextSupervisor(options = {}) {
25631
25648
  throw runtimeError("runtime_supervisor_unreachable", paths.registryDb, `runtime supervisor pid ${status.pid} is registered as running but cannot be probed`);
25632
25649
  }
25633
25650
  clearSupervisorError(paths);
25634
- const scriptPath = join9(repoRoot, "scripts", "kxm-runtime-supervisor.mjs");
25651
+ const scriptPath = join10(repoRoot, "scripts", "kxm-runtime-supervisor.mjs");
25635
25652
  const spawnImpl = options.spawnImpl ?? ((script, env) => {
25636
25653
  const child = spawn2(process.execPath, [script], {
25637
25654
  detached: true,
@@ -25684,12 +25701,13 @@ async function vnextRuntimeRequest(handle, method, path4, body) {
25684
25701
 
25685
25702
  // plugins/kxm/src/cli/types.ts
25686
25703
  import { spawn as spawn3 } from "node:child_process";
25687
- import { join as join12, resolve as resolve9 } from "node:path";
25704
+ import { join as join13, resolve as resolve9 } from "node:path";
25688
25705
  import { fileURLToPath as fileURLToPath3 } from "node:url";
25689
25706
 
25690
25707
  // plugins/kxm/src/redact.ts
25691
25708
  var SECRET_PATTERNS = [
25692
25709
  /\bsk-[A-Za-z0-9_-]{8,}\b/g,
25710
+ /\bsk-ant-[A-Za-z0-9_-]{8,}\b/g,
25693
25711
  /\bghp_[A-Za-z0-9_]{20,}\b/g,
25694
25712
  /\bgithub_pat_[A-Za-z0-9_]{20,}\b/g,
25695
25713
  /\bxox[baprs]-[A-Za-z0-9-]{10,}\b/gi,
@@ -25697,9 +25715,9 @@ var SECRET_PATTERNS = [
25697
25715
  /\bya29\.[A-Za-z0-9._~+/-]+=*/g,
25698
25716
  /\b1\/\/[A-Za-z0-9_-]+/g,
25699
25717
  /\b1\/[A-Za-z0-9_-]{20,}/g,
25700
- /("?(?:access_token|refresh_token|id_token)"?\s*[:=]\s*")[^"]*(")/gi,
25718
+ /("?(?:access_token|refresh_token|id_token|sessionKey|session_key|claude_oauth_token|anthropicApiKey)"?\s*[:=]\s*")[^"]*(")/gi,
25701
25719
  /\bKXM_[A-Z0-9_]*(TOKEN|SECRET|KEY)[A-Z0-9_]*=\S+/gi,
25702
- /\b(GITHUB_TOKEN|GH_TOKEN|KXM_AUTH_TOKEN|KXM_WORKFLOW_SIGNAL_SECRET)=\S+/gi,
25720
+ /\b(GITHUB_TOKEN|GH_TOKEN|KXM_AUTH_TOKEN|KXM_WORKFLOW_SIGNAL_SECRET|ANTHROPIC_API_KEY|ANTHROPIC_AUTH_TOKEN|CLAUDE_API_KEY)=\S+/gi,
25703
25721
  /\b[A-Fa-f0-9]{64}\b/g
25704
25722
  ];
25705
25723
  function redactSecrets(value) {
@@ -25714,8 +25732,8 @@ function redactStringList(values, maxItems = 32) {
25714
25732
  }
25715
25733
 
25716
25734
  // plugins/kxm/src/telemetry.ts
25717
- import { appendFileSync, mkdirSync as mkdirSync8, readFileSync as readFileSync10 } from "node:fs";
25718
- import { dirname as dirname7, join as join10 } from "node:path";
25735
+ import { appendFileSync, mkdirSync as mkdirSync8, readFileSync as readFileSync11 } from "node:fs";
25736
+ import { dirname as dirname7, join as join11 } from "node:path";
25719
25737
  var TELEMETRY_SCHEMA = "kxm.telemetry.v1";
25720
25738
  function inferImprovementTarget(input) {
25721
25739
  const explicit = input.env?.KXM_IMPROVE_TARGET?.trim();
@@ -25730,7 +25748,7 @@ function appendTelemetry(path4, event) {
25730
25748
  `, { encoding: "utf8", mode: 384 });
25731
25749
  }
25732
25750
  function telemetryPath(logsDir) {
25733
- return join10(logsDir, "telemetry.jsonl");
25751
+ return join11(logsDir, "telemetry.jsonl");
25734
25752
  }
25735
25753
  function makeTelemetryEvent(input) {
25736
25754
  return {
@@ -25745,7 +25763,7 @@ function makeTelemetryEvent(input) {
25745
25763
  function readRoutingRecords(path4) {
25746
25764
  const records = [];
25747
25765
  try {
25748
- const raw = readFileSync10(path4, "utf8");
25766
+ const raw = readFileSync11(path4, "utf8");
25749
25767
  for (const line of raw.split(/\r?\n/)) {
25750
25768
  if (!line.trim()) continue;
25751
25769
  try {
@@ -25822,9 +25840,9 @@ function workerResult(worker, payload) {
25822
25840
  }
25823
25841
 
25824
25842
  // plugins/kxm/src/hub-binding.ts
25825
- import { existsSync as existsSync11, mkdirSync as mkdirSync9, readFileSync as readFileSync11, renameSync as renameSync3, rmSync as rmSync3, writeFileSync as writeFileSync8 } from "node:fs";
25843
+ import { existsSync as existsSync11, mkdirSync as mkdirSync9, readFileSync as readFileSync12, renameSync as renameSync3, rmSync as rmSync3, writeFileSync as writeFileSync8 } from "node:fs";
25826
25844
  import { homedir as homedir3 } from "node:os";
25827
- import { dirname as dirname8, isAbsolute as isAbsolute5, join as join11, resolve as resolve8 } from "node:path";
25845
+ import { dirname as dirname8, isAbsolute as isAbsolute5, join as join12, resolve as resolve8 } from "node:path";
25828
25846
  var HUB_BINDING_SCHEMA = "kxm.hub-binding.v1";
25829
25847
  var HUB_HEALTH_PROBE_MS = 300;
25830
25848
  var HubBindingError = class extends Error {
@@ -25841,16 +25859,16 @@ function resolveUserStateRoot(env) {
25841
25859
  }
25842
25860
  if (process.platform === "win32") {
25843
25861
  const localAppData = env.LOCALAPPDATA?.trim();
25844
- const base2 = localAppData && isAbsolute5(localAppData) ? localAppData : join11(homedir3(), "AppData", "Local");
25862
+ const base2 = localAppData && isAbsolute5(localAppData) ? localAppData : join12(homedir3(), "AppData", "Local");
25845
25863
  return resolve8(base2, "KXM");
25846
25864
  }
25847
25865
  if (process.platform === "darwin") return resolve8(homedir3(), "Library", "Application Support", "KXM");
25848
25866
  const xdgState = env.XDG_STATE_HOME?.trim();
25849
- const base = xdgState && isAbsolute5(xdgState) ? xdgState : join11(homedir3(), ".local", "state");
25867
+ const base = xdgState && isAbsolute5(xdgState) ? xdgState : join12(homedir3(), ".local", "state");
25850
25868
  return resolve8(base, "kxm");
25851
25869
  }
25852
25870
  function hubBindingFile(env = process.env) {
25853
- return join11(resolveUserStateRoot(env), "hub-binding.json");
25871
+ return join12(resolveUserStateRoot(env), "hub-binding.json");
25854
25872
  }
25855
25873
  function validateHubUrl(raw) {
25856
25874
  let parsed;
@@ -25878,7 +25896,7 @@ function readHubBinding(env = process.env) {
25878
25896
  if (!existsSync11(file)) return void 0;
25879
25897
  let parsed;
25880
25898
  try {
25881
- parsed = JSON.parse(readFileSync11(file, "utf8"));
25899
+ parsed = JSON.parse(readFileSync12(file, "utf8"));
25882
25900
  } catch {
25883
25901
  throw new HubBindingError(`malformed hub binding at ${file}`);
25884
25902
  }
@@ -25901,7 +25919,7 @@ function readHubBinding(env = process.env) {
25901
25919
  function writeHubBinding(record, env = process.env) {
25902
25920
  const file = hubBindingFile(env);
25903
25921
  mkdirSync9(dirname8(file), { recursive: true, mode: 448 });
25904
- const temporary = join11(dirname8(file), `.hub-binding-${process.pid}.tmp`);
25922
+ const temporary = join12(dirname8(file), `.hub-binding-${process.pid}.tmp`);
25905
25923
  try {
25906
25924
  writeFileSync8(temporary, `${JSON.stringify(record, null, 2)}
25907
25925
  `, { encoding: "utf8", mode: 384 });
@@ -25949,7 +25967,7 @@ async function probeHubHealth(url, fetchImpl, timeoutMs = HUB_HEALTH_PROBE_MS) {
25949
25967
  var repoRoot2 = resolve9(fileURLToPath3(new URL("../../../../", import.meta.url)));
25950
25968
  function spawnScript(scriptName, extraEnv = {}) {
25951
25969
  return new Promise((resolveExit) => {
25952
- const child = spawn3(process.execPath, [join12(repoRoot2, "scripts", scriptName)], {
25970
+ const child = spawn3(process.execPath, [join13(repoRoot2, "scripts", scriptName)], {
25953
25971
  stdio: "inherit",
25954
25972
  env: { ...process.env, ...extraEnv }
25955
25973
  });
@@ -26039,10 +26057,10 @@ function workspaceDirs(cwd, workspaceFlag, env) {
26039
26057
  return {
26040
26058
  workdir,
26041
26059
  workspace,
26042
- config: derive ? join12(workspace, "config") : resolve9(workdir, env.KXM_CONFIG_DIR?.trim() || join12(workspace, "config")),
26043
- logs: derive ? join12(workspace, "logs") : resolve9(workdir, env.KXM_LOGS_DIR?.trim() || join12(workspace, "logs")),
26044
- assets: derive ? join12(workspace, "assets") : resolve9(workdir, env.KXM_ASSETS_DIR?.trim() || join12(workspace, "assets")),
26045
- state: derive ? join12(workspace, "state") : resolve9(workdir, env.KXM_STATE_DIR?.trim() || join12(workspace, "state"))
26060
+ config: derive ? join13(workspace, "config") : resolve9(workdir, env.KXM_CONFIG_DIR?.trim() || join13(workspace, "config")),
26061
+ logs: derive ? join13(workspace, "logs") : resolve9(workdir, env.KXM_LOGS_DIR?.trim() || join13(workspace, "logs")),
26062
+ assets: derive ? join13(workspace, "assets") : resolve9(workdir, env.KXM_ASSETS_DIR?.trim() || join13(workspace, "assets")),
26063
+ state: derive ? join13(workspace, "state") : resolve9(workdir, env.KXM_STATE_DIR?.trim() || join13(workspace, "state"))
26046
26064
  };
26047
26065
  }
26048
26066
  function maskEnvName(name) {
@@ -26110,20 +26128,20 @@ function workspaceEnv(runtime) {
26110
26128
  // plugins/kxm/src/cli/roles.ts
26111
26129
  var import_yaml8 = __toESM(require_dist(), 1);
26112
26130
  import { randomUUID as randomUUID5 } from "node:crypto";
26113
- import { existsSync as existsSync14, readFileSync as readFileSync14 } from "node:fs";
26114
- import { join as join15, resolve as resolve12 } from "node:path";
26131
+ import { existsSync as existsSync14, readFileSync as readFileSync15 } from "node:fs";
26132
+ import { join as join16, resolve as resolve12 } from "node:path";
26115
26133
  import { createInterface } from "node:readline";
26116
26134
 
26117
26135
  // plugins/kxm/src/role.ts
26118
26136
  var import_yaml7 = __toESM(require_dist(), 1);
26119
- import { existsSync as existsSync13, mkdirSync as mkdirSync11, readdirSync as readdirSync4, readFileSync as readFileSync13, rmSync as rmSync4, writeFileSync as writeFileSync10 } from "node:fs";
26120
- import { join as join14 } from "node:path";
26137
+ import { existsSync as existsSync13, mkdirSync as mkdirSync11, readdirSync as readdirSync4, readFileSync as readFileSync14, rmSync as rmSync4, writeFileSync as writeFileSync10 } from "node:fs";
26138
+ import { join as join15 } from "node:path";
26121
26139
 
26122
26140
  // plugins/kxm/src/config.ts
26123
26141
  var import_yaml6 = __toESM(require_dist(), 1);
26124
- import { existsSync as existsSync12, mkdirSync as mkdirSync10, readFileSync as readFileSync12, writeFileSync as writeFileSync9 } from "node:fs";
26142
+ import { existsSync as existsSync12, mkdirSync as mkdirSync10, readFileSync as readFileSync13, writeFileSync as writeFileSync9 } from "node:fs";
26125
26143
  import { homedir as homedir4 } from "node:os";
26126
- import { dirname as dirname9, join as join13, resolve as resolve10 } from "node:path";
26144
+ import { dirname as dirname9, join as join14, resolve as resolve10 } from "node:path";
26127
26145
  var KXM_CONFIG_SCHEMA = "kxm.config.v1";
26128
26146
  var DEFAULT_KXM_CONFIG = {
26129
26147
  schema: KXM_CONFIG_SCHEMA,
@@ -26144,6 +26162,9 @@ var DEFAULT_KXM_CONFIG = {
26144
26162
  sync: {
26145
26163
  defaultTracker: "none"
26146
26164
  },
26165
+ hub: {
26166
+ autoStart: "background"
26167
+ },
26147
26168
  improvement: {
26148
26169
  promotionPolicy: "manual_pr",
26149
26170
  telemetryHalfLifeDays: 14,
@@ -26174,7 +26195,7 @@ var DEFAULT_KXM_CONFIG = {
26174
26195
  };
26175
26196
  function userConfigDirectory(overrideDir) {
26176
26197
  if (overrideDir) return resolve10(overrideDir);
26177
- return resolve10(process.env.KXM_USER_CONFIG_DIR?.trim() || join13(homedir4(), ".config", "kxm"));
26198
+ return resolve10(process.env.KXM_USER_CONFIG_DIR?.trim() || join14(homedir4(), ".config", "kxm"));
26178
26199
  }
26179
26200
  function repoConfigDirectory(repoRoot6) {
26180
26201
  return resolve10(repoRoot6, ".kxm");
@@ -26191,16 +26212,20 @@ function deepMerge(target, source) {
26191
26212
  }
26192
26213
  return result;
26193
26214
  }
26215
+ function normalizeHubConfig(raw) {
26216
+ const autoStart = raw?.autoStart;
26217
+ return { autoStart: autoStart === "off" || autoStart === "background" ? autoStart : DEFAULT_KXM_CONFIG.hub.autoStart };
26218
+ }
26194
26219
  function loadKxmConfig(repoRoot6 = process.cwd(), options = {}) {
26195
26220
  const userDir = userConfigDirectory(options.userConfigDir);
26196
- const userConfigFile = join13(userDir, "config.yaml");
26221
+ const userConfigFile = join14(userDir, "config.yaml");
26197
26222
  const repoDir = repoConfigDirectory(repoRoot6);
26198
- const repoConfigFile = join13(repoDir, "config.yaml");
26223
+ const repoConfigFile = join14(repoDir, "config.yaml");
26199
26224
  let userRaw = {};
26200
26225
  let userLoadedPath;
26201
26226
  if (existsSync12(userConfigFile)) {
26202
26227
  try {
26203
- const text = readFileSync12(userConfigFile, "utf8");
26228
+ const text = readFileSync13(userConfigFile, "utf8");
26204
26229
  userRaw = (0, import_yaml6.parse)(text) ?? {};
26205
26230
  userLoadedPath = userConfigFile;
26206
26231
  } catch (error) {
@@ -26211,7 +26236,7 @@ function loadKxmConfig(repoRoot6 = process.cwd(), options = {}) {
26211
26236
  let repoLoadedPath;
26212
26237
  if (existsSync12(repoConfigFile)) {
26213
26238
  try {
26214
- const text = readFileSync12(repoConfigFile, "utf8");
26239
+ const text = readFileSync13(repoConfigFile, "utf8");
26215
26240
  repoRaw = (0, import_yaml6.parse)(text) ?? {};
26216
26241
  repoLoadedPath = repoConfigFile;
26217
26242
  } catch (error) {
@@ -26227,6 +26252,7 @@ function loadKxmConfig(repoRoot6 = process.cwd(), options = {}) {
26227
26252
  defaults: mergedAll.defaults ?? {},
26228
26253
  dash: mergedAll.dash ?? {},
26229
26254
  sync: mergedAll.sync ?? {},
26255
+ hub: normalizeHubConfig(mergedAll.hub),
26230
26256
  improvement: mergedAll.improvement ?? DEFAULT_KXM_CONFIG.improvement,
26231
26257
  routing: mergedAll.routing ?? DEFAULT_KXM_CONFIG.routing,
26232
26258
  telemetry: mergedAll.telemetry ?? DEFAULT_KXM_CONFIG.telemetry,
@@ -26247,12 +26273,12 @@ function getKxmConfigValue(config, keyPath) {
26247
26273
  }
26248
26274
  function setKxmConfigValue(repoRoot6, keyPath, value, options = {}) {
26249
26275
  const scope = options.scope ?? "project";
26250
- const targetFile2 = scope === "user" ? join13(userConfigDirectory(options.userConfigDir), "config.yaml") : join13(repoConfigDirectory(repoRoot6), "config.yaml");
26276
+ const targetFile2 = scope === "user" ? join14(userConfigDirectory(options.userConfigDir), "config.yaml") : join14(repoConfigDirectory(repoRoot6), "config.yaml");
26251
26277
  mkdirSync10(dirname9(targetFile2), { recursive: true });
26252
26278
  let existing = {};
26253
26279
  if (existsSync12(targetFile2)) {
26254
26280
  try {
26255
- existing = (0, import_yaml6.parse)(readFileSync12(targetFile2, "utf8")) ?? {};
26281
+ existing = (0, import_yaml6.parse)(readFileSync13(targetFile2, "utf8")) ?? {};
26256
26282
  } catch {
26257
26283
  existing = {};
26258
26284
  }
@@ -26363,9 +26389,9 @@ var DEFAULT_ROLES = {
26363
26389
  };
26364
26390
  function rolesDirectory(scope, repoRoot6 = process.cwd(), userConfigDir) {
26365
26391
  if (scope === "global") {
26366
- return join14(userConfigDirectory(userConfigDir), "roles");
26392
+ return join15(userConfigDirectory(userConfigDir), "roles");
26367
26393
  }
26368
- return join14(repoConfigDirectory(repoRoot6), "roles");
26394
+ return join15(repoConfigDirectory(repoRoot6), "roles");
26369
26395
  }
26370
26396
  function ensureRolesDirectory(scope, repoRoot6 = process.cwd(), userConfigDir) {
26371
26397
  const dir = rolesDirectory(scope, repoRoot6, userConfigDir);
@@ -26377,7 +26403,7 @@ function ensureRolesDirectory(scope, repoRoot6 = process.cwd(), userConfigDir) {
26377
26403
  function parseRoleFile(filePath) {
26378
26404
  if (!existsSync13(filePath)) return void 0;
26379
26405
  try {
26380
- const raw = readFileSync13(filePath, "utf8");
26406
+ const raw = readFileSync14(filePath, "utf8");
26381
26407
  const parsed = (0, import_yaml7.parse)(raw);
26382
26408
  if (!parsed || typeof parsed !== "object" || parsed.schema !== KXM_ROLE_SCHEMA) {
26383
26409
  return void 0;
@@ -26407,7 +26433,7 @@ function listRoles(options = {}) {
26407
26433
  if (scopeFilter !== "global" && existsSync13(localDir)) {
26408
26434
  for (const entry of readdirSync4(localDir)) {
26409
26435
  if (entry.endsWith(".yaml") || entry.endsWith(".yml")) {
26410
- const filePath = join14(localDir, entry);
26436
+ const filePath = join15(localDir, entry);
26411
26437
  const parsed = parseRoleFile(filePath);
26412
26438
  if (parsed) {
26413
26439
  localRoles.set(parsed.id, { role: parsed, filePath });
@@ -26419,7 +26445,7 @@ function listRoles(options = {}) {
26419
26445
  if (scopeFilter !== "local" && existsSync13(globalDir)) {
26420
26446
  for (const entry of readdirSync4(globalDir)) {
26421
26447
  if (entry.endsWith(".yaml") || entry.endsWith(".yml")) {
26422
- const filePath = join14(globalDir, entry);
26448
+ const filePath = join15(globalDir, entry);
26423
26449
  const parsed = parseRoleFile(filePath);
26424
26450
  if (parsed) {
26425
26451
  globalRoles.set(parsed.id, { role: parsed, filePath });
@@ -26467,13 +26493,13 @@ function getRole(roleId, options = {}) {
26467
26493
  const repoRoot6 = options.repoRoot ?? process.cwd();
26468
26494
  if (scope !== "global") {
26469
26495
  const localDir = rolesDirectory("local", repoRoot6, options.userConfigDir);
26470
- const localFile = join14(localDir, `${roleId}.yaml`);
26496
+ const localFile = join15(localDir, `${roleId}.yaml`);
26471
26497
  const parsed = parseRoleFile(localFile);
26472
26498
  if (parsed) return { role: parsed, scope: "local", filePath: localFile };
26473
26499
  }
26474
26500
  if (scope !== "local") {
26475
26501
  const globalDir = rolesDirectory("global", repoRoot6, options.userConfigDir);
26476
- const globalFile = join14(globalDir, `${roleId}.yaml`);
26502
+ const globalFile = join15(globalDir, `${roleId}.yaml`);
26477
26503
  const parsed = parseRoleFile(globalFile);
26478
26504
  if (parsed) return { role: parsed, scope: "global", filePath: globalFile };
26479
26505
  }
@@ -26483,7 +26509,7 @@ function addRole(role, options = {}) {
26483
26509
  const scope = options.scope ?? "local";
26484
26510
  const repoRoot6 = options.repoRoot ?? process.cwd();
26485
26511
  const dir = ensureRolesDirectory(scope, repoRoot6, options.userConfigDir);
26486
- const filePath = join14(dir, `${role.id}.yaml`);
26512
+ const filePath = join15(dir, `${role.id}.yaml`);
26487
26513
  if (existsSync13(filePath) && !options.overwrite) {
26488
26514
  throw new Error(`role_already_exists: role '${role.id}' already exists at ${filePath}`);
26489
26515
  }
@@ -26494,7 +26520,7 @@ function removeRole(roleId, options = {}) {
26494
26520
  const scope = options.scope ?? "local";
26495
26521
  const repoRoot6 = options.repoRoot ?? process.cwd();
26496
26522
  const dir = rolesDirectory(scope, repoRoot6, options.userConfigDir);
26497
- const filePath = join14(dir, `${roleId}.yaml`);
26523
+ const filePath = join15(dir, `${roleId}.yaml`);
26498
26524
  if (!existsSync13(filePath)) {
26499
26525
  throw new Error(`role_not_found: role '${roleId}' not found in ${scope} directory (${filePath})`);
26500
26526
  }
@@ -26516,7 +26542,7 @@ function modifyRole(roleId, updates, options = {}) {
26516
26542
  const scope = options.scope ?? target.scope;
26517
26543
  const repoRoot6 = options.repoRoot ?? process.cwd();
26518
26544
  const dir = ensureRolesDirectory(scope, repoRoot6, options.userConfigDir);
26519
- const filePath = join14(dir, `${roleId}.yaml`);
26545
+ const filePath = join15(dir, `${roleId}.yaml`);
26520
26546
  writeFileSync10(filePath, (0, import_yaml7.stringify)(updated), "utf8");
26521
26547
  return { id: roleId, role: updated, filePath, scope };
26522
26548
  }
@@ -26565,9 +26591,9 @@ var DEFAULT_ROLE_SEATS = {
26565
26591
  };
26566
26592
  function findExistingRoleHostsFile(scope, repoRoot6 = process.cwd(), userConfigDir) {
26567
26593
  const dir = scope === "global" ? userConfigDirectory(userConfigDir) : repoConfigDirectory(repoRoot6);
26568
- const yamlPath = join14(dir, "role-hosts.yaml");
26569
- const ymlPath = join14(dir, "role-hosts.yml");
26570
- const jsonPath = join14(dir, "role-hosts.json");
26594
+ const yamlPath = join15(dir, "role-hosts.yaml");
26595
+ const ymlPath = join15(dir, "role-hosts.yml");
26596
+ const jsonPath = join15(dir, "role-hosts.json");
26571
26597
  if (existsSync13(yamlPath)) return { filePath: yamlPath, exists: true, format: "yaml" };
26572
26598
  if (existsSync13(ymlPath)) return { filePath: ymlPath, exists: true, format: "yaml" };
26573
26599
  if (existsSync13(jsonPath)) return { filePath: jsonPath, exists: true, format: "json" };
@@ -26576,7 +26602,7 @@ function findExistingRoleHostsFile(scope, repoRoot6 = process.cwd(), userConfigD
26576
26602
  function parseRoleHostsFile(filePath) {
26577
26603
  if (!existsSync13(filePath)) return void 0;
26578
26604
  try {
26579
- const raw = readFileSync13(filePath, "utf8");
26605
+ const raw = readFileSync14(filePath, "utf8");
26580
26606
  const parsed = (0, import_yaml7.parse)(raw);
26581
26607
  if (!parsed || typeof parsed !== "object") return void 0;
26582
26608
  if (parsed.schema && parsed.schema !== KXM_ROLE_HOSTS_SCHEMA) return void 0;
@@ -26652,7 +26678,7 @@ function saveRoleHostsConfig(config, options = {}) {
26652
26678
  mkdirSync11(dir, { recursive: true });
26653
26679
  }
26654
26680
  const format = options.format ?? "yaml";
26655
- const filePath = join14(dir, format === "json" ? "role-hosts.json" : "role-hosts.yaml");
26681
+ const filePath = join15(dir, format === "json" ? "role-hosts.json" : "role-hosts.yaml");
26656
26682
  const payload = {
26657
26683
  schema: KXM_ROLE_HOSTS_SCHEMA,
26658
26684
  seats: config.seats ?? {},
@@ -26894,7 +26920,7 @@ async function cmdRoleAdd(runtime, roleId, options) {
26894
26920
  let roleDef;
26895
26921
  if (options.file) {
26896
26922
  const filePath = resolve12(runtime.cwd, options.file);
26897
- const content = readFileSync14(filePath, "utf8");
26923
+ const content = readFileSync15(filePath, "utf8");
26898
26924
  roleDef = (0, import_yaml8.parse)(content);
26899
26925
  roleDef.id = roleId;
26900
26926
  } else {
@@ -27193,7 +27219,7 @@ async function cmdRoleResume(runtime, runId, ruling) {
27193
27219
  return 1;
27194
27220
  }
27195
27221
  }
27196
- const dbPath = join15(runtime.cwd, ".kxm", "state", "kxm.db");
27222
+ const dbPath = join16(runtime.cwd, ".kxm", "state", "kxm.db");
27197
27223
  if (existsSync14(dbPath)) {
27198
27224
  try {
27199
27225
  const database = new DatabaseSync(dbPath);
@@ -27256,8 +27282,8 @@ async function cmdRoleResume(runtime, runId, ruling) {
27256
27282
 
27257
27283
  // plugins/kxm/src/cli/workflows.ts
27258
27284
  import { createHmac as createHmac3, randomUUID as randomUUID7 } from "node:crypto";
27259
- import { existsSync as existsSync16, readFileSync as readFileSync16 } from "node:fs";
27260
- import { join as join17, resolve as resolve15 } from "node:path";
27285
+ import { existsSync as existsSync16, readFileSync as readFileSync17 } from "node:fs";
27286
+ import { join as join18, resolve as resolve15 } from "node:path";
27261
27287
 
27262
27288
  // plugins/kxm/src/retrospective.ts
27263
27289
  import { mkdirSync as mkdirSync12, renameSync as renameSync4, writeFileSync as writeFileSync11 } from "node:fs";
@@ -27675,8 +27701,8 @@ async function watchGithubChecks(input) {
27675
27701
 
27676
27702
  // plugins/kxm/src/workflow-manager.ts
27677
27703
  var import_yaml9 = __toESM(require_dist(), 1);
27678
- import { existsSync as existsSync15, mkdirSync as mkdirSync13, readdirSync as readdirSync5, readFileSync as readFileSync15, rmSync as rmSync5, writeFileSync as writeFileSync12 } from "node:fs";
27679
- import { join as join16 } from "node:path";
27704
+ import { existsSync as existsSync15, mkdirSync as mkdirSync13, readdirSync as readdirSync5, readFileSync as readFileSync16, rmSync as rmSync5, writeFileSync as writeFileSync12 } from "node:fs";
27705
+ import { join as join17 } from "node:path";
27680
27706
  var WORKFLOW_TEMPLATES = {
27681
27707
  "implement-and-verify": {
27682
27708
  schema: "kxm.workflow.v1",
@@ -27827,9 +27853,9 @@ var WORKFLOW_TEMPLATES = {
27827
27853
  var DEFAULT_WORKFLOW_TEMPLATE = WORKFLOW_TEMPLATES["implement-and-verify"];
27828
27854
  function workflowsDirectory(scope, repoRoot6 = process.cwd(), userConfigDir) {
27829
27855
  if (scope === "global") {
27830
- return join16(userConfigDirectory(userConfigDir), "workflows");
27856
+ return join17(userConfigDirectory(userConfigDir), "workflows");
27831
27857
  }
27832
- return join16(repoConfigDirectory(repoRoot6), "workflows");
27858
+ return join17(repoConfigDirectory(repoRoot6), "workflows");
27833
27859
  }
27834
27860
  function ensureWorkflowsDirectory(scope, repoRoot6 = process.cwd(), userConfigDir) {
27835
27861
  const dir = workflowsDirectory(scope, repoRoot6, userConfigDir);
@@ -27841,7 +27867,7 @@ function ensureWorkflowsDirectory(scope, repoRoot6 = process.cwd(), userConfigDi
27841
27867
  function parseWorkflowFile(filePath) {
27842
27868
  if (!existsSync15(filePath)) return void 0;
27843
27869
  try {
27844
- const raw = readFileSync15(filePath, "utf8");
27870
+ const raw = readFileSync16(filePath, "utf8");
27845
27871
  const parsed = (0, import_yaml9.parse)(raw);
27846
27872
  if (!parsed || typeof parsed !== "object") return void 0;
27847
27873
  return parsed;
@@ -27858,7 +27884,7 @@ function listWorkflowDefinitions(options = {}) {
27858
27884
  if (scopeFilter !== "global" && existsSync15(localDir)) {
27859
27885
  for (const entry of readdirSync5(localDir)) {
27860
27886
  if (entry.endsWith(".yaml") || entry.endsWith(".yml")) {
27861
- const filePath = join16(localDir, entry);
27887
+ const filePath = join17(localDir, entry);
27862
27888
  const def = parseWorkflowFile(filePath);
27863
27889
  if (def) {
27864
27890
  const id = def.id || entry.replace(/\.ya?ml$/i, "");
@@ -27871,7 +27897,7 @@ function listWorkflowDefinitions(options = {}) {
27871
27897
  if (scopeFilter !== "local" && existsSync15(globalDir)) {
27872
27898
  for (const entry of readdirSync5(globalDir)) {
27873
27899
  if (entry.endsWith(".yaml") || entry.endsWith(".yml")) {
27874
- const filePath = join16(globalDir, entry);
27900
+ const filePath = join17(globalDir, entry);
27875
27901
  const def = parseWorkflowFile(filePath);
27876
27902
  if (def) {
27877
27903
  const id = def.id || entry.replace(/\.ya?ml$/i, "");
@@ -27927,13 +27953,13 @@ function getWorkflowDefinition(workflowId, options = {}) {
27927
27953
  const repoRoot6 = options.repoRoot ?? process.cwd();
27928
27954
  if (scope !== "global") {
27929
27955
  const localDir = workflowsDirectory("local", repoRoot6, options.userConfigDir);
27930
- const localFile = join16(localDir, `${workflowId}.yaml`);
27956
+ const localFile = join17(localDir, `${workflowId}.yaml`);
27931
27957
  const parsed = parseWorkflowFile(localFile);
27932
27958
  if (parsed) return { workflow: parsed, scope: "local", filePath: localFile };
27933
27959
  }
27934
27960
  if (scope !== "local") {
27935
27961
  const globalDir = workflowsDirectory("global", repoRoot6, options.userConfigDir);
27936
- const globalFile = join16(globalDir, `${workflowId}.yaml`);
27962
+ const globalFile = join17(globalDir, `${workflowId}.yaml`);
27937
27963
  const parsed = parseWorkflowFile(globalFile);
27938
27964
  if (parsed) return { workflow: parsed, scope: "global", filePath: globalFile };
27939
27965
  }
@@ -27943,7 +27969,7 @@ function addWorkflowDefinition(workflowId, content = DEFAULT_WORKFLOW_TEMPLATE,
27943
27969
  const scope = options.scope ?? "local";
27944
27970
  const repoRoot6 = options.repoRoot ?? process.cwd();
27945
27971
  const dir = ensureWorkflowsDirectory(scope, repoRoot6, options.userConfigDir);
27946
- const filePath = join16(dir, `${workflowId}.yaml`);
27972
+ const filePath = join17(dir, `${workflowId}.yaml`);
27947
27973
  if (existsSync15(filePath) && !options.overwrite) {
27948
27974
  throw new Error(`workflow_already_exists: workflow '${workflowId}' already exists at ${filePath}`);
27949
27975
  }
@@ -27955,7 +27981,7 @@ function removeWorkflowDefinition(workflowId, options = {}) {
27955
27981
  const scope = options.scope ?? "local";
27956
27982
  const repoRoot6 = options.repoRoot ?? process.cwd();
27957
27983
  const dir = workflowsDirectory(scope, repoRoot6, options.userConfigDir);
27958
- const filePath = join16(dir, `${workflowId}.yaml`);
27984
+ const filePath = join17(dir, `${workflowId}.yaml`);
27959
27985
  if (!existsSync15(filePath)) {
27960
27986
  throw new Error(`workflow_not_found: workflow '${workflowId}' not found in ${scope} directory (${filePath})`);
27961
27987
  }
@@ -27974,7 +28000,7 @@ function modifyWorkflowDefinition(workflowId, updates, options = {}) {
27974
28000
  const scope = options.scope ?? target.scope;
27975
28001
  const repoRoot6 = options.repoRoot ?? process.cwd();
27976
28002
  const dir = ensureWorkflowsDirectory(scope, repoRoot6, options.userConfigDir);
27977
- const filePath = join16(dir, `${workflowId}.yaml`);
28003
+ const filePath = join17(dir, `${workflowId}.yaml`);
27978
28004
  writeFileSync12(filePath, (0, import_yaml9.stringify)(updated), "utf8");
27979
28005
  return { id: workflowId, workflow: updated, filePath, scope };
27980
28006
  }
@@ -28059,7 +28085,7 @@ function activeWorkflowDefinition(runtime, definitionId) {
28059
28085
  let raw;
28060
28086
  if (file) {
28061
28087
  try {
28062
- raw = readFileSync16(resolve15(runtime.cwd, file), "utf8");
28088
+ raw = readFileSync17(resolve15(runtime.cwd, file), "utf8");
28063
28089
  } catch {
28064
28090
  throw new Error("workflow definition file is unavailable");
28065
28091
  }
@@ -28141,7 +28167,7 @@ async function cmdWorkflowAdd(runtime, workflowId, options) {
28141
28167
  }
28142
28168
  if (options.file) {
28143
28169
  const filePath = resolve15(runtime.cwd, options.file);
28144
- content = readFileSync16(filePath, "utf8");
28170
+ content = readFileSync17(filePath, "utf8");
28145
28171
  } else if (!content) {
28146
28172
  content = {
28147
28173
  schema: "kxm.workflow.v1",
@@ -28299,7 +28325,7 @@ async function cmdWorkflowStart(runtime, definitionIdArg, options) {
28299
28325
  }
28300
28326
  let payload;
28301
28327
  try {
28302
- const raw = payloadFlag.startsWith("@") ? readFileSync16(resolve15(runtime.cwd, payloadFlag.slice(1)), "utf8") : payloadFlag;
28328
+ const raw = payloadFlag.startsWith("@") ? readFileSync17(resolve15(runtime.cwd, payloadFlag.slice(1)), "utf8") : payloadFlag;
28303
28329
  const value = JSON.parse(raw);
28304
28330
  if (!value || typeof value !== "object" || Array.isArray(value)) throw new Error("object required");
28305
28331
  payload = value;
@@ -28366,7 +28392,7 @@ async function cmdWorkflowDegrade(runtime, runId, stageId, options) {
28366
28392
  }
28367
28393
  }
28368
28394
  async function cmdWorkflowInspect(runtime, action, runId) {
28369
- const dataPath = resolve15(runtime.dirs.workdir, runtime.env.KXM_DATA_PATH?.trim() || join17(runtime.dirs.state, "kxm.db"));
28395
+ const dataPath = resolve15(runtime.dirs.workdir, runtime.env.KXM_DATA_PATH?.trim() || join18(runtime.dirs.state, "kxm.db"));
28370
28396
  if (action === "get" && !runId) {
28371
28397
  runtime.io.stderr(`Usage: ${CLI_NAME} workflow get <runId>
28372
28398
  `);
@@ -28540,9 +28566,9 @@ async function cmdRetrospectiveExport(runtime, runId, options) {
28540
28566
  try {
28541
28567
  if (snapshotPath) {
28542
28568
  if (!existsSync16(snapshotPath)) throw new Error("snapshot_missing");
28543
- snapshot = JSON.parse(readFileSync16(snapshotPath, "utf8"));
28569
+ snapshot = JSON.parse(readFileSync17(snapshotPath, "utf8"));
28544
28570
  } else {
28545
- const dataPath = resolve15(runtime.dirs.workdir, runtime.env.KXM_DATA_PATH?.trim() || join17(runtime.dirs.state, "kxm.db"));
28571
+ const dataPath = resolve15(runtime.dirs.workdir, runtime.env.KXM_DATA_PATH?.trim() || join18(runtime.dirs.state, "kxm.db"));
28546
28572
  const local = localWorkflowSnapshot(dataPath, runId);
28547
28573
  if (!local.runs[0]) throw new Error("workflow_not_found");
28548
28574
  snapshot = { run: local.runs[0], journal: local.journal };
@@ -28554,7 +28580,7 @@ async function cmdRetrospectiveExport(runtime, runId, options) {
28554
28580
  return 1;
28555
28581
  }
28556
28582
  const doc = buildRetrospective(snapshot.run, snapshot.journal);
28557
- const outDir = resolve15(runtime.cwd, String(options.outDir || join17(runtime.dirs.assets, "retrospectives")));
28583
+ const outDir = resolve15(runtime.cwd, String(options.outDir || join18(runtime.dirs.assets, "retrospectives")));
28558
28584
  const assetsRoot = resolve15(runtime.dirs.assets);
28559
28585
  const assetsPrefix = `${assetsRoot}${process.platform === "win32" ? "\\" : "/"}`;
28560
28586
  if (outDir !== assetsRoot && !outDir.startsWith(assetsPrefix)) {
@@ -28572,8 +28598,8 @@ async function cmdRetrospectiveExport(runtime, runId, options) {
28572
28598
 
28573
28599
  // plugins/kxm/src/cli/tasks.ts
28574
28600
  var import_yaml13 = __toESM(require_dist(), 1);
28575
- import { existsSync as existsSync22, readFileSync as readFileSync21, readdirSync as readdirSync8 } from "node:fs";
28576
- import { basename as basename5, join as join25, resolve as resolve21 } from "node:path";
28601
+ import { existsSync as existsSync22, readFileSync as readFileSync22, readdirSync as readdirSync8 } from "node:fs";
28602
+ import { basename as basename6, join as join26, resolve as resolve21 } from "node:path";
28577
28603
 
28578
28604
  // plugins/kxm/src/suggest.ts
28579
28605
  var WORKFLOW_PATTERNS = [
@@ -28684,8 +28710,8 @@ function suggestWorkflowAndRoles(prompt, options = {}) {
28684
28710
  // plugins/kxm/src/task-manager.ts
28685
28711
  var import_yaml10 = __toESM(require_dist(), 1);
28686
28712
  import { randomUUID as randomUUID8 } from "node:crypto";
28687
- import { existsSync as existsSync17, mkdirSync as mkdirSync14, readFileSync as readFileSync17, readdirSync as readdirSync6, writeFileSync as writeFileSync13 } from "node:fs";
28688
- import { join as join18, resolve as resolve16 } from "node:path";
28713
+ import { existsSync as existsSync17, mkdirSync as mkdirSync14, readFileSync as readFileSync18, readdirSync as readdirSync6, writeFileSync as writeFileSync13 } from "node:fs";
28714
+ import { join as join19, resolve as resolve16 } from "node:path";
28689
28715
  var GOAL_SCHEMA = "kxm.goal.v1";
28690
28716
  var TASK_SCHEMA = "kxm.task.v1";
28691
28717
  function goalsDirectory(repoRoot6) {
@@ -28710,7 +28736,7 @@ function createGoal(repoRoot6, input) {
28710
28736
  createdAt: now,
28711
28737
  updatedAt: now
28712
28738
  };
28713
- const filePath = join18(dir, `${id}.yaml`);
28739
+ const filePath = join19(dir, `${id}.yaml`);
28714
28740
  writeFileSync13(filePath, (0, import_yaml10.stringify)(record).trim() + "\n", "utf8");
28715
28741
  return record;
28716
28742
  }
@@ -28722,7 +28748,7 @@ function listGoals(repoRoot6) {
28722
28748
  for (const entry of entries) {
28723
28749
  if (entry.isFile() && (entry.name.endsWith(".yaml") || entry.name.endsWith(".yml"))) {
28724
28750
  try {
28725
- const text = readFileSync17(join18(dir, entry.name), "utf8");
28751
+ const text = readFileSync18(join19(dir, entry.name), "utf8");
28726
28752
  const doc = (0, import_yaml10.parse)(text);
28727
28753
  if (doc && doc.schema === GOAL_SCHEMA) goals.push(doc);
28728
28754
  } catch {
@@ -28755,7 +28781,7 @@ function createTask(repoRoot6, input) {
28755
28781
  createdAt: now,
28756
28782
  updatedAt: now
28757
28783
  };
28758
- const filePath = join18(dir, `${id}.yaml`);
28784
+ const filePath = join19(dir, `${id}.yaml`);
28759
28785
  writeFileSync13(filePath, (0, import_yaml10.stringify)(record).trim() + "\n", "utf8");
28760
28786
  return record;
28761
28787
  }
@@ -28767,7 +28793,7 @@ function listTasks(repoRoot6, options = {}) {
28767
28793
  for (const entry of entries) {
28768
28794
  if (entry.isFile() && (entry.name.endsWith(".yaml") || entry.name.endsWith(".yml"))) {
28769
28795
  try {
28770
- const text = readFileSync17(join18(dir, entry.name), "utf8");
28796
+ const text = readFileSync18(join19(dir, entry.name), "utf8");
28771
28797
  const doc = (0, import_yaml10.parse)(text);
28772
28798
  if (doc && doc.schema === TASK_SCHEMA) {
28773
28799
  if (options.goalId && doc.goalId !== options.goalId) continue;
@@ -28782,10 +28808,10 @@ function listTasks(repoRoot6, options = {}) {
28782
28808
  }
28783
28809
  function getTask(repoRoot6, taskId) {
28784
28810
  const dir = tasksDirectory(repoRoot6);
28785
- const filePath = join18(dir, `${taskId}.yaml`);
28811
+ const filePath = join19(dir, `${taskId}.yaml`);
28786
28812
  if (!existsSync17(filePath)) return void 0;
28787
28813
  try {
28788
- const text = readFileSync17(filePath, "utf8");
28814
+ const text = readFileSync18(filePath, "utf8");
28789
28815
  const doc = (0, import_yaml10.parse)(text);
28790
28816
  return doc && doc.schema === TASK_SCHEMA ? doc : void 0;
28791
28817
  } catch {
@@ -28800,7 +28826,7 @@ function updateTaskStatus(repoRoot6, taskId, status, options = {}) {
28800
28826
  task.status = status;
28801
28827
  if (options.workflowRunId) task.workflowRunId = options.workflowRunId;
28802
28828
  task.updatedAt = (/* @__PURE__ */ new Date()).toISOString();
28803
- const filePath = join18(tasksDirectory(repoRoot6), `${taskId}.yaml`);
28829
+ const filePath = join19(tasksDirectory(repoRoot6), `${taskId}.yaml`);
28804
28830
  writeFileSync13(filePath, (0, import_yaml10.stringify)(task).trim() + "\n", "utf8");
28805
28831
  return task;
28806
28832
  }
@@ -28816,7 +28842,7 @@ function syncTaskWithTracker(repoRoot6, taskId, options = {}) {
28816
28842
  task.trackerSync.syncStatus = "synced";
28817
28843
  task.trackerSync.lastSyncedAt = now;
28818
28844
  task.updatedAt = now;
28819
- const filePath = join18(tasksDirectory(repoRoot6), `${taskId}.yaml`);
28845
+ const filePath = join19(tasksDirectory(repoRoot6), `${taskId}.yaml`);
28820
28846
  writeFileSync13(filePath, (0, import_yaml10.stringify)(task).trim() + "\n", "utf8");
28821
28847
  return task;
28822
28848
  }
@@ -29583,14 +29609,14 @@ function createStudioServer(options = {}) {
29583
29609
  }
29584
29610
 
29585
29611
  // plugins/kxm/src/cli/vnext.ts
29586
- import { join as join24, resolve as resolve20 } from "node:path";
29612
+ import { join as join25, resolve as resolve20 } from "node:path";
29587
29613
  import { createInterface as createInterface2 } from "node:readline";
29588
29614
  import { fileURLToPath as fileURLToPath4 } from "node:url";
29589
29615
 
29590
29616
  // plugins/kxm/src/model-inventory.ts
29591
29617
  var import_yaml11 = __toESM(require_dist(), 1);
29592
29618
  import { mkdirSync as mkdirSync15, writeFileSync as writeFileSync14 } from "node:fs";
29593
- import { join as join19 } from "node:path";
29619
+ import { join as join20 } from "node:path";
29594
29620
  var OR_URL = "https://openrouter.ai/api/v1/models";
29595
29621
  var NOUS_URL = "https://inference-api.nousresearch.com/v1/models";
29596
29622
  function price(value) {
@@ -29676,15 +29702,15 @@ async function refreshModelInventory(options) {
29676
29702
  sources.nous = { url: nousUrl, ok: !nous.error, ...nous.error ? { error: nous.error } : {} };
29677
29703
  for (const item of nous.data) add(item, "nous", "discount");
29678
29704
  const inventory = { schema: "kxm.model-inventory.v1", fetchedAt, currency: "USD", sources, models: [...byId.values()].sort((a, b2) => a.id.localeCompare(b2.id)) };
29679
- mkdirSync15(join19(options.outputRoot, ".kxm", "models"), { recursive: true });
29680
- writeFileSync14(join19(options.outputRoot, ".kxm", "models", "inventory.yaml"), (0, import_yaml11.stringify)(inventory), "utf8");
29705
+ mkdirSync15(join20(options.outputRoot, ".kxm", "models"), { recursive: true });
29706
+ writeFileSync14(join20(options.outputRoot, ".kxm", "models", "inventory.yaml"), (0, import_yaml11.stringify)(inventory), "utf8");
29681
29707
  return inventory;
29682
29708
  }
29683
29709
 
29684
29710
  // plugins/kxm/src/vnext-init.ts
29685
29711
  import { randomUUID as randomUUID11 } from "node:crypto";
29686
29712
  import { existsSync as existsSync20 } from "node:fs";
29687
- import { basename as basename4, join as join22 } from "node:path";
29713
+ import { basename as basename5, join as join23 } from "node:path";
29688
29714
 
29689
29715
  // plugins/kxm/src/vnext-repair.ts
29690
29716
  import { randomUUID as randomUUID10 } from "node:crypto";
@@ -29697,20 +29723,20 @@ import {
29697
29723
  lstatSync as lstatSync7,
29698
29724
  mkdirSync as mkdirSync17,
29699
29725
  openSync as openSync2,
29700
- readFileSync as readFileSync19,
29726
+ readFileSync as readFileSync20,
29701
29727
  readdirSync as readdirSync7,
29702
29728
  renameSync as renameSync5,
29703
29729
  rmSync as rmSync7,
29704
29730
  writeFileSync as writeFileSync16
29705
29731
  } from "node:fs";
29706
- import { dirname as dirname13, isAbsolute as isAbsolute6, join as join21, relative as relative4, resolve as resolve18 } from "node:path";
29732
+ import { dirname as dirname13, isAbsolute as isAbsolute6, join as join22, relative as relative4, resolve as resolve18 } from "node:path";
29707
29733
 
29708
29734
  // plugins/kxm/src/vnext-permission.ts
29709
29735
  import { spawnSync as spawnSync4 } from "node:child_process";
29710
29736
  import { createHash as createHash12 } from "node:crypto";
29711
- import { existsSync as existsSync18, mkdtempSync, mkdirSync as mkdirSync16, readFileSync as readFileSync18, rmSync as rmSync6, writeFileSync as writeFileSync15 } from "node:fs";
29737
+ import { existsSync as existsSync18, mkdtempSync, mkdirSync as mkdirSync16, readFileSync as readFileSync19, rmSync as rmSync6, writeFileSync as writeFileSync15 } from "node:fs";
29712
29738
  import { tmpdir } from "node:os";
29713
- import { dirname as dirname12, join as join20, resolve as resolve17, sep as sep3 } from "node:path";
29739
+ import { dirname as dirname12, join as join21, resolve as resolve17, sep as sep3 } from "node:path";
29714
29740
  var PROSE_FIELDS = {
29715
29741
  project: /* @__PURE__ */ new Set(["name", "description"]),
29716
29742
  repository: /* @__PURE__ */ new Set(["description"]),
@@ -30231,7 +30257,7 @@ function loadVnextProjectAtRevision(root, revision, options = {}) {
30231
30257
  const tree = resolveTreeRevision(root, revision);
30232
30258
  const listing = gitBuffer(root, ["ls-tree", "-r", "-z", "--name-only", tree]).toString("utf8");
30233
30259
  const paths = listing.split("\0").filter((line) => line.length > 0 && (line.startsWith(".kxm/") || line.includes("/.kxm/")));
30234
- const shadow = mkdtempSync(join20(tmpdir(), "kxm-permission-base-"));
30260
+ const shadow = mkdtempSync(join21(tmpdir(), "kxm-permission-base-"));
30235
30261
  const shadowResolved = resolve17(shadow);
30236
30262
  const shadowMembersDir = `.kxm-shadow-members-${createHash12("sha256").update(shadowResolved, "utf8").digest("hex").slice(0, 8)}`;
30237
30263
  try {
@@ -30245,7 +30271,7 @@ function loadVnextProjectAtRevision(root, revision, options = {}) {
30245
30271
  message: "Git tree entry contains a traversal or non-portable segment"
30246
30272
  }]);
30247
30273
  }
30248
- const absolute = join20(shadowResolved, ...segments);
30274
+ const absolute = join21(shadowResolved, ...segments);
30249
30275
  const resolved = resolve17(absolute);
30250
30276
  if (!resolved.startsWith(`${shadowResolved}${sep3}`)) {
30251
30277
  throw new VnextConfigError([{
@@ -30260,7 +30286,7 @@ function loadVnextProjectAtRevision(root, revision, options = {}) {
30260
30286
  writeFileSync15(absolute, content);
30261
30287
  }
30262
30288
  initShadowGitRoot(shadowResolved);
30263
- const baseProjectFile = join20(shadowResolved, ".kxm", "project.yaml");
30289
+ const baseProjectFile = join21(shadowResolved, ".kxm", "project.yaml");
30264
30290
  let baseProject;
30265
30291
  try {
30266
30292
  baseProject = loadBaseProjectDeclarations(baseProjectFile);
@@ -30338,7 +30364,7 @@ function loadVnextProjectAtRevision(root, revision, options = {}) {
30338
30364
  const memberTree = git(memberWorktree, ["rev-parse", "--verify", "--quiet", `${pinnedCommit}^{tree}`]).trim();
30339
30365
  const memberListing = gitBuffer(memberWorktree, ["ls-tree", "-r", "-z", "--name-only", memberTree]).toString("utf8");
30340
30366
  const memberPaths = memberListing.split("\0").filter((line) => line.length > 0 && (line.startsWith(".kxm/") || line.includes("/.kxm/")));
30341
- const memberShadowRoot = join20(shadowResolved, shadowMembersDir, member.repositoryId);
30367
+ const memberShadowRoot = join21(shadowResolved, shadowMembersDir, member.repositoryId);
30342
30368
  if (!resolve17(memberShadowRoot).startsWith(`${resolve17(shadowResolved, shadowMembersDir)}${sep3}`)) {
30343
30369
  throw new VnextConfigError([{
30344
30370
  phase: "path",
@@ -30352,7 +30378,7 @@ function loadVnextProjectAtRevision(root, revision, options = {}) {
30352
30378
  if (segments.some((segment) => segment === "" || segment === "." || segment === ".." || /[\\:]/.test(segment))) {
30353
30379
  throw new VnextConfigError([{ phase: "path", code: "git_tree_path_invalid", file: path4, message: "member Git tree entry contains a traversal or non-portable segment" }]);
30354
30380
  }
30355
- const absolute = join20(memberShadowRoot, ...segments);
30381
+ const absolute = join21(memberShadowRoot, ...segments);
30356
30382
  const resolved = resolve17(absolute);
30357
30383
  if (!resolved.startsWith(`${resolve17(memberShadowRoot)}${sep3}`)) {
30358
30384
  throw new VnextConfigError([{ phase: "path", code: "git_tree_path_invalid", file: path4, message: "member Git tree entry escapes the shadow root" }]);
@@ -30381,7 +30407,7 @@ function portableMemberPathHint(pathHint) {
30381
30407
  }
30382
30408
  function loadBaseProjectDeclarations(projectFile) {
30383
30409
  if (!existsSync18(projectFile)) return [];
30384
- const value = parseRestrictedYaml2(readFileSync18(projectFile, "utf8"), ".kxm/project.yaml");
30410
+ const value = parseRestrictedYaml2(readFileSync19(projectFile, "utf8"), ".kxm/project.yaml");
30385
30411
  const repositories = Array.isArray(value?.repositories) ? value.repositories : [];
30386
30412
  const members = [];
30387
30413
  for (const entry of repositories) {
@@ -30509,19 +30535,19 @@ function sameHostPath3(left, right) {
30509
30535
  return process.platform === "win32" ? first.toLocaleLowerCase("en-US") === second.toLocaleLowerCase("en-US") : first === second;
30510
30536
  }
30511
30537
  function transactionRoot(projectRoot) {
30512
- return join21(resolve18(projectRoot), TRANSACTION_NAME);
30538
+ return join22(resolve18(projectRoot), TRANSACTION_NAME);
30513
30539
  }
30514
30540
  function operationFile(projectRoot) {
30515
- return join21(transactionRoot(projectRoot), OPERATION_FILE);
30541
+ return join22(transactionRoot(projectRoot), OPERATION_FILE);
30516
30542
  }
30517
30543
  function targetFile(projectRoot, portablePath2) {
30518
- return join21(transactionRoot(projectRoot), "targets", ...portablePath2.split("/"));
30544
+ return join22(transactionRoot(projectRoot), "targets", ...portablePath2.split("/"));
30519
30545
  }
30520
30546
  function shadowRoot(projectRoot) {
30521
- return join21(transactionRoot(projectRoot), "shadow");
30547
+ return join22(transactionRoot(projectRoot), "shadow");
30522
30548
  }
30523
30549
  function backupFile(projectRoot, portablePath2) {
30524
- return join21(transactionRoot(projectRoot), "backups", ...portablePath2.split("/"));
30550
+ return join22(transactionRoot(projectRoot), "backups", ...portablePath2.split("/"));
30525
30551
  }
30526
30552
  function portableManagedPath(path4) {
30527
30553
  return path4.startsWith(".kxm/") && path4 !== VNEXT_TEMPLATE_PROVENANCE_PATH && path4.length <= 1024 && !path4.includes("\\") && !isAbsolute6(path4) && PORTABLE_PATH.test(path4) && !/[<>:"|?*]/.test(path4);
@@ -30530,10 +30556,10 @@ function readRegularBounded(file, label) {
30530
30556
  const stat = lstatSync7(file);
30531
30557
  if (stat.isSymbolicLink() || !stat.isFile()) fail3("repair_file_invalid", label, "managed file must be a regular file, not a link or directory", "path");
30532
30558
  if (stat.size > MAX_MANAGED_FILE_BYTES) fail3("repair_file_too_large", label, `managed file exceeds ${MAX_MANAGED_FILE_BYTES} bytes`, "parse");
30533
- return readFileSync19(file);
30559
+ return readFileSync20(file);
30534
30560
  }
30535
30561
  function readOptionalManaged(projectRoot, path4) {
30536
- const file = join21(projectRoot, ...path4.split("/"));
30562
+ const file = join22(projectRoot, ...path4.split("/"));
30537
30563
  if (!existsSync19(file)) return void 0;
30538
30564
  let parent = dirname13(file);
30539
30565
  const boundary = resolve18(projectRoot);
@@ -30545,8 +30571,8 @@ function readOptionalManaged(projectRoot, path4) {
30545
30571
  return readRegularBounded(file, path4);
30546
30572
  }
30547
30573
  function readProjectAndProvenance(projectRoot, schemasDir) {
30548
- const projectFile = join21(projectRoot, ".kxm", "project.yaml");
30549
- const provenanceFile = join21(projectRoot, ...VNEXT_TEMPLATE_PROVENANCE_PATH.split("/"));
30574
+ const projectFile = join22(projectRoot, ".kxm", "project.yaml");
30575
+ const provenanceFile = join22(projectRoot, ...VNEXT_TEMPLATE_PROVENANCE_PATH.split("/"));
30550
30576
  if (!existsSync19(projectFile) || !existsSync19(provenanceFile)) return void 0;
30551
30577
  const projectBytes = readOptionalManaged(projectRoot, ".kxm/project.yaml");
30552
30578
  const provenanceBytes = readOptionalManaged(projectRoot, VNEXT_TEMPLATE_PROVENANCE_PATH);
@@ -30711,7 +30737,7 @@ function operationPlanSha(operation) {
30711
30737
  function writeOperation(projectRoot, operation) {
30712
30738
  const root = transactionRoot(projectRoot);
30713
30739
  const file = operationFile(projectRoot);
30714
- const temporary = join21(root, `.operation-${operation.operationId}-${randomUUID10()}.tmp`);
30740
+ const temporary = join22(root, `.operation-${operation.operationId}-${randomUUID10()}.tmp`);
30715
30741
  try {
30716
30742
  writeDurableNew(temporary, Buffer.from(`${JSON.stringify(operation, null, 2)}
30717
30743
  `, "utf8"), 384);
@@ -30763,7 +30789,7 @@ function hasVnextInitTransaction(projectRoot) {
30763
30789
  return existsSync19(transactionRoot(projectRoot));
30764
30790
  }
30765
30791
  function readTarget(projectRoot, path4) {
30766
- return readOptionalManaged(join21(transactionRoot(projectRoot), "targets"), path4);
30792
+ return readOptionalManaged(join22(transactionRoot(projectRoot), "targets"), path4);
30767
30793
  }
30768
30794
  function writeTarget(projectRoot, path4, bytes) {
30769
30795
  if (bytes.byteLength > MAX_MANAGED_FILE_BYTES) fail3("template_target_too_large", path4, `target exceeds ${MAX_MANAGED_FILE_BYTES} bytes`);
@@ -30803,7 +30829,7 @@ function verifyBackups(projectRoot, operation) {
30803
30829
  if (operation.kind !== "repair") return;
30804
30830
  for (const entry of operation.files) {
30805
30831
  if (entry.observedSha256 === null) continue;
30806
- const bytes = readOptionalManaged(join21(transactionRoot(projectRoot), "backups"), entry.path);
30832
+ const bytes = readOptionalManaged(join22(transactionRoot(projectRoot), "backups"), entry.path);
30807
30833
  if (!bytes || vnextContentSha256(bytes) !== entry.observedSha256) {
30808
30834
  fail3("init_transaction_backup_invalid", entry.path, "pinned preimage backup is missing or corrupt");
30809
30835
  }
@@ -30837,9 +30863,9 @@ function sourceConfigFiles(projectRoot) {
30837
30863
  ".kxm/repo/repo.yaml",
30838
30864
  ".kxm/repo/env.yaml"
30839
30865
  ];
30840
- const files = fixed.filter((path4) => existsSync19(join21(projectRoot, ...path4.split("/"))));
30866
+ const files = fixed.filter((path4) => existsSync19(join22(projectRoot, ...path4.split("/"))));
30841
30867
  for (const directory of ["agents", "models", "workflows"]) {
30842
- const absolute = join21(projectRoot, ".kxm", directory);
30868
+ const absolute = join22(projectRoot, ".kxm", directory);
30843
30869
  if (!existsSync19(absolute)) continue;
30844
30870
  const stat = lstatSync7(absolute);
30845
30871
  if (stat.isSymbolicLink() || !stat.isDirectory()) fail3("repair_directory_invalid", `.kxm/${directory}`, "configuration directory must be regular", "path");
@@ -30876,8 +30902,8 @@ function prepareShadow(projectRoot, operation, options) {
30876
30902
  const bytes = readOptionalManaged(projectRoot, path4);
30877
30903
  if (!bytes) fail3("repair_snapshot_file_missing", path4, "configuration changed during shadow preparation");
30878
30904
  total += bytes.byteLength;
30879
- const source = join21(projectRoot, ...path4.split("/"));
30880
- const destination = join21(shadow, ...path4.split("/"));
30905
+ const source = join22(projectRoot, ...path4.split("/"));
30906
+ const destination = join22(shadow, ...path4.split("/"));
30881
30907
  mkdirSync17(dirname13(destination), { recursive: true, mode: 448 });
30882
30908
  writeDurableNew(destination, bytes, lstatSync7(source).mode & 511);
30883
30909
  if (total > MAX_MANAGED_TOTAL_BYTES) fail3("repair_snapshot_too_large", ".kxm", `configuration snapshot exceeds ${MAX_MANAGED_TOTAL_BYTES} bytes`, "parse");
@@ -30886,12 +30912,12 @@ function prepareShadow(projectRoot, operation, options) {
30886
30912
  for (const entry of operation.files) {
30887
30913
  const bytes = readTarget(projectRoot, entry.path);
30888
30914
  if (!bytes) fail3("init_transaction_target_missing", entry.path, "pinned target artifact is missing");
30889
- const destination = join21(shadow, ...entry.path.split("/"));
30915
+ const destination = join22(shadow, ...entry.path.split("/"));
30890
30916
  mkdirSync17(dirname13(destination), { recursive: true, mode: 448 });
30891
30917
  const mode = existsSync19(destination) ? lstatSync7(destination).mode & 511 : 420;
30892
30918
  writeDurable(destination, bytes, mode);
30893
30919
  }
30894
- const project = parseRestrictedYaml2(readFileSync19(join21(shadow, ".kxm", "project.yaml")), ".kxm/project.yaml");
30920
+ const project = parseRestrictedYaml2(readFileSync20(join22(shadow, ".kxm", "project.yaml")), ".kxm/project.yaml");
30895
30921
  const bound = absoluteMemberBindings(projectRoot, project, options.repositoryBindings);
30896
30922
  loadVnextProject(shadow, { ...loaderOptions(options), repositoryBindings: bound });
30897
30923
  const provenance = readProjectAndProvenance(shadow, options.schemasDir)?.provenance;
@@ -30955,21 +30981,21 @@ function ensureDestinationParents(projectRoot, path4) {
30955
30981
  const segments = path4.split("/").slice(0, -1);
30956
30982
  let current = boundary;
30957
30983
  for (const segment of segments) {
30958
- current = join21(current, segment);
30984
+ current = join22(current, segment);
30959
30985
  if (!existsSync19(current)) mkdirSync17(current, { mode: 448 });
30960
30986
  const stat = lstatSync7(current);
30961
30987
  if (stat.isSymbolicLink() || !stat.isDirectory()) fail3("repair_destination_parent_invalid", path4, "destination parent must be a regular directory", "path");
30962
30988
  }
30963
30989
  }
30964
30990
  function destinationSha(projectRoot, path4) {
30965
- const file = join21(projectRoot, ...path4.split("/"));
30991
+ const file = join22(projectRoot, ...path4.split("/"));
30966
30992
  if (!existsSync19(file)) return void 0;
30967
30993
  return vnextContentSha256(readRegularBounded(file, path4));
30968
30994
  }
30969
30995
  function requireConditionalLinkSupport(directory, operationId, path4) {
30970
30996
  const nonce = randomUUID10();
30971
- const source = join21(directory, `.kxm-repair-${operationId}-${nonce}.link-source`);
30972
- const target = join21(directory, `.kxm-repair-${operationId}-${nonce}.link-target`);
30997
+ const source = join22(directory, `.kxm-repair-${operationId}-${nonce}.link-source`);
30998
+ const target = join22(directory, `.kxm-repair-${operationId}-${nonce}.link-target`);
30973
30999
  try {
30974
31000
  writeDurableNew(source, Buffer.from("kxm-link-probe\n", "utf8"), 384);
30975
31001
  try {
@@ -30984,16 +31010,16 @@ function requireConditionalLinkSupport(directory, operationId, path4) {
30984
31010
  }
30985
31011
  }
30986
31012
  function atomicInstallTarget(projectRoot, operation, entry) {
30987
- const destination = join21(projectRoot, ...entry.path.split("/"));
31013
+ const destination = join22(projectRoot, ...entry.path.split("/"));
30988
31014
  ensureDestinationParents(projectRoot, entry.path);
30989
31015
  const directory = dirname13(destination);
30990
31016
  const temporaryPrefix = `.kxm-repair-${operation.operationId}-`;
30991
31017
  const pathKey = vnextContentSha256(entry.path).slice("sha256:".length, "sha256:".length + 16);
30992
- const displaced = join21(directory, `${temporaryPrefix}${pathKey}.preimage`);
31018
+ const displaced = join22(directory, `${temporaryPrefix}${pathKey}.preimage`);
30993
31019
  if (existsSync19(displaced)) {
30994
31020
  const stat = lstatSync7(displaced);
30995
31021
  if (stat.isSymbolicLink() || !stat.isFile()) fail3("repair_preimage_temporary_invalid", entry.path, "stale displaced preimage is not a regular file", "path");
30996
- if (entry.observedSha256 === null || vnextContentSha256(readFileSync19(displaced)) !== entry.observedSha256) {
31022
+ if (entry.observedSha256 === null || vnextContentSha256(readFileSync20(displaced)) !== entry.observedSha256) {
30997
31023
  fail3("repair_preimage_temporary_mismatch", entry.path, "stale displaced preimage does not match the pinned operation");
30998
31024
  }
30999
31025
  if (!existsSync19(destination)) {
@@ -31011,7 +31037,7 @@ function atomicInstallTarget(projectRoot, operation, entry) {
31011
31037
  const owned = candidate.name.startsWith(temporaryPrefix) && (candidate.name.endsWith(".tmp") || candidate.name.endsWith(".link-source") || candidate.name.endsWith(".link-target"));
31012
31038
  if (!owned) continue;
31013
31039
  if (!candidate.isFile()) fail3("repair_temporary_invalid", entry.path, "stale operation temporary is not a regular file", "path");
31014
- rmSync7(join21(directory, candidate.name), { force: true });
31040
+ rmSync7(join22(directory, candidate.name), { force: true });
31015
31041
  }
31016
31042
  const current = destinationSha(projectRoot, entry.path);
31017
31043
  if (current === entry.targetSha256) return;
@@ -31021,14 +31047,14 @@ function atomicInstallTarget(projectRoot, operation, entry) {
31021
31047
  requireConditionalLinkSupport(directory, operation.operationId, entry.path);
31022
31048
  const bytes = readTarget(projectRoot, entry.path);
31023
31049
  if (!bytes) fail3("init_transaction_target_missing", entry.path, "pinned target artifact is missing");
31024
- const temporary = join21(directory, `${temporaryPrefix}${randomUUID10()}.tmp`);
31050
+ const temporary = join22(directory, `${temporaryPrefix}${randomUUID10()}.tmp`);
31025
31051
  const mode = existsSync19(destination) ? lstatSync7(destination).mode & 511 : 420;
31026
31052
  try {
31027
31053
  writeDurableNew(temporary, bytes, mode);
31028
31054
  if (entry.observedSha256 !== null) {
31029
31055
  renameSync5(destination, displaced);
31030
31056
  syncDirectory2(directory);
31031
- if (vnextContentSha256(readFileSync19(displaced)) !== entry.observedSha256) {
31057
+ if (vnextContentSha256(readFileSync20(displaced)) !== entry.observedSha256) {
31032
31058
  if (!existsSync19(destination)) {
31033
31059
  try {
31034
31060
  linkSync(displaced, destination);
@@ -31067,12 +31093,12 @@ function atomicInstallTarget(projectRoot, operation, entry) {
31067
31093
  if (destinationSha(projectRoot, entry.path) !== entry.targetSha256) fail3("repair_install_verification_failed", entry.path, "installed target hash does not match the pinned operation");
31068
31094
  }
31069
31095
  function installedCreateMatches(projectRoot, operation) {
31070
- const configRoot = join21(projectRoot, ".kxm");
31096
+ const configRoot = join22(projectRoot, ".kxm");
31071
31097
  if (!existsSync19(configRoot)) return false;
31072
31098
  const actual = [];
31073
31099
  const visit2 = (directory) => {
31074
31100
  for (const entry of readdirSync7(directory, { withFileTypes: true })) {
31075
- const absolute = join21(directory, entry.name);
31101
+ const absolute = join22(directory, entry.name);
31076
31102
  if (entry.isSymbolicLink()) fail3("create_resume_link", relativeConfigPath(projectRoot, absolute), "created configuration must not contain links", "path");
31077
31103
  if (entry.isDirectory()) visit2(absolute);
31078
31104
  else if (entry.isFile()) actual.push(relativeConfigPath(projectRoot, absolute));
@@ -31093,7 +31119,7 @@ function syncTreeDirectories(root) {
31093
31119
  const visit2 = (directory) => {
31094
31120
  directories.push(directory);
31095
31121
  for (const entry of readdirSync7(directory, { withFileTypes: true })) {
31096
- if (entry.isDirectory()) visit2(join21(directory, entry.name));
31122
+ if (entry.isDirectory()) visit2(join22(directory, entry.name));
31097
31123
  }
31098
31124
  };
31099
31125
  visit2(root);
@@ -31107,7 +31133,7 @@ function rebuildCreateShadow(projectRoot, operation, options) {
31107
31133
  if (stat.isSymbolicLink() || !stat.isDirectory() || !installedCreateMatches(shadow, operation)) {
31108
31134
  fail3("create_shadow_invalid", TRANSACTION_NAME, "reconstructed create shadow does not exactly match pinned target files", "path");
31109
31135
  }
31110
- syncTreeDirectories(join21(shadow, ".kxm"));
31136
+ syncTreeDirectories(join22(shadow, ".kxm"));
31111
31137
  }
31112
31138
  function applyOperation(projectRoot, original, options, resumed) {
31113
31139
  assertNoRegisteredGates(options);
@@ -31117,10 +31143,10 @@ function applyOperation(projectRoot, original, options, resumed) {
31117
31143
  verifyBackups(projectRoot, operation);
31118
31144
  operation = updatePhase(projectRoot, operation, "applying");
31119
31145
  if (operation.kind === "create") {
31120
- const destination = join21(projectRoot, ".kxm");
31146
+ const destination = join22(projectRoot, ".kxm");
31121
31147
  if (!existsSync19(destination)) {
31122
31148
  rebuildCreateShadow(projectRoot, operation, effectiveOptions);
31123
- renameSync5(join21(shadowRoot(projectRoot), ".kxm"), destination);
31149
+ renameSync5(join22(shadowRoot(projectRoot), ".kxm"), destination);
31124
31150
  syncDirectory2(projectRoot);
31125
31151
  } else if (!installedCreateMatches(projectRoot, operation)) {
31126
31152
  fail3("create_resume_conflict", ".kxm", "existing project configuration does not match the pinned create operation");
@@ -31147,7 +31173,7 @@ function applyOperation(projectRoot, original, options, resumed) {
31147
31173
  operation = updatePhase(projectRoot, operation, "verified");
31148
31174
  if (options.testFaultAt === "verified") throw new Error("injected init fault after verification");
31149
31175
  const files = operation.files.map((entry) => entry.path);
31150
- syncTreeDirectories(join21(projectRoot, ".kxm"));
31176
+ syncTreeDirectories(join22(projectRoot, ".kxm"));
31151
31177
  return { kind: operation.kind, resumed, bundle, files };
31152
31178
  }
31153
31179
  function prepareAndApplyVnextCreate(projectRoot, rendered, options = {}) {
@@ -31262,7 +31288,7 @@ function finishPreparingOperation(projectRoot, operation, options) {
31262
31288
  const rendered = rendererForOperation(operation);
31263
31289
  if (!rendered) fail3("init_transaction_renderer_unavailable", TRANSACTION_NAME, "this binary cannot reproduce the pinned pre-application target");
31264
31290
  for (const directory of ["targets", "backups", "shadow"]) {
31265
- rmSync7(join21(transactionRoot(projectRoot), directory), { recursive: true, force: true });
31291
+ rmSync7(join22(transactionRoot(projectRoot), directory), { recursive: true, force: true });
31266
31292
  }
31267
31293
  for (const entry of operation.files) {
31268
31294
  const bytes = rendered.files.get(entry.path);
@@ -31297,7 +31323,7 @@ function commitVnextInitTransaction(projectRoot, schemasDir) {
31297
31323
  fail3("init_transaction_not_verified", TRANSACTION_NAME, "initialization transaction cannot commit before installed state is verified");
31298
31324
  }
31299
31325
  const transaction = transactionRoot(projectRoot);
31300
- const retired = join21(projectRoot, `${TRANSACTION_NAME}-cleanup-${operation.operationId}-${randomUUID10()}`);
31326
+ const retired = join22(projectRoot, `${TRANSACTION_NAME}-cleanup-${operation.operationId}-${randomUUID10()}`);
31301
31327
  renameSync5(transaction, retired);
31302
31328
  syncDirectory2(projectRoot);
31303
31329
  rmSync7(retired, { recursive: true, force: true });
@@ -31318,7 +31344,7 @@ function initIssue(code, file, message) {
31318
31344
  return { phase: "discovery", code, file, message };
31319
31345
  }
31320
31346
  function normalizedProjectName(root, requested) {
31321
- const name = (requested ?? basename4(root) ?? "KXM Project").trim();
31347
+ const name = (requested ?? basename5(root) ?? "KXM Project").trim();
31322
31348
  if (name.length < 1 || name.length > 120 || /[\u0000\r\n]/.test(name)) {
31323
31349
  throw new VnextConfigError([initIssue("project_name_invalid", ".kxm/project.yaml", "project name must contain 1-120 characters on one line")]);
31324
31350
  }
@@ -31406,7 +31432,7 @@ function validateBindingIdentities(bundle, persisted, explicit) {
31406
31432
  }
31407
31433
  function initializeVnextProjectAtGitRoot(start, gitRoot, options, mutationLock) {
31408
31434
  const storeOptions = bindingStoreOptions(options);
31409
- const persisted = existsSync20(join22(gitRoot, ".kxm", "project.yaml")) ? readVnextLocalBindings(gitRoot, storeOptions) : void 0;
31435
+ const persisted = existsSync20(join23(gitRoot, ".kxm", "project.yaml")) ? readVnextLocalBindings(gitRoot, storeOptions) : void 0;
31410
31436
  const repositoryBindings = Object.fromEntries([
31411
31437
  ...Object.entries(persisted?.repositories ?? {}),
31412
31438
  ...Object.entries(options.repositoryBindings ?? {})
@@ -31595,7 +31621,7 @@ function initializeVnextProjectAtGitRoot(start, gitRoot, options, mutationLock)
31595
31621
  const files = [...rendered.files.keys()];
31596
31622
  if (options.dryRun) return { action: "planned", plan, projectRoot: gitRoot, files };
31597
31623
  if (!mutationLock) throw new Error("project mutation lock is required to create configuration");
31598
- if (existsSync20(join22(gitRoot, ".kxm"))) {
31624
+ if (existsSync20(join23(gitRoot, ".kxm"))) {
31599
31625
  throw new VnextConfigError([initIssue("workspace_changed", ".kxm", "workspace changed after planning; existing .kxm state was not overwritten")]);
31600
31626
  }
31601
31627
  const created = prepareAndApplyVnextCreate(gitRoot, rendered, transactionOptions);
@@ -31627,8 +31653,8 @@ function initializeVnextProject(start = process.cwd(), options = {}) {
31627
31653
  // plugins/kxm/src/vnext-migrate.ts
31628
31654
  var import_yaml12 = __toESM(require_dist(), 1);
31629
31655
  import { createHash as createHash13 } from "node:crypto";
31630
- import { chmodSync as chmodSync6, closeSync as closeSync3, existsSync as existsSync21, fsyncSync as fsyncSync3, lstatSync as lstatSync8, mkdirSync as mkdirSync18, openSync as openSync3, readFileSync as readFileSync20, renameSync as renameSync6, rmSync as rmSync8, writeFileSync as writeFileSync17 } from "node:fs";
31631
- import { join as join23 } from "node:path";
31656
+ import { chmodSync as chmodSync6, closeSync as closeSync3, existsSync as existsSync21, fsyncSync as fsyncSync3, lstatSync as lstatSync8, mkdirSync as mkdirSync18, openSync as openSync3, readFileSync as readFileSync21, renameSync as renameSync6, rmSync as rmSync8, writeFileSync as writeFileSync17 } from "node:fs";
31657
+ import { join as join24 } from "node:path";
31632
31658
  var MAX_LEGACY_JSON_BYTES = 1024 * 1024;
31633
31659
  var MAX_LEGACY_JSON_DEPTH = 32;
31634
31660
  var MAX_LEGACY_JSON_NODES = 32768;
@@ -31797,12 +31823,12 @@ function readVnextLegacySources(root) {
31797
31823
  throw new VnextConfigError([migrateIssue("discovery", "legacy_source_limit", ".kxm/config", `legacy configuration exceeds ${MAX_LEGACY_SOURCES} files`)]);
31798
31824
  }
31799
31825
  return files.map((path4) => {
31800
- const absolute = join23(root, ...path4.split("/"));
31826
+ const absolute = join24(root, ...path4.split("/"));
31801
31827
  const stat = lstatSync8(absolute);
31802
31828
  if (stat.isSymbolicLink() || !stat.isFile()) {
31803
31829
  throw new VnextConfigError([migrateIssue("path", "legacy_source_invalid", path4, "legacy configuration must be a regular file, not a link")]);
31804
31830
  }
31805
- const buffer = readFileSync20(absolute);
31831
+ const buffer = readFileSync21(absolute);
31806
31832
  let text;
31807
31833
  try {
31808
31834
  text = new TextDecoder("utf-8", { fatal: true }).decode(buffer);
@@ -32879,7 +32905,7 @@ function readVnextMigrationDecisions(path4, schemasDir) {
32879
32905
  throw new VnextConfigError([migrateIssue("discovery", "decisions_missing", path4, "migration decisions file does not exist")]);
32880
32906
  }
32881
32907
  const registry = new VnextSchemaRegistry(schemasDir);
32882
- const value = parseRestrictedYaml2(readFileSync20(path4), path4);
32908
+ const value = parseRestrictedYaml2(readFileSync21(path4), path4);
32883
32909
  const issues = registry.validateMigrationDecision(value, path4);
32884
32910
  if (issues.length > 0) throw new VnextConfigError(issues);
32885
32911
  return value;
@@ -32918,7 +32944,7 @@ function writeDurable2(path4, content) {
32918
32944
  chmodSync6(path4, 384);
32919
32945
  } catch {
32920
32946
  }
32921
- syncDirectory3(join23(path4, ".."));
32947
+ syncDirectory3(join24(path4, ".."));
32922
32948
  } finally {
32923
32949
  if (created && existsSync21(temp)) rmSync8(temp, { force: true });
32924
32950
  }
@@ -32930,7 +32956,7 @@ function applyVnextMigration(projectRoot, options = {}) {
32930
32956
  ...options.schemasDir === void 0 ? {} : { schemasDir: options.schemasDir }
32931
32957
  };
32932
32958
  const execute = (lock) => {
32933
- const receiptAbsolute = join23(root, ...VNEXT_MIGRATION_RECEIPT_PATH.split("/"));
32959
+ const receiptAbsolute = join24(root, ...VNEXT_MIGRATION_RECEIPT_PATH.split("/"));
32934
32960
  if (existsSync21(receiptAbsolute)) {
32935
32961
  const stat = lstatSync8(receiptAbsolute);
32936
32962
  if (stat.isSymbolicLink() || !stat.isFile()) {
@@ -32984,7 +33010,7 @@ function applyVnextMigration(projectRoot, options = {}) {
32984
33010
  return { action: "planned", projectRoot: root, files: [], plan: first.plan };
32985
33011
  }
32986
33012
  const files = [...first.resources.entries()].sort(([left], [right]) => compareCodeUnits6(left, right)).map(([path4, value]) => ({ path: path4, bytes: Buffer.from((0, import_yaml12.stringify)(value, { lineWidth: 0 }), "utf8") }));
32987
- const collisions = files.filter((file) => existsSync21(join23(root, ...file.path.split("/"))));
33013
+ const collisions = files.filter((file) => existsSync21(join24(root, ...file.path.split("/"))));
32988
33014
  if (collisions.length > 0) {
32989
33015
  throw new VnextConfigError(collisions.map((file) => migrateIssue("semantic", "migration_target_exists", file.path, "target resource already exists; refusing to overwrite")));
32990
33016
  }
@@ -32993,7 +33019,7 @@ function applyVnextMigration(projectRoot, options = {}) {
32993
33019
  const segments = file.path.split("/");
32994
33020
  let current = root;
32995
33021
  for (const segment of segments.slice(0, -1)) {
32996
- current = join23(current, segment);
33022
+ current = join24(current, segment);
32997
33023
  if (!existsSync21(current)) continue;
32998
33024
  const stat = lstatSync8(current);
32999
33025
  if (stat.isSymbolicLink() || !stat.isDirectory()) {
@@ -33010,8 +33036,8 @@ function applyVnextMigration(projectRoot, options = {}) {
33010
33036
  const written = [];
33011
33037
  try {
33012
33038
  for (const file of files) {
33013
- const absolute = join23(root, ...file.path.split("/"));
33014
- mkdirSync18(join23(absolute, ".."), { recursive: true });
33039
+ const absolute = join24(root, ...file.path.split("/"));
33040
+ mkdirSync18(join24(absolute, ".."), { recursive: true });
33015
33041
  written.push(absolute);
33016
33042
  writeDurable2(absolute, file.bytes);
33017
33043
  }
@@ -33057,7 +33083,7 @@ ${bundle.configRevision}`).slice(7, 39)}`,
33057
33083
  }
33058
33084
  function verifyVnextMigration(projectRoot, options = {}) {
33059
33085
  const root = migrationGitRoot(projectRoot);
33060
- const receiptAbsolute = join23(root, ...VNEXT_MIGRATION_RECEIPT_PATH.split("/"));
33086
+ const receiptAbsolute = join24(root, ...VNEXT_MIGRATION_RECEIPT_PATH.split("/"));
33061
33087
  if (!existsSync21(receiptAbsolute)) {
33062
33088
  return {
33063
33089
  ok: false,
@@ -33368,7 +33394,7 @@ async function cmdBackup(runtime, options) {
33368
33394
  const summary = [
33369
33395
  `Created SQLite backup with ${manifest.stores.length} store(s):`,
33370
33396
  ...manifest.stores.map((s) => ` - ${s.storeId}: ${s.sourcePath} -> ${s.backupFile} (schema v${s.schemaVersion}, ${s.bytes} bytes, sha256 ${s.sha256.slice(0, 12)}...)`),
33371
- `Manifest: ${join24(outDir, "manifest.json")}`
33397
+ `Manifest: ${join25(outDir, "manifest.json")}`
33372
33398
  ].join("\n");
33373
33399
  print(runtime.io, runtime.json, payload, summary);
33374
33400
  return 0;
@@ -33938,7 +33964,7 @@ async function cmdStudioLayout(runtime, workflowPath) {
33938
33964
  let yamlContent;
33939
33965
  let workflowId = "default";
33940
33966
  if (existsSync22(filePath)) {
33941
- yamlContent = readFileSync21(filePath, "utf8");
33967
+ yamlContent = readFileSync22(filePath, "utf8");
33942
33968
  } else {
33943
33969
  yamlContent = `schema: kxm.workflow.v1
33944
33970
  description: Feature implementation workflow
@@ -34011,17 +34037,17 @@ async function cmdStudioServe(runtime, options) {
34011
34037
  sessionToken,
34012
34038
  planProvider: () => {
34013
34039
  try {
34014
- const wfDir = join25(runtime.cwd, ".kxm", "workflows");
34015
- const defaultPath = join25(wfDir, "default.yaml");
34040
+ const wfDir = join26(runtime.cwd, ".kxm", "workflows");
34041
+ const defaultPath = join26(wfDir, "default.yaml");
34016
34042
  let targetPath = existsSync22(defaultPath) ? defaultPath : void 0;
34017
34043
  if (!targetPath && existsSync22(wfDir)) {
34018
34044
  const yml = readdirSync8(wfDir).find((f) => f.endsWith(".yaml") || f.endsWith(".yml"));
34019
- if (yml) targetPath = join25(wfDir, yml);
34045
+ if (yml) targetPath = join26(wfDir, yml);
34020
34046
  }
34021
34047
  if (targetPath && existsSync22(targetPath)) {
34022
- const raw = readFileSync21(targetPath, "utf8");
34048
+ const raw = readFileSync22(targetPath, "utf8");
34023
34049
  const parsed = (0, import_yaml13.parse)(raw);
34024
- const wfId = basename5(targetPath).replace(/\.(yaml|yml)$/, "");
34050
+ const wfId = basename6(targetPath).replace(/\.(yaml|yml)$/, "");
34025
34051
  return compileVnextWorkflow({ id: wfId, value: parsed });
34026
34052
  }
34027
34053
  } catch {
@@ -34069,14 +34095,14 @@ Press Ctrl+C to stop.
34069
34095
  }
34070
34096
 
34071
34097
  // plugins/kxm/src/cli/context-skills.ts
34072
- import { readFileSync as readFileSync24 } from "node:fs";
34073
- import { join as join29, relative as relative5 } from "node:path";
34098
+ import { readFileSync as readFileSync25 } from "node:fs";
34099
+ import { join as join30, relative as relative5 } from "node:path";
34074
34100
 
34075
34101
  // plugins/kxm/src/memory.ts
34076
34102
  var import_yaml14 = __toESM(require_dist(), 1);
34077
34103
  import { randomUUID as randomUUID12 } from "node:crypto";
34078
- import { existsSync as existsSync23, mkdirSync as mkdirSync19, readdirSync as readdirSync9, readFileSync as readFileSync22, writeFileSync as writeFileSync18 } from "node:fs";
34079
- import { extname as extname2, join as join26, resolve as resolve22 } from "node:path";
34104
+ import { existsSync as existsSync23, mkdirSync as mkdirSync19, readdirSync as readdirSync9, readFileSync as readFileSync23, writeFileSync as writeFileSync18 } from "node:fs";
34105
+ import { extname as extname2, join as join27, resolve as resolve22 } from "node:path";
34080
34106
  var MEMORY_SCHEMA = "kxm.memory.v1";
34081
34107
  var MEMORY_BRIEF_SCHEMA = "kxm.memory-brief.v1";
34082
34108
  var MEMORY_MARKER_START = "<!-- kxm:memory:start -->";
@@ -34203,8 +34229,8 @@ ${yamlText}
34203
34229
  }
34204
34230
  function memoryDirectories(repoRoot6) {
34205
34231
  const root = resolve22(repoRoot6);
34206
- const memoryDir = join26(root, ".kxm", "memory");
34207
- const candidatesDir = join26(memoryDir, "candidates");
34232
+ const memoryDir = join27(root, ".kxm", "memory");
34233
+ const candidatesDir = join27(memoryDir, "candidates");
34208
34234
  return { memoryDir, candidatesDir };
34209
34235
  }
34210
34236
  function loadAuthoredMemory(repoRoot6) {
@@ -34214,9 +34240,9 @@ function loadAuthoredMemory(repoRoot6) {
34214
34240
  const entries = readdirSync9(memoryDir, { withFileTypes: true });
34215
34241
  for (const entry of entries) {
34216
34242
  if (entry.isFile() && extname2(entry.name) === ".md") {
34217
- const fullPath = join26(memoryDir, entry.name);
34243
+ const fullPath = join27(memoryDir, entry.name);
34218
34244
  try {
34219
- const text = readFileSync22(fullPath, "utf8");
34245
+ const text = readFileSync23(fullPath, "utf8");
34220
34246
  const record = parseMemoryRecord(text, entry.name);
34221
34247
  if (record.lifecycle === "active") {
34222
34248
  records.push(record);
@@ -34255,7 +34281,7 @@ function createMemoryNote(repoRoot6, summary, options = {}) {
34255
34281
  evidenceRefs: [],
34256
34282
  ...options.body ? { body: options.body.trim() } : {}
34257
34283
  };
34258
- const targetPath = join26(candidatesDir, `${id}.md`);
34284
+ const targetPath = join27(candidatesDir, `${id}.md`);
34259
34285
  writeFileSync18(targetPath, formatMemoryRecord(record), "utf8");
34260
34286
  return { record, path: targetPath };
34261
34287
  }
@@ -34293,7 +34319,7 @@ function formatHarnessMemoryBlock(records) {
34293
34319
  function updateHarnessDocument(filePath, block, defaultHeader) {
34294
34320
  let original = "";
34295
34321
  if (existsSync23(filePath)) {
34296
- original = readFileSync22(filePath, "utf8");
34322
+ original = readFileSync23(filePath, "utf8");
34297
34323
  }
34298
34324
  let updated = "";
34299
34325
  if (original.includes(MEMORY_MARKER_START) && original.includes(MEMORY_MARKER_END)) {
@@ -34332,14 +34358,14 @@ function syncHarnessMemory(repoRoot6) {
34332
34358
  const block = formatHarnessMemoryBlock(records);
34333
34359
  const updated = [];
34334
34360
  const created = [];
34335
- const agentsPath = join26(root, "AGENTS.md");
34361
+ const agentsPath = join27(root, "AGENTS.md");
34336
34362
  const agentsHeader = "# AGENTS\n\nFollow project instructions.\n";
34337
34363
  const agentsExisted = existsSync23(agentsPath);
34338
34364
  if (updateHarnessDocument(agentsPath, block, agentsHeader)) {
34339
34365
  if (agentsExisted) updated.push("AGENTS.md");
34340
34366
  else created.push("AGENTS.md");
34341
34367
  }
34342
- const claudePath = join26(root, "CLAUDE.md");
34368
+ const claudePath = join27(root, "CLAUDE.md");
34343
34369
  const claudeHeader = `# KXM (Claude)
34344
34370
 
34345
34371
  Follow [\`AGENTS.md\`](AGENTS.md). Official phase tracking:
@@ -34355,7 +34381,7 @@ artifacts, not hub \`peer-reply\` evidence.
34355
34381
  if (claudeExisted) updated.push("CLAUDE.md");
34356
34382
  else created.push("CLAUDE.md");
34357
34383
  }
34358
- const geminiPath = join26(root, "GEMINI.md");
34384
+ const geminiPath = join27(root, "GEMINI.md");
34359
34385
  const geminiHeader = `# KXM (Gemini / Antigravity)
34360
34386
 
34361
34387
  Follow [\`AGENTS.md\`](AGENTS.md). Official phase tracking:
@@ -34375,8 +34401,8 @@ for Gemini models. Starting rotation remains Grok.
34375
34401
  // plugins/kxm/src/skills.ts
34376
34402
  var import_yaml15 = __toESM(require_dist(), 1);
34377
34403
  import { createHash as createHash14 } from "node:crypto";
34378
- import { existsSync as existsSync24, mkdirSync as mkdirSync20, readdirSync as readdirSync10, readFileSync as readFileSync23, renameSync as renameSync7, rmSync as rmSync9, statSync as statSync3, writeFileSync as writeFileSync19 } from "node:fs";
34379
- import { join as join27 } from "node:path";
34404
+ import { existsSync as existsSync24, mkdirSync as mkdirSync20, readdirSync as readdirSync10, readFileSync as readFileSync24, renameSync as renameSync7, rmSync as rmSync9, statSync as statSync3, writeFileSync as writeFileSync19 } from "node:fs";
34405
+ import { join as join28 } from "node:path";
34380
34406
  var SKILL_CANDIDATE_SCHEMA = "kxm.skill-candidate.v1";
34381
34407
  var SKILL_EVALUATION_SCHEMA = "kxm.skill-evaluation.v1";
34382
34408
  var SKILL_DECISION_SCHEMA = "kxm.skill-decision.v1";
@@ -34470,21 +34496,21 @@ var SkillLifecycle = class {
34470
34496
  this.allowOptimizationEvals = options.allowOptimizationEvals === true;
34471
34497
  }
34472
34498
  dir(state) {
34473
- return join27(this.root, state === "candidate" ? "candidates" : `${state}s`.replace("rejecteds", "rejected").replace("promoteds", "promoted"));
34499
+ return join28(this.root, state === "candidate" ? "candidates" : `${state}s`.replace("rejecteds", "rejected").replace("promoteds", "promoted"));
34474
34500
  }
34475
34501
  historyFile(id) {
34476
- return join27(this.root, "history", `${id}.jsonl`);
34502
+ return join28(this.root, "history", `${id}.jsonl`);
34477
34503
  }
34478
34504
  paths(state, id) {
34479
- const dir = join27(this.dir(state), id);
34480
- return { dir, metadata: join27(dir, "metadata.json"), skill: join27(dir, "SKILL.md") };
34505
+ const dir = join28(this.dir(state), id);
34506
+ return { dir, metadata: join28(dir, "metadata.json"), skill: join28(dir, "SKILL.md") };
34481
34507
  }
34482
34508
  appendHistory(id, record) {
34483
- mkdirSync20(join27(this.root, "history"), { recursive: true });
34509
+ mkdirSync20(join28(this.root, "history"), { recursive: true });
34484
34510
  const line = `${JSON.stringify(record)}
34485
34511
  `;
34486
34512
  if (existsSync24(this.historyFile(id))) {
34487
- const existing = readFileSync23(this.historyFile(id), "utf8");
34513
+ const existing = readFileSync24(this.historyFile(id), "utf8");
34488
34514
  const lines = existing.split("\n").filter((entry) => entry.trim());
34489
34515
  writeFileSync19(this.historyFile(id), [...lines.slice(-499), line.trim()].join("\n") + "\n");
34490
34516
  } else {
@@ -34494,18 +34520,18 @@ var SkillLifecycle = class {
34494
34520
  history(id) {
34495
34521
  const file = this.historyFile(id);
34496
34522
  if (!existsSync24(file)) return [];
34497
- return readFileSync23(file, "utf8").split("\n").filter((line) => line.trim()).map((line) => JSON.parse(line));
34523
+ return readFileSync24(file, "utf8").split("\n").filter((line) => line.trim()).map((line) => JSON.parse(line));
34498
34524
  }
34499
34525
  readMetadata(state, id) {
34500
34526
  const { metadata } = this.paths(state, id);
34501
34527
  if (!existsSync24(metadata)) {
34502
34528
  throw new SkillLifecycleError("skill_not_found", `skill ${id} not found in ${state}`);
34503
34529
  }
34504
- return JSON.parse(readFileSync23(metadata, "utf8"));
34530
+ return JSON.parse(readFileSync24(metadata, "utf8"));
34505
34531
  }
34506
34532
  move(from, to, id) {
34507
- const fromDir = join27(this.dir(from), id);
34508
- const toDir = join27(this.dir(to), id);
34533
+ const fromDir = join28(this.dir(from), id);
34534
+ const toDir = join28(this.dir(to), id);
34509
34535
  if (!existsSync24(fromDir)) {
34510
34536
  throw new SkillLifecycleError("skill_not_found", `skill ${id} not found in ${from}`);
34511
34537
  }
@@ -34664,13 +34690,13 @@ var SkillLifecycle = class {
34664
34690
  const candidatePaths = this.paths("candidate", candidateId);
34665
34691
  const promotedPaths = this.paths("promoted", candidateId);
34666
34692
  mkdirSync20(promotedPaths.dir, { recursive: true });
34667
- const skillContent = readFileSync23(candidatePaths.skill, "utf8");
34668
- const metadataContent = readFileSync23(candidatePaths.metadata, "utf8");
34693
+ const skillContent = readFileSync24(candidatePaths.skill, "utf8");
34694
+ const metadataContent = readFileSync24(candidatePaths.metadata, "utf8");
34669
34695
  writeFileSync19(promotedPaths.skill, skillContent);
34670
34696
  writeFileSync19(promotedPaths.metadata, metadataContent);
34671
- const patchesDir = join27(this.root, "patches");
34697
+ const patchesDir = join28(this.root, "patches");
34672
34698
  mkdirSync20(patchesDir, { recursive: true });
34673
- const patchPath = join27(patchesDir, `${candidateId}.patch`);
34699
+ const patchPath = join28(patchesDir, `${candidateId}.patch`);
34674
34700
  const relSkillPath = `.kxm/skills/promoted/${candidateId}/SKILL.md`;
34675
34701
  const relMetaPath = `.kxm/skills/promoted/${candidateId}/metadata.json`;
34676
34702
  const patch = `${createUnifiedPatch(relSkillPath, skillContent)}${createUnifiedPatch(relMetaPath, metadataContent)}`;
@@ -34698,7 +34724,7 @@ var SkillLifecycle = class {
34698
34724
  verify(state, id) {
34699
34725
  const metadata = this.readMetadata(state, id);
34700
34726
  const { skill } = this.paths(state, id);
34701
- const content = readFileSync23(skill, "utf8");
34727
+ const content = readFileSync24(skill, "utf8");
34702
34728
  if (skillContentSha256(content) !== metadata.contentSha256) {
34703
34729
  throw new SkillLifecycleError(
34704
34730
  "skill_integrity_violation",
@@ -34729,7 +34755,7 @@ var SkillLifecycle = class {
34729
34755
  read(state, id) {
34730
34756
  const metadata = this.readMetadata(state, id);
34731
34757
  const { skill } = this.paths(state, id);
34732
- return { metadata, content: readFileSync23(skill, "utf8") };
34758
+ return { metadata, content: readFileSync24(skill, "utf8") };
34733
34759
  }
34734
34760
  };
34735
34761
  function boundedList(value, field) {
@@ -34744,16 +34770,16 @@ function boundedList(value, field) {
34744
34770
  return [...new Set(refs)];
34745
34771
  }
34746
34772
  function readdirSorted(dir) {
34747
- return readdirSync10(dir).filter((entry) => statSync3(join27(dir, entry)).isDirectory()).sort();
34773
+ return readdirSync10(dir).filter((entry) => statSync3(join28(dir, entry)).isDirectory()).sort();
34748
34774
  }
34749
34775
 
34750
34776
  // plugins/kxm/src/wiki.ts
34751
34777
  import { mkdirSync as mkdirSync21, writeFileSync as writeFileSync20 } from "node:fs";
34752
- import { join as join28 } from "node:path";
34778
+ import { join as join29 } from "node:path";
34753
34779
  function writeCompiledWiki(root, wiki) {
34754
34780
  const written = [];
34755
34781
  for (const [relativePath, content] of [...wiki.pages].sort(([left], [right]) => left.localeCompare(right))) {
34756
- const absolute = join28(root, relativePath);
34782
+ const absolute = join29(root, relativePath);
34757
34783
  mkdirSync21(absolute.slice(0, absolute.lastIndexOf("/")), { recursive: true });
34758
34784
  writeFileSync20(absolute, content);
34759
34785
  written.push(relativePath);
@@ -34921,7 +34947,7 @@ function skillStateFromFlag(value) {
34921
34947
  throw new Error(`invalid skill state ${value}`);
34922
34948
  }
34923
34949
  function skillsRoot(runtime) {
34924
- return join29(runtime.dirs.workdir, ".kxm", "skills");
34950
+ return join30(runtime.dirs.workdir, ".kxm", "skills");
34925
34951
  }
34926
34952
  function csv(value) {
34927
34953
  if (!value) return void 0;
@@ -34938,7 +34964,7 @@ async function cmdSkillsCreate(runtime, options) {
34938
34964
  const metadata = lifecycle.create({
34939
34965
  name: options.name,
34940
34966
  description: options.description ?? "",
34941
- content: readFileSync24(options.file, "utf8"),
34967
+ content: readFileSync25(options.file, "utf8"),
34942
34968
  createdBy: options.createdBy,
34943
34969
  sources: {
34944
34970
  runIds: csv(options.run) ?? [],
@@ -35096,8 +35122,8 @@ async function cmdMemorySync(runtime) {
35096
35122
 
35097
35123
  // plugins/kxm/src/cli/hub.ts
35098
35124
  import { randomUUID as randomUUID14 } from "node:crypto";
35099
- import { existsSync as existsSync30, mkdirSync as mkdirSync25, readFileSync as readFileSync30, readdirSync as readdirSync12, rmSync as rmSync10, writeFileSync as writeFileSync23 } from "node:fs";
35100
- import { basename as basename7, join as join39, resolve as resolve25 } from "node:path";
35125
+ import { existsSync as existsSync30, mkdirSync as mkdirSync25, readFileSync as readFileSync31, readdirSync as readdirSync12, rmSync as rmSync10, writeFileSync as writeFileSync23 } from "node:fs";
35126
+ import { join as join40, resolve as resolve25 } from "node:path";
35101
35127
 
35102
35128
  // node_modules/marked/lib/marked.esm.js
35103
35129
  function M() {
@@ -41030,7 +41056,7 @@ import * as path2 from "node:path";
41030
41056
 
41031
41057
  // node_modules/@earendil-works/pi-tui/dist/native-module-path.js
41032
41058
  import { createRequire as createRequire2 } from "node:module";
41033
- import { dirname as dirname16, join as join30 } from "node:path";
41059
+ import { dirname as dirname16, join as join31 } from "node:path";
41034
41060
  import { fileURLToPath as fileURLToPath5 } from "node:url";
41035
41061
  var moduleRequire = createRequire2(import.meta.url);
41036
41062
  var TUI_PACKAGE_NAME = "@earendil-works/pi-tui";
@@ -41039,10 +41065,10 @@ function getNativeModuleCandidates(nativePath, options = {}) {
41039
41065
  const candidates = [];
41040
41066
  try {
41041
41067
  const packageEntry = (options.resolvePackage ?? moduleRequire.resolve)(TUI_PACKAGE_NAME);
41042
- candidates.push(join30(dirname16(packageEntry), "..", nativePath));
41068
+ candidates.push(join31(dirname16(packageEntry), "..", nativePath));
41043
41069
  } catch {
41044
41070
  }
41045
- candidates.push(join30(moduleDir, "..", nativePath), join30(moduleDir, nativePath), join30(dirname16(options.execPath ?? process.execPath), nativePath));
41071
+ candidates.push(join31(moduleDir, "..", nativePath), join31(moduleDir, nativePath), join31(dirname16(options.execPath ?? process.execPath), nativePath));
41046
41072
  return Array.from(new Set(candidates));
41047
41073
  }
41048
41074
 
@@ -43499,7 +43525,7 @@ var MAX_RENDER_WRITE_CHARS = 1024 * 1024;
43499
43525
 
43500
43526
  // plugins/kxm/src/tui.ts
43501
43527
  import { mkdirSync as mkdirSync22 } from "node:fs";
43502
- import { join as join34, resolve as resolve24, dirname as dirname17 } from "node:path";
43528
+ import { join as join35, resolve as resolve24, dirname as dirname17 } from "node:path";
43503
43529
  import { spawnSync as spawnSync5 } from "node:child_process";
43504
43530
 
43505
43531
  // plugins/kxm/src/external-effects.ts
@@ -43510,9 +43536,9 @@ function slugifyBranchPart(text, maxLength = 40) {
43510
43536
  }
43511
43537
 
43512
43538
  // plugins/kxm/src/local-snapshot.ts
43513
- import { existsSync as existsSync25, readdirSync as readdirSync11, readFileSync as readFileSync25 } from "node:fs";
43539
+ import { existsSync as existsSync25, readdirSync as readdirSync11, readFileSync as readFileSync26 } from "node:fs";
43514
43540
  import { homedir as homedir5 } from "node:os";
43515
- import { isAbsolute as isAbsolute7, join as join33, resolve as resolve23 } from "node:path";
43541
+ import { isAbsolute as isAbsolute7, join as join34, resolve as resolve23 } from "node:path";
43516
43542
  function processExists2(pid) {
43517
43543
  try {
43518
43544
  process.kill(pid, 0);
@@ -43632,16 +43658,16 @@ function readOpenMessageMetadata(database) {
43632
43658
  return messages;
43633
43659
  }
43634
43660
  function resolveKxmSnapshotPaths(cwd, env = process.env) {
43635
- const stateDir = env.KXM_STATE_DIR?.trim() || join33(cwd, ".kxm", "state");
43661
+ const stateDir = env.KXM_STATE_DIR?.trim() || join34(cwd, ".kxm", "state");
43636
43662
  const configured = env.KXM_DATA_PATH?.trim();
43637
- const dataPath = configured ? resolve23(cwd, configured) : join33(stateDir, "kxm.db");
43663
+ const dataPath = configured ? resolve23(cwd, configured) : join34(stateDir, "kxm.db");
43638
43664
  return { dataPath, stateDir };
43639
43665
  }
43640
43666
  function resolveVnextStateRoot(stateDir, options) {
43641
43667
  if (options?.vnextStateRoot && existsSync25(options.vnextStateRoot)) {
43642
43668
  return resolve23(options.vnextStateRoot);
43643
43669
  }
43644
- if (existsSync25(join33(stateDir, "runtime", "registry.db")) || existsSync25(join33(stateDir, "runtime", "projects"))) {
43670
+ if (existsSync25(join34(stateDir, "runtime", "registry.db")) || existsSync25(join34(stateDir, "runtime", "projects"))) {
43645
43671
  return stateDir;
43646
43672
  }
43647
43673
  const env = options?.env ?? process.env;
@@ -43652,13 +43678,13 @@ function resolveVnextStateRoot(stateDir, options) {
43652
43678
  let base;
43653
43679
  if (process.platform === "win32") {
43654
43680
  const localAppData = env.LOCALAPPDATA?.trim();
43655
- base = localAppData && isAbsolute7(localAppData) ? localAppData : join33(homedir5(), "AppData", "Local");
43681
+ base = localAppData && isAbsolute7(localAppData) ? localAppData : join34(homedir5(), "AppData", "Local");
43656
43682
  base = resolve23(base, "KXM");
43657
43683
  } else if (process.platform === "darwin") {
43658
43684
  base = resolve23(homedir5(), "Library", "Application Support", "KXM");
43659
43685
  } else {
43660
43686
  const xdgState = env.XDG_STATE_HOME?.trim();
43661
- base = xdgState && isAbsolute7(xdgState) ? xdgState : join33(homedir5(), ".local", "state");
43687
+ base = xdgState && isAbsolute7(xdgState) ? xdgState : join34(homedir5(), ".local", "state");
43662
43688
  base = resolve23(base, "kxm");
43663
43689
  }
43664
43690
  if (existsSync25(base)) return base;
@@ -43692,9 +43718,9 @@ function loadLocalMeshSnapshot(dataPath, stateDir, options) {
43692
43718
  let vnextRunTotal = 0;
43693
43719
  const vnextStateRoot = resolveVnextStateRoot(stateDir, options);
43694
43720
  if (vnextStateRoot) {
43695
- const runtimeDir = join33(vnextStateRoot, "runtime");
43696
- const registryDbPath = join33(runtimeDir, "registry.db");
43697
- const projectsDir = join33(runtimeDir, "projects");
43721
+ const runtimeDir = join34(vnextStateRoot, "runtime");
43722
+ const registryDbPath = join34(runtimeDir, "registry.db");
43723
+ const projectsDir = join34(runtimeDir, "projects");
43698
43724
  const projectKeys = /* @__PURE__ */ new Set();
43699
43725
  if (existsSync25(registryDbPath)) {
43700
43726
  hasVnext = true;
@@ -43723,7 +43749,7 @@ function loadLocalMeshSnapshot(dataPath, stateDir, options) {
43723
43749
  }
43724
43750
  }
43725
43751
  for (const key of projectKeys) {
43726
- const eventDbPath = join33(projectsDir, key, "run-events.db");
43752
+ const eventDbPath = join34(projectsDir, key, "run-events.db");
43727
43753
  if (existsSync25(eventDbPath)) {
43728
43754
  hasVnext = true;
43729
43755
  try {
@@ -43757,7 +43783,7 @@ function loadLocalMeshSnapshot(dataPath, stateDir, options) {
43757
43783
  if (existsSync25(stateDir)) {
43758
43784
  for (const file of readdirSync11(stateDir).filter((name) => name.endsWith(".pid"))) {
43759
43785
  try {
43760
- const record = JSON.parse(readFileSync25(join33(stateDir, file), "utf8"));
43786
+ const record = JSON.parse(readFileSync26(join34(stateDir, file), "utf8"));
43761
43787
  pids.push({
43762
43788
  file,
43763
43789
  ...record.role ? { role: record.role } : {},
@@ -43796,7 +43822,7 @@ function loadLocalMeshSnapshot(dataPath, stateDir, options) {
43796
43822
  } else {
43797
43823
  source = "legacy";
43798
43824
  }
43799
- const telemetryFile = join33(stateDir, "telemetry.jsonl");
43825
+ const telemetryFile = join34(stateDir, "telemetry.jsonl");
43800
43826
  const spend = existsSync25(telemetryFile) ? readRoutingRecords(telemetryFile) : [];
43801
43827
  return {
43802
43828
  source,
@@ -43931,7 +43957,7 @@ function spawnDegradeWorktree(repoRoot6, runId, options) {
43931
43957
  const cleanRunId = runId.replace(/^run_/, "");
43932
43958
  const desc = options?.description ? slugifyBranchPart(options.description, 30) : "degrade";
43933
43959
  const branchName = `kxm/run-${cleanRunId}-${desc}`;
43934
- const relativeWtPath = join34(".kxm", "worktrees", `run-${cleanRunId}-${desc}`);
43960
+ const relativeWtPath = join35(".kxm", "worktrees", `run-${cleanRunId}-${desc}`);
43935
43961
  const absoluteWtPath = resolve24(repoRoot6, relativeWtPath);
43936
43962
  const jumpCommand = `cd "${absoluteWtPath}"`;
43937
43963
  try {
@@ -44701,8 +44727,8 @@ async function runMeshTui(input) {
44701
44727
  // plugins/kxm/src/session-work.ts
44702
44728
  import { spawnSync as spawnSync6 } from "node:child_process";
44703
44729
  import { randomUUID as randomUUID13 } from "node:crypto";
44704
- import { existsSync as existsSync26, mkdirSync as mkdirSync23, readFileSync as readFileSync26, renameSync as renameSync8, writeFileSync as writeFileSync21 } from "node:fs";
44705
- import { join as join35 } from "node:path";
44730
+ import { existsSync as existsSync26, mkdirSync as mkdirSync23, readFileSync as readFileSync27, renameSync as renameSync8, writeFileSync as writeFileSync21 } from "node:fs";
44731
+ import { join as join36 } from "node:path";
44706
44732
  var MAX_SESSION_BRIEF_TASKS = 5;
44707
44733
  var MAX_SESSION_BRIEF_PLANS = 5;
44708
44734
  var SESSION_BRIEF_SCHEMA = "kxm.session-brief.v1";
@@ -44858,10 +44884,10 @@ function buildSessionBrief(snapshot, current, hub, ship, updateLatest, cost, ses
44858
44884
  };
44859
44885
  }
44860
44886
  function readCachedSessionBrief(stateDir) {
44861
- const file = join35(stateDir, "session-brief.json");
44887
+ const file = join36(stateDir, "session-brief.json");
44862
44888
  try {
44863
44889
  if (!existsSync26(file)) return void 0;
44864
- const raw = readFileSync26(file, "utf8");
44890
+ const raw = readFileSync27(file, "utf8");
44865
44891
  const parsed = JSON.parse(raw);
44866
44892
  if (parsed && parsed.schema === "kxm.session-brief.v1" && typeof parsed.generatedAt === "string") {
44867
44893
  const ageMs = Date.now() - Date.parse(parsed.generatedAt);
@@ -44877,7 +44903,7 @@ function readCachedSessionBrief(stateDir) {
44877
44903
  function writeCachedSessionBrief(stateDir, brief) {
44878
44904
  try {
44879
44905
  mkdirSync23(stateDir, { recursive: true, mode: 448 });
44880
- const file = join35(stateDir, "session-brief.json");
44906
+ const file = join36(stateDir, "session-brief.json");
44881
44907
  const tmp = `${file}.tmp.${randomUUID13().slice(0, 8)}`;
44882
44908
  writeFileSync21(tmp, JSON.stringify(brief, null, 2), { encoding: "utf8", mode: 384 });
44883
44909
  renameSync8(tmp, file);
@@ -44886,7 +44912,7 @@ function writeCachedSessionBrief(stateDir, brief) {
44886
44912
  }
44887
44913
  function estimateSessionCost(stateDir) {
44888
44914
  try {
44889
- const telemetryFile = join35(stateDir, "telemetry.jsonl");
44915
+ const telemetryFile = join36(stateDir, "telemetry.jsonl");
44890
44916
  if (!existsSync26(telemetryFile)) return void 0;
44891
44917
  const records = readRoutingRecords(telemetryFile);
44892
44918
  if (records.length === 0) return void 0;
@@ -45055,11 +45081,11 @@ function formatSessionBriefText(brief) {
45055
45081
  }
45056
45082
 
45057
45083
  // plugins/kxm/src/kxm-install-kind.ts
45058
- import { existsSync as existsSync27, readFileSync as readFileSync27 } from "node:fs";
45059
- import { dirname as dirname18, join as join36 } from "node:path";
45084
+ import { existsSync as existsSync27, readFileSync as readFileSync28 } from "node:fs";
45085
+ import { dirname as dirname18, join as join37 } from "node:path";
45060
45086
  function packageIsKxm(root) {
45061
45087
  try {
45062
- const pkg = JSON.parse(readFileSync27(join36(root, "package.json"), "utf8"));
45088
+ const pkg = JSON.parse(readFileSync28(join37(root, "package.json"), "utf8"));
45063
45089
  return pkg.name === "@kontextmind/kxm";
45064
45090
  } catch {
45065
45091
  return false;
@@ -45108,12 +45134,12 @@ function report(kind, root) {
45108
45134
  return { kind, root, instruction: installKindInstruction(kind, root) };
45109
45135
  }
45110
45136
  function classifyInstallRoot(probe) {
45111
- const piGitRoot = join36(probe.homeDir, ".pi", "agent", "git");
45137
+ const piGitRoot = join37(probe.homeDir, ".pi", "agent", "git");
45112
45138
  if (isUnder(probe.repoRoot, piGitRoot, probe.platform)) return report("pi-git", probe.repoRoot);
45113
- const claudeHome = probe.env.CLAUDE_CONFIG_DIR?.trim() || join36(probe.homeDir, ".claude");
45114
- const pluginsRoot = join36(claudeHome, "plugins");
45139
+ const claudeHome = probe.env.CLAUDE_CONFIG_DIR?.trim() || join37(probe.homeDir, ".claude");
45140
+ const pluginsRoot = join37(claudeHome, "plugins");
45115
45141
  if (isUnder(probe.moduleDir, pluginsRoot, probe.platform)) return report("claude-marketplace", probe.moduleDir);
45116
- const hasGit = existsSync27(join36(probe.repoRoot, ".git"));
45142
+ const hasGit = existsSync27(join37(probe.repoRoot, ".git"));
45117
45143
  if (hasGit && packageIsKxm(probe.repoRoot)) return report("source", probe.repoRoot);
45118
45144
  if (isNpmPackageLayout(probe.repoRoot, probe.platform) && packageIsKxm(probe.repoRoot) && !hasGit) {
45119
45145
  return report("npm-package", probe.repoRoot);
@@ -45134,14 +45160,14 @@ function resolveInstallKind(probe, npmGlobalRoot) {
45134
45160
 
45135
45161
  // plugins/kxm/src/kxm-update-config.ts
45136
45162
  var import_yaml16 = __toESM(require_dist(), 1);
45137
- import { existsSync as existsSync28, readFileSync as readFileSync28 } from "node:fs";
45138
- import { join as join37 } from "node:path";
45163
+ import { existsSync as existsSync28, readFileSync as readFileSync29 } from "node:fs";
45164
+ import { join as join38 } from "node:path";
45139
45165
  function loadKxmUpdateConfig(env = process.env) {
45140
- const path4 = join37(vnextUserStateRoot({ env }), "update.yaml");
45166
+ const path4 = join38(vnextUserStateRoot({ env }), "update.yaml");
45141
45167
  if (!existsSync28(path4)) return { schema: KXM_UPDATE_SCHEMA, auto: false, source: "github" };
45142
45168
  let parsed;
45143
45169
  try {
45144
- parsed = (0, import_yaml16.parse)(readFileSync28(path4, "utf8"));
45170
+ parsed = (0, import_yaml16.parse)(readFileSync29(path4, "utf8"));
45145
45171
  } catch {
45146
45172
  throw new KxmUpdateConfigError("update.yaml is not valid YAML");
45147
45173
  }
@@ -45167,8 +45193,8 @@ function loadKxmUpdateConfig(env = process.env) {
45167
45193
  }
45168
45194
 
45169
45195
  // plugins/kxm/src/session.ts
45170
- import { existsSync as existsSync29, mkdirSync as mkdirSync24, readFileSync as readFileSync29, writeFileSync as writeFileSync22 } from "node:fs";
45171
- import { join as join38 } from "node:path";
45196
+ import { existsSync as existsSync29, mkdirSync as mkdirSync24, readFileSync as readFileSync30, writeFileSync as writeFileSync22 } from "node:fs";
45197
+ import { join as join39 } from "node:path";
45172
45198
  var SESSION_SCHEMA = "kxm.session.v1";
45173
45199
  var SessionConfigError = class extends Error {
45174
45200
  code = "session_config_invalid";
@@ -45178,12 +45204,12 @@ var SessionConfigError = class extends Error {
45178
45204
  }
45179
45205
  };
45180
45206
  function workflowAssetDirs(assetsDir, workflowId) {
45181
- const root = join38(assetsDir, "workflows", workflowId);
45182
- return [root, join38(root, "inputs"), join38(root, "outputs"), join38(root, "generated")];
45207
+ const root = join39(assetsDir, "workflows", workflowId);
45208
+ return [root, join39(root, "inputs"), join39(root, "outputs"), join39(root, "generated")];
45183
45209
  }
45184
45210
  function sessionAssetDirs(assetsDir, sessionId) {
45185
- const root = join38(assetsDir, "sessions", sessionId);
45186
- return [root, join38(root, "inputs"), join38(root, "outputs")];
45211
+ const root = join39(assetsDir, "sessions", sessionId);
45212
+ return [root, join39(root, "inputs"), join39(root, "outputs")];
45187
45213
  }
45188
45214
  function rosterNames(configDir) {
45189
45215
  return [...loadRosterMap(configDir).values()].map((row) => String(row.name));
@@ -45233,7 +45259,7 @@ function workerFromRosterRow(name, row, project) {
45233
45259
  function loadRosterMap(configDir) {
45234
45260
  const byName = /* @__PURE__ */ new Map();
45235
45261
  for (const [file, key] of [["agents.json", "agents"], ["gates.json", "gates"]]) {
45236
- const path4 = join38(configDir, file);
45262
+ const path4 = join39(configDir, file);
45237
45263
  for (const row of loadRoster(path4, key)) {
45238
45264
  const name = String(row.name).trim();
45239
45265
  const lowered = name.toLowerCase();
@@ -45250,7 +45276,7 @@ function loadRoster(path4, key) {
45250
45276
  if (!existsSync29(path4)) return [];
45251
45277
  let parsed;
45252
45278
  try {
45253
- parsed = JSON.parse(readFileSync29(path4, "utf8"));
45279
+ parsed = JSON.parse(readFileSync30(path4, "utf8"));
45254
45280
  } catch (error) {
45255
45281
  throw new SessionConfigError(
45256
45282
  `${key} roster at ${path4} is not valid JSON: ${error instanceof Error ? error.message : String(error)}`
@@ -45275,7 +45301,7 @@ function loadRoster(path4, key) {
45275
45301
  });
45276
45302
  }
45277
45303
  function createSession(input) {
45278
- const assetDir = input.mode === "workflow" && input.workflowId ? join38("assets", "workflows", input.workflowId) : join38("assets", "sessions", input.id);
45304
+ const assetDir = input.mode === "workflow" && input.workflowId ? join39("assets", "workflows", input.workflowId) : join39("assets", "sessions", input.id);
45279
45305
  return {
45280
45306
  schema: SESSION_SCHEMA,
45281
45307
  id: input.id,
@@ -45288,8 +45314,8 @@ function createSession(input) {
45288
45314
  };
45289
45315
  }
45290
45316
  function writeSession(assetsDir, session, dryRun = false) {
45291
- const dir = join38(assetsDir, "sessions", session.id);
45292
- const path4 = join38(dir, "session.json");
45317
+ const dir = join39(assetsDir, "sessions", session.id);
45318
+ const path4 = join39(dir, "session.json");
45293
45319
  if (!dryRun) {
45294
45320
  mkdirSync24(dir, { recursive: true });
45295
45321
  writeFileSync22(path4, `${JSON.stringify(session, null, 2)}
@@ -45327,9 +45353,9 @@ function installProbeFrom(runtime) {
45327
45353
  };
45328
45354
  }
45329
45355
  function warnIgnoredProjectUpdateYaml(runtime) {
45330
- const projectFile = join39(runtime.dirs.workspace, "update.yaml");
45356
+ const projectFile = join40(runtime.dirs.workspace, "update.yaml");
45331
45357
  if (!existsSync30(projectFile)) return;
45332
- const userFile = join39(vnextUserStateRoot({ env: runtime.env }), "update.yaml");
45358
+ const userFile = join40(vnextUserStateRoot({ env: runtime.env }), "update.yaml");
45333
45359
  runtime.io.stderr(`kxm: ignoring .kxm/update.yaml in ${runtime.dirs.workdir}; update settings are read only from ${userFile}
45334
45360
  `);
45335
45361
  }
@@ -45355,7 +45381,7 @@ async function cmdDash(runtime, options = {}) {
45355
45381
  return 2;
45356
45382
  }
45357
45383
  const screen = requested;
45358
- const dataPath = resolve25(runtime.dirs.workdir, runtime.env.KXM_DATA_PATH?.trim() || join39(runtime.dirs.state, "kxm.db"));
45384
+ const dataPath = resolve25(runtime.dirs.workdir, runtime.env.KXM_DATA_PATH?.trim() || join40(runtime.dirs.state, "kxm.db"));
45359
45385
  if (runtime.dryRun) {
45360
45386
  print(runtime.io, runtime.json, {
45361
45387
  ok: true,
@@ -45371,7 +45397,7 @@ async function cmdDash(runtime, options = {}) {
45371
45397
  runtime.io.stderr("kxm dash does not support --json; use kxm hub view\n");
45372
45398
  return 2;
45373
45399
  }
45374
- const project = runtime.env.KXM_PROJECT?.trim() || basename7(runtime.dirs.workdir) || "project";
45400
+ const project = defaultProjectName(runtime.dirs.workdir, runtime.env) || "project";
45375
45401
  const authToken = runtime.env.KXM_AUTH_TOKEN?.trim();
45376
45402
  return await runMeshTui({
45377
45403
  serverUrl: runtime.serverUrl,
@@ -45401,7 +45427,7 @@ async function cmdHub(runtime) {
45401
45427
  config = loadKxmUpdateConfig(runtime.env);
45402
45428
  } catch (error) {
45403
45429
  if (error instanceof KxmUpdateConfigError) {
45404
- const yamlPath = join39(vnextUserStateRoot({ env: runtime.env }), "update.yaml");
45430
+ const yamlPath = join40(vnextUserStateRoot({ env: runtime.env }), "update.yaml");
45405
45431
  runtime.io.stderr(`kxm: ${error.message}; update check skipped; fix or remove ${yamlPath}
45406
45432
  `);
45407
45433
  } else {
@@ -45552,7 +45578,7 @@ async function cmdStop(runtime, waitMsFlag) {
45552
45578
  const orphans = [];
45553
45579
  for (const file of pids) {
45554
45580
  try {
45555
- const record = JSON.parse(readFileSync30(join39(runtime.dirs.state, file), "utf8"));
45581
+ const record = JSON.parse(readFileSync31(join40(runtime.dirs.state, file), "utf8"));
45556
45582
  const expectedControl = file === "hub.pid" ? "hub.stop" : file.startsWith("worker-") ? `${file.slice(0, -4)}.stop` : void 0;
45557
45583
  const expectedRole = file === "hub.pid" ? "hub" : file.startsWith("worker-") ? "worker" : void 0;
45558
45584
  if (record.version !== 1 || !Number.isInteger(record.pid) || record.pid <= 0 || !record.startedAt || !expectedControl || record.controlFile !== expectedControl || record.role !== expectedRole) {
@@ -45572,7 +45598,7 @@ async function cmdStop(runtime, waitMsFlag) {
45572
45598
  ignored.push(file);
45573
45599
  continue;
45574
45600
  }
45575
- writeFileSync23(join39(runtime.dirs.state, record.controlFile), `${JSON.stringify({ startedAt: record.startedAt, ...record.generation ? { generation: record.generation } : {}, requestedAt: (/* @__PURE__ */ new Date()).toISOString() })}
45601
+ writeFileSync23(join40(runtime.dirs.state, record.controlFile), `${JSON.stringify({ startedAt: record.startedAt, ...record.generation ? { generation: record.generation } : {}, requestedAt: (/* @__PURE__ */ new Date()).toISOString() })}
45576
45602
  `, { encoding: "utf8", mode: 384 });
45577
45603
  requested.push(file);
45578
45604
  records.set(file, { pid: record.pid, startedAt: record.startedAt, ...record.generation ? { generation: record.generation } : {} });
@@ -45590,7 +45616,7 @@ async function cmdStop(runtime, waitMsFlag) {
45590
45616
  while (Date.now() <= deadline && stopped.size < requested.length) {
45591
45617
  for (const [file, record] of records) {
45592
45618
  try {
45593
- const current = JSON.parse(readFileSync30(join39(runtime.dirs.state, file), "utf8"));
45619
+ const current = JSON.parse(readFileSync31(join40(runtime.dirs.state, file), "utf8"));
45594
45620
  if (current.pid !== record.pid || current.startedAt !== record.startedAt || current.generation !== record.generation || !processExists(record.pid)) stopped.add(file);
45595
45621
  } catch {
45596
45622
  stopped.add(file);
@@ -45603,7 +45629,7 @@ async function cmdStop(runtime, waitMsFlag) {
45603
45629
  for (const file of orphans) {
45604
45630
  while (Date.now() <= deadlineOrphans) {
45605
45631
  try {
45606
- const current = JSON.parse(readFileSync30(join39(runtime.dirs.state, file), "utf8"));
45632
+ const current = JSON.parse(readFileSync31(join40(runtime.dirs.state, file), "utf8"));
45607
45633
  if (!Number.isInteger(current.serverPid) || !processExists(current.serverPid)) break;
45608
45634
  } catch {
45609
45635
  break;
@@ -45611,14 +45637,14 @@ async function cmdStop(runtime, waitMsFlag) {
45611
45637
  await (runtime.io.sleep ?? ((ms) => new Promise((resolveSleep) => setTimeout(resolveSleep, ms))))(100);
45612
45638
  }
45613
45639
  try {
45614
- const current = JSON.parse(readFileSync30(join39(runtime.dirs.state, file), "utf8"));
45640
+ const current = JSON.parse(readFileSync31(join40(runtime.dirs.state, file), "utf8"));
45615
45641
  if (Number.isInteger(current.serverPid) && processExists(current.serverPid)) {
45616
45642
  try {
45617
45643
  process.kill(current.serverPid, "SIGKILL");
45618
45644
  } catch {
45619
45645
  }
45620
45646
  }
45621
- rmSync10(join39(runtime.dirs.state, file), { force: true });
45647
+ rmSync10(join40(runtime.dirs.state, file), { force: true });
45622
45648
  } catch {
45623
45649
  }
45624
45650
  stopped.add(file);
@@ -45633,7 +45659,7 @@ async function cmdSessionStatus(runtime) {
45633
45659
  const claims = [];
45634
45660
  for (const file of names3.filter((name) => name.endsWith(".pid"))) {
45635
45661
  try {
45636
- const record = JSON.parse(readFileSync30(join39(stateDir, file), "utf8"));
45662
+ const record = JSON.parse(readFileSync31(join40(stateDir, file), "utf8"));
45637
45663
  claims.push({
45638
45664
  file,
45639
45665
  role: record.role,
@@ -45648,7 +45674,7 @@ async function cmdSessionStatus(runtime) {
45648
45674
  const recoveries = [];
45649
45675
  for (const file of names3.filter((name) => name.startsWith("worker-recovery-") && name.endsWith(".json"))) {
45650
45676
  try {
45651
- const envelope = JSON.parse(readFileSync30(join39(stateDir, file), "utf8"));
45677
+ const envelope = JSON.parse(readFileSync31(join40(stateDir, file), "utf8"));
45652
45678
  recoveries.push({
45653
45679
  file,
45654
45680
  reason: envelope.reason,
@@ -45753,7 +45779,7 @@ async function cmdSessionBrief(runtime, options = {}) {
45753
45779
  print(runtime.io, runtime.json, { ok: true, command: "session brief", sessionToken }, sessionToken);
45754
45780
  return 0;
45755
45781
  }
45756
- const dataPath = resolve25(runtime.dirs.workdir, runtime.env.KXM_DATA_PATH?.trim() || join39(runtime.dirs.state, "kxm.db"));
45782
+ const dataPath = resolve25(runtime.dirs.workdir, runtime.env.KXM_DATA_PATH?.trim() || join40(runtime.dirs.state, "kxm.db"));
45757
45783
  const env = {
45758
45784
  ...runtime.env,
45759
45785
  KXM_STATE_DIR: runtime.dirs.state,
@@ -45845,16 +45871,16 @@ async function cmdSessionStart(runtime, options) {
45845
45871
  // plugins/kxm/src/cli/system.ts
45846
45872
  import { spawnSync as spawnSync8 } from "node:child_process";
45847
45873
  import { createHash as createHash16 } from "node:crypto";
45848
- import { existsSync as existsSync36, mkdtempSync as mkdtempSync2, readFileSync as readFileSync35, rmSync as rmSync12 } from "node:fs";
45874
+ import { existsSync as existsSync36, mkdtempSync as mkdtempSync2, readFileSync as readFileSync36, rmSync as rmSync12 } from "node:fs";
45849
45875
  import { tmpdir as tmpdir2 } from "node:os";
45850
- import { join as join45, resolve as resolve29 } from "node:path";
45876
+ import { join as join46, resolve as resolve29 } from "node:path";
45851
45877
  import { createInterface as createInterface3 } from "node:readline";
45852
45878
  import { fileURLToPath as fileURLToPath7 } from "node:url";
45853
45879
 
45854
45880
  // plugins/kxm/src/improve.ts
45855
45881
  import { createHash as createHash15 } from "node:crypto";
45856
45882
  import { existsSync as existsSync31, mkdirSync as mkdirSync26, writeFileSync as writeFileSync24 } from "node:fs";
45857
- import { join as join40, relative as relative6, resolve as resolve26 } from "node:path";
45883
+ import { join as join41, relative as relative6, resolve as resolve26 } from "node:path";
45858
45884
  var CANDIDATE_SCHEMA = "kxm.candidate.v1";
45859
45885
  var IMPROVEMENT_REPORT_SCHEMA = "kxm.improvement-report.v2";
45860
45886
  function classifyCandidateKind(stepId, agentRole) {
@@ -46026,7 +46052,7 @@ function groupRoutingRecords(records, options = {}) {
46026
46052
  }
46027
46053
  function buildImprovementReport(records, options = {}) {
46028
46054
  const projectRoot = options.projectRoot ? resolve26(options.projectRoot) : process.cwd();
46029
- const candidatesDir = options.candidatesDir ? resolve26(options.candidatesDir) : join40(projectRoot, ".kxm", "candidates");
46055
+ const candidatesDir = options.candidatesDir ? resolve26(options.candidatesDir) : join41(projectRoot, ".kxm", "candidates");
46030
46056
  const groups = groupRoutingRecords(records, options);
46031
46057
  const candidates = [];
46032
46058
  for (const group of groups) {
@@ -46038,7 +46064,7 @@ function buildImprovementReport(records, options = {}) {
46038
46064
  group.workflowHash
46039
46065
  );
46040
46066
  const diffFileName = `${group.candidateId}.diff`;
46041
- const diffFilePath = join40(candidatesDir, diffFileName);
46067
+ const diffFilePath = join41(candidatesDir, diffFileName);
46042
46068
  const relDiffPath = relative6(projectRoot, diffFilePath).replace(/\\/g, "/");
46043
46069
  const candidate = {
46044
46070
  schema: CANDIDATE_SCHEMA,
@@ -46064,7 +46090,7 @@ function buildImprovementReport(records, options = {}) {
46064
46090
  mkdirSync26(candidatesDir, { recursive: true });
46065
46091
  }
46066
46092
  writeFileSync24(diffFilePath, diff, "utf8");
46067
- const jsonFilePath = join40(candidatesDir, `${group.candidateId}.json`);
46093
+ const jsonFilePath = join41(candidatesDir, `${group.candidateId}.json`);
46068
46094
  writeFileSync24(jsonFilePath, JSON.stringify(candidate, null, 2) + "\n", "utf8");
46069
46095
  }
46070
46096
  candidates.push(candidate);
@@ -46080,7 +46106,7 @@ function buildImprovementReport(records, options = {}) {
46080
46106
  }
46081
46107
  function writeImprovementReport(improvementsDir, report2, dryRun = false) {
46082
46108
  const stamp = report2.createdAt.replace(/[:.]/g, "-");
46083
- const path4 = join40(improvementsDir, `${stamp}.json`);
46109
+ const path4 = join41(improvementsDir, `${stamp}.json`);
46084
46110
  if (!dryRun) {
46085
46111
  mkdirSync26(improvementsDir, { recursive: true });
46086
46112
  writeFileSync24(path4, `${JSON.stringify(report2, null, 2)}
@@ -46123,8 +46149,8 @@ function formatImprovementReport(report2) {
46123
46149
 
46124
46150
  // plugins/kxm/src/modes.ts
46125
46151
  var import_yaml17 = __toESM(require_dist(), 1);
46126
- import { existsSync as existsSync32, readFileSync as readFileSync32 } from "node:fs";
46127
- import { join as join41 } from "node:path";
46152
+ import { existsSync as existsSync32, readFileSync as readFileSync33 } from "node:fs";
46153
+ import { join as join42 } from "node:path";
46128
46154
  var DEFAULT_MODES_CONFIG = Object.freeze({
46129
46155
  schema: "kxm.modes.v1",
46130
46156
  majorModes: {
@@ -46187,12 +46213,12 @@ function loadModesConfig(projectRoot) {
46187
46213
  if (!projectRoot) {
46188
46214
  return DEFAULT_MODES_CONFIG;
46189
46215
  }
46190
- const modesPath = join41(projectRoot, ".kxm", "modes.yaml");
46216
+ const modesPath = join42(projectRoot, ".kxm", "modes.yaml");
46191
46217
  if (!existsSync32(modesPath)) {
46192
46218
  return DEFAULT_MODES_CONFIG;
46193
46219
  }
46194
46220
  try {
46195
- const raw = readFileSync32(modesPath, "utf8");
46221
+ const raw = readFileSync33(modesPath, "utf8");
46196
46222
  const parsed = (0, import_yaml17.parse)(raw);
46197
46223
  if (parsed && parsed.schema === "kxm.modes.v1" && parsed.majorModes) {
46198
46224
  return {
@@ -46278,11 +46304,11 @@ function calculatePromptFootprint(resolved, projectRoot = process.cwd(), catalog
46278
46304
  estimatedTokens: estimateTokens(baseSystemPromptChars)
46279
46305
  });
46280
46306
  for (const relPath of resolved.contextFiles) {
46281
- const fullPath = join41(projectRoot, relPath);
46307
+ const fullPath = join42(projectRoot, relPath);
46282
46308
  let chars = 0;
46283
46309
  if (existsSync32(fullPath)) {
46284
46310
  try {
46285
- chars = readFileSync32(fullPath, "utf8").length;
46311
+ chars = readFileSync33(fullPath, "utf8").length;
46286
46312
  } catch {
46287
46313
  chars = 0;
46288
46314
  }
@@ -46414,9 +46440,9 @@ ${divider}
46414
46440
 
46415
46441
  // plugins/kxm/src/ssh-remote.ts
46416
46442
  import { spawnSync as spawnSync7 } from "node:child_process";
46417
- import { existsSync as existsSync33, mkdirSync as mkdirSync27, readFileSync as readFileSync33, readdirSync as readdirSync13, rmSync as rmSync11, statSync as statSync5 } from "node:fs";
46443
+ import { existsSync as existsSync33, mkdirSync as mkdirSync27, readFileSync as readFileSync34, readdirSync as readdirSync13, rmSync as rmSync11, statSync as statSync5 } from "node:fs";
46418
46444
  import { homedir as homedir7 } from "node:os";
46419
- import { join as join42, resolve as resolve27 } from "node:path";
46445
+ import { join as join43, resolve as resolve27 } from "node:path";
46420
46446
  var MAX_SSH_OUTPUT_BYTES = 50 * 1024;
46421
46447
  var MAX_SSH_OUTPUT_LINES = 2e3;
46422
46448
  var DEFAULT_SOCKET_DIR = ".kxm/run/ssh-sockets";
@@ -46442,12 +46468,12 @@ function truncateSshOutput(raw) {
46442
46468
  return { text, truncated };
46443
46469
  }
46444
46470
  function parseSshConfig(configPath) {
46445
- const targetPath = configPath ?? join42(homedir7(), ".ssh", "config");
46471
+ const targetPath = configPath ?? join43(homedir7(), ".ssh", "config");
46446
46472
  if (!existsSync33(targetPath)) {
46447
46473
  return [];
46448
46474
  }
46449
46475
  try {
46450
- const content = readFileSync33(targetPath, "utf-8");
46476
+ const content = readFileSync34(targetPath, "utf-8");
46451
46477
  const lines = content.split("\n");
46452
46478
  const hosts = [];
46453
46479
  let currentHosts = [];
@@ -46532,7 +46558,7 @@ function ensureSocketDir(socketDir = DEFAULT_SOCKET_DIR) {
46532
46558
  }
46533
46559
  function buildSshArgs(options) {
46534
46560
  const socketDir = ensureSocketDir(options.socketDir ?? DEFAULT_SOCKET_DIR);
46535
- const controlPath = join42(socketDir, "%C");
46561
+ const controlPath = join43(socketDir, "%C");
46536
46562
  const persist = options.controlPersist ?? DEFAULT_CONTROL_PERSIST;
46537
46563
  const args = [
46538
46564
  "-o",
@@ -46557,7 +46583,7 @@ function buildSshArgs(options) {
46557
46583
  }
46558
46584
  function checkControlSocket(host, socketDir = DEFAULT_SOCKET_DIR, execFn = spawnSync7) {
46559
46585
  const resolvedDir = ensureSocketDir(socketDir);
46560
- const controlPath = join42(resolvedDir, "%C");
46586
+ const controlPath = join43(resolvedDir, "%C");
46561
46587
  try {
46562
46588
  const result = execFn("ssh", ["-O", "check", "-o", `ControlPath=${controlPath}`, host], {
46563
46589
  encoding: "utf-8"
@@ -46569,7 +46595,7 @@ function checkControlSocket(host, socketDir = DEFAULT_SOCKET_DIR, execFn = spawn
46569
46595
  }
46570
46596
  function closeControlSocket(host, socketDir = DEFAULT_SOCKET_DIR, execFn = spawnSync7) {
46571
46597
  const resolvedDir = ensureSocketDir(socketDir);
46572
- const controlPath = join42(resolvedDir, "%C");
46598
+ const controlPath = join43(resolvedDir, "%C");
46573
46599
  try {
46574
46600
  const result = execFn("ssh", ["-O", "stop", "-o", `ControlPath=${controlPath}`, host], {
46575
46601
  encoding: "utf-8"
@@ -47015,9 +47041,9 @@ complete -c kxm -n "__fish_seen_subcommand_from goal" -a "create list get"
47015
47041
  }
47016
47042
 
47017
47043
  // plugins/kxm/src/completion-install.ts
47018
- import { existsSync as existsSync34, mkdirSync as mkdirSync28, readFileSync as readFileSync34, writeFileSync as writeFileSync25 } from "node:fs";
47044
+ import { existsSync as existsSync34, mkdirSync as mkdirSync28, readFileSync as readFileSync35, writeFileSync as writeFileSync25 } from "node:fs";
47019
47045
  import { homedir as homedir8 } from "node:os";
47020
- import { basename as basename9, delimiter, dirname as dirname21, isAbsolute as isAbsolute8, join as join43, resolve as resolve28 } from "node:path";
47046
+ import { basename as basename9, delimiter, dirname as dirname21, isAbsolute as isAbsolute8, join as join44, resolve as resolve28 } from "node:path";
47021
47047
  var COMPLETION_MARKER = "# kxm completion";
47022
47048
  var PATH_MARKER = "# kxm path";
47023
47049
  function detectShell(env = process.env, platform = process.platform) {
@@ -47039,25 +47065,25 @@ function completionScriptPath(shell, options = {}) {
47039
47065
  const env = options.env ?? process.env;
47040
47066
  const explicit = options.configDir ?? env.KXM_USER_CONFIG_DIR?.trim();
47041
47067
  const base = explicit && explicit.length > 0 ? resolve28(explicit) : resolve28(effectiveHome(options), ".config", "kxm");
47042
- return join43(base, "completions", `kxm.${shell}`);
47068
+ return join44(base, "completions", `kxm.${shell}`);
47043
47069
  }
47044
47070
  function bashRcCandidate(options) {
47045
47071
  const home = effectiveHome(options);
47046
- const candidates = [join43(home, ".bashrc"), join43(home, ".bash_profile")];
47072
+ const candidates = [join44(home, ".bashrc"), join44(home, ".bash_profile")];
47047
47073
  const existing = candidates.find((candidate) => existsSync34(candidate));
47048
47074
  return existing ?? candidates[0];
47049
47075
  }
47050
47076
  function zshRcCandidate(options) {
47051
47077
  const env = options.env ?? process.env;
47052
47078
  const home = effectiveHome(options);
47053
- if (env.ZDOTDIR?.trim()) return join43(resolve28(env.ZDOTDIR.trim()), ".zshrc");
47054
- return join43(home, ".zshrc");
47079
+ if (env.ZDOTDIR?.trim()) return join44(resolve28(env.ZDOTDIR.trim()), ".zshrc");
47080
+ return join44(home, ".zshrc");
47055
47081
  }
47056
47082
  function fishCompletionTarget(shell, options) {
47057
47083
  const env = options.env ?? process.env;
47058
47084
  const home = effectiveHome(options);
47059
- if (env.XDG_CONFIG_HOME?.trim()) return join43(resolve28(env.XDG_CONFIG_HOME.trim()), "fish", "completions", "kxm.fish");
47060
- return join43(home, ".config", "fish", "completions", "kxm.fish");
47085
+ if (env.XDG_CONFIG_HOME?.trim()) return join44(resolve28(env.XDG_CONFIG_HOME.trim()), "fish", "completions", "kxm.fish");
47086
+ return join44(home, ".config", "fish", "completions", "kxm.fish");
47061
47087
  }
47062
47088
  function completionRcTarget(shell, options = {}) {
47063
47089
  if (shell === "fish") {
@@ -47090,12 +47116,12 @@ function installShellCompletion(shellInput, options = {}) {
47090
47116
  const { rcFile } = completionRcTarget(shell, options);
47091
47117
  const script = generateShellCompletion(shell);
47092
47118
  const existingScript = existsSync34(scriptPath);
47093
- const existingScriptMatches = existingScript && readFileSync34(scriptPath, "utf8") === script;
47119
+ const existingScriptMatches = existingScript && readFileSync35(scriptPath, "utf8") === script;
47094
47120
  let rcModified = false;
47095
47121
  let alreadyInstalled = false;
47096
47122
  if (shell === "fish") {
47097
47123
  const fishTarget = fishCompletionTarget(shell, options);
47098
- const fishInstalled = existsSync34(fishTarget) && readFileSync34(fishTarget, "utf8") === script;
47124
+ const fishInstalled = existsSync34(fishTarget) && readFileSync35(fishTarget, "utf8") === script;
47099
47125
  alreadyInstalled = fishInstalled;
47100
47126
  if (!options.dryRun && (!fishInstalled || options.overwrite)) {
47101
47127
  mkdirSync28(resolve28(fishTarget, ".."), { recursive: true });
@@ -47112,7 +47138,7 @@ function installShellCompletion(shellInput, options = {}) {
47112
47138
  }
47113
47139
  if (rcFile) {
47114
47140
  const line = sourceLine(shell, scriptPath);
47115
- const rcContent = existsSync34(rcFile) ? readFileSync34(rcFile, "utf8") : "";
47141
+ const rcContent = existsSync34(rcFile) ? readFileSync35(rcFile, "utf8") : "";
47116
47142
  alreadyInstalled = rcContent.includes(line) || rcContent.includes(`${COMPLETION_MARKER}`);
47117
47143
  }
47118
47144
  if (!options.dryRun) {
@@ -47128,7 +47154,7 @@ ${marker}
47128
47154
  ${line}
47129
47155
  `;
47130
47156
  mkdirSync28(resolve28(rcFile, ".."), { recursive: true });
47131
- writeFileSync25(rcFile, (existsSync34(rcFile) ? readFileSync34(rcFile, "utf8") : "") + stanza, { encoding: "utf8" });
47157
+ writeFileSync25(rcFile, (existsSync34(rcFile) ? readFileSync35(rcFile, "utf8") : "") + stanza, { encoding: "utf8" });
47132
47158
  rcModified = true;
47133
47159
  }
47134
47160
  }
@@ -47145,7 +47171,7 @@ function kxmBinDir(env = process.env) {
47145
47171
  const argv1 = env.KXM_ENTRY ?? process.argv[1];
47146
47172
  if (argv1 && isAbsolute8(argv1)) {
47147
47173
  const dir = dirname21(argv1);
47148
- if (existsSync34(join43(dir, process.platform === "win32" ? "kxm.cmd" : "kxm"))) return dir;
47174
+ if (existsSync34(join44(dir, process.platform === "win32" ? "kxm.cmd" : "kxm"))) return dir;
47149
47175
  }
47150
47176
  const pathEnv = env.PATH ?? "";
47151
47177
  for (const part of pathEnv.split(delimiter)) {
@@ -47169,7 +47195,7 @@ function installPathEntry(shellInput, options = {}) {
47169
47195
  }
47170
47196
  const { rcFile } = completionRcTarget(shell, options);
47171
47197
  const line = pathLine(binDir);
47172
- const rcContent = existsSync34(rcFile ?? "") ? readFileSync34(rcFile, "utf8") : "";
47198
+ const rcContent = existsSync34(rcFile ?? "") ? readFileSync35(rcFile, "utf8") : "";
47173
47199
  const alreadyInstalled = rcContent.includes(binDir) || (options.env?.PATH ?? process.env.PATH ?? "").split(delimiter).includes(binDir);
47174
47200
  if (!options.dryRun && rcFile && !alreadyInstalled) {
47175
47201
  mkdirSync28(dirname21(rcFile), { recursive: true });
@@ -47184,7 +47210,7 @@ ${line}
47184
47210
  // plugins/kxm/src/init-guide-setup.ts
47185
47211
  var import_yaml18 = __toESM(require_dist(), 1);
47186
47212
  import { existsSync as existsSync35, mkdirSync as mkdirSync29, writeFileSync as writeFileSync26 } from "node:fs";
47187
- import { dirname as dirname22, join as join44 } from "node:path";
47213
+ import { dirname as dirname22, join as join45 } from "node:path";
47188
47214
  var NATIVE_VENDOR_HARNESS = Object.freeze({
47189
47215
  anthropic: "claude",
47190
47216
  openai: "codex",
@@ -47583,13 +47609,13 @@ function renderGuideSetupFiles(projectRoot, plan) {
47583
47609
  const stage = roleStages.get(role);
47584
47610
  if (!stage) continue;
47585
47611
  files.push({
47586
- path: join44(projectRoot, ".kxm", "agents", `${role}.yaml`),
47612
+ path: join45(projectRoot, ".kxm", "agents", `${role}.yaml`),
47587
47613
  content: (0, import_yaml18.stringify)(agentDocument(role, stage, binding))
47588
47614
  });
47589
47615
  }
47590
47616
  for (const workflow of plan.workflows) {
47591
47617
  files.push({
47592
- path: join44(projectRoot, ".kxm", "workflows", `${workflow.slug}.yaml`),
47618
+ path: join45(projectRoot, ".kxm", "workflows", `${workflow.slug}.yaml`),
47593
47619
  content: (0, import_yaml18.stringify)(workflowDocument(workflow))
47594
47620
  });
47595
47621
  }
@@ -47668,7 +47694,7 @@ function applyKxmPackageUpdate(runtime, notice) {
47668
47694
  detail: `release v${notice.latest} has no sha256 digest for ${name}; refusing to install`
47669
47695
  };
47670
47696
  }
47671
- const releaseDir = mkdtempSync2(join45(tmpdir2(), "kxm-pkg-update-"));
47697
+ const releaseDir = mkdtempSync2(join46(tmpdir2(), "kxm-pkg-update-"));
47672
47698
  try {
47673
47699
  const planned = planKxmPackageUpdate(notice.source, notice.latest, releaseDir, notice.asset);
47674
47700
  if (runtime.dryRun) {
@@ -47677,7 +47703,7 @@ function applyKxmPackageUpdate(runtime, notice) {
47677
47703
  for (const step of planned) {
47678
47704
  if (step.kind === "verify") {
47679
47705
  if (!verifyReleaseAssetDigest(step.path, step.sha256)) {
47680
- const actual = existsSync36(step.path) ? createHash16("sha256").update(readFileSync35(step.path)).digest("hex") : "missing";
47706
+ const actual = existsSync36(step.path) ? createHash16("sha256").update(readFileSync36(step.path)).digest("hex") : "missing";
47681
47707
  return {
47682
47708
  ok: false,
47683
47709
  error: "release_digest_mismatch",
@@ -47948,7 +47974,7 @@ async function cmdValidate(runtime, fileFlag) {
47948
47974
  return 1;
47949
47975
  }
47950
47976
  try {
47951
- const raw = file ? readFileSync35(file, "utf8") : inline;
47977
+ const raw = file ? readFileSync36(file, "utf8") : inline;
47952
47978
  const warnings = [];
47953
47979
  const definitions = parseWorkflowDefinitions(raw, runtime.env, (message) => warnings.push(message));
47954
47980
  const secretEnvs = definitions.map((definition) => ({
@@ -47994,13 +48020,13 @@ async function cmdArtifactsExist(runtime, pathFlag) {
47994
48020
  async function cmdImprove(runtime, options = {}) {
47995
48021
  const file = options.file ? resolve29(runtime.cwd, options.file) : telemetryPath(runtime.dirs.logs);
47996
48022
  const routingRecords = existsSync36(file) ? readRoutingRecords(file).map((entry) => entry.routing) : [];
47997
- const candidatesDir = options.outDir ? resolve29(runtime.cwd, options.outDir) : join45(runtime.cwd, ".kxm", "candidates");
48023
+ const candidatesDir = options.outDir ? resolve29(runtime.cwd, options.outDir) : join46(runtime.cwd, ".kxm", "candidates");
47998
48024
  const report2 = buildImprovementReport(routingRecords, {
47999
48025
  candidatesDir,
48000
48026
  projectRoot: runtime.cwd,
48001
48027
  dryRun: runtime.dryRun
48002
48028
  });
48003
- const reportDir = join45(runtime.dirs.assets, "improvements");
48029
+ const reportDir = join46(runtime.dirs.assets, "improvements");
48004
48030
  const reportPath = writeImprovementReport(reportDir, report2, runtime.dryRun);
48005
48031
  const text = formatImprovementReport(report2);
48006
48032
  print(runtime.io, runtime.json, {
@@ -48134,7 +48160,7 @@ async function maybeOfferCompletionInstall(runtime) {
48134
48160
  const { rcFile } = completionRcTarget(shell, { env: runtime.env });
48135
48161
  if (rcFile && existsSync36(rcFile)) {
48136
48162
  try {
48137
- if (readFileSync35(rcFile, "utf8").includes(scriptPath)) return;
48163
+ if (readFileSync36(rcFile, "utf8").includes(scriptPath)) return;
48138
48164
  } catch {
48139
48165
  }
48140
48166
  }
@@ -48266,7 +48292,7 @@ async function cmdRoutingReport(runtime, options) {
48266
48292
  let catalog;
48267
48293
  if (includeEquivalentListCost) {
48268
48294
  try {
48269
- const pricesPath = options.prices ? resolve29(runtime.cwd, options.prices) : join45(runtime.dirs.workspace, "prices.yaml");
48295
+ const pricesPath = options.prices ? resolve29(runtime.cwd, options.prices) : join46(runtime.dirs.workspace, "prices.yaml");
48270
48296
  catalog = loadPriceCatalog(pricesPath);
48271
48297
  } catch {
48272
48298
  }
@@ -48369,7 +48395,7 @@ function addGlobalOptions(command) {
48369
48395
  }
48370
48396
  async function ensureCliClient(runtime) {
48371
48397
  const serverUrl = runtime.serverUrl;
48372
- const project = runtime.env.KXM_PROJECT?.trim() || basename10(runtime.dirs.workspace || runtime.cwd);
48398
+ const project = defaultProjectName(runtime.cwd, runtime.env);
48373
48399
  const name = runtime.env.KXM_AGENT_NAME?.trim() || `cli-${process.pid}`;
48374
48400
  const purpose = runtime.env.KXM_AGENT_PURPOSE?.trim() || "CLI agent client";
48375
48401
  const authToken = runtime.env.KXM_AUTH_TOKEN?.trim();