@kontextmind/kxm 0.7.18 → 0.7.20

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.
@@ -14779,7 +14779,7 @@ var require_dist = __commonJS({
14779
14779
  });
14780
14780
 
14781
14781
  // plugins/kxm/src/cli.ts
14782
- import { basename as basename10, resolve as resolve30 } from "node:path";
14782
+ import { resolve as resolve30 } from "node:path";
14783
14783
  import { fileURLToPath as fileURLToPath8 } from "node:url";
14784
14784
 
14785
14785
  // node_modules/commander/lib/error.js
@@ -19571,11 +19571,25 @@ var HubClient = class {
19571
19571
  }
19572
19572
  };
19573
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
+
19574
19588
  // plugins/kxm/src/commands.ts
19575
19589
  import { createHash as createHash4, randomUUID as randomUUID2, timingSafeEqual } from "node:crypto";
19576
- 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";
19577
19591
  import { homedir } from "node:os";
19578
- import { dirname, join as join2, resolve } from "node:path";
19592
+ import { dirname, join as join3, resolve } from "node:path";
19579
19593
  function requiredString(value, name) {
19580
19594
  if (typeof value !== "string" || value.trim() === "") throw new Error(`${name} is required`);
19581
19595
  return value.trim();
@@ -20324,10 +20338,10 @@ function parseSessionToken(token) {
20324
20338
  }
20325
20339
  function resolveUserConfigDirectory(overrideDir) {
20326
20340
  if (overrideDir) return resolve(overrideDir);
20327
- 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"));
20328
20342
  }
20329
20343
  function sessionTokenPath(userConfigDir) {
20330
- return join2(resolveUserConfigDirectory(userConfigDir), "session.token");
20344
+ return join3(resolveUserConfigDirectory(userConfigDir), "session.token");
20331
20345
  }
20332
20346
  function persistSessionTokenToDisk(token, options) {
20333
20347
  const filePath = sessionTokenPath(options?.userConfigDir);
@@ -20346,7 +20360,7 @@ function readSessionTokenFromDisk(options) {
20346
20360
  const filePath = sessionTokenPath(options?.userConfigDir);
20347
20361
  if (!existsSync2(filePath)) return void 0;
20348
20362
  try {
20349
- const token = readFileSync2(filePath, "utf8").trim();
20363
+ const token = readFileSync3(filePath, "utf8").trim();
20350
20364
  if (!token) return void 0;
20351
20365
  const payload = parseSessionToken(token);
20352
20366
  if (!payload) return void 0;
@@ -20459,7 +20473,7 @@ function enforceToolPolicy(commandName, env = process.env, options) {
20459
20473
  if (existsSync2(tokenFile)) {
20460
20474
  let tokenRaw;
20461
20475
  try {
20462
- tokenRaw = readFileSync2(tokenFile, "utf8").trim();
20476
+ tokenRaw = readFileSync3(tokenFile, "utf8").trim();
20463
20477
  } catch {
20464
20478
  return { allowed: false, error: "session_token_invalid", detail: "Session token file on disk could not be read" };
20465
20479
  }
@@ -20483,8 +20497,8 @@ function enforceToolPolicy(commandName, env = process.env, options) {
20483
20497
  var import__ = __toESM(require__(), 1);
20484
20498
  import { spawnSync as spawnSync2 } from "node:child_process";
20485
20499
  import { createHash as createHash6 } from "node:crypto";
20486
- import { existsSync as existsSync4, lstatSync, readFileSync as readFileSync3, readdirSync, realpathSync } from "node:fs";
20487
- 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";
20488
20502
  import { fileURLToPath } from "node:url";
20489
20503
 
20490
20504
  // plugins/kxm/src/restricted-yaml.mjs
@@ -21880,7 +21894,7 @@ var VnextConfigError = class extends Error {
21880
21894
  }
21881
21895
  };
21882
21896
  var PACKAGE_ROOT = resolve2(dirname2(fileURLToPath(import.meta.url)), "../../..");
21883
- var DEFAULT_SCHEMA_DIR = join3(PACKAGE_ROOT, "schemas", "vnext");
21897
+ var DEFAULT_SCHEMA_DIR = join4(PACKAGE_ROOT, "schemas", "vnext");
21884
21898
  var RESOURCE_SCHEMA = Object.freeze({
21885
21899
  project: { identity: "kxm.project.v1", file: "project.schema.json" },
21886
21900
  repository: { identity: "kxm.repository.v1", file: "repository.schema.json" },
@@ -21926,7 +21940,7 @@ function parseRestrictedYaml2(input, label = "<yaml>", limits = VNEXT_YAML_LIMIT
21926
21940
  }
21927
21941
  }
21928
21942
  function readJsonObject(file) {
21929
- const parsed = JSON.parse(readFileSync3(file, "utf8"));
21943
+ const parsed = JSON.parse(readFileSync4(file, "utf8"));
21930
21944
  if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) throw new Error(`${file} is not a JSON object`);
21931
21945
  return parsed;
21932
21946
  }
@@ -21945,10 +21959,10 @@ var VnextSchemaRegistry = class {
21945
21959
  constructor(schemasDir = DEFAULT_SCHEMA_DIR) {
21946
21960
  this.schemasDir = resolve2(schemasDir);
21947
21961
  this.ajv = new import__.Ajv2020({ allErrors: true, strict: true, strictRequired: false });
21948
- const common = readJsonObject(join3(this.schemasDir, "common.schema.json"));
21962
+ const common = readJsonObject(join4(this.schemasDir, "common.schema.json"));
21949
21963
  this.ajv.addSchema(common);
21950
21964
  for (const definition of Object.values(RESOURCE_SCHEMA)) {
21951
- this.ajv.addSchema(readJsonObject(join3(this.schemasDir, definition.file)));
21965
+ this.ajv.addSchema(readJsonObject(join4(this.schemasDir, definition.file)));
21952
21966
  }
21953
21967
  const localBindingsFile = "local-repository-bindings.schema.json";
21954
21968
  const templateProvenanceFile = "template-provenance.schema.json";
@@ -21958,14 +21972,14 @@ var VnextSchemaRegistry = class {
21958
21972
  const migrationReceiptFile = "migration-receipt.schema.json";
21959
21973
  const permissionDiffFile = "permission-diff.schema.json";
21960
21974
  const runEventFile = "run-event.schema.json";
21961
- this.ajv.addSchema(readJsonObject(join3(this.schemasDir, localBindingsFile)));
21962
- this.ajv.addSchema(readJsonObject(join3(this.schemasDir, templateProvenanceFile)));
21963
- this.ajv.addSchema(readJsonObject(join3(this.schemasDir, initOperationFile)));
21964
- this.ajv.addSchema(readJsonObject(join3(this.schemasDir, migrationPlanFile)));
21965
- this.ajv.addSchema(readJsonObject(join3(this.schemasDir, migrationDecisionFile)));
21966
- this.ajv.addSchema(readJsonObject(join3(this.schemasDir, migrationReceiptFile)));
21967
- this.ajv.addSchema(readJsonObject(join3(this.schemasDir, permissionDiffFile)));
21968
- 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)));
21969
21983
  for (const [kind, definition] of Object.entries(RESOURCE_SCHEMA)) {
21970
21984
  const validator = this.ajv.getSchema(`https://schemas.kxm.dev/vnext/${definition.file}`);
21971
21985
  if (!validator) throw new Error(`schema did not compile: ${definition.file}`);
@@ -22060,7 +22074,7 @@ function containedHostPath(root, candidate) {
22060
22074
  function portableBindingIssue(root, pathHint, repositoryId) {
22061
22075
  let current = root;
22062
22076
  for (const segment of pathHint === "." ? [] : pathHint.split("/")) {
22063
- current = join3(current, segment);
22077
+ current = join4(current, segment);
22064
22078
  if (!existsSync4(current)) break;
22065
22079
  const stat = lstatSync(current);
22066
22080
  if (stat.isSymbolicLink()) {
@@ -22119,20 +22133,20 @@ function readResource(registry, root, file, logicalPath, kind, id, containmentRo
22119
22133
  parent = dirname2(parent);
22120
22134
  }
22121
22135
  if (!stat.isFile()) fail2("path", "resource_not_file", label, "configuration resource must be a regular file");
22122
- const value = parseRestrictedYaml2(readFileSync3(file), label);
22136
+ const value = parseRestrictedYaml2(readFileSync4(file), label);
22123
22137
  const issues = registry.validate(kind, value, label);
22124
22138
  if (issues.length > 0) throw new VnextConfigError(issues);
22125
22139
  return { kind, ...id === void 0 ? {} : { id }, file, logicalPath, value };
22126
22140
  }
22127
22141
  function readTemplateProvenance(registry, root) {
22128
- const file = join3(root, ".kxm", "template-provenance.yaml");
22142
+ const file = join4(root, ".kxm", "template-provenance.yaml");
22129
22143
  if (!existsSync4(file)) return void 0;
22130
22144
  const label = ".kxm/template-provenance.yaml";
22131
22145
  const stat = lstatSync(file);
22132
22146
  if (stat.isSymbolicLink() || !stat.isFile()) {
22133
22147
  fail2("path", "resource_not_file", label, "template provenance must be a regular file, not a link or directory");
22134
22148
  }
22135
- const configRoot = join3(root, ".kxm");
22149
+ const configRoot = join4(root, ".kxm");
22136
22150
  let parent = dirname2(file);
22137
22151
  while (parent !== root) {
22138
22152
  const parentStat = lstatSync(parent);
@@ -22142,7 +22156,7 @@ function readTemplateProvenance(registry, root) {
22142
22156
  if (parent === configRoot) break;
22143
22157
  parent = dirname2(parent);
22144
22158
  }
22145
- const value = parseRestrictedYaml2(readFileSync3(file), label);
22159
+ const value = parseRestrictedYaml2(readFileSync4(file), label);
22146
22160
  const issues = registry.validateTemplateProvenance(value, label);
22147
22161
  if (issues.length > 0) throw new VnextConfigError(issues);
22148
22162
  if (!resolveVnextTemplateBaseline(value)) {
@@ -22182,27 +22196,27 @@ function listNamedResources(registry, root, directory, logicalDirectory, kind) {
22182
22196
  const entries = readdirSync(directory, { withFileTypes: true }).sort((left, right) => compareCodeUnits3(left.name, right.name));
22183
22197
  for (const entry of entries) {
22184
22198
  if (entry.isDirectory()) {
22185
- 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"));
22186
22200
  continue;
22187
22201
  }
22188
22202
  if (!entry.name.toLowerCase().endsWith(".yaml") && !entry.name.toLowerCase().endsWith(".yml")) continue;
22189
22203
  if (!entry.isFile() || extname(entry.name) !== ".yaml") {
22190
- 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"));
22191
22205
  continue;
22192
22206
  }
22193
- const id = basename(entry.name, ".yaml");
22207
+ const id = basename2(entry.name, ".yaml");
22194
22208
  if (kind === "model" && id === "inventory") continue;
22195
22209
  if (!resourceIdentifier(id)) {
22196
- 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`));
22197
22211
  continue;
22198
22212
  }
22199
22213
  const collision = [...resources.keys()].find((candidate) => candidate.toLocaleLowerCase("en-US") === id.toLocaleLowerCase("en-US"));
22200
22214
  if (collision) {
22201
- 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}`));
22202
22216
  continue;
22203
22217
  }
22204
22218
  try {
22205
- 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);
22206
22220
  resources.set(id, resource);
22207
22221
  } catch (error) {
22208
22222
  if (error instanceof VnextConfigError) issues.push(...error.issues);
@@ -22523,8 +22537,8 @@ function validateWorkflow(workflow, agents, models, repositories, gates, issues)
22523
22537
  const writable = Object.values(objectValue(step.repositories) ?? {}).filter((access) => access === "write").length;
22524
22538
  if (maxWriteRepositories > writable) issues.push(issue2("semantic", "write_repository_bound_invalid", file, `${stepId} maxWriteRepositories exceeds writable repository scope`));
22525
22539
  }
22526
- const join47 = objectValue(step.join);
22527
- 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;
22528
22542
  if (minimumPassed !== void 0 && minimumPassed > maximum) issues.push(issue2("semantic", "join_impossible", file, `${stepId} minimumPassed exceeds assignment maximum`));
22529
22543
  const distinctBy = names(assignment?.distinctBy);
22530
22544
  if (distinctBy.length > 0) {
@@ -22738,11 +22752,11 @@ function validateBundle(project, repositories, agents, models, workflows, enviro
22738
22752
  if (!workflows.has(defaultWorkflow)) issues.push(issue2("reference", "default_workflow_unknown", project.logicalPath, `default workflow ${defaultWorkflow} does not exist`));
22739
22753
  for (const workflow of workflows.values()) validateWorkflow(workflow, agents, models, repositoryIds, gates, issues);
22740
22754
  if (projectRoot) {
22741
- const writerRolePath = join3(projectRoot, ".kxm", "roles", "writer.yaml");
22755
+ const writerRolePath = join4(projectRoot, ".kxm", "roles", "writer.yaml");
22742
22756
  const implementerAgent = agents.get("implementer") ?? agents.get("writer");
22743
22757
  if (existsSync4(writerRolePath) && implementerAgent) {
22744
22758
  try {
22745
- const rawRole = parseRestrictedYaml2(readFileSync3(writerRolePath, "utf8"));
22759
+ const rawRole = parseRestrictedYaml2(readFileSync4(writerRolePath, "utf8"));
22746
22760
  const roleObj = objectValue(rawRole);
22747
22761
  const rosterEntries = valuesOf(roleObj ?? {}, "roster").map((candidate) => objectValue(candidate)).filter((entry) => Boolean(entry));
22748
22762
  const enabledRosterModels = rosterEntries.filter((entry) => entry.enabled !== false).map((entry) => stringValue(entry.model)).filter((m2) => Boolean(m2));
@@ -22802,7 +22816,7 @@ function discoverGitRoot(start = process.cwd()) {
22802
22816
  }
22803
22817
  function discoverVnextProjectRoot(start = process.cwd()) {
22804
22818
  const gitRoot = discoverGitRoot(start);
22805
- return gitRoot && existsSync4(join3(gitRoot, ".kxm", "project.yaml")) ? gitRoot : void 0;
22819
+ return gitRoot && existsSync4(join4(gitRoot, ".kxm", "project.yaml")) ? gitRoot : void 0;
22806
22820
  }
22807
22821
  function assertNoRegisteredGates(options) {
22808
22822
  if ("registeredGates" in options) {
@@ -22819,7 +22833,7 @@ function loadVnextProject(projectRoot, options = {}) {
22819
22833
  migrationReceipt = receiptCheck.receipt;
22820
22834
  }
22821
22835
  const registry = new VnextSchemaRegistry(options.schemasDir);
22822
- 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");
22823
22837
  const earlyIssues = [];
22824
22838
  validatePortablePaths(project, earlyIssues);
22825
22839
  const templateProvenance = readTemplateProvenance(registry, root);
@@ -22841,15 +22855,15 @@ function loadVnextProject(projectRoot, options = {}) {
22841
22855
  }
22842
22856
  }
22843
22857
  if (earlyIssues.length > 0) throw new VnextConfigError(earlyIssues);
22844
- const agents = listNamedResources(registry, root, join3(root, ".kxm", "agents"), ".kxm/agents", "agent");
22845
- const models = listNamedResources(registry, root, join3(root, ".kxm", "models"), ".kxm/models", "model");
22846
- const workflows = listNamedResources(registry, root, join3(root, ".kxm", "workflows"), ".kxm/workflows", "workflow");
22847
- 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");
22848
22862
  const gateRegistry = existsSync4(gatePath) ? readResource(registry, root, gatePath, ".kxm/gates.yaml", "gate-registry") : void 0;
22849
22863
  const environments = [];
22850
22864
  const repositories = /* @__PURE__ */ new Map();
22851
22865
  const loadIssues = [];
22852
- const projectEnvironment = join3(root, ".kxm", "project", "env.yaml");
22866
+ const projectEnvironment = join4(root, ".kxm", "project", "env.yaml");
22853
22867
  if (existsSync4(projectEnvironment)) {
22854
22868
  try {
22855
22869
  environments.push(readResource(registry, root, projectEnvironment, ".kxm/project/env.yaml", "environment"));
@@ -22915,7 +22929,7 @@ function loadVnextProject(projectRoot, options = {}) {
22915
22929
  continue;
22916
22930
  }
22917
22931
  seenBindings.set(foldedBinding, repositoryId);
22918
- const repositoryFile = join3(binding, ".kxm", "repo", "repo.yaml");
22932
+ const repositoryFile = join4(binding, ".kxm", "repo", "repo.yaml");
22919
22933
  let definitionValidated = false;
22920
22934
  if (existsSync4(repositoryFile)) {
22921
22935
  try {
@@ -22933,7 +22947,7 @@ function loadVnextProject(projectRoot, options = {}) {
22933
22947
  } else if (required || hasLocalBinding) {
22934
22948
  loadIssues.push(issue2("discovery", "repository_definition_missing", `.kxm/repositories/${repositoryId}/repo.yaml`, `${hasLocalBinding ? "explicit" : "required"} repository ${repositoryId} has no repo.yaml`));
22935
22949
  }
22936
- const environmentFile = join3(binding, ".kxm", "repo", "env.yaml");
22950
+ const environmentFile = join4(binding, ".kxm", "repo", "env.yaml");
22937
22951
  if (existsSync4(environmentFile)) {
22938
22952
  if (!definitionValidated) {
22939
22953
  loadIssues.push(issue2("reference", "repository_environment_without_definition", `.kxm/repositories/${repositoryId}/env.yaml`, `repository ${repositoryId} environment requires a validated matching repo.yaml`));
@@ -23012,20 +23026,20 @@ function legacyInputsAt(root) {
23012
23026
  ".kxm/config/workflows",
23013
23027
  ".kxm/state/kxm.db"
23014
23028
  ];
23015
- return candidates.filter((candidate) => existsSync4(join3(root, ...candidate.split("/"))));
23029
+ return candidates.filter((candidate) => existsSync4(join4(root, ...candidate.split("/"))));
23016
23030
  }
23017
23031
  var VNEXT_MIGRATION_RECEIPT_PATH = ".kxm/migration-receipt.yaml";
23018
23032
  var LEGACY_CONFIG_FILES = [".kxm/config/agents.json", ".kxm/config/gates.json"];
23019
23033
  function legacyConfigFilesAt(root) {
23020
23034
  const files = [];
23021
23035
  for (const component of [".kxm", ".kxm/config"]) {
23022
- const absolute = join3(root, ...component.split("/"));
23036
+ const absolute = join4(root, ...component.split("/"));
23023
23037
  if (existsSync4(absolute) && lstatSync(absolute).isSymbolicLink()) return [component];
23024
23038
  }
23025
23039
  for (const candidate of LEGACY_CONFIG_FILES) {
23026
- if (existsSync4(join3(root, ...candidate.split("/")))) files.push(candidate);
23040
+ if (existsSync4(join4(root, ...candidate.split("/")))) files.push(candidate);
23027
23041
  }
23028
- const workflowsDir = join3(root, ".kxm", "config", "workflows");
23042
+ const workflowsDir = join4(root, ".kxm", "config", "workflows");
23029
23043
  if (existsSync4(workflowsDir)) {
23030
23044
  const stat = lstatSync(workflowsDir);
23031
23045
  if (stat.isSymbolicLink()) {
@@ -23041,9 +23055,9 @@ function legacyConfigFilesAt(root) {
23041
23055
  return files;
23042
23056
  }
23043
23057
  function hashFileRecord(root, relativePath) {
23044
- const absolute = join3(root, ...relativePath.split("/"));
23058
+ const absolute = join4(root, ...relativePath.split("/"));
23045
23059
  if (!existsSync4(absolute)) return void 0;
23046
- const bytes = readFileSync3(absolute);
23060
+ const bytes = readFileSync4(absolute);
23047
23061
  return {
23048
23062
  path: relativePath,
23049
23063
  sha256: `sha256:${createHash6("sha256").update(bytes).digest("hex")}`,
@@ -23055,7 +23069,7 @@ function migrationReceiptSelfHash(receipt) {
23055
23069
  return `sha256:${createHash6("sha256").update(vnextCanonicalJson(unsigned), "utf8").digest("hex")}`;
23056
23070
  }
23057
23071
  function readVnextMigrationReceipt(root, options = {}) {
23058
- const receiptPath = join3(root, ...VNEXT_MIGRATION_RECEIPT_PATH.split("/"));
23072
+ const receiptPath = join4(root, ...VNEXT_MIGRATION_RECEIPT_PATH.split("/"));
23059
23073
  const legacyFiles = legacyConfigFilesAt(root);
23060
23074
  if (!existsSync4(receiptPath)) {
23061
23075
  return {
@@ -23068,7 +23082,7 @@ function readVnextMigrationReceipt(root, options = {}) {
23068
23082
  }
23069
23083
  let receipt;
23070
23084
  try {
23071
- receipt = parseRestrictedYaml2(readFileSync3(receiptPath), VNEXT_MIGRATION_RECEIPT_PATH);
23085
+ receipt = parseRestrictedYaml2(readFileSync4(receiptPath), VNEXT_MIGRATION_RECEIPT_PATH);
23072
23086
  } catch (error) {
23073
23087
  if (error instanceof VnextConfigError) return { issues: [...error.issues] };
23074
23088
  throw error;
@@ -23129,7 +23143,7 @@ function planVnextInitialization(start = process.cwd(), options = {}) {
23129
23143
  }
23130
23144
  const gitRoot = discoverGitRoot(inspectedFrom);
23131
23145
  const candidateRoot = gitRoot ?? inspectedFrom;
23132
- if (existsSync4(join3(candidateRoot, ".kxm"))) {
23146
+ if (existsSync4(join4(candidateRoot, ".kxm"))) {
23133
23147
  return {
23134
23148
  mode: "repair",
23135
23149
  inspectedFrom,
@@ -23145,14 +23159,14 @@ function planVnextInitialization(start = process.cwd(), options = {}) {
23145
23159
  // plugins/kxm/src/vnext-runtime-supervisor.ts
23146
23160
  import { spawn as spawn2 } from "node:child_process";
23147
23161
  import { createHash as createHash11, createHmac, randomBytes as randomBytes2, timingSafeEqual as timingSafeEqual2 } from "node:crypto";
23148
- 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";
23149
- 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";
23150
23164
  import { fileURLToPath as fileURLToPath2 } from "node:url";
23151
23165
 
23152
23166
  // plugins/kxm/src/vnext-runtime-store.ts
23153
23167
  import { createHash as createHash9, randomUUID as randomUUID4 } from "node:crypto";
23154
- import { existsSync as existsSync7, lstatSync as lstatSync4, mkdirSync as mkdirSync5, readFileSync as readFileSync6, realpathSync as realpathSync3, writeFileSync as writeFileSync5 } from "node:fs";
23155
- 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";
23156
23170
 
23157
23171
  // plugins/kxm/src/vnext-bindings.ts
23158
23172
  import { spawnSync as spawnSync3 } from "node:child_process";
@@ -23165,7 +23179,7 @@ import {
23165
23179
  lstatSync as lstatSync2,
23166
23180
  mkdirSync as mkdirSync3,
23167
23181
  openSync,
23168
- readFileSync as readFileSync4,
23182
+ readFileSync as readFileSync5,
23169
23183
  realpathSync as realpathSync2,
23170
23184
  renameSync,
23171
23185
  rmSync,
@@ -23213,7 +23227,7 @@ var DatabaseSync = class {
23213
23227
  };
23214
23228
 
23215
23229
  // plugins/kxm/src/vnext-bindings.ts
23216
- 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";
23217
23231
  var MAX_BINDING_RECORD_BYTES = 256 * 1024;
23218
23232
  var BINDING_LABEL = "Runtime-local repository bindings";
23219
23233
  var activeLocks = /* @__PURE__ */ new WeakSet();
@@ -23247,12 +23261,12 @@ function vnextUserStateRoot(options = {}) {
23247
23261
  }
23248
23262
  if (platform === "win32") {
23249
23263
  const localAppData = env.LOCALAPPDATA?.trim();
23250
- const base2 = localAppData && isAbsolute2(localAppData) ? localAppData : join4(home, "AppData", "Local");
23264
+ const base2 = localAppData && isAbsolute2(localAppData) ? localAppData : join5(home, "AppData", "Local");
23251
23265
  return resolve3(base2, "KXM");
23252
23266
  }
23253
23267
  if (platform === "darwin") return resolve3(home, "Library", "Application Support", "KXM");
23254
23268
  const xdgState = env.XDG_STATE_HOME?.trim();
23255
- const base = xdgState && isAbsolute2(xdgState) ? xdgState : join4(home, ".local", "state");
23269
+ const base = xdgState && isAbsolute2(xdgState) ? xdgState : join5(home, ".local", "state");
23256
23270
  return resolve3(base, "kxm");
23257
23271
  }
23258
23272
  function projectBindingKey(projectRoot, platform = process.platform) {
@@ -23262,7 +23276,7 @@ function projectBindingKey(projectRoot, platform = process.platform) {
23262
23276
  }
23263
23277
  function vnextLocalBindingFile(projectRoot, options = {}) {
23264
23278
  const stateRoot = vnextUserStateRoot(options);
23265
- return join4(stateRoot, "projects", projectBindingKey(projectRoot, options.platform), "repository-bindings.json");
23279
+ return join5(stateRoot, "projects", projectBindingKey(projectRoot, options.platform), "repository-bindings.json");
23266
23280
  }
23267
23281
  function checkedDirectory(path4, description) {
23268
23282
  if (!existsSync5(path4)) return false;
@@ -23273,7 +23287,7 @@ function checkedDirectory(path4, description) {
23273
23287
  return true;
23274
23288
  }
23275
23289
  function existingBindingDirectory(file, stateRoot) {
23276
- const projects = join4(stateRoot, "projects");
23290
+ const projects = join5(stateRoot, "projects");
23277
23291
  const project = dirname3(file);
23278
23292
  if (!checkedDirectory(stateRoot, "local state root")) return false;
23279
23293
  if (!checkedDirectory(projects, "local projects directory")) return false;
@@ -23308,7 +23322,7 @@ function readVnextLocalBindings(projectRoot, options = {}) {
23308
23322
  if (stat.size > MAX_BINDING_RECORD_BYTES) {
23309
23323
  bindingError("parse", "local_binding_file_too_large", `binding record exceeds ${MAX_BINDING_RECORD_BYTES} bytes`);
23310
23324
  }
23311
- const parsed = parseRestrictedYaml2(readFileSync4(file), BINDING_LABEL);
23325
+ const parsed = parseRestrictedYaml2(readFileSync5(file), BINDING_LABEL);
23312
23326
  return asRecord2(parsed, file, root, options.schemasDir);
23313
23327
  }
23314
23328
  function normalizedRecord(projectRoot, projectId, repositories, schemasDir) {
@@ -23376,7 +23390,7 @@ function ensureBindingDirectory(file, stateRoot) {
23376
23390
  ensureDurableDirectory(stateRoot, "local state root");
23377
23391
  checkedDirectory(stateRoot, "local state root");
23378
23392
  syncDirectory(stateRoot);
23379
- const projects = join4(stateRoot, "projects");
23393
+ const projects = join5(stateRoot, "projects");
23380
23394
  createDirectoryIfMissing(projects);
23381
23395
  checkedDirectory(projects, "local projects directory");
23382
23396
  const project = dirname3(file);
@@ -23389,7 +23403,7 @@ function assertNoLinkedDirectoryComponents(path4, description) {
23389
23403
  let current = filesystemRoot;
23390
23404
  const remainder = relative2(filesystemRoot, absolute);
23391
23405
  for (const segment of remainder.split(sep2).filter(Boolean)) {
23392
- current = join4(current, segment);
23406
+ current = join5(current, segment);
23393
23407
  const stat = lstatSync2(current);
23394
23408
  if (stat.isSymbolicLink() || !stat.isDirectory()) {
23395
23409
  bindingError("path", "project_operation_lock_parent_invalid", `${description} contains a linked or non-directory component`);
@@ -23416,7 +23430,7 @@ function projectOperationLockFile(projectRoot) {
23416
23430
  if (gitStat.isSymbolicLink() || !gitStat.isDirectory()) {
23417
23431
  bindingError("path", "project_operation_lock_parent_invalid", "authoritative Git metadata must resolve to a regular directory");
23418
23432
  }
23419
- const lockDirectory = join4(gitDirectory, "kxm");
23433
+ const lockDirectory = join5(gitDirectory, "kxm");
23420
23434
  if (existsSync5(lockDirectory)) {
23421
23435
  const stat = lstatSync2(lockDirectory);
23422
23436
  if (stat.isSymbolicLink() || !stat.isDirectory()) {
@@ -23426,7 +23440,7 @@ function projectOperationLockFile(projectRoot) {
23426
23440
  mkdirSync3(lockDirectory, { mode: 448 });
23427
23441
  syncDirectory(gitDirectory);
23428
23442
  }
23429
- return join4(lockDirectory, "project-operation-lock.sqlite");
23443
+ return join5(lockDirectory, "project-operation-lock.sqlite");
23430
23444
  }
23431
23445
  function withVnextLocalBindingLock(projectRoot, options, callback) {
23432
23446
  const root = resolve3(projectRoot);
@@ -23485,7 +23499,7 @@ function writeVnextLocalBindings(projectRoot, projectId, repositories, options =
23485
23499
  const { file, record } = planned;
23486
23500
  if (!planned.written) return planned;
23487
23501
  ensureBindingDirectory(file, vnextUserStateRoot(options));
23488
- const temporary = join4(dirname3(file), `.repository-bindings-${process.pid}-${randomUUID3()}.tmp`);
23502
+ const temporary = join5(dirname3(file), `.repository-bindings-${process.pid}-${randomUUID3()}.tmp`);
23489
23503
  let descriptor;
23490
23504
  try {
23491
23505
  descriptor = openSync(temporary, "wx", 384);
@@ -23516,11 +23530,11 @@ import {
23516
23530
  lstatSync as lstatSync3,
23517
23531
  mkdirSync as mkdirSync4,
23518
23532
  readdirSync as readdirSync2,
23519
- readFileSync as readFileSync5,
23533
+ readFileSync as readFileSync6,
23520
23534
  unlinkSync as unlinkSync2,
23521
23535
  writeFileSync as writeFileSync4
23522
23536
  } from "node:fs";
23523
- 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";
23524
23538
  function databaseError(code, file, message) {
23525
23539
  const issue3 = { phase: "semantic", code, file, message };
23526
23540
  return new VnextConfigError([issue3]);
@@ -23669,7 +23683,7 @@ function checkIntegrity(database) {
23669
23683
  return rows.length === 1 && rows[0]?.integrity_check === "ok";
23670
23684
  }
23671
23685
  function fileSha256(filePath) {
23672
- const bytes = readFileSync5(filePath);
23686
+ const bytes = readFileSync6(filePath);
23673
23687
  return `sha256:${createHash8("sha256").update(bytes).digest("hex")}`;
23674
23688
  }
23675
23689
  function backupDatabaseFile(sourcePath, targetPath, storeId) {
@@ -23716,7 +23730,7 @@ function backupDatabaseFile(sourcePath, targetPath, storeId) {
23716
23730
  return {
23717
23731
  storeId,
23718
23732
  sourcePath: resolvedSource,
23719
- backupFile: basename2(resolvedTarget),
23733
+ backupFile: basename3(resolvedTarget),
23720
23734
  schemaVersion,
23721
23735
  sha256,
23722
23736
  bytes,
@@ -23782,7 +23796,7 @@ function restoreDatabaseFile(backupPath, targetPath, storeId, expectedSchemaVers
23782
23796
  return {
23783
23797
  storeId,
23784
23798
  sourcePath: resolvedTarget,
23785
- backupFile: basename2(resolvedBackup),
23799
+ backupFile: basename3(resolvedBackup),
23786
23800
  schemaVersion,
23787
23801
  integrity: "ok"
23788
23802
  };
@@ -23790,19 +23804,19 @@ function restoreDatabaseFile(backupPath, targetPath, storeId, expectedSchemaVers
23790
23804
  function discoverProjectStores(projectRoot, options = {}) {
23791
23805
  const root = resolve4(projectRoot);
23792
23806
  const stores = [];
23793
- 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");
23794
23808
  if (existsSync6(hubPath)) {
23795
23809
  stores.push({ storeId: "hub-store", sourcePath: hubPath, maxSupportedVersion: 3 });
23796
23810
  }
23797
- const registryPath = join5(root, ".kxm", "runtime", "registry.db");
23811
+ const registryPath = join6(root, ".kxm", "runtime", "registry.db");
23798
23812
  if (existsSync6(registryPath)) {
23799
23813
  stores.push({ storeId: "registry", sourcePath: registryPath, maxSupportedVersion: 1 });
23800
23814
  }
23801
- const bindingsPath = join5(root, ".kxm", "runtime", "bindings.db");
23815
+ const bindingsPath = join6(root, ".kxm", "runtime", "bindings.db");
23802
23816
  if (existsSync6(bindingsPath)) {
23803
23817
  stores.push({ storeId: "binding-store", sourcePath: bindingsPath, maxSupportedVersion: 1 });
23804
23818
  }
23805
- const eventsDir = join5(root, ".kxm", "runtime", "events");
23819
+ const eventsDir = join6(root, ".kxm", "runtime", "events");
23806
23820
  if (existsSync6(eventsDir)) {
23807
23821
  const entries = readdirSync2(eventsDir, { withFileTypes: true });
23808
23822
  for (const entry of entries) {
@@ -23810,7 +23824,7 @@ function discoverProjectStores(projectRoot, options = {}) {
23810
23824
  const key = entry.name.replace(/\.db$/, "");
23811
23825
  stores.push({
23812
23826
  storeId: `events:${key}`,
23813
- sourcePath: join5(eventsDir, entry.name),
23827
+ sourcePath: join6(eventsDir, entry.name),
23814
23828
  maxSupportedVersion: 3
23815
23829
  });
23816
23830
  }
@@ -23829,20 +23843,20 @@ function createBackup(options = {}) {
23829
23843
  const now = /* @__PURE__ */ new Date();
23830
23844
  const timestamp = now.toISOString().replace(/[:.]/g, "-");
23831
23845
  const backupId = `bk_${randomBytes(8).toString("hex")}`;
23832
- 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}`);
23833
23847
  if (!existsSync6(outDir)) {
23834
23848
  mkdirSync4(outDir, { recursive: true, mode: 448 });
23835
23849
  }
23836
23850
  const backedUpStores = [];
23837
23851
  const usedFilenames = /* @__PURE__ */ new Set();
23838
23852
  for (const store of stores) {
23839
- let filename = basename2(store.sourcePath);
23853
+ let filename = basename3(store.sourcePath);
23840
23854
  if (usedFilenames.has(filename)) {
23841
23855
  const sanitizedId = store.storeId.replace(/[^a-zA-Z0-9_.-]/g, "_");
23842
23856
  filename = `${sanitizedId}-${filename}`;
23843
23857
  }
23844
23858
  usedFilenames.add(filename);
23845
- const targetFile2 = join5(outDir, filename);
23859
+ const targetFile2 = join6(outDir, filename);
23846
23860
  const record = backupDatabaseFile(store.sourcePath, targetFile2, store.storeId);
23847
23861
  backedUpStores.push(record);
23848
23862
  }
@@ -23857,7 +23871,7 @@ function createBackup(options = {}) {
23857
23871
  const manifestSha256 = `sha256:${createHash8("sha256").update(manifestJson, "utf8").digest("hex")}`;
23858
23872
  manifest.manifestSha256 = manifestSha256;
23859
23873
  const finalJson = JSON.stringify(manifest, null, 2) + "\n";
23860
- const manifestPath = join5(outDir, "manifest.json");
23874
+ const manifestPath = join6(outDir, "manifest.json");
23861
23875
  writeFileSync4(manifestPath, finalJson, "utf8");
23862
23876
  return { manifest, outDir };
23863
23877
  }
@@ -23868,13 +23882,13 @@ function restoreBackup(manifestPathOrDir, options = {}) {
23868
23882
  throw databaseError("runtime_path_invalid", manifestPath, `manifest path ${manifestPath} does not exist`);
23869
23883
  }
23870
23884
  if (stat.isDirectory()) {
23871
- manifestPath = join5(manifestPath, "manifest.json");
23885
+ manifestPath = join6(manifestPath, "manifest.json");
23872
23886
  }
23873
23887
  if (!existsSync6(manifestPath)) {
23874
23888
  throw databaseError("runtime_path_invalid", manifestPath, `backup manifest ${manifestPath} not found`);
23875
23889
  }
23876
23890
  const manifestDir = dirname4(manifestPath);
23877
- const rawText = readFileSync5(manifestPath, "utf8");
23891
+ const rawText = readFileSync6(manifestPath, "utf8");
23878
23892
  let manifest;
23879
23893
  try {
23880
23894
  manifest = JSON.parse(rawText);
@@ -23886,7 +23900,7 @@ function restoreBackup(manifestPathOrDir, options = {}) {
23886
23900
  }
23887
23901
  const restoredStores = [];
23888
23902
  for (const store of manifest.stores) {
23889
- const backupFilePath = join5(manifestDir, store.backupFile);
23903
+ const backupFilePath = join6(manifestDir, store.backupFile);
23890
23904
  if (!existsSync6(backupFilePath)) {
23891
23905
  throw databaseError("restore_file_missing", backupFilePath, `backup file ${store.backupFile} missing from ${manifestDir}`);
23892
23906
  }
@@ -23905,7 +23919,7 @@ function restoreBackup(manifestPathOrDir, options = {}) {
23905
23919
  let targetPath = store.sourcePath;
23906
23920
  if (options.projectRoot && manifest.projectRoot && targetPath.startsWith(manifest.projectRoot)) {
23907
23921
  const rel = targetPath.slice(manifest.projectRoot.length).replace(/^[\\/]+/, "");
23908
- targetPath = join5(resolve4(options.projectRoot), rel);
23922
+ targetPath = join6(resolve4(options.projectRoot), rel);
23909
23923
  }
23910
23924
  const result = restoreDatabaseFile(
23911
23925
  backupFilePath,
@@ -23926,12 +23940,12 @@ function restoreBackup(manifestPathOrDir, options = {}) {
23926
23940
  // plugins/kxm/src/vnext-runtime-store.ts
23927
23941
  function vnextRuntimePaths(options = {}) {
23928
23942
  const stateRoot = options.stateRoot ? resolve5(options.stateRoot) : vnextUserStateRoot({ ...options.env ? { env: options.env } : {}, ...options.homeDir ? { homeDir: options.homeDir } : {} });
23929
- const runtimeDir = join6(stateRoot, "runtime");
23943
+ const runtimeDir = join7(stateRoot, "runtime");
23930
23944
  return {
23931
23945
  stateRoot,
23932
23946
  runtimeDir,
23933
- registryDb: join6(runtimeDir, "registry.db"),
23934
- projectsDir: join6(runtimeDir, "projects")
23947
+ registryDb: join7(runtimeDir, "registry.db"),
23948
+ projectsDir: join7(runtimeDir, "projects")
23935
23949
  };
23936
23950
  }
23937
23951
  function runtimeIssue(phase, code, file, message) {
@@ -24290,7 +24304,7 @@ function compileStep(step, index, stepIndex, requirePlanHash, sink) {
24290
24304
  const maxAttempts = compileCountField(step.maxAttempts, 1, `${id}.maxAttempts`, id, sink);
24291
24305
  const timeoutMs = compileOptionalDuration(step.timeoutMs, `${id}.timeoutMs`, id, sink);
24292
24306
  const assignments = compileAssignments(step, id, agent, sink);
24293
- const join47 = compileJoin(step, id, sink);
24307
+ const join48 = compileJoin(step, id, sink);
24294
24308
  const requiredEvidence = compileEvidence(step, id, sink);
24295
24309
  const transitions = compileTransitions(step, id, index, stepIndex, sink);
24296
24310
  const outcomes = Object.keys(transitions).sort(compareCodeUnits4);
@@ -24318,7 +24332,7 @@ function compileStep(step, index, stepIndex, requirePlanHash, sink) {
24318
24332
  transitions: orderedTransitions,
24319
24333
  requiresPlanHash: requirePlanHash.includes(id),
24320
24334
  assignments,
24321
- join: join47
24335
+ join: join48
24322
24336
  };
24323
24337
  if (kind === "agent" || kind === "moa") {
24324
24338
  if (!agent) return void 0;
@@ -24368,15 +24382,15 @@ function compileAssignments(step, stepId, primaryAgentId, sink) {
24368
24382
  };
24369
24383
  }
24370
24384
  function compileJoin(step, stepId, sink) {
24371
- const join47 = objectValue2(step.join);
24372
- if (!join47) return { strategy: "all" };
24373
- const declared = stringValue2(join47.strategy);
24385
+ const join48 = objectValue2(step.join);
24386
+ if (!join48) return { strategy: "all" };
24387
+ const declared = stringValue2(join48.strategy);
24374
24388
  const strategy = declared && JOIN_STRATEGIES.has(declared) ? declared : "all";
24375
- const minimumPassed = compileOptionalCount(join47.minimumPassed, `${stepId}.join.minimumPassed`, stepId, sink);
24389
+ const minimumPassed = compileOptionalCount(join48.minimumPassed, `${stepId}.join.minimumPassed`, stepId, sink);
24376
24390
  const compiled = {
24377
24391
  strategy,
24378
24392
  ...minimumPassed !== void 0 ? { minimumPassed } : {},
24379
- ...typeof join47.cancelRemaining === "boolean" ? { cancelRemaining: join47.cancelRemaining } : {}
24393
+ ...typeof join48.cancelRemaining === "boolean" ? { cancelRemaining: join48.cancelRemaining } : {}
24380
24394
  };
24381
24395
  return compiled;
24382
24396
  }
@@ -24656,8 +24670,8 @@ var RECORD_LIMIT = 16 * 1024 * 1024;
24656
24670
  // plugins/kxm/src/prices.ts
24657
24671
  var import_yaml3 = __toESM(require_dist(), 1);
24658
24672
  import { createHash as createHash10 } from "node:crypto";
24659
- import { existsSync as existsSync8, readFileSync as readFileSync7, statSync } from "node:fs";
24660
- 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";
24661
24675
 
24662
24676
  // plugins/kxm/src/price-calc.ts
24663
24677
  var PRICES_SCHEMA = "kxm.prices.v1";
@@ -24809,11 +24823,11 @@ function parsePriceCatalog(text) {
24809
24823
  return catalog;
24810
24824
  }
24811
24825
  function loadPriceCatalog(rootOrPath) {
24812
- 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;
24813
24827
  if (!candidatePath || !existsSync8(candidatePath)) {
24814
24828
  return void 0;
24815
24829
  }
24816
- const content = readFileSync7(candidatePath, "utf8");
24830
+ const content = readFileSync8(candidatePath, "utf8");
24817
24831
  return parsePriceCatalog(content);
24818
24832
  }
24819
24833
  function loadPriceCatalogForEstimate(options) {
@@ -24834,13 +24848,13 @@ var import_yaml5 = __toESM(require_dist(), 1);
24834
24848
 
24835
24849
  // plugins/kxm/src/producers.ts
24836
24850
  var import_yaml4 = __toESM(require_dist(), 1);
24837
- import { existsSync as existsSync9, readFileSync as readFileSync8, mkdirSync as mkdirSync6, writeFileSync as writeFileSync6, readdirSync as readdirSync3 } from "node:fs";
24838
- 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";
24839
24853
  var empty = () => ({ schema: "kxm.producers.v1", updatedAt: (/* @__PURE__ */ new Date()).toISOString(), promoted: [], demoted: [], enabled: [], disabled: [], roles: {} });
24840
24854
  function loadProducerPolicy(root) {
24841
- const path4 = join8(root, ".kxm", "producers.yaml");
24855
+ const path4 = join9(root, ".kxm", "producers.yaml");
24842
24856
  if (!existsSync9(path4)) return empty();
24843
- const value = (0, import_yaml4.parse)(readFileSync8(path4, "utf8"));
24857
+ const value = (0, import_yaml4.parse)(readFileSync9(path4, "utf8"));
24844
24858
  if (value?.schema !== "kxm.producers.v1" || !Array.isArray(value.promoted) || !Array.isArray(value.demoted)) throw new Error("invalid .kxm/producers.yaml");
24845
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")])) : {} };
24846
24860
  }
@@ -24850,8 +24864,8 @@ function updateProducer(root, model, status) {
24850
24864
  policy.demoted = policy.demoted.filter((x2) => x2 !== model);
24851
24865
  policy[status].push(model);
24852
24866
  policy.updatedAt = (/* @__PURE__ */ new Date()).toISOString();
24853
- mkdirSync6(join8(root, ".kxm"), { recursive: true });
24854
- 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");
24855
24869
  return policy;
24856
24870
  }
24857
24871
  function setModelState(root, model, state, role, removeRole2 = false) {
@@ -24861,10 +24875,10 @@ function setModelState(root, model, state, role, removeRole2 = false) {
24861
24875
  policy[state].push(model);
24862
24876
  if (role) {
24863
24877
  if (!/^[a-z][a-z0-9_-]{0,63}$/i.test(role)) throw new Error("invalid role id");
24864
- const rolePath = join8(root, ".kxm", "roles", `${role}.yaml`);
24878
+ const rolePath = join9(root, ".kxm", "roles", `${role}.yaml`);
24865
24879
  let roleFile = {};
24866
24880
  if (existsSync9(rolePath)) {
24867
- const parsed = (0, import_yaml4.parse)(readFileSync8(rolePath, "utf8"));
24881
+ const parsed = (0, import_yaml4.parse)(readFileSync9(rolePath, "utf8"));
24868
24882
  if (parsed && typeof parsed === "object" && !Array.isArray(parsed)) roleFile = parsed;
24869
24883
  }
24870
24884
  const roster = Array.isArray(roleFile.roster) ? roleFile.roster.filter((entry) => Boolean(entry) && typeof entry === "object" && !Array.isArray(entry)) : [];
@@ -24875,29 +24889,29 @@ function setModelState(root, model, state, role, removeRole2 = false) {
24875
24889
  roleFile.schema ??= "kxm.role.v1";
24876
24890
  roleFile.id ??= role;
24877
24891
  roleFile.roster = roster;
24878
- mkdirSync6(join8(root, ".kxm", "roles"), { recursive: true });
24892
+ mkdirSync6(join9(root, ".kxm", "roles"), { recursive: true });
24879
24893
  writeFileSync6(rolePath, (0, import_yaml4.stringify)(roleFile), "utf8");
24880
24894
  }
24881
24895
  policy.updatedAt = (/* @__PURE__ */ new Date()).toISOString();
24882
- mkdirSync6(join8(root, ".kxm"), { recursive: true });
24883
- 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");
24884
24898
  return policy;
24885
24899
  }
24886
24900
  function listRoleBindings(root) {
24887
- const dir = join8(root, ".kxm", "roles");
24901
+ const dir = join9(root, ".kxm", "roles");
24888
24902
  const result = {};
24889
24903
  if (!existsSync9(dir)) return result;
24890
24904
  for (const file of readdirSync3(dir).filter((name) => name.endsWith(".yaml"))) {
24891
24905
  const role = file.slice(0, -5);
24892
- const value = (0, import_yaml4.parse)(readFileSync8(join8(dir, file), "utf8"));
24906
+ const value = (0, import_yaml4.parse)(readFileSync9(join9(dir, file), "utf8"));
24893
24907
  result[role] = (value.roster ?? []).map((entry) => entry.model).filter((model) => typeof model === "string");
24894
24908
  }
24895
24909
  return result;
24896
24910
  }
24897
24911
  function listInventoryModels(root) {
24898
- const path4 = join8(root, ".kxm", "models", "inventory.yaml");
24912
+ const path4 = join9(root, ".kxm", "models", "inventory.yaml");
24899
24913
  if (!existsSync9(path4)) return [];
24900
- const value = (0, import_yaml4.parse)(readFileSync8(path4, "utf8"));
24914
+ const value = (0, import_yaml4.parse)(readFileSync9(path4, "utf8"));
24901
24915
  return (value.models ?? []).map((m2) => m2.id).filter((id) => typeof id === "string");
24902
24916
  }
24903
24917
 
@@ -25531,7 +25545,7 @@ function formatRoutingReport(report2, options = {}) {
25531
25545
  // plugins/kxm/src/vnext-runtime-supervisor.ts
25532
25546
  var repoRoot = resolve7(fileURLToPath2(new URL("../../../", import.meta.url)));
25533
25547
  function vnextSupervisorTokenFile(paths) {
25534
- return join9(paths.runtimeDir, "supervisor.token");
25548
+ return join10(paths.runtimeDir, "supervisor.token");
25535
25549
  }
25536
25550
  function readVnextSupervisorToken(paths) {
25537
25551
  const file = vnextSupervisorTokenFile(paths);
@@ -25540,7 +25554,7 @@ function readVnextSupervisorToken(paths) {
25540
25554
  if (stat.isSymbolicLink() || !stat.isFile()) {
25541
25555
  throw runtimeError("runtime_path_invalid", file, "supervisor token file must be a regular file, not a link");
25542
25556
  }
25543
- const token = readFileSync9(file, "utf8").trim();
25557
+ const token = readFileSync10(file, "utf8").trim();
25544
25558
  return token.length >= 32 ? token : void 0;
25545
25559
  }
25546
25560
  function processAlive(pid) {
@@ -25554,7 +25568,7 @@ function processAlive(pid) {
25554
25568
  var HEARTBEAT_STALE_MS = 15e3;
25555
25569
  var SUPERVISOR_ERROR_MAX_AGE_MS = 3e4;
25556
25570
  function supervisorErrorFile(paths) {
25557
- return join9(paths.runtimeDir, "supervisor.error");
25571
+ return join10(paths.runtimeDir, "supervisor.error");
25558
25572
  }
25559
25573
  function clearSupervisorError(paths) {
25560
25574
  const file = supervisorErrorFile(paths);
@@ -25567,7 +25581,7 @@ function readRecentSupervisorError(paths) {
25567
25581
  const ageMs = Date.now() - stat.mtimeMs;
25568
25582
  if (ageMs > SUPERVISOR_ERROR_MAX_AGE_MS) return void 0;
25569
25583
  try {
25570
- return readFileSync9(file, "utf8").trim();
25584
+ return readFileSync10(file, "utf8").trim();
25571
25585
  } catch {
25572
25586
  return void 0;
25573
25587
  }
@@ -25634,7 +25648,7 @@ async function ensureVnextSupervisor(options = {}) {
25634
25648
  throw runtimeError("runtime_supervisor_unreachable", paths.registryDb, `runtime supervisor pid ${status.pid} is registered as running but cannot be probed`);
25635
25649
  }
25636
25650
  clearSupervisorError(paths);
25637
- const scriptPath = join9(repoRoot, "scripts", "kxm-runtime-supervisor.mjs");
25651
+ const scriptPath = join10(repoRoot, "scripts", "kxm-runtime-supervisor.mjs");
25638
25652
  const spawnImpl = options.spawnImpl ?? ((script, env) => {
25639
25653
  const child = spawn2(process.execPath, [script], {
25640
25654
  detached: true,
@@ -25687,7 +25701,7 @@ async function vnextRuntimeRequest(handle, method, path4, body) {
25687
25701
 
25688
25702
  // plugins/kxm/src/cli/types.ts
25689
25703
  import { spawn as spawn3 } from "node:child_process";
25690
- import { join as join12, resolve as resolve9 } from "node:path";
25704
+ import { join as join13, resolve as resolve9 } from "node:path";
25691
25705
  import { fileURLToPath as fileURLToPath3 } from "node:url";
25692
25706
 
25693
25707
  // plugins/kxm/src/redact.ts
@@ -25718,8 +25732,8 @@ function redactStringList(values, maxItems = 32) {
25718
25732
  }
25719
25733
 
25720
25734
  // plugins/kxm/src/telemetry.ts
25721
- import { appendFileSync, mkdirSync as mkdirSync8, readFileSync as readFileSync10 } from "node:fs";
25722
- 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";
25723
25737
  var TELEMETRY_SCHEMA = "kxm.telemetry.v1";
25724
25738
  function inferImprovementTarget(input) {
25725
25739
  const explicit = input.env?.KXM_IMPROVE_TARGET?.trim();
@@ -25734,7 +25748,7 @@ function appendTelemetry(path4, event) {
25734
25748
  `, { encoding: "utf8", mode: 384 });
25735
25749
  }
25736
25750
  function telemetryPath(logsDir) {
25737
- return join10(logsDir, "telemetry.jsonl");
25751
+ return join11(logsDir, "telemetry.jsonl");
25738
25752
  }
25739
25753
  function makeTelemetryEvent(input) {
25740
25754
  return {
@@ -25749,7 +25763,7 @@ function makeTelemetryEvent(input) {
25749
25763
  function readRoutingRecords(path4) {
25750
25764
  const records = [];
25751
25765
  try {
25752
- const raw = readFileSync10(path4, "utf8");
25766
+ const raw = readFileSync11(path4, "utf8");
25753
25767
  for (const line of raw.split(/\r?\n/)) {
25754
25768
  if (!line.trim()) continue;
25755
25769
  try {
@@ -25826,9 +25840,9 @@ function workerResult(worker, payload) {
25826
25840
  }
25827
25841
 
25828
25842
  // plugins/kxm/src/hub-binding.ts
25829
- 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";
25830
25844
  import { homedir as homedir3 } from "node:os";
25831
- 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";
25832
25846
  var HUB_BINDING_SCHEMA = "kxm.hub-binding.v1";
25833
25847
  var HUB_HEALTH_PROBE_MS = 300;
25834
25848
  var HubBindingError = class extends Error {
@@ -25845,16 +25859,16 @@ function resolveUserStateRoot(env) {
25845
25859
  }
25846
25860
  if (process.platform === "win32") {
25847
25861
  const localAppData = env.LOCALAPPDATA?.trim();
25848
- const base2 = localAppData && isAbsolute5(localAppData) ? localAppData : join11(homedir3(), "AppData", "Local");
25862
+ const base2 = localAppData && isAbsolute5(localAppData) ? localAppData : join12(homedir3(), "AppData", "Local");
25849
25863
  return resolve8(base2, "KXM");
25850
25864
  }
25851
25865
  if (process.platform === "darwin") return resolve8(homedir3(), "Library", "Application Support", "KXM");
25852
25866
  const xdgState = env.XDG_STATE_HOME?.trim();
25853
- const base = xdgState && isAbsolute5(xdgState) ? xdgState : join11(homedir3(), ".local", "state");
25867
+ const base = xdgState && isAbsolute5(xdgState) ? xdgState : join12(homedir3(), ".local", "state");
25854
25868
  return resolve8(base, "kxm");
25855
25869
  }
25856
25870
  function hubBindingFile(env = process.env) {
25857
- return join11(resolveUserStateRoot(env), "hub-binding.json");
25871
+ return join12(resolveUserStateRoot(env), "hub-binding.json");
25858
25872
  }
25859
25873
  function validateHubUrl(raw) {
25860
25874
  let parsed;
@@ -25882,7 +25896,7 @@ function readHubBinding(env = process.env) {
25882
25896
  if (!existsSync11(file)) return void 0;
25883
25897
  let parsed;
25884
25898
  try {
25885
- parsed = JSON.parse(readFileSync11(file, "utf8"));
25899
+ parsed = JSON.parse(readFileSync12(file, "utf8"));
25886
25900
  } catch {
25887
25901
  throw new HubBindingError(`malformed hub binding at ${file}`);
25888
25902
  }
@@ -25905,7 +25919,7 @@ function readHubBinding(env = process.env) {
25905
25919
  function writeHubBinding(record, env = process.env) {
25906
25920
  const file = hubBindingFile(env);
25907
25921
  mkdirSync9(dirname8(file), { recursive: true, mode: 448 });
25908
- const temporary = join11(dirname8(file), `.hub-binding-${process.pid}.tmp`);
25922
+ const temporary = join12(dirname8(file), `.hub-binding-${process.pid}.tmp`);
25909
25923
  try {
25910
25924
  writeFileSync8(temporary, `${JSON.stringify(record, null, 2)}
25911
25925
  `, { encoding: "utf8", mode: 384 });
@@ -25953,7 +25967,7 @@ async function probeHubHealth(url, fetchImpl, timeoutMs = HUB_HEALTH_PROBE_MS) {
25953
25967
  var repoRoot2 = resolve9(fileURLToPath3(new URL("../../../../", import.meta.url)));
25954
25968
  function spawnScript(scriptName, extraEnv = {}) {
25955
25969
  return new Promise((resolveExit) => {
25956
- const child = spawn3(process.execPath, [join12(repoRoot2, "scripts", scriptName)], {
25970
+ const child = spawn3(process.execPath, [join13(repoRoot2, "scripts", scriptName)], {
25957
25971
  stdio: "inherit",
25958
25972
  env: { ...process.env, ...extraEnv }
25959
25973
  });
@@ -26043,10 +26057,10 @@ function workspaceDirs(cwd, workspaceFlag, env) {
26043
26057
  return {
26044
26058
  workdir,
26045
26059
  workspace,
26046
- config: derive ? join12(workspace, "config") : resolve9(workdir, env.KXM_CONFIG_DIR?.trim() || join12(workspace, "config")),
26047
- logs: derive ? join12(workspace, "logs") : resolve9(workdir, env.KXM_LOGS_DIR?.trim() || join12(workspace, "logs")),
26048
- assets: derive ? join12(workspace, "assets") : resolve9(workdir, env.KXM_ASSETS_DIR?.trim() || join12(workspace, "assets")),
26049
- 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"))
26050
26064
  };
26051
26065
  }
26052
26066
  function maskEnvName(name) {
@@ -26114,20 +26128,20 @@ function workspaceEnv(runtime) {
26114
26128
  // plugins/kxm/src/cli/roles.ts
26115
26129
  var import_yaml8 = __toESM(require_dist(), 1);
26116
26130
  import { randomUUID as randomUUID5 } from "node:crypto";
26117
- import { existsSync as existsSync14, readFileSync as readFileSync14 } from "node:fs";
26118
- 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";
26119
26133
  import { createInterface } from "node:readline";
26120
26134
 
26121
26135
  // plugins/kxm/src/role.ts
26122
26136
  var import_yaml7 = __toESM(require_dist(), 1);
26123
- import { existsSync as existsSync13, mkdirSync as mkdirSync11, readdirSync as readdirSync4, readFileSync as readFileSync13, rmSync as rmSync4, writeFileSync as writeFileSync10 } from "node:fs";
26124
- 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";
26125
26139
 
26126
26140
  // plugins/kxm/src/config.ts
26127
26141
  var import_yaml6 = __toESM(require_dist(), 1);
26128
- 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";
26129
26143
  import { homedir as homedir4 } from "node:os";
26130
- 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";
26131
26145
  var KXM_CONFIG_SCHEMA = "kxm.config.v1";
26132
26146
  var DEFAULT_KXM_CONFIG = {
26133
26147
  schema: KXM_CONFIG_SCHEMA,
@@ -26148,6 +26162,9 @@ var DEFAULT_KXM_CONFIG = {
26148
26162
  sync: {
26149
26163
  defaultTracker: "none"
26150
26164
  },
26165
+ hub: {
26166
+ autoStart: "background"
26167
+ },
26151
26168
  improvement: {
26152
26169
  promotionPolicy: "manual_pr",
26153
26170
  telemetryHalfLifeDays: 14,
@@ -26178,7 +26195,7 @@ var DEFAULT_KXM_CONFIG = {
26178
26195
  };
26179
26196
  function userConfigDirectory(overrideDir) {
26180
26197
  if (overrideDir) return resolve10(overrideDir);
26181
- 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"));
26182
26199
  }
26183
26200
  function repoConfigDirectory(repoRoot6) {
26184
26201
  return resolve10(repoRoot6, ".kxm");
@@ -26195,16 +26212,20 @@ function deepMerge(target, source) {
26195
26212
  }
26196
26213
  return result;
26197
26214
  }
26215
+ function normalizeHubConfig(raw) {
26216
+ const autoStart = raw?.autoStart;
26217
+ return { autoStart: autoStart === "off" || autoStart === "background" ? autoStart : DEFAULT_KXM_CONFIG.hub.autoStart };
26218
+ }
26198
26219
  function loadKxmConfig(repoRoot6 = process.cwd(), options = {}) {
26199
26220
  const userDir = userConfigDirectory(options.userConfigDir);
26200
- const userConfigFile = join13(userDir, "config.yaml");
26221
+ const userConfigFile = join14(userDir, "config.yaml");
26201
26222
  const repoDir = repoConfigDirectory(repoRoot6);
26202
- const repoConfigFile = join13(repoDir, "config.yaml");
26223
+ const repoConfigFile = join14(repoDir, "config.yaml");
26203
26224
  let userRaw = {};
26204
26225
  let userLoadedPath;
26205
26226
  if (existsSync12(userConfigFile)) {
26206
26227
  try {
26207
- const text = readFileSync12(userConfigFile, "utf8");
26228
+ const text = readFileSync13(userConfigFile, "utf8");
26208
26229
  userRaw = (0, import_yaml6.parse)(text) ?? {};
26209
26230
  userLoadedPath = userConfigFile;
26210
26231
  } catch (error) {
@@ -26215,7 +26236,7 @@ function loadKxmConfig(repoRoot6 = process.cwd(), options = {}) {
26215
26236
  let repoLoadedPath;
26216
26237
  if (existsSync12(repoConfigFile)) {
26217
26238
  try {
26218
- const text = readFileSync12(repoConfigFile, "utf8");
26239
+ const text = readFileSync13(repoConfigFile, "utf8");
26219
26240
  repoRaw = (0, import_yaml6.parse)(text) ?? {};
26220
26241
  repoLoadedPath = repoConfigFile;
26221
26242
  } catch (error) {
@@ -26231,6 +26252,7 @@ function loadKxmConfig(repoRoot6 = process.cwd(), options = {}) {
26231
26252
  defaults: mergedAll.defaults ?? {},
26232
26253
  dash: mergedAll.dash ?? {},
26233
26254
  sync: mergedAll.sync ?? {},
26255
+ hub: normalizeHubConfig(mergedAll.hub),
26234
26256
  improvement: mergedAll.improvement ?? DEFAULT_KXM_CONFIG.improvement,
26235
26257
  routing: mergedAll.routing ?? DEFAULT_KXM_CONFIG.routing,
26236
26258
  telemetry: mergedAll.telemetry ?? DEFAULT_KXM_CONFIG.telemetry,
@@ -26251,12 +26273,12 @@ function getKxmConfigValue(config, keyPath) {
26251
26273
  }
26252
26274
  function setKxmConfigValue(repoRoot6, keyPath, value, options = {}) {
26253
26275
  const scope = options.scope ?? "project";
26254
- 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");
26255
26277
  mkdirSync10(dirname9(targetFile2), { recursive: true });
26256
26278
  let existing = {};
26257
26279
  if (existsSync12(targetFile2)) {
26258
26280
  try {
26259
- existing = (0, import_yaml6.parse)(readFileSync12(targetFile2, "utf8")) ?? {};
26281
+ existing = (0, import_yaml6.parse)(readFileSync13(targetFile2, "utf8")) ?? {};
26260
26282
  } catch {
26261
26283
  existing = {};
26262
26284
  }
@@ -26367,9 +26389,9 @@ var DEFAULT_ROLES = {
26367
26389
  };
26368
26390
  function rolesDirectory(scope, repoRoot6 = process.cwd(), userConfigDir) {
26369
26391
  if (scope === "global") {
26370
- return join14(userConfigDirectory(userConfigDir), "roles");
26392
+ return join15(userConfigDirectory(userConfigDir), "roles");
26371
26393
  }
26372
- return join14(repoConfigDirectory(repoRoot6), "roles");
26394
+ return join15(repoConfigDirectory(repoRoot6), "roles");
26373
26395
  }
26374
26396
  function ensureRolesDirectory(scope, repoRoot6 = process.cwd(), userConfigDir) {
26375
26397
  const dir = rolesDirectory(scope, repoRoot6, userConfigDir);
@@ -26381,7 +26403,7 @@ function ensureRolesDirectory(scope, repoRoot6 = process.cwd(), userConfigDir) {
26381
26403
  function parseRoleFile(filePath) {
26382
26404
  if (!existsSync13(filePath)) return void 0;
26383
26405
  try {
26384
- const raw = readFileSync13(filePath, "utf8");
26406
+ const raw = readFileSync14(filePath, "utf8");
26385
26407
  const parsed = (0, import_yaml7.parse)(raw);
26386
26408
  if (!parsed || typeof parsed !== "object" || parsed.schema !== KXM_ROLE_SCHEMA) {
26387
26409
  return void 0;
@@ -26411,7 +26433,7 @@ function listRoles(options = {}) {
26411
26433
  if (scopeFilter !== "global" && existsSync13(localDir)) {
26412
26434
  for (const entry of readdirSync4(localDir)) {
26413
26435
  if (entry.endsWith(".yaml") || entry.endsWith(".yml")) {
26414
- const filePath = join14(localDir, entry);
26436
+ const filePath = join15(localDir, entry);
26415
26437
  const parsed = parseRoleFile(filePath);
26416
26438
  if (parsed) {
26417
26439
  localRoles.set(parsed.id, { role: parsed, filePath });
@@ -26423,7 +26445,7 @@ function listRoles(options = {}) {
26423
26445
  if (scopeFilter !== "local" && existsSync13(globalDir)) {
26424
26446
  for (const entry of readdirSync4(globalDir)) {
26425
26447
  if (entry.endsWith(".yaml") || entry.endsWith(".yml")) {
26426
- const filePath = join14(globalDir, entry);
26448
+ const filePath = join15(globalDir, entry);
26427
26449
  const parsed = parseRoleFile(filePath);
26428
26450
  if (parsed) {
26429
26451
  globalRoles.set(parsed.id, { role: parsed, filePath });
@@ -26471,13 +26493,13 @@ function getRole(roleId, options = {}) {
26471
26493
  const repoRoot6 = options.repoRoot ?? process.cwd();
26472
26494
  if (scope !== "global") {
26473
26495
  const localDir = rolesDirectory("local", repoRoot6, options.userConfigDir);
26474
- const localFile = join14(localDir, `${roleId}.yaml`);
26496
+ const localFile = join15(localDir, `${roleId}.yaml`);
26475
26497
  const parsed = parseRoleFile(localFile);
26476
26498
  if (parsed) return { role: parsed, scope: "local", filePath: localFile };
26477
26499
  }
26478
26500
  if (scope !== "local") {
26479
26501
  const globalDir = rolesDirectory("global", repoRoot6, options.userConfigDir);
26480
- const globalFile = join14(globalDir, `${roleId}.yaml`);
26502
+ const globalFile = join15(globalDir, `${roleId}.yaml`);
26481
26503
  const parsed = parseRoleFile(globalFile);
26482
26504
  if (parsed) return { role: parsed, scope: "global", filePath: globalFile };
26483
26505
  }
@@ -26487,7 +26509,7 @@ function addRole(role, options = {}) {
26487
26509
  const scope = options.scope ?? "local";
26488
26510
  const repoRoot6 = options.repoRoot ?? process.cwd();
26489
26511
  const dir = ensureRolesDirectory(scope, repoRoot6, options.userConfigDir);
26490
- const filePath = join14(dir, `${role.id}.yaml`);
26512
+ const filePath = join15(dir, `${role.id}.yaml`);
26491
26513
  if (existsSync13(filePath) && !options.overwrite) {
26492
26514
  throw new Error(`role_already_exists: role '${role.id}' already exists at ${filePath}`);
26493
26515
  }
@@ -26498,7 +26520,7 @@ function removeRole(roleId, options = {}) {
26498
26520
  const scope = options.scope ?? "local";
26499
26521
  const repoRoot6 = options.repoRoot ?? process.cwd();
26500
26522
  const dir = rolesDirectory(scope, repoRoot6, options.userConfigDir);
26501
- const filePath = join14(dir, `${roleId}.yaml`);
26523
+ const filePath = join15(dir, `${roleId}.yaml`);
26502
26524
  if (!existsSync13(filePath)) {
26503
26525
  throw new Error(`role_not_found: role '${roleId}' not found in ${scope} directory (${filePath})`);
26504
26526
  }
@@ -26520,7 +26542,7 @@ function modifyRole(roleId, updates, options = {}) {
26520
26542
  const scope = options.scope ?? target.scope;
26521
26543
  const repoRoot6 = options.repoRoot ?? process.cwd();
26522
26544
  const dir = ensureRolesDirectory(scope, repoRoot6, options.userConfigDir);
26523
- const filePath = join14(dir, `${roleId}.yaml`);
26545
+ const filePath = join15(dir, `${roleId}.yaml`);
26524
26546
  writeFileSync10(filePath, (0, import_yaml7.stringify)(updated), "utf8");
26525
26547
  return { id: roleId, role: updated, filePath, scope };
26526
26548
  }
@@ -26569,9 +26591,9 @@ var DEFAULT_ROLE_SEATS = {
26569
26591
  };
26570
26592
  function findExistingRoleHostsFile(scope, repoRoot6 = process.cwd(), userConfigDir) {
26571
26593
  const dir = scope === "global" ? userConfigDirectory(userConfigDir) : repoConfigDirectory(repoRoot6);
26572
- const yamlPath = join14(dir, "role-hosts.yaml");
26573
- const ymlPath = join14(dir, "role-hosts.yml");
26574
- 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");
26575
26597
  if (existsSync13(yamlPath)) return { filePath: yamlPath, exists: true, format: "yaml" };
26576
26598
  if (existsSync13(ymlPath)) return { filePath: ymlPath, exists: true, format: "yaml" };
26577
26599
  if (existsSync13(jsonPath)) return { filePath: jsonPath, exists: true, format: "json" };
@@ -26580,7 +26602,7 @@ function findExistingRoleHostsFile(scope, repoRoot6 = process.cwd(), userConfigD
26580
26602
  function parseRoleHostsFile(filePath) {
26581
26603
  if (!existsSync13(filePath)) return void 0;
26582
26604
  try {
26583
- const raw = readFileSync13(filePath, "utf8");
26605
+ const raw = readFileSync14(filePath, "utf8");
26584
26606
  const parsed = (0, import_yaml7.parse)(raw);
26585
26607
  if (!parsed || typeof parsed !== "object") return void 0;
26586
26608
  if (parsed.schema && parsed.schema !== KXM_ROLE_HOSTS_SCHEMA) return void 0;
@@ -26656,7 +26678,7 @@ function saveRoleHostsConfig(config, options = {}) {
26656
26678
  mkdirSync11(dir, { recursive: true });
26657
26679
  }
26658
26680
  const format = options.format ?? "yaml";
26659
- 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");
26660
26682
  const payload = {
26661
26683
  schema: KXM_ROLE_HOSTS_SCHEMA,
26662
26684
  seats: config.seats ?? {},
@@ -26898,7 +26920,7 @@ async function cmdRoleAdd(runtime, roleId, options) {
26898
26920
  let roleDef;
26899
26921
  if (options.file) {
26900
26922
  const filePath = resolve12(runtime.cwd, options.file);
26901
- const content = readFileSync14(filePath, "utf8");
26923
+ const content = readFileSync15(filePath, "utf8");
26902
26924
  roleDef = (0, import_yaml8.parse)(content);
26903
26925
  roleDef.id = roleId;
26904
26926
  } else {
@@ -27197,7 +27219,7 @@ async function cmdRoleResume(runtime, runId, ruling) {
27197
27219
  return 1;
27198
27220
  }
27199
27221
  }
27200
- const dbPath = join15(runtime.cwd, ".kxm", "state", "kxm.db");
27222
+ const dbPath = join16(runtime.cwd, ".kxm", "state", "kxm.db");
27201
27223
  if (existsSync14(dbPath)) {
27202
27224
  try {
27203
27225
  const database = new DatabaseSync(dbPath);
@@ -27260,8 +27282,8 @@ async function cmdRoleResume(runtime, runId, ruling) {
27260
27282
 
27261
27283
  // plugins/kxm/src/cli/workflows.ts
27262
27284
  import { createHmac as createHmac3, randomUUID as randomUUID7 } from "node:crypto";
27263
- import { existsSync as existsSync16, readFileSync as readFileSync16 } from "node:fs";
27264
- 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";
27265
27287
 
27266
27288
  // plugins/kxm/src/retrospective.ts
27267
27289
  import { mkdirSync as mkdirSync12, renameSync as renameSync4, writeFileSync as writeFileSync11 } from "node:fs";
@@ -27679,8 +27701,8 @@ async function watchGithubChecks(input) {
27679
27701
 
27680
27702
  // plugins/kxm/src/workflow-manager.ts
27681
27703
  var import_yaml9 = __toESM(require_dist(), 1);
27682
- import { existsSync as existsSync15, mkdirSync as mkdirSync13, readdirSync as readdirSync5, readFileSync as readFileSync15, rmSync as rmSync5, writeFileSync as writeFileSync12 } from "node:fs";
27683
- 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";
27684
27706
  var WORKFLOW_TEMPLATES = {
27685
27707
  "implement-and-verify": {
27686
27708
  schema: "kxm.workflow.v1",
@@ -27831,9 +27853,9 @@ var WORKFLOW_TEMPLATES = {
27831
27853
  var DEFAULT_WORKFLOW_TEMPLATE = WORKFLOW_TEMPLATES["implement-and-verify"];
27832
27854
  function workflowsDirectory(scope, repoRoot6 = process.cwd(), userConfigDir) {
27833
27855
  if (scope === "global") {
27834
- return join16(userConfigDirectory(userConfigDir), "workflows");
27856
+ return join17(userConfigDirectory(userConfigDir), "workflows");
27835
27857
  }
27836
- return join16(repoConfigDirectory(repoRoot6), "workflows");
27858
+ return join17(repoConfigDirectory(repoRoot6), "workflows");
27837
27859
  }
27838
27860
  function ensureWorkflowsDirectory(scope, repoRoot6 = process.cwd(), userConfigDir) {
27839
27861
  const dir = workflowsDirectory(scope, repoRoot6, userConfigDir);
@@ -27845,7 +27867,7 @@ function ensureWorkflowsDirectory(scope, repoRoot6 = process.cwd(), userConfigDi
27845
27867
  function parseWorkflowFile(filePath) {
27846
27868
  if (!existsSync15(filePath)) return void 0;
27847
27869
  try {
27848
- const raw = readFileSync15(filePath, "utf8");
27870
+ const raw = readFileSync16(filePath, "utf8");
27849
27871
  const parsed = (0, import_yaml9.parse)(raw);
27850
27872
  if (!parsed || typeof parsed !== "object") return void 0;
27851
27873
  return parsed;
@@ -27862,7 +27884,7 @@ function listWorkflowDefinitions(options = {}) {
27862
27884
  if (scopeFilter !== "global" && existsSync15(localDir)) {
27863
27885
  for (const entry of readdirSync5(localDir)) {
27864
27886
  if (entry.endsWith(".yaml") || entry.endsWith(".yml")) {
27865
- const filePath = join16(localDir, entry);
27887
+ const filePath = join17(localDir, entry);
27866
27888
  const def = parseWorkflowFile(filePath);
27867
27889
  if (def) {
27868
27890
  const id = def.id || entry.replace(/\.ya?ml$/i, "");
@@ -27875,7 +27897,7 @@ function listWorkflowDefinitions(options = {}) {
27875
27897
  if (scopeFilter !== "local" && existsSync15(globalDir)) {
27876
27898
  for (const entry of readdirSync5(globalDir)) {
27877
27899
  if (entry.endsWith(".yaml") || entry.endsWith(".yml")) {
27878
- const filePath = join16(globalDir, entry);
27900
+ const filePath = join17(globalDir, entry);
27879
27901
  const def = parseWorkflowFile(filePath);
27880
27902
  if (def) {
27881
27903
  const id = def.id || entry.replace(/\.ya?ml$/i, "");
@@ -27931,13 +27953,13 @@ function getWorkflowDefinition(workflowId, options = {}) {
27931
27953
  const repoRoot6 = options.repoRoot ?? process.cwd();
27932
27954
  if (scope !== "global") {
27933
27955
  const localDir = workflowsDirectory("local", repoRoot6, options.userConfigDir);
27934
- const localFile = join16(localDir, `${workflowId}.yaml`);
27956
+ const localFile = join17(localDir, `${workflowId}.yaml`);
27935
27957
  const parsed = parseWorkflowFile(localFile);
27936
27958
  if (parsed) return { workflow: parsed, scope: "local", filePath: localFile };
27937
27959
  }
27938
27960
  if (scope !== "local") {
27939
27961
  const globalDir = workflowsDirectory("global", repoRoot6, options.userConfigDir);
27940
- const globalFile = join16(globalDir, `${workflowId}.yaml`);
27962
+ const globalFile = join17(globalDir, `${workflowId}.yaml`);
27941
27963
  const parsed = parseWorkflowFile(globalFile);
27942
27964
  if (parsed) return { workflow: parsed, scope: "global", filePath: globalFile };
27943
27965
  }
@@ -27947,7 +27969,7 @@ function addWorkflowDefinition(workflowId, content = DEFAULT_WORKFLOW_TEMPLATE,
27947
27969
  const scope = options.scope ?? "local";
27948
27970
  const repoRoot6 = options.repoRoot ?? process.cwd();
27949
27971
  const dir = ensureWorkflowsDirectory(scope, repoRoot6, options.userConfigDir);
27950
- const filePath = join16(dir, `${workflowId}.yaml`);
27972
+ const filePath = join17(dir, `${workflowId}.yaml`);
27951
27973
  if (existsSync15(filePath) && !options.overwrite) {
27952
27974
  throw new Error(`workflow_already_exists: workflow '${workflowId}' already exists at ${filePath}`);
27953
27975
  }
@@ -27959,7 +27981,7 @@ function removeWorkflowDefinition(workflowId, options = {}) {
27959
27981
  const scope = options.scope ?? "local";
27960
27982
  const repoRoot6 = options.repoRoot ?? process.cwd();
27961
27983
  const dir = workflowsDirectory(scope, repoRoot6, options.userConfigDir);
27962
- const filePath = join16(dir, `${workflowId}.yaml`);
27984
+ const filePath = join17(dir, `${workflowId}.yaml`);
27963
27985
  if (!existsSync15(filePath)) {
27964
27986
  throw new Error(`workflow_not_found: workflow '${workflowId}' not found in ${scope} directory (${filePath})`);
27965
27987
  }
@@ -27978,7 +28000,7 @@ function modifyWorkflowDefinition(workflowId, updates, options = {}) {
27978
28000
  const scope = options.scope ?? target.scope;
27979
28001
  const repoRoot6 = options.repoRoot ?? process.cwd();
27980
28002
  const dir = ensureWorkflowsDirectory(scope, repoRoot6, options.userConfigDir);
27981
- const filePath = join16(dir, `${workflowId}.yaml`);
28003
+ const filePath = join17(dir, `${workflowId}.yaml`);
27982
28004
  writeFileSync12(filePath, (0, import_yaml9.stringify)(updated), "utf8");
27983
28005
  return { id: workflowId, workflow: updated, filePath, scope };
27984
28006
  }
@@ -28063,7 +28085,7 @@ function activeWorkflowDefinition(runtime, definitionId) {
28063
28085
  let raw;
28064
28086
  if (file) {
28065
28087
  try {
28066
- raw = readFileSync16(resolve15(runtime.cwd, file), "utf8");
28088
+ raw = readFileSync17(resolve15(runtime.cwd, file), "utf8");
28067
28089
  } catch {
28068
28090
  throw new Error("workflow definition file is unavailable");
28069
28091
  }
@@ -28145,7 +28167,7 @@ async function cmdWorkflowAdd(runtime, workflowId, options) {
28145
28167
  }
28146
28168
  if (options.file) {
28147
28169
  const filePath = resolve15(runtime.cwd, options.file);
28148
- content = readFileSync16(filePath, "utf8");
28170
+ content = readFileSync17(filePath, "utf8");
28149
28171
  } else if (!content) {
28150
28172
  content = {
28151
28173
  schema: "kxm.workflow.v1",
@@ -28303,7 +28325,7 @@ async function cmdWorkflowStart(runtime, definitionIdArg, options) {
28303
28325
  }
28304
28326
  let payload;
28305
28327
  try {
28306
- 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;
28307
28329
  const value = JSON.parse(raw);
28308
28330
  if (!value || typeof value !== "object" || Array.isArray(value)) throw new Error("object required");
28309
28331
  payload = value;
@@ -28370,7 +28392,7 @@ async function cmdWorkflowDegrade(runtime, runId, stageId, options) {
28370
28392
  }
28371
28393
  }
28372
28394
  async function cmdWorkflowInspect(runtime, action, runId) {
28373
- 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"));
28374
28396
  if (action === "get" && !runId) {
28375
28397
  runtime.io.stderr(`Usage: ${CLI_NAME} workflow get <runId>
28376
28398
  `);
@@ -28544,9 +28566,9 @@ async function cmdRetrospectiveExport(runtime, runId, options) {
28544
28566
  try {
28545
28567
  if (snapshotPath) {
28546
28568
  if (!existsSync16(snapshotPath)) throw new Error("snapshot_missing");
28547
- snapshot = JSON.parse(readFileSync16(snapshotPath, "utf8"));
28569
+ snapshot = JSON.parse(readFileSync17(snapshotPath, "utf8"));
28548
28570
  } else {
28549
- 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"));
28550
28572
  const local = localWorkflowSnapshot(dataPath, runId);
28551
28573
  if (!local.runs[0]) throw new Error("workflow_not_found");
28552
28574
  snapshot = { run: local.runs[0], journal: local.journal };
@@ -28558,7 +28580,7 @@ async function cmdRetrospectiveExport(runtime, runId, options) {
28558
28580
  return 1;
28559
28581
  }
28560
28582
  const doc = buildRetrospective(snapshot.run, snapshot.journal);
28561
- 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")));
28562
28584
  const assetsRoot = resolve15(runtime.dirs.assets);
28563
28585
  const assetsPrefix = `${assetsRoot}${process.platform === "win32" ? "\\" : "/"}`;
28564
28586
  if (outDir !== assetsRoot && !outDir.startsWith(assetsPrefix)) {
@@ -28576,8 +28598,8 @@ async function cmdRetrospectiveExport(runtime, runId, options) {
28576
28598
 
28577
28599
  // plugins/kxm/src/cli/tasks.ts
28578
28600
  var import_yaml13 = __toESM(require_dist(), 1);
28579
- import { existsSync as existsSync22, readFileSync as readFileSync21, readdirSync as readdirSync8 } from "node:fs";
28580
- 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";
28581
28603
 
28582
28604
  // plugins/kxm/src/suggest.ts
28583
28605
  var WORKFLOW_PATTERNS = [
@@ -28688,8 +28710,8 @@ function suggestWorkflowAndRoles(prompt, options = {}) {
28688
28710
  // plugins/kxm/src/task-manager.ts
28689
28711
  var import_yaml10 = __toESM(require_dist(), 1);
28690
28712
  import { randomUUID as randomUUID8 } from "node:crypto";
28691
- import { existsSync as existsSync17, mkdirSync as mkdirSync14, readFileSync as readFileSync17, readdirSync as readdirSync6, writeFileSync as writeFileSync13 } from "node:fs";
28692
- 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";
28693
28715
  var GOAL_SCHEMA = "kxm.goal.v1";
28694
28716
  var TASK_SCHEMA = "kxm.task.v1";
28695
28717
  function goalsDirectory(repoRoot6) {
@@ -28714,7 +28736,7 @@ function createGoal(repoRoot6, input) {
28714
28736
  createdAt: now,
28715
28737
  updatedAt: now
28716
28738
  };
28717
- const filePath = join18(dir, `${id}.yaml`);
28739
+ const filePath = join19(dir, `${id}.yaml`);
28718
28740
  writeFileSync13(filePath, (0, import_yaml10.stringify)(record).trim() + "\n", "utf8");
28719
28741
  return record;
28720
28742
  }
@@ -28726,7 +28748,7 @@ function listGoals(repoRoot6) {
28726
28748
  for (const entry of entries) {
28727
28749
  if (entry.isFile() && (entry.name.endsWith(".yaml") || entry.name.endsWith(".yml"))) {
28728
28750
  try {
28729
- const text = readFileSync17(join18(dir, entry.name), "utf8");
28751
+ const text = readFileSync18(join19(dir, entry.name), "utf8");
28730
28752
  const doc = (0, import_yaml10.parse)(text);
28731
28753
  if (doc && doc.schema === GOAL_SCHEMA) goals.push(doc);
28732
28754
  } catch {
@@ -28759,7 +28781,7 @@ function createTask(repoRoot6, input) {
28759
28781
  createdAt: now,
28760
28782
  updatedAt: now
28761
28783
  };
28762
- const filePath = join18(dir, `${id}.yaml`);
28784
+ const filePath = join19(dir, `${id}.yaml`);
28763
28785
  writeFileSync13(filePath, (0, import_yaml10.stringify)(record).trim() + "\n", "utf8");
28764
28786
  return record;
28765
28787
  }
@@ -28771,7 +28793,7 @@ function listTasks(repoRoot6, options = {}) {
28771
28793
  for (const entry of entries) {
28772
28794
  if (entry.isFile() && (entry.name.endsWith(".yaml") || entry.name.endsWith(".yml"))) {
28773
28795
  try {
28774
- const text = readFileSync17(join18(dir, entry.name), "utf8");
28796
+ const text = readFileSync18(join19(dir, entry.name), "utf8");
28775
28797
  const doc = (0, import_yaml10.parse)(text);
28776
28798
  if (doc && doc.schema === TASK_SCHEMA) {
28777
28799
  if (options.goalId && doc.goalId !== options.goalId) continue;
@@ -28786,10 +28808,10 @@ function listTasks(repoRoot6, options = {}) {
28786
28808
  }
28787
28809
  function getTask(repoRoot6, taskId) {
28788
28810
  const dir = tasksDirectory(repoRoot6);
28789
- const filePath = join18(dir, `${taskId}.yaml`);
28811
+ const filePath = join19(dir, `${taskId}.yaml`);
28790
28812
  if (!existsSync17(filePath)) return void 0;
28791
28813
  try {
28792
- const text = readFileSync17(filePath, "utf8");
28814
+ const text = readFileSync18(filePath, "utf8");
28793
28815
  const doc = (0, import_yaml10.parse)(text);
28794
28816
  return doc && doc.schema === TASK_SCHEMA ? doc : void 0;
28795
28817
  } catch {
@@ -28804,7 +28826,7 @@ function updateTaskStatus(repoRoot6, taskId, status, options = {}) {
28804
28826
  task.status = status;
28805
28827
  if (options.workflowRunId) task.workflowRunId = options.workflowRunId;
28806
28828
  task.updatedAt = (/* @__PURE__ */ new Date()).toISOString();
28807
- const filePath = join18(tasksDirectory(repoRoot6), `${taskId}.yaml`);
28829
+ const filePath = join19(tasksDirectory(repoRoot6), `${taskId}.yaml`);
28808
28830
  writeFileSync13(filePath, (0, import_yaml10.stringify)(task).trim() + "\n", "utf8");
28809
28831
  return task;
28810
28832
  }
@@ -28820,7 +28842,7 @@ function syncTaskWithTracker(repoRoot6, taskId, options = {}) {
28820
28842
  task.trackerSync.syncStatus = "synced";
28821
28843
  task.trackerSync.lastSyncedAt = now;
28822
28844
  task.updatedAt = now;
28823
- const filePath = join18(tasksDirectory(repoRoot6), `${taskId}.yaml`);
28845
+ const filePath = join19(tasksDirectory(repoRoot6), `${taskId}.yaml`);
28824
28846
  writeFileSync13(filePath, (0, import_yaml10.stringify)(task).trim() + "\n", "utf8");
28825
28847
  return task;
28826
28848
  }
@@ -29587,14 +29609,14 @@ function createStudioServer(options = {}) {
29587
29609
  }
29588
29610
 
29589
29611
  // plugins/kxm/src/cli/vnext.ts
29590
- import { join as join24, resolve as resolve20 } from "node:path";
29612
+ import { join as join25, resolve as resolve20 } from "node:path";
29591
29613
  import { createInterface as createInterface2 } from "node:readline";
29592
29614
  import { fileURLToPath as fileURLToPath4 } from "node:url";
29593
29615
 
29594
29616
  // plugins/kxm/src/model-inventory.ts
29595
29617
  var import_yaml11 = __toESM(require_dist(), 1);
29596
29618
  import { mkdirSync as mkdirSync15, writeFileSync as writeFileSync14 } from "node:fs";
29597
- import { join as join19 } from "node:path";
29619
+ import { join as join20 } from "node:path";
29598
29620
  var OR_URL = "https://openrouter.ai/api/v1/models";
29599
29621
  var NOUS_URL = "https://inference-api.nousresearch.com/v1/models";
29600
29622
  function price(value) {
@@ -29680,15 +29702,15 @@ async function refreshModelInventory(options) {
29680
29702
  sources.nous = { url: nousUrl, ok: !nous.error, ...nous.error ? { error: nous.error } : {} };
29681
29703
  for (const item of nous.data) add(item, "nous", "discount");
29682
29704
  const inventory = { schema: "kxm.model-inventory.v1", fetchedAt, currency: "USD", sources, models: [...byId.values()].sort((a, b2) => a.id.localeCompare(b2.id)) };
29683
- mkdirSync15(join19(options.outputRoot, ".kxm", "models"), { recursive: true });
29684
- 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");
29685
29707
  return inventory;
29686
29708
  }
29687
29709
 
29688
29710
  // plugins/kxm/src/vnext-init.ts
29689
29711
  import { randomUUID as randomUUID11 } from "node:crypto";
29690
29712
  import { existsSync as existsSync20 } from "node:fs";
29691
- import { basename as basename4, join as join22 } from "node:path";
29713
+ import { basename as basename5, join as join23 } from "node:path";
29692
29714
 
29693
29715
  // plugins/kxm/src/vnext-repair.ts
29694
29716
  import { randomUUID as randomUUID10 } from "node:crypto";
@@ -29701,20 +29723,20 @@ import {
29701
29723
  lstatSync as lstatSync7,
29702
29724
  mkdirSync as mkdirSync17,
29703
29725
  openSync as openSync2,
29704
- readFileSync as readFileSync19,
29726
+ readFileSync as readFileSync20,
29705
29727
  readdirSync as readdirSync7,
29706
29728
  renameSync as renameSync5,
29707
29729
  rmSync as rmSync7,
29708
29730
  writeFileSync as writeFileSync16
29709
29731
  } from "node:fs";
29710
- 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";
29711
29733
 
29712
29734
  // plugins/kxm/src/vnext-permission.ts
29713
29735
  import { spawnSync as spawnSync4 } from "node:child_process";
29714
29736
  import { createHash as createHash12 } from "node:crypto";
29715
- 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";
29716
29738
  import { tmpdir } from "node:os";
29717
- 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";
29718
29740
  var PROSE_FIELDS = {
29719
29741
  project: /* @__PURE__ */ new Set(["name", "description"]),
29720
29742
  repository: /* @__PURE__ */ new Set(["description"]),
@@ -30235,7 +30257,7 @@ function loadVnextProjectAtRevision(root, revision, options = {}) {
30235
30257
  const tree = resolveTreeRevision(root, revision);
30236
30258
  const listing = gitBuffer(root, ["ls-tree", "-r", "-z", "--name-only", tree]).toString("utf8");
30237
30259
  const paths = listing.split("\0").filter((line) => line.length > 0 && (line.startsWith(".kxm/") || line.includes("/.kxm/")));
30238
- const shadow = mkdtempSync(join20(tmpdir(), "kxm-permission-base-"));
30260
+ const shadow = mkdtempSync(join21(tmpdir(), "kxm-permission-base-"));
30239
30261
  const shadowResolved = resolve17(shadow);
30240
30262
  const shadowMembersDir = `.kxm-shadow-members-${createHash12("sha256").update(shadowResolved, "utf8").digest("hex").slice(0, 8)}`;
30241
30263
  try {
@@ -30249,7 +30271,7 @@ function loadVnextProjectAtRevision(root, revision, options = {}) {
30249
30271
  message: "Git tree entry contains a traversal or non-portable segment"
30250
30272
  }]);
30251
30273
  }
30252
- const absolute = join20(shadowResolved, ...segments);
30274
+ const absolute = join21(shadowResolved, ...segments);
30253
30275
  const resolved = resolve17(absolute);
30254
30276
  if (!resolved.startsWith(`${shadowResolved}${sep3}`)) {
30255
30277
  throw new VnextConfigError([{
@@ -30264,7 +30286,7 @@ function loadVnextProjectAtRevision(root, revision, options = {}) {
30264
30286
  writeFileSync15(absolute, content);
30265
30287
  }
30266
30288
  initShadowGitRoot(shadowResolved);
30267
- const baseProjectFile = join20(shadowResolved, ".kxm", "project.yaml");
30289
+ const baseProjectFile = join21(shadowResolved, ".kxm", "project.yaml");
30268
30290
  let baseProject;
30269
30291
  try {
30270
30292
  baseProject = loadBaseProjectDeclarations(baseProjectFile);
@@ -30342,7 +30364,7 @@ function loadVnextProjectAtRevision(root, revision, options = {}) {
30342
30364
  const memberTree = git(memberWorktree, ["rev-parse", "--verify", "--quiet", `${pinnedCommit}^{tree}`]).trim();
30343
30365
  const memberListing = gitBuffer(memberWorktree, ["ls-tree", "-r", "-z", "--name-only", memberTree]).toString("utf8");
30344
30366
  const memberPaths = memberListing.split("\0").filter((line) => line.length > 0 && (line.startsWith(".kxm/") || line.includes("/.kxm/")));
30345
- const memberShadowRoot = join20(shadowResolved, shadowMembersDir, member.repositoryId);
30367
+ const memberShadowRoot = join21(shadowResolved, shadowMembersDir, member.repositoryId);
30346
30368
  if (!resolve17(memberShadowRoot).startsWith(`${resolve17(shadowResolved, shadowMembersDir)}${sep3}`)) {
30347
30369
  throw new VnextConfigError([{
30348
30370
  phase: "path",
@@ -30356,7 +30378,7 @@ function loadVnextProjectAtRevision(root, revision, options = {}) {
30356
30378
  if (segments.some((segment) => segment === "" || segment === "." || segment === ".." || /[\\:]/.test(segment))) {
30357
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" }]);
30358
30380
  }
30359
- const absolute = join20(memberShadowRoot, ...segments);
30381
+ const absolute = join21(memberShadowRoot, ...segments);
30360
30382
  const resolved = resolve17(absolute);
30361
30383
  if (!resolved.startsWith(`${resolve17(memberShadowRoot)}${sep3}`)) {
30362
30384
  throw new VnextConfigError([{ phase: "path", code: "git_tree_path_invalid", file: path4, message: "member Git tree entry escapes the shadow root" }]);
@@ -30385,7 +30407,7 @@ function portableMemberPathHint(pathHint) {
30385
30407
  }
30386
30408
  function loadBaseProjectDeclarations(projectFile) {
30387
30409
  if (!existsSync18(projectFile)) return [];
30388
- const value = parseRestrictedYaml2(readFileSync18(projectFile, "utf8"), ".kxm/project.yaml");
30410
+ const value = parseRestrictedYaml2(readFileSync19(projectFile, "utf8"), ".kxm/project.yaml");
30389
30411
  const repositories = Array.isArray(value?.repositories) ? value.repositories : [];
30390
30412
  const members = [];
30391
30413
  for (const entry of repositories) {
@@ -30513,19 +30535,19 @@ function sameHostPath3(left, right) {
30513
30535
  return process.platform === "win32" ? first.toLocaleLowerCase("en-US") === second.toLocaleLowerCase("en-US") : first === second;
30514
30536
  }
30515
30537
  function transactionRoot(projectRoot) {
30516
- return join21(resolve18(projectRoot), TRANSACTION_NAME);
30538
+ return join22(resolve18(projectRoot), TRANSACTION_NAME);
30517
30539
  }
30518
30540
  function operationFile(projectRoot) {
30519
- return join21(transactionRoot(projectRoot), OPERATION_FILE);
30541
+ return join22(transactionRoot(projectRoot), OPERATION_FILE);
30520
30542
  }
30521
30543
  function targetFile(projectRoot, portablePath2) {
30522
- return join21(transactionRoot(projectRoot), "targets", ...portablePath2.split("/"));
30544
+ return join22(transactionRoot(projectRoot), "targets", ...portablePath2.split("/"));
30523
30545
  }
30524
30546
  function shadowRoot(projectRoot) {
30525
- return join21(transactionRoot(projectRoot), "shadow");
30547
+ return join22(transactionRoot(projectRoot), "shadow");
30526
30548
  }
30527
30549
  function backupFile(projectRoot, portablePath2) {
30528
- return join21(transactionRoot(projectRoot), "backups", ...portablePath2.split("/"));
30550
+ return join22(transactionRoot(projectRoot), "backups", ...portablePath2.split("/"));
30529
30551
  }
30530
30552
  function portableManagedPath(path4) {
30531
30553
  return path4.startsWith(".kxm/") && path4 !== VNEXT_TEMPLATE_PROVENANCE_PATH && path4.length <= 1024 && !path4.includes("\\") && !isAbsolute6(path4) && PORTABLE_PATH.test(path4) && !/[<>:"|?*]/.test(path4);
@@ -30534,10 +30556,10 @@ function readRegularBounded(file, label) {
30534
30556
  const stat = lstatSync7(file);
30535
30557
  if (stat.isSymbolicLink() || !stat.isFile()) fail3("repair_file_invalid", label, "managed file must be a regular file, not a link or directory", "path");
30536
30558
  if (stat.size > MAX_MANAGED_FILE_BYTES) fail3("repair_file_too_large", label, `managed file exceeds ${MAX_MANAGED_FILE_BYTES} bytes`, "parse");
30537
- return readFileSync19(file);
30559
+ return readFileSync20(file);
30538
30560
  }
30539
30561
  function readOptionalManaged(projectRoot, path4) {
30540
- const file = join21(projectRoot, ...path4.split("/"));
30562
+ const file = join22(projectRoot, ...path4.split("/"));
30541
30563
  if (!existsSync19(file)) return void 0;
30542
30564
  let parent = dirname13(file);
30543
30565
  const boundary = resolve18(projectRoot);
@@ -30549,8 +30571,8 @@ function readOptionalManaged(projectRoot, path4) {
30549
30571
  return readRegularBounded(file, path4);
30550
30572
  }
30551
30573
  function readProjectAndProvenance(projectRoot, schemasDir) {
30552
- const projectFile = join21(projectRoot, ".kxm", "project.yaml");
30553
- 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("/"));
30554
30576
  if (!existsSync19(projectFile) || !existsSync19(provenanceFile)) return void 0;
30555
30577
  const projectBytes = readOptionalManaged(projectRoot, ".kxm/project.yaml");
30556
30578
  const provenanceBytes = readOptionalManaged(projectRoot, VNEXT_TEMPLATE_PROVENANCE_PATH);
@@ -30715,7 +30737,7 @@ function operationPlanSha(operation) {
30715
30737
  function writeOperation(projectRoot, operation) {
30716
30738
  const root = transactionRoot(projectRoot);
30717
30739
  const file = operationFile(projectRoot);
30718
- const temporary = join21(root, `.operation-${operation.operationId}-${randomUUID10()}.tmp`);
30740
+ const temporary = join22(root, `.operation-${operation.operationId}-${randomUUID10()}.tmp`);
30719
30741
  try {
30720
30742
  writeDurableNew(temporary, Buffer.from(`${JSON.stringify(operation, null, 2)}
30721
30743
  `, "utf8"), 384);
@@ -30767,7 +30789,7 @@ function hasVnextInitTransaction(projectRoot) {
30767
30789
  return existsSync19(transactionRoot(projectRoot));
30768
30790
  }
30769
30791
  function readTarget(projectRoot, path4) {
30770
- return readOptionalManaged(join21(transactionRoot(projectRoot), "targets"), path4);
30792
+ return readOptionalManaged(join22(transactionRoot(projectRoot), "targets"), path4);
30771
30793
  }
30772
30794
  function writeTarget(projectRoot, path4, bytes) {
30773
30795
  if (bytes.byteLength > MAX_MANAGED_FILE_BYTES) fail3("template_target_too_large", path4, `target exceeds ${MAX_MANAGED_FILE_BYTES} bytes`);
@@ -30807,7 +30829,7 @@ function verifyBackups(projectRoot, operation) {
30807
30829
  if (operation.kind !== "repair") return;
30808
30830
  for (const entry of operation.files) {
30809
30831
  if (entry.observedSha256 === null) continue;
30810
- const bytes = readOptionalManaged(join21(transactionRoot(projectRoot), "backups"), entry.path);
30832
+ const bytes = readOptionalManaged(join22(transactionRoot(projectRoot), "backups"), entry.path);
30811
30833
  if (!bytes || vnextContentSha256(bytes) !== entry.observedSha256) {
30812
30834
  fail3("init_transaction_backup_invalid", entry.path, "pinned preimage backup is missing or corrupt");
30813
30835
  }
@@ -30841,9 +30863,9 @@ function sourceConfigFiles(projectRoot) {
30841
30863
  ".kxm/repo/repo.yaml",
30842
30864
  ".kxm/repo/env.yaml"
30843
30865
  ];
30844
- const files = fixed.filter((path4) => existsSync19(join21(projectRoot, ...path4.split("/"))));
30866
+ const files = fixed.filter((path4) => existsSync19(join22(projectRoot, ...path4.split("/"))));
30845
30867
  for (const directory of ["agents", "models", "workflows"]) {
30846
- const absolute = join21(projectRoot, ".kxm", directory);
30868
+ const absolute = join22(projectRoot, ".kxm", directory);
30847
30869
  if (!existsSync19(absolute)) continue;
30848
30870
  const stat = lstatSync7(absolute);
30849
30871
  if (stat.isSymbolicLink() || !stat.isDirectory()) fail3("repair_directory_invalid", `.kxm/${directory}`, "configuration directory must be regular", "path");
@@ -30880,8 +30902,8 @@ function prepareShadow(projectRoot, operation, options) {
30880
30902
  const bytes = readOptionalManaged(projectRoot, path4);
30881
30903
  if (!bytes) fail3("repair_snapshot_file_missing", path4, "configuration changed during shadow preparation");
30882
30904
  total += bytes.byteLength;
30883
- const source = join21(projectRoot, ...path4.split("/"));
30884
- const destination = join21(shadow, ...path4.split("/"));
30905
+ const source = join22(projectRoot, ...path4.split("/"));
30906
+ const destination = join22(shadow, ...path4.split("/"));
30885
30907
  mkdirSync17(dirname13(destination), { recursive: true, mode: 448 });
30886
30908
  writeDurableNew(destination, bytes, lstatSync7(source).mode & 511);
30887
30909
  if (total > MAX_MANAGED_TOTAL_BYTES) fail3("repair_snapshot_too_large", ".kxm", `configuration snapshot exceeds ${MAX_MANAGED_TOTAL_BYTES} bytes`, "parse");
@@ -30890,12 +30912,12 @@ function prepareShadow(projectRoot, operation, options) {
30890
30912
  for (const entry of operation.files) {
30891
30913
  const bytes = readTarget(projectRoot, entry.path);
30892
30914
  if (!bytes) fail3("init_transaction_target_missing", entry.path, "pinned target artifact is missing");
30893
- const destination = join21(shadow, ...entry.path.split("/"));
30915
+ const destination = join22(shadow, ...entry.path.split("/"));
30894
30916
  mkdirSync17(dirname13(destination), { recursive: true, mode: 448 });
30895
30917
  const mode = existsSync19(destination) ? lstatSync7(destination).mode & 511 : 420;
30896
30918
  writeDurable(destination, bytes, mode);
30897
30919
  }
30898
- 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");
30899
30921
  const bound = absoluteMemberBindings(projectRoot, project, options.repositoryBindings);
30900
30922
  loadVnextProject(shadow, { ...loaderOptions(options), repositoryBindings: bound });
30901
30923
  const provenance = readProjectAndProvenance(shadow, options.schemasDir)?.provenance;
@@ -30959,21 +30981,21 @@ function ensureDestinationParents(projectRoot, path4) {
30959
30981
  const segments = path4.split("/").slice(0, -1);
30960
30982
  let current = boundary;
30961
30983
  for (const segment of segments) {
30962
- current = join21(current, segment);
30984
+ current = join22(current, segment);
30963
30985
  if (!existsSync19(current)) mkdirSync17(current, { mode: 448 });
30964
30986
  const stat = lstatSync7(current);
30965
30987
  if (stat.isSymbolicLink() || !stat.isDirectory()) fail3("repair_destination_parent_invalid", path4, "destination parent must be a regular directory", "path");
30966
30988
  }
30967
30989
  }
30968
30990
  function destinationSha(projectRoot, path4) {
30969
- const file = join21(projectRoot, ...path4.split("/"));
30991
+ const file = join22(projectRoot, ...path4.split("/"));
30970
30992
  if (!existsSync19(file)) return void 0;
30971
30993
  return vnextContentSha256(readRegularBounded(file, path4));
30972
30994
  }
30973
30995
  function requireConditionalLinkSupport(directory, operationId, path4) {
30974
30996
  const nonce = randomUUID10();
30975
- const source = join21(directory, `.kxm-repair-${operationId}-${nonce}.link-source`);
30976
- 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`);
30977
30999
  try {
30978
31000
  writeDurableNew(source, Buffer.from("kxm-link-probe\n", "utf8"), 384);
30979
31001
  try {
@@ -30988,16 +31010,16 @@ function requireConditionalLinkSupport(directory, operationId, path4) {
30988
31010
  }
30989
31011
  }
30990
31012
  function atomicInstallTarget(projectRoot, operation, entry) {
30991
- const destination = join21(projectRoot, ...entry.path.split("/"));
31013
+ const destination = join22(projectRoot, ...entry.path.split("/"));
30992
31014
  ensureDestinationParents(projectRoot, entry.path);
30993
31015
  const directory = dirname13(destination);
30994
31016
  const temporaryPrefix = `.kxm-repair-${operation.operationId}-`;
30995
31017
  const pathKey = vnextContentSha256(entry.path).slice("sha256:".length, "sha256:".length + 16);
30996
- const displaced = join21(directory, `${temporaryPrefix}${pathKey}.preimage`);
31018
+ const displaced = join22(directory, `${temporaryPrefix}${pathKey}.preimage`);
30997
31019
  if (existsSync19(displaced)) {
30998
31020
  const stat = lstatSync7(displaced);
30999
31021
  if (stat.isSymbolicLink() || !stat.isFile()) fail3("repair_preimage_temporary_invalid", entry.path, "stale displaced preimage is not a regular file", "path");
31000
- if (entry.observedSha256 === null || vnextContentSha256(readFileSync19(displaced)) !== entry.observedSha256) {
31022
+ if (entry.observedSha256 === null || vnextContentSha256(readFileSync20(displaced)) !== entry.observedSha256) {
31001
31023
  fail3("repair_preimage_temporary_mismatch", entry.path, "stale displaced preimage does not match the pinned operation");
31002
31024
  }
31003
31025
  if (!existsSync19(destination)) {
@@ -31015,7 +31037,7 @@ function atomicInstallTarget(projectRoot, operation, entry) {
31015
31037
  const owned = candidate.name.startsWith(temporaryPrefix) && (candidate.name.endsWith(".tmp") || candidate.name.endsWith(".link-source") || candidate.name.endsWith(".link-target"));
31016
31038
  if (!owned) continue;
31017
31039
  if (!candidate.isFile()) fail3("repair_temporary_invalid", entry.path, "stale operation temporary is not a regular file", "path");
31018
- rmSync7(join21(directory, candidate.name), { force: true });
31040
+ rmSync7(join22(directory, candidate.name), { force: true });
31019
31041
  }
31020
31042
  const current = destinationSha(projectRoot, entry.path);
31021
31043
  if (current === entry.targetSha256) return;
@@ -31025,14 +31047,14 @@ function atomicInstallTarget(projectRoot, operation, entry) {
31025
31047
  requireConditionalLinkSupport(directory, operation.operationId, entry.path);
31026
31048
  const bytes = readTarget(projectRoot, entry.path);
31027
31049
  if (!bytes) fail3("init_transaction_target_missing", entry.path, "pinned target artifact is missing");
31028
- const temporary = join21(directory, `${temporaryPrefix}${randomUUID10()}.tmp`);
31050
+ const temporary = join22(directory, `${temporaryPrefix}${randomUUID10()}.tmp`);
31029
31051
  const mode = existsSync19(destination) ? lstatSync7(destination).mode & 511 : 420;
31030
31052
  try {
31031
31053
  writeDurableNew(temporary, bytes, mode);
31032
31054
  if (entry.observedSha256 !== null) {
31033
31055
  renameSync5(destination, displaced);
31034
31056
  syncDirectory2(directory);
31035
- if (vnextContentSha256(readFileSync19(displaced)) !== entry.observedSha256) {
31057
+ if (vnextContentSha256(readFileSync20(displaced)) !== entry.observedSha256) {
31036
31058
  if (!existsSync19(destination)) {
31037
31059
  try {
31038
31060
  linkSync(displaced, destination);
@@ -31071,12 +31093,12 @@ function atomicInstallTarget(projectRoot, operation, entry) {
31071
31093
  if (destinationSha(projectRoot, entry.path) !== entry.targetSha256) fail3("repair_install_verification_failed", entry.path, "installed target hash does not match the pinned operation");
31072
31094
  }
31073
31095
  function installedCreateMatches(projectRoot, operation) {
31074
- const configRoot = join21(projectRoot, ".kxm");
31096
+ const configRoot = join22(projectRoot, ".kxm");
31075
31097
  if (!existsSync19(configRoot)) return false;
31076
31098
  const actual = [];
31077
31099
  const visit2 = (directory) => {
31078
31100
  for (const entry of readdirSync7(directory, { withFileTypes: true })) {
31079
- const absolute = join21(directory, entry.name);
31101
+ const absolute = join22(directory, entry.name);
31080
31102
  if (entry.isSymbolicLink()) fail3("create_resume_link", relativeConfigPath(projectRoot, absolute), "created configuration must not contain links", "path");
31081
31103
  if (entry.isDirectory()) visit2(absolute);
31082
31104
  else if (entry.isFile()) actual.push(relativeConfigPath(projectRoot, absolute));
@@ -31097,7 +31119,7 @@ function syncTreeDirectories(root) {
31097
31119
  const visit2 = (directory) => {
31098
31120
  directories.push(directory);
31099
31121
  for (const entry of readdirSync7(directory, { withFileTypes: true })) {
31100
- if (entry.isDirectory()) visit2(join21(directory, entry.name));
31122
+ if (entry.isDirectory()) visit2(join22(directory, entry.name));
31101
31123
  }
31102
31124
  };
31103
31125
  visit2(root);
@@ -31111,7 +31133,7 @@ function rebuildCreateShadow(projectRoot, operation, options) {
31111
31133
  if (stat.isSymbolicLink() || !stat.isDirectory() || !installedCreateMatches(shadow, operation)) {
31112
31134
  fail3("create_shadow_invalid", TRANSACTION_NAME, "reconstructed create shadow does not exactly match pinned target files", "path");
31113
31135
  }
31114
- syncTreeDirectories(join21(shadow, ".kxm"));
31136
+ syncTreeDirectories(join22(shadow, ".kxm"));
31115
31137
  }
31116
31138
  function applyOperation(projectRoot, original, options, resumed) {
31117
31139
  assertNoRegisteredGates(options);
@@ -31121,10 +31143,10 @@ function applyOperation(projectRoot, original, options, resumed) {
31121
31143
  verifyBackups(projectRoot, operation);
31122
31144
  operation = updatePhase(projectRoot, operation, "applying");
31123
31145
  if (operation.kind === "create") {
31124
- const destination = join21(projectRoot, ".kxm");
31146
+ const destination = join22(projectRoot, ".kxm");
31125
31147
  if (!existsSync19(destination)) {
31126
31148
  rebuildCreateShadow(projectRoot, operation, effectiveOptions);
31127
- renameSync5(join21(shadowRoot(projectRoot), ".kxm"), destination);
31149
+ renameSync5(join22(shadowRoot(projectRoot), ".kxm"), destination);
31128
31150
  syncDirectory2(projectRoot);
31129
31151
  } else if (!installedCreateMatches(projectRoot, operation)) {
31130
31152
  fail3("create_resume_conflict", ".kxm", "existing project configuration does not match the pinned create operation");
@@ -31151,7 +31173,7 @@ function applyOperation(projectRoot, original, options, resumed) {
31151
31173
  operation = updatePhase(projectRoot, operation, "verified");
31152
31174
  if (options.testFaultAt === "verified") throw new Error("injected init fault after verification");
31153
31175
  const files = operation.files.map((entry) => entry.path);
31154
- syncTreeDirectories(join21(projectRoot, ".kxm"));
31176
+ syncTreeDirectories(join22(projectRoot, ".kxm"));
31155
31177
  return { kind: operation.kind, resumed, bundle, files };
31156
31178
  }
31157
31179
  function prepareAndApplyVnextCreate(projectRoot, rendered, options = {}) {
@@ -31266,7 +31288,7 @@ function finishPreparingOperation(projectRoot, operation, options) {
31266
31288
  const rendered = rendererForOperation(operation);
31267
31289
  if (!rendered) fail3("init_transaction_renderer_unavailable", TRANSACTION_NAME, "this binary cannot reproduce the pinned pre-application target");
31268
31290
  for (const directory of ["targets", "backups", "shadow"]) {
31269
- rmSync7(join21(transactionRoot(projectRoot), directory), { recursive: true, force: true });
31291
+ rmSync7(join22(transactionRoot(projectRoot), directory), { recursive: true, force: true });
31270
31292
  }
31271
31293
  for (const entry of operation.files) {
31272
31294
  const bytes = rendered.files.get(entry.path);
@@ -31301,7 +31323,7 @@ function commitVnextInitTransaction(projectRoot, schemasDir) {
31301
31323
  fail3("init_transaction_not_verified", TRANSACTION_NAME, "initialization transaction cannot commit before installed state is verified");
31302
31324
  }
31303
31325
  const transaction = transactionRoot(projectRoot);
31304
- const retired = join21(projectRoot, `${TRANSACTION_NAME}-cleanup-${operation.operationId}-${randomUUID10()}`);
31326
+ const retired = join22(projectRoot, `${TRANSACTION_NAME}-cleanup-${operation.operationId}-${randomUUID10()}`);
31305
31327
  renameSync5(transaction, retired);
31306
31328
  syncDirectory2(projectRoot);
31307
31329
  rmSync7(retired, { recursive: true, force: true });
@@ -31322,7 +31344,7 @@ function initIssue(code, file, message) {
31322
31344
  return { phase: "discovery", code, file, message };
31323
31345
  }
31324
31346
  function normalizedProjectName(root, requested) {
31325
- const name = (requested ?? basename4(root) ?? "KXM Project").trim();
31347
+ const name = (requested ?? basename5(root) ?? "KXM Project").trim();
31326
31348
  if (name.length < 1 || name.length > 120 || /[\u0000\r\n]/.test(name)) {
31327
31349
  throw new VnextConfigError([initIssue("project_name_invalid", ".kxm/project.yaml", "project name must contain 1-120 characters on one line")]);
31328
31350
  }
@@ -31410,7 +31432,7 @@ function validateBindingIdentities(bundle, persisted, explicit) {
31410
31432
  }
31411
31433
  function initializeVnextProjectAtGitRoot(start, gitRoot, options, mutationLock) {
31412
31434
  const storeOptions = bindingStoreOptions(options);
31413
- 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;
31414
31436
  const repositoryBindings = Object.fromEntries([
31415
31437
  ...Object.entries(persisted?.repositories ?? {}),
31416
31438
  ...Object.entries(options.repositoryBindings ?? {})
@@ -31599,7 +31621,7 @@ function initializeVnextProjectAtGitRoot(start, gitRoot, options, mutationLock)
31599
31621
  const files = [...rendered.files.keys()];
31600
31622
  if (options.dryRun) return { action: "planned", plan, projectRoot: gitRoot, files };
31601
31623
  if (!mutationLock) throw new Error("project mutation lock is required to create configuration");
31602
- if (existsSync20(join22(gitRoot, ".kxm"))) {
31624
+ if (existsSync20(join23(gitRoot, ".kxm"))) {
31603
31625
  throw new VnextConfigError([initIssue("workspace_changed", ".kxm", "workspace changed after planning; existing .kxm state was not overwritten")]);
31604
31626
  }
31605
31627
  const created = prepareAndApplyVnextCreate(gitRoot, rendered, transactionOptions);
@@ -31631,8 +31653,8 @@ function initializeVnextProject(start = process.cwd(), options = {}) {
31631
31653
  // plugins/kxm/src/vnext-migrate.ts
31632
31654
  var import_yaml12 = __toESM(require_dist(), 1);
31633
31655
  import { createHash as createHash13 } from "node:crypto";
31634
- 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";
31635
- 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";
31636
31658
  var MAX_LEGACY_JSON_BYTES = 1024 * 1024;
31637
31659
  var MAX_LEGACY_JSON_DEPTH = 32;
31638
31660
  var MAX_LEGACY_JSON_NODES = 32768;
@@ -31801,12 +31823,12 @@ function readVnextLegacySources(root) {
31801
31823
  throw new VnextConfigError([migrateIssue("discovery", "legacy_source_limit", ".kxm/config", `legacy configuration exceeds ${MAX_LEGACY_SOURCES} files`)]);
31802
31824
  }
31803
31825
  return files.map((path4) => {
31804
- const absolute = join23(root, ...path4.split("/"));
31826
+ const absolute = join24(root, ...path4.split("/"));
31805
31827
  const stat = lstatSync8(absolute);
31806
31828
  if (stat.isSymbolicLink() || !stat.isFile()) {
31807
31829
  throw new VnextConfigError([migrateIssue("path", "legacy_source_invalid", path4, "legacy configuration must be a regular file, not a link")]);
31808
31830
  }
31809
- const buffer = readFileSync20(absolute);
31831
+ const buffer = readFileSync21(absolute);
31810
31832
  let text;
31811
31833
  try {
31812
31834
  text = new TextDecoder("utf-8", { fatal: true }).decode(buffer);
@@ -32883,7 +32905,7 @@ function readVnextMigrationDecisions(path4, schemasDir) {
32883
32905
  throw new VnextConfigError([migrateIssue("discovery", "decisions_missing", path4, "migration decisions file does not exist")]);
32884
32906
  }
32885
32907
  const registry = new VnextSchemaRegistry(schemasDir);
32886
- const value = parseRestrictedYaml2(readFileSync20(path4), path4);
32908
+ const value = parseRestrictedYaml2(readFileSync21(path4), path4);
32887
32909
  const issues = registry.validateMigrationDecision(value, path4);
32888
32910
  if (issues.length > 0) throw new VnextConfigError(issues);
32889
32911
  return value;
@@ -32922,7 +32944,7 @@ function writeDurable2(path4, content) {
32922
32944
  chmodSync6(path4, 384);
32923
32945
  } catch {
32924
32946
  }
32925
- syncDirectory3(join23(path4, ".."));
32947
+ syncDirectory3(join24(path4, ".."));
32926
32948
  } finally {
32927
32949
  if (created && existsSync21(temp)) rmSync8(temp, { force: true });
32928
32950
  }
@@ -32934,7 +32956,7 @@ function applyVnextMigration(projectRoot, options = {}) {
32934
32956
  ...options.schemasDir === void 0 ? {} : { schemasDir: options.schemasDir }
32935
32957
  };
32936
32958
  const execute = (lock) => {
32937
- const receiptAbsolute = join23(root, ...VNEXT_MIGRATION_RECEIPT_PATH.split("/"));
32959
+ const receiptAbsolute = join24(root, ...VNEXT_MIGRATION_RECEIPT_PATH.split("/"));
32938
32960
  if (existsSync21(receiptAbsolute)) {
32939
32961
  const stat = lstatSync8(receiptAbsolute);
32940
32962
  if (stat.isSymbolicLink() || !stat.isFile()) {
@@ -32988,7 +33010,7 @@ function applyVnextMigration(projectRoot, options = {}) {
32988
33010
  return { action: "planned", projectRoot: root, files: [], plan: first.plan };
32989
33011
  }
32990
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") }));
32991
- const collisions = files.filter((file) => existsSync21(join23(root, ...file.path.split("/"))));
33013
+ const collisions = files.filter((file) => existsSync21(join24(root, ...file.path.split("/"))));
32992
33014
  if (collisions.length > 0) {
32993
33015
  throw new VnextConfigError(collisions.map((file) => migrateIssue("semantic", "migration_target_exists", file.path, "target resource already exists; refusing to overwrite")));
32994
33016
  }
@@ -32997,7 +33019,7 @@ function applyVnextMigration(projectRoot, options = {}) {
32997
33019
  const segments = file.path.split("/");
32998
33020
  let current = root;
32999
33021
  for (const segment of segments.slice(0, -1)) {
33000
- current = join23(current, segment);
33022
+ current = join24(current, segment);
33001
33023
  if (!existsSync21(current)) continue;
33002
33024
  const stat = lstatSync8(current);
33003
33025
  if (stat.isSymbolicLink() || !stat.isDirectory()) {
@@ -33014,8 +33036,8 @@ function applyVnextMigration(projectRoot, options = {}) {
33014
33036
  const written = [];
33015
33037
  try {
33016
33038
  for (const file of files) {
33017
- const absolute = join23(root, ...file.path.split("/"));
33018
- mkdirSync18(join23(absolute, ".."), { recursive: true });
33039
+ const absolute = join24(root, ...file.path.split("/"));
33040
+ mkdirSync18(join24(absolute, ".."), { recursive: true });
33019
33041
  written.push(absolute);
33020
33042
  writeDurable2(absolute, file.bytes);
33021
33043
  }
@@ -33061,7 +33083,7 @@ ${bundle.configRevision}`).slice(7, 39)}`,
33061
33083
  }
33062
33084
  function verifyVnextMigration(projectRoot, options = {}) {
33063
33085
  const root = migrationGitRoot(projectRoot);
33064
- const receiptAbsolute = join23(root, ...VNEXT_MIGRATION_RECEIPT_PATH.split("/"));
33086
+ const receiptAbsolute = join24(root, ...VNEXT_MIGRATION_RECEIPT_PATH.split("/"));
33065
33087
  if (!existsSync21(receiptAbsolute)) {
33066
33088
  return {
33067
33089
  ok: false,
@@ -33372,7 +33394,7 @@ async function cmdBackup(runtime, options) {
33372
33394
  const summary = [
33373
33395
  `Created SQLite backup with ${manifest.stores.length} store(s):`,
33374
33396
  ...manifest.stores.map((s) => ` - ${s.storeId}: ${s.sourcePath} -> ${s.backupFile} (schema v${s.schemaVersion}, ${s.bytes} bytes, sha256 ${s.sha256.slice(0, 12)}...)`),
33375
- `Manifest: ${join24(outDir, "manifest.json")}`
33397
+ `Manifest: ${join25(outDir, "manifest.json")}`
33376
33398
  ].join("\n");
33377
33399
  print(runtime.io, runtime.json, payload, summary);
33378
33400
  return 0;
@@ -33942,7 +33964,7 @@ async function cmdStudioLayout(runtime, workflowPath) {
33942
33964
  let yamlContent;
33943
33965
  let workflowId = "default";
33944
33966
  if (existsSync22(filePath)) {
33945
- yamlContent = readFileSync21(filePath, "utf8");
33967
+ yamlContent = readFileSync22(filePath, "utf8");
33946
33968
  } else {
33947
33969
  yamlContent = `schema: kxm.workflow.v1
33948
33970
  description: Feature implementation workflow
@@ -34015,17 +34037,17 @@ async function cmdStudioServe(runtime, options) {
34015
34037
  sessionToken,
34016
34038
  planProvider: () => {
34017
34039
  try {
34018
- const wfDir = join25(runtime.cwd, ".kxm", "workflows");
34019
- const defaultPath = join25(wfDir, "default.yaml");
34040
+ const wfDir = join26(runtime.cwd, ".kxm", "workflows");
34041
+ const defaultPath = join26(wfDir, "default.yaml");
34020
34042
  let targetPath = existsSync22(defaultPath) ? defaultPath : void 0;
34021
34043
  if (!targetPath && existsSync22(wfDir)) {
34022
34044
  const yml = readdirSync8(wfDir).find((f) => f.endsWith(".yaml") || f.endsWith(".yml"));
34023
- if (yml) targetPath = join25(wfDir, yml);
34045
+ if (yml) targetPath = join26(wfDir, yml);
34024
34046
  }
34025
34047
  if (targetPath && existsSync22(targetPath)) {
34026
- const raw = readFileSync21(targetPath, "utf8");
34048
+ const raw = readFileSync22(targetPath, "utf8");
34027
34049
  const parsed = (0, import_yaml13.parse)(raw);
34028
- const wfId = basename5(targetPath).replace(/\.(yaml|yml)$/, "");
34050
+ const wfId = basename6(targetPath).replace(/\.(yaml|yml)$/, "");
34029
34051
  return compileVnextWorkflow({ id: wfId, value: parsed });
34030
34052
  }
34031
34053
  } catch {
@@ -34073,14 +34095,14 @@ Press Ctrl+C to stop.
34073
34095
  }
34074
34096
 
34075
34097
  // plugins/kxm/src/cli/context-skills.ts
34076
- import { readFileSync as readFileSync24 } from "node:fs";
34077
- 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";
34078
34100
 
34079
34101
  // plugins/kxm/src/memory.ts
34080
34102
  var import_yaml14 = __toESM(require_dist(), 1);
34081
34103
  import { randomUUID as randomUUID12 } from "node:crypto";
34082
- import { existsSync as existsSync23, mkdirSync as mkdirSync19, readdirSync as readdirSync9, readFileSync as readFileSync22, writeFileSync as writeFileSync18 } from "node:fs";
34083
- 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";
34084
34106
  var MEMORY_SCHEMA = "kxm.memory.v1";
34085
34107
  var MEMORY_BRIEF_SCHEMA = "kxm.memory-brief.v1";
34086
34108
  var MEMORY_MARKER_START = "<!-- kxm:memory:start -->";
@@ -34207,8 +34229,8 @@ ${yamlText}
34207
34229
  }
34208
34230
  function memoryDirectories(repoRoot6) {
34209
34231
  const root = resolve22(repoRoot6);
34210
- const memoryDir = join26(root, ".kxm", "memory");
34211
- const candidatesDir = join26(memoryDir, "candidates");
34232
+ const memoryDir = join27(root, ".kxm", "memory");
34233
+ const candidatesDir = join27(memoryDir, "candidates");
34212
34234
  return { memoryDir, candidatesDir };
34213
34235
  }
34214
34236
  function loadAuthoredMemory(repoRoot6) {
@@ -34218,9 +34240,9 @@ function loadAuthoredMemory(repoRoot6) {
34218
34240
  const entries = readdirSync9(memoryDir, { withFileTypes: true });
34219
34241
  for (const entry of entries) {
34220
34242
  if (entry.isFile() && extname2(entry.name) === ".md") {
34221
- const fullPath = join26(memoryDir, entry.name);
34243
+ const fullPath = join27(memoryDir, entry.name);
34222
34244
  try {
34223
- const text = readFileSync22(fullPath, "utf8");
34245
+ const text = readFileSync23(fullPath, "utf8");
34224
34246
  const record = parseMemoryRecord(text, entry.name);
34225
34247
  if (record.lifecycle === "active") {
34226
34248
  records.push(record);
@@ -34259,7 +34281,7 @@ function createMemoryNote(repoRoot6, summary, options = {}) {
34259
34281
  evidenceRefs: [],
34260
34282
  ...options.body ? { body: options.body.trim() } : {}
34261
34283
  };
34262
- const targetPath = join26(candidatesDir, `${id}.md`);
34284
+ const targetPath = join27(candidatesDir, `${id}.md`);
34263
34285
  writeFileSync18(targetPath, formatMemoryRecord(record), "utf8");
34264
34286
  return { record, path: targetPath };
34265
34287
  }
@@ -34297,7 +34319,7 @@ function formatHarnessMemoryBlock(records) {
34297
34319
  function updateHarnessDocument(filePath, block, defaultHeader) {
34298
34320
  let original = "";
34299
34321
  if (existsSync23(filePath)) {
34300
- original = readFileSync22(filePath, "utf8");
34322
+ original = readFileSync23(filePath, "utf8");
34301
34323
  }
34302
34324
  let updated = "";
34303
34325
  if (original.includes(MEMORY_MARKER_START) && original.includes(MEMORY_MARKER_END)) {
@@ -34336,14 +34358,14 @@ function syncHarnessMemory(repoRoot6) {
34336
34358
  const block = formatHarnessMemoryBlock(records);
34337
34359
  const updated = [];
34338
34360
  const created = [];
34339
- const agentsPath = join26(root, "AGENTS.md");
34361
+ const agentsPath = join27(root, "AGENTS.md");
34340
34362
  const agentsHeader = "# AGENTS\n\nFollow project instructions.\n";
34341
34363
  const agentsExisted = existsSync23(agentsPath);
34342
34364
  if (updateHarnessDocument(agentsPath, block, agentsHeader)) {
34343
34365
  if (agentsExisted) updated.push("AGENTS.md");
34344
34366
  else created.push("AGENTS.md");
34345
34367
  }
34346
- const claudePath = join26(root, "CLAUDE.md");
34368
+ const claudePath = join27(root, "CLAUDE.md");
34347
34369
  const claudeHeader = `# KXM (Claude)
34348
34370
 
34349
34371
  Follow [\`AGENTS.md\`](AGENTS.md). Official phase tracking:
@@ -34359,7 +34381,7 @@ artifacts, not hub \`peer-reply\` evidence.
34359
34381
  if (claudeExisted) updated.push("CLAUDE.md");
34360
34382
  else created.push("CLAUDE.md");
34361
34383
  }
34362
- const geminiPath = join26(root, "GEMINI.md");
34384
+ const geminiPath = join27(root, "GEMINI.md");
34363
34385
  const geminiHeader = `# KXM (Gemini / Antigravity)
34364
34386
 
34365
34387
  Follow [\`AGENTS.md\`](AGENTS.md). Official phase tracking:
@@ -34379,8 +34401,8 @@ for Gemini models. Starting rotation remains Grok.
34379
34401
  // plugins/kxm/src/skills.ts
34380
34402
  var import_yaml15 = __toESM(require_dist(), 1);
34381
34403
  import { createHash as createHash14 } from "node:crypto";
34382
- 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";
34383
- 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";
34384
34406
  var SKILL_CANDIDATE_SCHEMA = "kxm.skill-candidate.v1";
34385
34407
  var SKILL_EVALUATION_SCHEMA = "kxm.skill-evaluation.v1";
34386
34408
  var SKILL_DECISION_SCHEMA = "kxm.skill-decision.v1";
@@ -34474,21 +34496,21 @@ var SkillLifecycle = class {
34474
34496
  this.allowOptimizationEvals = options.allowOptimizationEvals === true;
34475
34497
  }
34476
34498
  dir(state) {
34477
- 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"));
34478
34500
  }
34479
34501
  historyFile(id) {
34480
- return join27(this.root, "history", `${id}.jsonl`);
34502
+ return join28(this.root, "history", `${id}.jsonl`);
34481
34503
  }
34482
34504
  paths(state, id) {
34483
- const dir = join27(this.dir(state), id);
34484
- 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") };
34485
34507
  }
34486
34508
  appendHistory(id, record) {
34487
- mkdirSync20(join27(this.root, "history"), { recursive: true });
34509
+ mkdirSync20(join28(this.root, "history"), { recursive: true });
34488
34510
  const line = `${JSON.stringify(record)}
34489
34511
  `;
34490
34512
  if (existsSync24(this.historyFile(id))) {
34491
- const existing = readFileSync23(this.historyFile(id), "utf8");
34513
+ const existing = readFileSync24(this.historyFile(id), "utf8");
34492
34514
  const lines = existing.split("\n").filter((entry) => entry.trim());
34493
34515
  writeFileSync19(this.historyFile(id), [...lines.slice(-499), line.trim()].join("\n") + "\n");
34494
34516
  } else {
@@ -34498,18 +34520,18 @@ var SkillLifecycle = class {
34498
34520
  history(id) {
34499
34521
  const file = this.historyFile(id);
34500
34522
  if (!existsSync24(file)) return [];
34501
- 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));
34502
34524
  }
34503
34525
  readMetadata(state, id) {
34504
34526
  const { metadata } = this.paths(state, id);
34505
34527
  if (!existsSync24(metadata)) {
34506
34528
  throw new SkillLifecycleError("skill_not_found", `skill ${id} not found in ${state}`);
34507
34529
  }
34508
- return JSON.parse(readFileSync23(metadata, "utf8"));
34530
+ return JSON.parse(readFileSync24(metadata, "utf8"));
34509
34531
  }
34510
34532
  move(from, to, id) {
34511
- const fromDir = join27(this.dir(from), id);
34512
- const toDir = join27(this.dir(to), id);
34533
+ const fromDir = join28(this.dir(from), id);
34534
+ const toDir = join28(this.dir(to), id);
34513
34535
  if (!existsSync24(fromDir)) {
34514
34536
  throw new SkillLifecycleError("skill_not_found", `skill ${id} not found in ${from}`);
34515
34537
  }
@@ -34668,13 +34690,13 @@ var SkillLifecycle = class {
34668
34690
  const candidatePaths = this.paths("candidate", candidateId);
34669
34691
  const promotedPaths = this.paths("promoted", candidateId);
34670
34692
  mkdirSync20(promotedPaths.dir, { recursive: true });
34671
- const skillContent = readFileSync23(candidatePaths.skill, "utf8");
34672
- const metadataContent = readFileSync23(candidatePaths.metadata, "utf8");
34693
+ const skillContent = readFileSync24(candidatePaths.skill, "utf8");
34694
+ const metadataContent = readFileSync24(candidatePaths.metadata, "utf8");
34673
34695
  writeFileSync19(promotedPaths.skill, skillContent);
34674
34696
  writeFileSync19(promotedPaths.metadata, metadataContent);
34675
- const patchesDir = join27(this.root, "patches");
34697
+ const patchesDir = join28(this.root, "patches");
34676
34698
  mkdirSync20(patchesDir, { recursive: true });
34677
- const patchPath = join27(patchesDir, `${candidateId}.patch`);
34699
+ const patchPath = join28(patchesDir, `${candidateId}.patch`);
34678
34700
  const relSkillPath = `.kxm/skills/promoted/${candidateId}/SKILL.md`;
34679
34701
  const relMetaPath = `.kxm/skills/promoted/${candidateId}/metadata.json`;
34680
34702
  const patch = `${createUnifiedPatch(relSkillPath, skillContent)}${createUnifiedPatch(relMetaPath, metadataContent)}`;
@@ -34702,7 +34724,7 @@ var SkillLifecycle = class {
34702
34724
  verify(state, id) {
34703
34725
  const metadata = this.readMetadata(state, id);
34704
34726
  const { skill } = this.paths(state, id);
34705
- const content = readFileSync23(skill, "utf8");
34727
+ const content = readFileSync24(skill, "utf8");
34706
34728
  if (skillContentSha256(content) !== metadata.contentSha256) {
34707
34729
  throw new SkillLifecycleError(
34708
34730
  "skill_integrity_violation",
@@ -34733,7 +34755,7 @@ var SkillLifecycle = class {
34733
34755
  read(state, id) {
34734
34756
  const metadata = this.readMetadata(state, id);
34735
34757
  const { skill } = this.paths(state, id);
34736
- return { metadata, content: readFileSync23(skill, "utf8") };
34758
+ return { metadata, content: readFileSync24(skill, "utf8") };
34737
34759
  }
34738
34760
  };
34739
34761
  function boundedList(value, field) {
@@ -34748,16 +34770,16 @@ function boundedList(value, field) {
34748
34770
  return [...new Set(refs)];
34749
34771
  }
34750
34772
  function readdirSorted(dir) {
34751
- return readdirSync10(dir).filter((entry) => statSync3(join27(dir, entry)).isDirectory()).sort();
34773
+ return readdirSync10(dir).filter((entry) => statSync3(join28(dir, entry)).isDirectory()).sort();
34752
34774
  }
34753
34775
 
34754
34776
  // plugins/kxm/src/wiki.ts
34755
34777
  import { mkdirSync as mkdirSync21, writeFileSync as writeFileSync20 } from "node:fs";
34756
- import { join as join28 } from "node:path";
34778
+ import { join as join29 } from "node:path";
34757
34779
  function writeCompiledWiki(root, wiki) {
34758
34780
  const written = [];
34759
34781
  for (const [relativePath, content] of [...wiki.pages].sort(([left], [right]) => left.localeCompare(right))) {
34760
- const absolute = join28(root, relativePath);
34782
+ const absolute = join29(root, relativePath);
34761
34783
  mkdirSync21(absolute.slice(0, absolute.lastIndexOf("/")), { recursive: true });
34762
34784
  writeFileSync20(absolute, content);
34763
34785
  written.push(relativePath);
@@ -34925,7 +34947,7 @@ function skillStateFromFlag(value) {
34925
34947
  throw new Error(`invalid skill state ${value}`);
34926
34948
  }
34927
34949
  function skillsRoot(runtime) {
34928
- return join29(runtime.dirs.workdir, ".kxm", "skills");
34950
+ return join30(runtime.dirs.workdir, ".kxm", "skills");
34929
34951
  }
34930
34952
  function csv(value) {
34931
34953
  if (!value) return void 0;
@@ -34942,7 +34964,7 @@ async function cmdSkillsCreate(runtime, options) {
34942
34964
  const metadata = lifecycle.create({
34943
34965
  name: options.name,
34944
34966
  description: options.description ?? "",
34945
- content: readFileSync24(options.file, "utf8"),
34967
+ content: readFileSync25(options.file, "utf8"),
34946
34968
  createdBy: options.createdBy,
34947
34969
  sources: {
34948
34970
  runIds: csv(options.run) ?? [],
@@ -35100,8 +35122,8 @@ async function cmdMemorySync(runtime) {
35100
35122
 
35101
35123
  // plugins/kxm/src/cli/hub.ts
35102
35124
  import { randomUUID as randomUUID14 } from "node:crypto";
35103
- import { existsSync as existsSync30, mkdirSync as mkdirSync25, readFileSync as readFileSync30, readdirSync as readdirSync12, rmSync as rmSync10, writeFileSync as writeFileSync23 } from "node:fs";
35104
- 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";
35105
35127
 
35106
35128
  // node_modules/marked/lib/marked.esm.js
35107
35129
  function M() {
@@ -41034,7 +41056,7 @@ import * as path2 from "node:path";
41034
41056
 
41035
41057
  // node_modules/@earendil-works/pi-tui/dist/native-module-path.js
41036
41058
  import { createRequire as createRequire2 } from "node:module";
41037
- import { dirname as dirname16, join as join30 } from "node:path";
41059
+ import { dirname as dirname16, join as join31 } from "node:path";
41038
41060
  import { fileURLToPath as fileURLToPath5 } from "node:url";
41039
41061
  var moduleRequire = createRequire2(import.meta.url);
41040
41062
  var TUI_PACKAGE_NAME = "@earendil-works/pi-tui";
@@ -41043,10 +41065,10 @@ function getNativeModuleCandidates(nativePath, options = {}) {
41043
41065
  const candidates = [];
41044
41066
  try {
41045
41067
  const packageEntry = (options.resolvePackage ?? moduleRequire.resolve)(TUI_PACKAGE_NAME);
41046
- candidates.push(join30(dirname16(packageEntry), "..", nativePath));
41068
+ candidates.push(join31(dirname16(packageEntry), "..", nativePath));
41047
41069
  } catch {
41048
41070
  }
41049
- 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));
41050
41072
  return Array.from(new Set(candidates));
41051
41073
  }
41052
41074
 
@@ -43503,7 +43525,7 @@ var MAX_RENDER_WRITE_CHARS = 1024 * 1024;
43503
43525
 
43504
43526
  // plugins/kxm/src/tui.ts
43505
43527
  import { mkdirSync as mkdirSync22 } from "node:fs";
43506
- 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";
43507
43529
  import { spawnSync as spawnSync5 } from "node:child_process";
43508
43530
 
43509
43531
  // plugins/kxm/src/external-effects.ts
@@ -43514,9 +43536,9 @@ function slugifyBranchPart(text, maxLength = 40) {
43514
43536
  }
43515
43537
 
43516
43538
  // plugins/kxm/src/local-snapshot.ts
43517
- 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";
43518
43540
  import { homedir as homedir5 } from "node:os";
43519
- 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";
43520
43542
  function processExists2(pid) {
43521
43543
  try {
43522
43544
  process.kill(pid, 0);
@@ -43636,16 +43658,16 @@ function readOpenMessageMetadata(database) {
43636
43658
  return messages;
43637
43659
  }
43638
43660
  function resolveKxmSnapshotPaths(cwd, env = process.env) {
43639
- const stateDir = env.KXM_STATE_DIR?.trim() || join33(cwd, ".kxm", "state");
43661
+ const stateDir = env.KXM_STATE_DIR?.trim() || join34(cwd, ".kxm", "state");
43640
43662
  const configured = env.KXM_DATA_PATH?.trim();
43641
- const dataPath = configured ? resolve23(cwd, configured) : join33(stateDir, "kxm.db");
43663
+ const dataPath = configured ? resolve23(cwd, configured) : join34(stateDir, "kxm.db");
43642
43664
  return { dataPath, stateDir };
43643
43665
  }
43644
43666
  function resolveVnextStateRoot(stateDir, options) {
43645
43667
  if (options?.vnextStateRoot && existsSync25(options.vnextStateRoot)) {
43646
43668
  return resolve23(options.vnextStateRoot);
43647
43669
  }
43648
- 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"))) {
43649
43671
  return stateDir;
43650
43672
  }
43651
43673
  const env = options?.env ?? process.env;
@@ -43656,13 +43678,13 @@ function resolveVnextStateRoot(stateDir, options) {
43656
43678
  let base;
43657
43679
  if (process.platform === "win32") {
43658
43680
  const localAppData = env.LOCALAPPDATA?.trim();
43659
- base = localAppData && isAbsolute7(localAppData) ? localAppData : join33(homedir5(), "AppData", "Local");
43681
+ base = localAppData && isAbsolute7(localAppData) ? localAppData : join34(homedir5(), "AppData", "Local");
43660
43682
  base = resolve23(base, "KXM");
43661
43683
  } else if (process.platform === "darwin") {
43662
43684
  base = resolve23(homedir5(), "Library", "Application Support", "KXM");
43663
43685
  } else {
43664
43686
  const xdgState = env.XDG_STATE_HOME?.trim();
43665
- base = xdgState && isAbsolute7(xdgState) ? xdgState : join33(homedir5(), ".local", "state");
43687
+ base = xdgState && isAbsolute7(xdgState) ? xdgState : join34(homedir5(), ".local", "state");
43666
43688
  base = resolve23(base, "kxm");
43667
43689
  }
43668
43690
  if (existsSync25(base)) return base;
@@ -43696,9 +43718,9 @@ function loadLocalMeshSnapshot(dataPath, stateDir, options) {
43696
43718
  let vnextRunTotal = 0;
43697
43719
  const vnextStateRoot = resolveVnextStateRoot(stateDir, options);
43698
43720
  if (vnextStateRoot) {
43699
- const runtimeDir = join33(vnextStateRoot, "runtime");
43700
- const registryDbPath = join33(runtimeDir, "registry.db");
43701
- const projectsDir = join33(runtimeDir, "projects");
43721
+ const runtimeDir = join34(vnextStateRoot, "runtime");
43722
+ const registryDbPath = join34(runtimeDir, "registry.db");
43723
+ const projectsDir = join34(runtimeDir, "projects");
43702
43724
  const projectKeys = /* @__PURE__ */ new Set();
43703
43725
  if (existsSync25(registryDbPath)) {
43704
43726
  hasVnext = true;
@@ -43727,7 +43749,7 @@ function loadLocalMeshSnapshot(dataPath, stateDir, options) {
43727
43749
  }
43728
43750
  }
43729
43751
  for (const key of projectKeys) {
43730
- const eventDbPath = join33(projectsDir, key, "run-events.db");
43752
+ const eventDbPath = join34(projectsDir, key, "run-events.db");
43731
43753
  if (existsSync25(eventDbPath)) {
43732
43754
  hasVnext = true;
43733
43755
  try {
@@ -43761,7 +43783,7 @@ function loadLocalMeshSnapshot(dataPath, stateDir, options) {
43761
43783
  if (existsSync25(stateDir)) {
43762
43784
  for (const file of readdirSync11(stateDir).filter((name) => name.endsWith(".pid"))) {
43763
43785
  try {
43764
- const record = JSON.parse(readFileSync25(join33(stateDir, file), "utf8"));
43786
+ const record = JSON.parse(readFileSync26(join34(stateDir, file), "utf8"));
43765
43787
  pids.push({
43766
43788
  file,
43767
43789
  ...record.role ? { role: record.role } : {},
@@ -43800,7 +43822,7 @@ function loadLocalMeshSnapshot(dataPath, stateDir, options) {
43800
43822
  } else {
43801
43823
  source = "legacy";
43802
43824
  }
43803
- const telemetryFile = join33(stateDir, "telemetry.jsonl");
43825
+ const telemetryFile = join34(stateDir, "telemetry.jsonl");
43804
43826
  const spend = existsSync25(telemetryFile) ? readRoutingRecords(telemetryFile) : [];
43805
43827
  return {
43806
43828
  source,
@@ -43935,7 +43957,7 @@ function spawnDegradeWorktree(repoRoot6, runId, options) {
43935
43957
  const cleanRunId = runId.replace(/^run_/, "");
43936
43958
  const desc = options?.description ? slugifyBranchPart(options.description, 30) : "degrade";
43937
43959
  const branchName = `kxm/run-${cleanRunId}-${desc}`;
43938
- const relativeWtPath = join34(".kxm", "worktrees", `run-${cleanRunId}-${desc}`);
43960
+ const relativeWtPath = join35(".kxm", "worktrees", `run-${cleanRunId}-${desc}`);
43939
43961
  const absoluteWtPath = resolve24(repoRoot6, relativeWtPath);
43940
43962
  const jumpCommand = `cd "${absoluteWtPath}"`;
43941
43963
  try {
@@ -44705,8 +44727,8 @@ async function runMeshTui(input) {
44705
44727
  // plugins/kxm/src/session-work.ts
44706
44728
  import { spawnSync as spawnSync6 } from "node:child_process";
44707
44729
  import { randomUUID as randomUUID13 } from "node:crypto";
44708
- import { existsSync as existsSync26, mkdirSync as mkdirSync23, readFileSync as readFileSync26, renameSync as renameSync8, writeFileSync as writeFileSync21 } from "node:fs";
44709
- 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";
44710
44732
  var MAX_SESSION_BRIEF_TASKS = 5;
44711
44733
  var MAX_SESSION_BRIEF_PLANS = 5;
44712
44734
  var SESSION_BRIEF_SCHEMA = "kxm.session-brief.v1";
@@ -44862,10 +44884,10 @@ function buildSessionBrief(snapshot, current, hub, ship, updateLatest, cost, ses
44862
44884
  };
44863
44885
  }
44864
44886
  function readCachedSessionBrief(stateDir) {
44865
- const file = join35(stateDir, "session-brief.json");
44887
+ const file = join36(stateDir, "session-brief.json");
44866
44888
  try {
44867
44889
  if (!existsSync26(file)) return void 0;
44868
- const raw = readFileSync26(file, "utf8");
44890
+ const raw = readFileSync27(file, "utf8");
44869
44891
  const parsed = JSON.parse(raw);
44870
44892
  if (parsed && parsed.schema === "kxm.session-brief.v1" && typeof parsed.generatedAt === "string") {
44871
44893
  const ageMs = Date.now() - Date.parse(parsed.generatedAt);
@@ -44881,7 +44903,7 @@ function readCachedSessionBrief(stateDir) {
44881
44903
  function writeCachedSessionBrief(stateDir, brief) {
44882
44904
  try {
44883
44905
  mkdirSync23(stateDir, { recursive: true, mode: 448 });
44884
- const file = join35(stateDir, "session-brief.json");
44906
+ const file = join36(stateDir, "session-brief.json");
44885
44907
  const tmp = `${file}.tmp.${randomUUID13().slice(0, 8)}`;
44886
44908
  writeFileSync21(tmp, JSON.stringify(brief, null, 2), { encoding: "utf8", mode: 384 });
44887
44909
  renameSync8(tmp, file);
@@ -44890,7 +44912,7 @@ function writeCachedSessionBrief(stateDir, brief) {
44890
44912
  }
44891
44913
  function estimateSessionCost(stateDir) {
44892
44914
  try {
44893
- const telemetryFile = join35(stateDir, "telemetry.jsonl");
44915
+ const telemetryFile = join36(stateDir, "telemetry.jsonl");
44894
44916
  if (!existsSync26(telemetryFile)) return void 0;
44895
44917
  const records = readRoutingRecords(telemetryFile);
44896
44918
  if (records.length === 0) return void 0;
@@ -45059,11 +45081,11 @@ function formatSessionBriefText(brief) {
45059
45081
  }
45060
45082
 
45061
45083
  // plugins/kxm/src/kxm-install-kind.ts
45062
- import { existsSync as existsSync27, readFileSync as readFileSync27 } from "node:fs";
45063
- 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";
45064
45086
  function packageIsKxm(root) {
45065
45087
  try {
45066
- const pkg = JSON.parse(readFileSync27(join36(root, "package.json"), "utf8"));
45088
+ const pkg = JSON.parse(readFileSync28(join37(root, "package.json"), "utf8"));
45067
45089
  return pkg.name === "@kontextmind/kxm";
45068
45090
  } catch {
45069
45091
  return false;
@@ -45112,12 +45134,12 @@ function report(kind, root) {
45112
45134
  return { kind, root, instruction: installKindInstruction(kind, root) };
45113
45135
  }
45114
45136
  function classifyInstallRoot(probe) {
45115
- const piGitRoot = join36(probe.homeDir, ".pi", "agent", "git");
45137
+ const piGitRoot = join37(probe.homeDir, ".pi", "agent", "git");
45116
45138
  if (isUnder(probe.repoRoot, piGitRoot, probe.platform)) return report("pi-git", probe.repoRoot);
45117
- const claudeHome = probe.env.CLAUDE_CONFIG_DIR?.trim() || join36(probe.homeDir, ".claude");
45118
- const pluginsRoot = join36(claudeHome, "plugins");
45139
+ const claudeHome = probe.env.CLAUDE_CONFIG_DIR?.trim() || join37(probe.homeDir, ".claude");
45140
+ const pluginsRoot = join37(claudeHome, "plugins");
45119
45141
  if (isUnder(probe.moduleDir, pluginsRoot, probe.platform)) return report("claude-marketplace", probe.moduleDir);
45120
- const hasGit = existsSync27(join36(probe.repoRoot, ".git"));
45142
+ const hasGit = existsSync27(join37(probe.repoRoot, ".git"));
45121
45143
  if (hasGit && packageIsKxm(probe.repoRoot)) return report("source", probe.repoRoot);
45122
45144
  if (isNpmPackageLayout(probe.repoRoot, probe.platform) && packageIsKxm(probe.repoRoot) && !hasGit) {
45123
45145
  return report("npm-package", probe.repoRoot);
@@ -45138,14 +45160,14 @@ function resolveInstallKind(probe, npmGlobalRoot) {
45138
45160
 
45139
45161
  // plugins/kxm/src/kxm-update-config.ts
45140
45162
  var import_yaml16 = __toESM(require_dist(), 1);
45141
- import { existsSync as existsSync28, readFileSync as readFileSync28 } from "node:fs";
45142
- 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";
45143
45165
  function loadKxmUpdateConfig(env = process.env) {
45144
- const path4 = join37(vnextUserStateRoot({ env }), "update.yaml");
45166
+ const path4 = join38(vnextUserStateRoot({ env }), "update.yaml");
45145
45167
  if (!existsSync28(path4)) return { schema: KXM_UPDATE_SCHEMA, auto: false, source: "github" };
45146
45168
  let parsed;
45147
45169
  try {
45148
- parsed = (0, import_yaml16.parse)(readFileSync28(path4, "utf8"));
45170
+ parsed = (0, import_yaml16.parse)(readFileSync29(path4, "utf8"));
45149
45171
  } catch {
45150
45172
  throw new KxmUpdateConfigError("update.yaml is not valid YAML");
45151
45173
  }
@@ -45171,8 +45193,8 @@ function loadKxmUpdateConfig(env = process.env) {
45171
45193
  }
45172
45194
 
45173
45195
  // plugins/kxm/src/session.ts
45174
- import { existsSync as existsSync29, mkdirSync as mkdirSync24, readFileSync as readFileSync29, writeFileSync as writeFileSync22 } from "node:fs";
45175
- 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";
45176
45198
  var SESSION_SCHEMA = "kxm.session.v1";
45177
45199
  var SessionConfigError = class extends Error {
45178
45200
  code = "session_config_invalid";
@@ -45182,12 +45204,12 @@ var SessionConfigError = class extends Error {
45182
45204
  }
45183
45205
  };
45184
45206
  function workflowAssetDirs(assetsDir, workflowId) {
45185
- const root = join38(assetsDir, "workflows", workflowId);
45186
- 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")];
45187
45209
  }
45188
45210
  function sessionAssetDirs(assetsDir, sessionId) {
45189
- const root = join38(assetsDir, "sessions", sessionId);
45190
- return [root, join38(root, "inputs"), join38(root, "outputs")];
45211
+ const root = join39(assetsDir, "sessions", sessionId);
45212
+ return [root, join39(root, "inputs"), join39(root, "outputs")];
45191
45213
  }
45192
45214
  function rosterNames(configDir) {
45193
45215
  return [...loadRosterMap(configDir).values()].map((row) => String(row.name));
@@ -45237,7 +45259,7 @@ function workerFromRosterRow(name, row, project) {
45237
45259
  function loadRosterMap(configDir) {
45238
45260
  const byName = /* @__PURE__ */ new Map();
45239
45261
  for (const [file, key] of [["agents.json", "agents"], ["gates.json", "gates"]]) {
45240
- const path4 = join38(configDir, file);
45262
+ const path4 = join39(configDir, file);
45241
45263
  for (const row of loadRoster(path4, key)) {
45242
45264
  const name = String(row.name).trim();
45243
45265
  const lowered = name.toLowerCase();
@@ -45254,7 +45276,7 @@ function loadRoster(path4, key) {
45254
45276
  if (!existsSync29(path4)) return [];
45255
45277
  let parsed;
45256
45278
  try {
45257
- parsed = JSON.parse(readFileSync29(path4, "utf8"));
45279
+ parsed = JSON.parse(readFileSync30(path4, "utf8"));
45258
45280
  } catch (error) {
45259
45281
  throw new SessionConfigError(
45260
45282
  `${key} roster at ${path4} is not valid JSON: ${error instanceof Error ? error.message : String(error)}`
@@ -45279,7 +45301,7 @@ function loadRoster(path4, key) {
45279
45301
  });
45280
45302
  }
45281
45303
  function createSession(input) {
45282
- 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);
45283
45305
  return {
45284
45306
  schema: SESSION_SCHEMA,
45285
45307
  id: input.id,
@@ -45292,8 +45314,8 @@ function createSession(input) {
45292
45314
  };
45293
45315
  }
45294
45316
  function writeSession(assetsDir, session, dryRun = false) {
45295
- const dir = join38(assetsDir, "sessions", session.id);
45296
- const path4 = join38(dir, "session.json");
45317
+ const dir = join39(assetsDir, "sessions", session.id);
45318
+ const path4 = join39(dir, "session.json");
45297
45319
  if (!dryRun) {
45298
45320
  mkdirSync24(dir, { recursive: true });
45299
45321
  writeFileSync22(path4, `${JSON.stringify(session, null, 2)}
@@ -45331,9 +45353,9 @@ function installProbeFrom(runtime) {
45331
45353
  };
45332
45354
  }
45333
45355
  function warnIgnoredProjectUpdateYaml(runtime) {
45334
- const projectFile = join39(runtime.dirs.workspace, "update.yaml");
45356
+ const projectFile = join40(runtime.dirs.workspace, "update.yaml");
45335
45357
  if (!existsSync30(projectFile)) return;
45336
- const userFile = join39(vnextUserStateRoot({ env: runtime.env }), "update.yaml");
45358
+ const userFile = join40(vnextUserStateRoot({ env: runtime.env }), "update.yaml");
45337
45359
  runtime.io.stderr(`kxm: ignoring .kxm/update.yaml in ${runtime.dirs.workdir}; update settings are read only from ${userFile}
45338
45360
  `);
45339
45361
  }
@@ -45359,7 +45381,7 @@ async function cmdDash(runtime, options = {}) {
45359
45381
  return 2;
45360
45382
  }
45361
45383
  const screen = requested;
45362
- 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"));
45363
45385
  if (runtime.dryRun) {
45364
45386
  print(runtime.io, runtime.json, {
45365
45387
  ok: true,
@@ -45375,7 +45397,7 @@ async function cmdDash(runtime, options = {}) {
45375
45397
  runtime.io.stderr("kxm dash does not support --json; use kxm hub view\n");
45376
45398
  return 2;
45377
45399
  }
45378
- const project = runtime.env.KXM_PROJECT?.trim() || basename7(runtime.dirs.workdir) || "project";
45400
+ const project = defaultProjectName(runtime.dirs.workdir, runtime.env) || "project";
45379
45401
  const authToken = runtime.env.KXM_AUTH_TOKEN?.trim();
45380
45402
  return await runMeshTui({
45381
45403
  serverUrl: runtime.serverUrl,
@@ -45405,7 +45427,7 @@ async function cmdHub(runtime) {
45405
45427
  config = loadKxmUpdateConfig(runtime.env);
45406
45428
  } catch (error) {
45407
45429
  if (error instanceof KxmUpdateConfigError) {
45408
- const yamlPath = join39(vnextUserStateRoot({ env: runtime.env }), "update.yaml");
45430
+ const yamlPath = join40(vnextUserStateRoot({ env: runtime.env }), "update.yaml");
45409
45431
  runtime.io.stderr(`kxm: ${error.message}; update check skipped; fix or remove ${yamlPath}
45410
45432
  `);
45411
45433
  } else {
@@ -45556,7 +45578,7 @@ async function cmdStop(runtime, waitMsFlag) {
45556
45578
  const orphans = [];
45557
45579
  for (const file of pids) {
45558
45580
  try {
45559
- const record = JSON.parse(readFileSync30(join39(runtime.dirs.state, file), "utf8"));
45581
+ const record = JSON.parse(readFileSync31(join40(runtime.dirs.state, file), "utf8"));
45560
45582
  const expectedControl = file === "hub.pid" ? "hub.stop" : file.startsWith("worker-") ? `${file.slice(0, -4)}.stop` : void 0;
45561
45583
  const expectedRole = file === "hub.pid" ? "hub" : file.startsWith("worker-") ? "worker" : void 0;
45562
45584
  if (record.version !== 1 || !Number.isInteger(record.pid) || record.pid <= 0 || !record.startedAt || !expectedControl || record.controlFile !== expectedControl || record.role !== expectedRole) {
@@ -45576,7 +45598,7 @@ async function cmdStop(runtime, waitMsFlag) {
45576
45598
  ignored.push(file);
45577
45599
  continue;
45578
45600
  }
45579
- 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() })}
45580
45602
  `, { encoding: "utf8", mode: 384 });
45581
45603
  requested.push(file);
45582
45604
  records.set(file, { pid: record.pid, startedAt: record.startedAt, ...record.generation ? { generation: record.generation } : {} });
@@ -45594,7 +45616,7 @@ async function cmdStop(runtime, waitMsFlag) {
45594
45616
  while (Date.now() <= deadline && stopped.size < requested.length) {
45595
45617
  for (const [file, record] of records) {
45596
45618
  try {
45597
- const current = JSON.parse(readFileSync30(join39(runtime.dirs.state, file), "utf8"));
45619
+ const current = JSON.parse(readFileSync31(join40(runtime.dirs.state, file), "utf8"));
45598
45620
  if (current.pid !== record.pid || current.startedAt !== record.startedAt || current.generation !== record.generation || !processExists(record.pid)) stopped.add(file);
45599
45621
  } catch {
45600
45622
  stopped.add(file);
@@ -45607,7 +45629,7 @@ async function cmdStop(runtime, waitMsFlag) {
45607
45629
  for (const file of orphans) {
45608
45630
  while (Date.now() <= deadlineOrphans) {
45609
45631
  try {
45610
- const current = JSON.parse(readFileSync30(join39(runtime.dirs.state, file), "utf8"));
45632
+ const current = JSON.parse(readFileSync31(join40(runtime.dirs.state, file), "utf8"));
45611
45633
  if (!Number.isInteger(current.serverPid) || !processExists(current.serverPid)) break;
45612
45634
  } catch {
45613
45635
  break;
@@ -45615,14 +45637,14 @@ async function cmdStop(runtime, waitMsFlag) {
45615
45637
  await (runtime.io.sleep ?? ((ms) => new Promise((resolveSleep) => setTimeout(resolveSleep, ms))))(100);
45616
45638
  }
45617
45639
  try {
45618
- const current = JSON.parse(readFileSync30(join39(runtime.dirs.state, file), "utf8"));
45640
+ const current = JSON.parse(readFileSync31(join40(runtime.dirs.state, file), "utf8"));
45619
45641
  if (Number.isInteger(current.serverPid) && processExists(current.serverPid)) {
45620
45642
  try {
45621
45643
  process.kill(current.serverPid, "SIGKILL");
45622
45644
  } catch {
45623
45645
  }
45624
45646
  }
45625
- rmSync10(join39(runtime.dirs.state, file), { force: true });
45647
+ rmSync10(join40(runtime.dirs.state, file), { force: true });
45626
45648
  } catch {
45627
45649
  }
45628
45650
  stopped.add(file);
@@ -45637,7 +45659,7 @@ async function cmdSessionStatus(runtime) {
45637
45659
  const claims = [];
45638
45660
  for (const file of names3.filter((name) => name.endsWith(".pid"))) {
45639
45661
  try {
45640
- const record = JSON.parse(readFileSync30(join39(stateDir, file), "utf8"));
45662
+ const record = JSON.parse(readFileSync31(join40(stateDir, file), "utf8"));
45641
45663
  claims.push({
45642
45664
  file,
45643
45665
  role: record.role,
@@ -45652,7 +45674,7 @@ async function cmdSessionStatus(runtime) {
45652
45674
  const recoveries = [];
45653
45675
  for (const file of names3.filter((name) => name.startsWith("worker-recovery-") && name.endsWith(".json"))) {
45654
45676
  try {
45655
- const envelope = JSON.parse(readFileSync30(join39(stateDir, file), "utf8"));
45677
+ const envelope = JSON.parse(readFileSync31(join40(stateDir, file), "utf8"));
45656
45678
  recoveries.push({
45657
45679
  file,
45658
45680
  reason: envelope.reason,
@@ -45757,7 +45779,7 @@ async function cmdSessionBrief(runtime, options = {}) {
45757
45779
  print(runtime.io, runtime.json, { ok: true, command: "session brief", sessionToken }, sessionToken);
45758
45780
  return 0;
45759
45781
  }
45760
- 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"));
45761
45783
  const env = {
45762
45784
  ...runtime.env,
45763
45785
  KXM_STATE_DIR: runtime.dirs.state,
@@ -45849,16 +45871,16 @@ async function cmdSessionStart(runtime, options) {
45849
45871
  // plugins/kxm/src/cli/system.ts
45850
45872
  import { spawnSync as spawnSync8 } from "node:child_process";
45851
45873
  import { createHash as createHash16 } from "node:crypto";
45852
- 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";
45853
45875
  import { tmpdir as tmpdir2 } from "node:os";
45854
- import { join as join45, resolve as resolve29 } from "node:path";
45876
+ import { join as join46, resolve as resolve29 } from "node:path";
45855
45877
  import { createInterface as createInterface3 } from "node:readline";
45856
45878
  import { fileURLToPath as fileURLToPath7 } from "node:url";
45857
45879
 
45858
45880
  // plugins/kxm/src/improve.ts
45859
45881
  import { createHash as createHash15 } from "node:crypto";
45860
45882
  import { existsSync as existsSync31, mkdirSync as mkdirSync26, writeFileSync as writeFileSync24 } from "node:fs";
45861
- 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";
45862
45884
  var CANDIDATE_SCHEMA = "kxm.candidate.v1";
45863
45885
  var IMPROVEMENT_REPORT_SCHEMA = "kxm.improvement-report.v2";
45864
45886
  function classifyCandidateKind(stepId, agentRole) {
@@ -46030,7 +46052,7 @@ function groupRoutingRecords(records, options = {}) {
46030
46052
  }
46031
46053
  function buildImprovementReport(records, options = {}) {
46032
46054
  const projectRoot = options.projectRoot ? resolve26(options.projectRoot) : process.cwd();
46033
- const candidatesDir = options.candidatesDir ? resolve26(options.candidatesDir) : join40(projectRoot, ".kxm", "candidates");
46055
+ const candidatesDir = options.candidatesDir ? resolve26(options.candidatesDir) : join41(projectRoot, ".kxm", "candidates");
46034
46056
  const groups = groupRoutingRecords(records, options);
46035
46057
  const candidates = [];
46036
46058
  for (const group of groups) {
@@ -46042,7 +46064,7 @@ function buildImprovementReport(records, options = {}) {
46042
46064
  group.workflowHash
46043
46065
  );
46044
46066
  const diffFileName = `${group.candidateId}.diff`;
46045
- const diffFilePath = join40(candidatesDir, diffFileName);
46067
+ const diffFilePath = join41(candidatesDir, diffFileName);
46046
46068
  const relDiffPath = relative6(projectRoot, diffFilePath).replace(/\\/g, "/");
46047
46069
  const candidate = {
46048
46070
  schema: CANDIDATE_SCHEMA,
@@ -46068,7 +46090,7 @@ function buildImprovementReport(records, options = {}) {
46068
46090
  mkdirSync26(candidatesDir, { recursive: true });
46069
46091
  }
46070
46092
  writeFileSync24(diffFilePath, diff, "utf8");
46071
- const jsonFilePath = join40(candidatesDir, `${group.candidateId}.json`);
46093
+ const jsonFilePath = join41(candidatesDir, `${group.candidateId}.json`);
46072
46094
  writeFileSync24(jsonFilePath, JSON.stringify(candidate, null, 2) + "\n", "utf8");
46073
46095
  }
46074
46096
  candidates.push(candidate);
@@ -46084,7 +46106,7 @@ function buildImprovementReport(records, options = {}) {
46084
46106
  }
46085
46107
  function writeImprovementReport(improvementsDir, report2, dryRun = false) {
46086
46108
  const stamp = report2.createdAt.replace(/[:.]/g, "-");
46087
- const path4 = join40(improvementsDir, `${stamp}.json`);
46109
+ const path4 = join41(improvementsDir, `${stamp}.json`);
46088
46110
  if (!dryRun) {
46089
46111
  mkdirSync26(improvementsDir, { recursive: true });
46090
46112
  writeFileSync24(path4, `${JSON.stringify(report2, null, 2)}
@@ -46127,8 +46149,8 @@ function formatImprovementReport(report2) {
46127
46149
 
46128
46150
  // plugins/kxm/src/modes.ts
46129
46151
  var import_yaml17 = __toESM(require_dist(), 1);
46130
- import { existsSync as existsSync32, readFileSync as readFileSync32 } from "node:fs";
46131
- 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";
46132
46154
  var DEFAULT_MODES_CONFIG = Object.freeze({
46133
46155
  schema: "kxm.modes.v1",
46134
46156
  majorModes: {
@@ -46191,12 +46213,12 @@ function loadModesConfig(projectRoot) {
46191
46213
  if (!projectRoot) {
46192
46214
  return DEFAULT_MODES_CONFIG;
46193
46215
  }
46194
- const modesPath = join41(projectRoot, ".kxm", "modes.yaml");
46216
+ const modesPath = join42(projectRoot, ".kxm", "modes.yaml");
46195
46217
  if (!existsSync32(modesPath)) {
46196
46218
  return DEFAULT_MODES_CONFIG;
46197
46219
  }
46198
46220
  try {
46199
- const raw = readFileSync32(modesPath, "utf8");
46221
+ const raw = readFileSync33(modesPath, "utf8");
46200
46222
  const parsed = (0, import_yaml17.parse)(raw);
46201
46223
  if (parsed && parsed.schema === "kxm.modes.v1" && parsed.majorModes) {
46202
46224
  return {
@@ -46282,11 +46304,11 @@ function calculatePromptFootprint(resolved, projectRoot = process.cwd(), catalog
46282
46304
  estimatedTokens: estimateTokens(baseSystemPromptChars)
46283
46305
  });
46284
46306
  for (const relPath of resolved.contextFiles) {
46285
- const fullPath = join41(projectRoot, relPath);
46307
+ const fullPath = join42(projectRoot, relPath);
46286
46308
  let chars = 0;
46287
46309
  if (existsSync32(fullPath)) {
46288
46310
  try {
46289
- chars = readFileSync32(fullPath, "utf8").length;
46311
+ chars = readFileSync33(fullPath, "utf8").length;
46290
46312
  } catch {
46291
46313
  chars = 0;
46292
46314
  }
@@ -46418,9 +46440,9 @@ ${divider}
46418
46440
 
46419
46441
  // plugins/kxm/src/ssh-remote.ts
46420
46442
  import { spawnSync as spawnSync7 } from "node:child_process";
46421
- 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";
46422
46444
  import { homedir as homedir7 } from "node:os";
46423
- import { join as join42, resolve as resolve27 } from "node:path";
46445
+ import { join as join43, resolve as resolve27 } from "node:path";
46424
46446
  var MAX_SSH_OUTPUT_BYTES = 50 * 1024;
46425
46447
  var MAX_SSH_OUTPUT_LINES = 2e3;
46426
46448
  var DEFAULT_SOCKET_DIR = ".kxm/run/ssh-sockets";
@@ -46446,12 +46468,12 @@ function truncateSshOutput(raw) {
46446
46468
  return { text, truncated };
46447
46469
  }
46448
46470
  function parseSshConfig(configPath) {
46449
- const targetPath = configPath ?? join42(homedir7(), ".ssh", "config");
46471
+ const targetPath = configPath ?? join43(homedir7(), ".ssh", "config");
46450
46472
  if (!existsSync33(targetPath)) {
46451
46473
  return [];
46452
46474
  }
46453
46475
  try {
46454
- const content = readFileSync33(targetPath, "utf-8");
46476
+ const content = readFileSync34(targetPath, "utf-8");
46455
46477
  const lines = content.split("\n");
46456
46478
  const hosts = [];
46457
46479
  let currentHosts = [];
@@ -46536,7 +46558,7 @@ function ensureSocketDir(socketDir = DEFAULT_SOCKET_DIR) {
46536
46558
  }
46537
46559
  function buildSshArgs(options) {
46538
46560
  const socketDir = ensureSocketDir(options.socketDir ?? DEFAULT_SOCKET_DIR);
46539
- const controlPath = join42(socketDir, "%C");
46561
+ const controlPath = join43(socketDir, "%C");
46540
46562
  const persist = options.controlPersist ?? DEFAULT_CONTROL_PERSIST;
46541
46563
  const args = [
46542
46564
  "-o",
@@ -46561,7 +46583,7 @@ function buildSshArgs(options) {
46561
46583
  }
46562
46584
  function checkControlSocket(host, socketDir = DEFAULT_SOCKET_DIR, execFn = spawnSync7) {
46563
46585
  const resolvedDir = ensureSocketDir(socketDir);
46564
- const controlPath = join42(resolvedDir, "%C");
46586
+ const controlPath = join43(resolvedDir, "%C");
46565
46587
  try {
46566
46588
  const result = execFn("ssh", ["-O", "check", "-o", `ControlPath=${controlPath}`, host], {
46567
46589
  encoding: "utf-8"
@@ -46573,7 +46595,7 @@ function checkControlSocket(host, socketDir = DEFAULT_SOCKET_DIR, execFn = spawn
46573
46595
  }
46574
46596
  function closeControlSocket(host, socketDir = DEFAULT_SOCKET_DIR, execFn = spawnSync7) {
46575
46597
  const resolvedDir = ensureSocketDir(socketDir);
46576
- const controlPath = join42(resolvedDir, "%C");
46598
+ const controlPath = join43(resolvedDir, "%C");
46577
46599
  try {
46578
46600
  const result = execFn("ssh", ["-O", "stop", "-o", `ControlPath=${controlPath}`, host], {
46579
46601
  encoding: "utf-8"
@@ -47019,9 +47041,9 @@ complete -c kxm -n "__fish_seen_subcommand_from goal" -a "create list get"
47019
47041
  }
47020
47042
 
47021
47043
  // plugins/kxm/src/completion-install.ts
47022
- 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";
47023
47045
  import { homedir as homedir8 } from "node:os";
47024
- 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";
47025
47047
  var COMPLETION_MARKER = "# kxm completion";
47026
47048
  var PATH_MARKER = "# kxm path";
47027
47049
  function detectShell(env = process.env, platform = process.platform) {
@@ -47043,25 +47065,25 @@ function completionScriptPath(shell, options = {}) {
47043
47065
  const env = options.env ?? process.env;
47044
47066
  const explicit = options.configDir ?? env.KXM_USER_CONFIG_DIR?.trim();
47045
47067
  const base = explicit && explicit.length > 0 ? resolve28(explicit) : resolve28(effectiveHome(options), ".config", "kxm");
47046
- return join43(base, "completions", `kxm.${shell}`);
47068
+ return join44(base, "completions", `kxm.${shell}`);
47047
47069
  }
47048
47070
  function bashRcCandidate(options) {
47049
47071
  const home = effectiveHome(options);
47050
- const candidates = [join43(home, ".bashrc"), join43(home, ".bash_profile")];
47072
+ const candidates = [join44(home, ".bashrc"), join44(home, ".bash_profile")];
47051
47073
  const existing = candidates.find((candidate) => existsSync34(candidate));
47052
47074
  return existing ?? candidates[0];
47053
47075
  }
47054
47076
  function zshRcCandidate(options) {
47055
47077
  const env = options.env ?? process.env;
47056
47078
  const home = effectiveHome(options);
47057
- if (env.ZDOTDIR?.trim()) return join43(resolve28(env.ZDOTDIR.trim()), ".zshrc");
47058
- return join43(home, ".zshrc");
47079
+ if (env.ZDOTDIR?.trim()) return join44(resolve28(env.ZDOTDIR.trim()), ".zshrc");
47080
+ return join44(home, ".zshrc");
47059
47081
  }
47060
47082
  function fishCompletionTarget(shell, options) {
47061
47083
  const env = options.env ?? process.env;
47062
47084
  const home = effectiveHome(options);
47063
- if (env.XDG_CONFIG_HOME?.trim()) return join43(resolve28(env.XDG_CONFIG_HOME.trim()), "fish", "completions", "kxm.fish");
47064
- 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");
47065
47087
  }
47066
47088
  function completionRcTarget(shell, options = {}) {
47067
47089
  if (shell === "fish") {
@@ -47094,12 +47116,12 @@ function installShellCompletion(shellInput, options = {}) {
47094
47116
  const { rcFile } = completionRcTarget(shell, options);
47095
47117
  const script = generateShellCompletion(shell);
47096
47118
  const existingScript = existsSync34(scriptPath);
47097
- const existingScriptMatches = existingScript && readFileSync34(scriptPath, "utf8") === script;
47119
+ const existingScriptMatches = existingScript && readFileSync35(scriptPath, "utf8") === script;
47098
47120
  let rcModified = false;
47099
47121
  let alreadyInstalled = false;
47100
47122
  if (shell === "fish") {
47101
47123
  const fishTarget = fishCompletionTarget(shell, options);
47102
- const fishInstalled = existsSync34(fishTarget) && readFileSync34(fishTarget, "utf8") === script;
47124
+ const fishInstalled = existsSync34(fishTarget) && readFileSync35(fishTarget, "utf8") === script;
47103
47125
  alreadyInstalled = fishInstalled;
47104
47126
  if (!options.dryRun && (!fishInstalled || options.overwrite)) {
47105
47127
  mkdirSync28(resolve28(fishTarget, ".."), { recursive: true });
@@ -47116,7 +47138,7 @@ function installShellCompletion(shellInput, options = {}) {
47116
47138
  }
47117
47139
  if (rcFile) {
47118
47140
  const line = sourceLine(shell, scriptPath);
47119
- const rcContent = existsSync34(rcFile) ? readFileSync34(rcFile, "utf8") : "";
47141
+ const rcContent = existsSync34(rcFile) ? readFileSync35(rcFile, "utf8") : "";
47120
47142
  alreadyInstalled = rcContent.includes(line) || rcContent.includes(`${COMPLETION_MARKER}`);
47121
47143
  }
47122
47144
  if (!options.dryRun) {
@@ -47132,7 +47154,7 @@ ${marker}
47132
47154
  ${line}
47133
47155
  `;
47134
47156
  mkdirSync28(resolve28(rcFile, ".."), { recursive: true });
47135
- writeFileSync25(rcFile, (existsSync34(rcFile) ? readFileSync34(rcFile, "utf8") : "") + stanza, { encoding: "utf8" });
47157
+ writeFileSync25(rcFile, (existsSync34(rcFile) ? readFileSync35(rcFile, "utf8") : "") + stanza, { encoding: "utf8" });
47136
47158
  rcModified = true;
47137
47159
  }
47138
47160
  }
@@ -47149,7 +47171,7 @@ function kxmBinDir(env = process.env) {
47149
47171
  const argv1 = env.KXM_ENTRY ?? process.argv[1];
47150
47172
  if (argv1 && isAbsolute8(argv1)) {
47151
47173
  const dir = dirname21(argv1);
47152
- 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;
47153
47175
  }
47154
47176
  const pathEnv = env.PATH ?? "";
47155
47177
  for (const part of pathEnv.split(delimiter)) {
@@ -47173,7 +47195,7 @@ function installPathEntry(shellInput, options = {}) {
47173
47195
  }
47174
47196
  const { rcFile } = completionRcTarget(shell, options);
47175
47197
  const line = pathLine(binDir);
47176
- const rcContent = existsSync34(rcFile ?? "") ? readFileSync34(rcFile, "utf8") : "";
47198
+ const rcContent = existsSync34(rcFile ?? "") ? readFileSync35(rcFile, "utf8") : "";
47177
47199
  const alreadyInstalled = rcContent.includes(binDir) || (options.env?.PATH ?? process.env.PATH ?? "").split(delimiter).includes(binDir);
47178
47200
  if (!options.dryRun && rcFile && !alreadyInstalled) {
47179
47201
  mkdirSync28(dirname21(rcFile), { recursive: true });
@@ -47188,7 +47210,7 @@ ${line}
47188
47210
  // plugins/kxm/src/init-guide-setup.ts
47189
47211
  var import_yaml18 = __toESM(require_dist(), 1);
47190
47212
  import { existsSync as existsSync35, mkdirSync as mkdirSync29, writeFileSync as writeFileSync26 } from "node:fs";
47191
- import { dirname as dirname22, join as join44 } from "node:path";
47213
+ import { dirname as dirname22, join as join45 } from "node:path";
47192
47214
  var NATIVE_VENDOR_HARNESS = Object.freeze({
47193
47215
  anthropic: "claude",
47194
47216
  openai: "codex",
@@ -47587,13 +47609,13 @@ function renderGuideSetupFiles(projectRoot, plan) {
47587
47609
  const stage = roleStages.get(role);
47588
47610
  if (!stage) continue;
47589
47611
  files.push({
47590
- path: join44(projectRoot, ".kxm", "agents", `${role}.yaml`),
47612
+ path: join45(projectRoot, ".kxm", "agents", `${role}.yaml`),
47591
47613
  content: (0, import_yaml18.stringify)(agentDocument(role, stage, binding))
47592
47614
  });
47593
47615
  }
47594
47616
  for (const workflow of plan.workflows) {
47595
47617
  files.push({
47596
- path: join44(projectRoot, ".kxm", "workflows", `${workflow.slug}.yaml`),
47618
+ path: join45(projectRoot, ".kxm", "workflows", `${workflow.slug}.yaml`),
47597
47619
  content: (0, import_yaml18.stringify)(workflowDocument(workflow))
47598
47620
  });
47599
47621
  }
@@ -47672,7 +47694,7 @@ function applyKxmPackageUpdate(runtime, notice) {
47672
47694
  detail: `release v${notice.latest} has no sha256 digest for ${name}; refusing to install`
47673
47695
  };
47674
47696
  }
47675
- const releaseDir = mkdtempSync2(join45(tmpdir2(), "kxm-pkg-update-"));
47697
+ const releaseDir = mkdtempSync2(join46(tmpdir2(), "kxm-pkg-update-"));
47676
47698
  try {
47677
47699
  const planned = planKxmPackageUpdate(notice.source, notice.latest, releaseDir, notice.asset);
47678
47700
  if (runtime.dryRun) {
@@ -47681,7 +47703,7 @@ function applyKxmPackageUpdate(runtime, notice) {
47681
47703
  for (const step of planned) {
47682
47704
  if (step.kind === "verify") {
47683
47705
  if (!verifyReleaseAssetDigest(step.path, step.sha256)) {
47684
- 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";
47685
47707
  return {
47686
47708
  ok: false,
47687
47709
  error: "release_digest_mismatch",
@@ -47952,7 +47974,7 @@ async function cmdValidate(runtime, fileFlag) {
47952
47974
  return 1;
47953
47975
  }
47954
47976
  try {
47955
- const raw = file ? readFileSync35(file, "utf8") : inline;
47977
+ const raw = file ? readFileSync36(file, "utf8") : inline;
47956
47978
  const warnings = [];
47957
47979
  const definitions = parseWorkflowDefinitions(raw, runtime.env, (message) => warnings.push(message));
47958
47980
  const secretEnvs = definitions.map((definition) => ({
@@ -47998,13 +48020,13 @@ async function cmdArtifactsExist(runtime, pathFlag) {
47998
48020
  async function cmdImprove(runtime, options = {}) {
47999
48021
  const file = options.file ? resolve29(runtime.cwd, options.file) : telemetryPath(runtime.dirs.logs);
48000
48022
  const routingRecords = existsSync36(file) ? readRoutingRecords(file).map((entry) => entry.routing) : [];
48001
- 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");
48002
48024
  const report2 = buildImprovementReport(routingRecords, {
48003
48025
  candidatesDir,
48004
48026
  projectRoot: runtime.cwd,
48005
48027
  dryRun: runtime.dryRun
48006
48028
  });
48007
- const reportDir = join45(runtime.dirs.assets, "improvements");
48029
+ const reportDir = join46(runtime.dirs.assets, "improvements");
48008
48030
  const reportPath = writeImprovementReport(reportDir, report2, runtime.dryRun);
48009
48031
  const text = formatImprovementReport(report2);
48010
48032
  print(runtime.io, runtime.json, {
@@ -48138,7 +48160,7 @@ async function maybeOfferCompletionInstall(runtime) {
48138
48160
  const { rcFile } = completionRcTarget(shell, { env: runtime.env });
48139
48161
  if (rcFile && existsSync36(rcFile)) {
48140
48162
  try {
48141
- if (readFileSync35(rcFile, "utf8").includes(scriptPath)) return;
48163
+ if (readFileSync36(rcFile, "utf8").includes(scriptPath)) return;
48142
48164
  } catch {
48143
48165
  }
48144
48166
  }
@@ -48270,7 +48292,7 @@ async function cmdRoutingReport(runtime, options) {
48270
48292
  let catalog;
48271
48293
  if (includeEquivalentListCost) {
48272
48294
  try {
48273
- 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");
48274
48296
  catalog = loadPriceCatalog(pricesPath);
48275
48297
  } catch {
48276
48298
  }
@@ -48373,7 +48395,7 @@ function addGlobalOptions(command) {
48373
48395
  }
48374
48396
  async function ensureCliClient(runtime) {
48375
48397
  const serverUrl = runtime.serverUrl;
48376
- const project = runtime.env.KXM_PROJECT?.trim() || basename10(runtime.dirs.workspace || runtime.cwd);
48398
+ const project = defaultProjectName(runtime.cwd, runtime.env);
48377
48399
  const name = runtime.env.KXM_AGENT_NAME?.trim() || `cli-${process.pid}`;
48378
48400
  const purpose = runtime.env.KXM_AGENT_PURPOSE?.trim() || "CLI agent client";
48379
48401
  const authToken = runtime.env.KXM_AUTH_TOKEN?.trim();