@kontextmind/kxm 0.7.163 → 0.7.165

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (38) hide show
  1. package/.claude-plugin/marketplace.json +1 -1
  2. package/CHANGELOG.md +22 -0
  3. package/README.md +2 -0
  4. package/docs/README.md +1 -0
  5. package/docs/architecture/inventory.md +4 -3
  6. package/docs/contributing/harness-routing-internals.md +28 -27
  7. package/docs/glossary.md +3 -3
  8. package/docs/operations/troubleshooting.md +3 -0
  9. package/docs/operations.md +154 -0
  10. package/docs/reference/cli-reference.md +4 -3
  11. package/docs/reference/configuration.md +11 -1
  12. package/docs/reference/harness-routing.md +17 -15
  13. package/package.json +1 -1
  14. package/plugins/kxm/.claude-plugin/plugin.json +2 -2
  15. package/plugins/kxm/README.md +2 -2
  16. package/plugins/kxm/dist/claude-hook.js +120 -16
  17. package/plugins/kxm/dist/cli.js +14929 -14542
  18. package/plugins/kxm/dist/extension.js +299 -122
  19. package/plugins/kxm/dist/mcp-server.js +7690 -106
  20. package/plugins/kxm/dist/runtime-supervisor.js +151 -4
  21. package/plugins/kxm/dist/runtime.js +158 -11
  22. package/plugins/kxm/package.json +1 -1
  23. package/plugins/kxm/skills/kxm-hub-ops/SKILL.md +5 -1
  24. package/plugins/kxm/src/cli/context-skills.ts +64 -10
  25. package/plugins/kxm/src/cli/hub.ts +128 -17
  26. package/plugins/kxm/src/cli/project.ts +7 -3
  27. package/plugins/kxm/src/cli/types.ts +6 -0
  28. package/plugins/kxm/src/cli/workflows.ts +12 -1
  29. package/plugins/kxm/src/cli.ts +23 -5
  30. package/plugins/kxm/src/extension.ts +7 -3
  31. package/plugins/kxm/src/hub-autostart.ts +3 -0
  32. package/plugins/kxm/src/hub-binding.ts +182 -2
  33. package/plugins/kxm/src/hub-env.ts +71 -0
  34. package/plugins/kxm/src/mcp-server.ts +3 -2
  35. package/plugins/kxm/src/project-name.ts +34 -7
  36. package/plugins/kxm/src/runtime-supervisor.ts +9 -3
  37. package/plugins/kxm/src/tenant-status.ts +9 -2
  38. package/scripts/build-runtime.mjs +5 -0
@@ -10319,7 +10319,7 @@ var require_compile = __commonJS({
10319
10319
  const schOrFunc = root.refs[ref];
10320
10320
  if (schOrFunc)
10321
10321
  return schOrFunc;
10322
- let _sch = resolve8.call(this, root, ref);
10322
+ let _sch = resolve9.call(this, root, ref);
10323
10323
  if (_sch === void 0) {
10324
10324
  const schema = (_a3 = root.localRefs) === null || _a3 === void 0 ? void 0 : _a3[ref];
10325
10325
  const { schemaId } = this.opts;
@@ -10346,7 +10346,7 @@ var require_compile = __commonJS({
10346
10346
  function sameSchemaEnv(s1, s2) {
10347
10347
  return s1.schema === s2.schema && s1.root === s2.root && s1.baseId === s2.baseId;
10348
10348
  }
10349
- function resolve8(root, ref) {
10349
+ function resolve9(root, ref) {
10350
10350
  let sch;
10351
10351
  while (typeof (sch = this.refs[ref]) == "string")
10352
10352
  ref = sch;
@@ -11171,7 +11171,7 @@ var require_fast_uri = __commonJS({
11171
11171
  }
11172
11172
  return uri;
11173
11173
  }
11174
- function resolve8(baseURI, relativeURI, options) {
11174
+ function resolve9(baseURI, relativeURI, options) {
11175
11175
  const schemelessOptions = options ? Object.assign({ scheme: "null" }, options) : { scheme: "null" };
11176
11176
  const {
11177
11177
  parsed: baseParsed,
@@ -11533,7 +11533,7 @@ var require_fast_uri = __commonJS({
11533
11533
  var fastUri = {
11534
11534
  SCHEMES,
11535
11535
  normalize,
11536
- resolve: resolve8,
11536
+ resolve: resolve9,
11537
11537
  resolveComponent,
11538
11538
  equal,
11539
11539
  serialize,
@@ -14523,9 +14523,9 @@ var require_dist2 = __commonJS({
14523
14523
  });
14524
14524
 
14525
14525
  // plugins/kxm/src/extension.ts
14526
- import { spawnSync as spawnSync2 } from "node:child_process";
14527
- import { existsSync as existsSync12, mkdirSync as mkdirSync9, readFileSync as readFileSync14, renameSync as renameSync5, rmSync as rmSync4, writeFileSync as writeFileSync7 } from "node:fs";
14528
- import { dirname as dirname7, join as join15 } from "node:path";
14526
+ import { spawnSync as spawnSync3 } from "node:child_process";
14527
+ import { existsSync as existsSync13, mkdirSync as mkdirSync9, readFileSync as readFileSync14, renameSync as renameSync5, rmSync as rmSync4, writeFileSync as writeFileSync7 } from "node:fs";
14528
+ import { dirname as dirname8, join as join15 } from "node:path";
14529
14529
 
14530
14530
  // plugins/kxm/src/commands.ts
14531
14531
  import { chmodSync, existsSync, mkdirSync, readFileSync, unlinkSync, writeFileSync } from "node:fs";
@@ -14967,7 +14967,7 @@ var HubClient = class {
14967
14967
  if (signal?.aborted) throw new MeshWaitError("aborted", messageId);
14968
14968
  const message = await this.getMessage(messageId);
14969
14969
  if (["replied", "cancelled", "expired", "error"].includes(message.status)) return message;
14970
- await new Promise((resolve8, reject) => {
14970
+ await new Promise((resolve9, reject) => {
14971
14971
  const onAbort = () => {
14972
14972
  signal?.removeEventListener("abort", onAbort);
14973
14973
  clearTimeout(timer);
@@ -14975,7 +14975,7 @@ var HubClient = class {
14975
14975
  };
14976
14976
  const timer = setTimeout(() => {
14977
14977
  signal?.removeEventListener("abort", onAbort);
14978
- resolve8();
14978
+ resolve9();
14979
14979
  }, Math.min(500, Math.max(1, deadline - Date.now())));
14980
14980
  signal?.addEventListener("abort", onAbort, { once: true });
14981
14981
  if (signal?.aborted) onAbort();
@@ -15030,7 +15030,7 @@ var HubClient = class {
15030
15030
  } catch (error2) {
15031
15031
  if (this.stopped || error2 instanceof Error && error2.name === "AbortError") return;
15032
15032
  }
15033
- if (!this.stopped) await new Promise((resolve8) => setTimeout(resolve8, this.options.reconnectMs));
15033
+ if (!this.stopped) await new Promise((resolve9) => setTimeout(resolve9, this.options.reconnectMs));
15034
15034
  }
15035
15035
  }
15036
15036
  headers(includeIdentity = true) {
@@ -16145,15 +16145,27 @@ function loadKxmConfig(repoRoot = process.cwd(), options = {}) {
16145
16145
 
16146
16146
  // plugins/kxm/src/hub-autostart.ts
16147
16147
  import { spawn } from "node:child_process";
16148
- import { closeSync, mkdirSync as mkdirSync5, openSync, readFileSync as readFileSync5 } from "node:fs";
16149
- import { join as join6, resolve as resolve5 } from "node:path";
16148
+ import { closeSync, mkdirSync as mkdirSync5, openSync, readFileSync as readFileSync6 } from "node:fs";
16149
+ import { join as join7, resolve as resolve6 } from "node:path";
16150
16150
 
16151
16151
  // plugins/kxm/src/hub-binding.ts
16152
+ import { spawnSync } from "node:child_process";
16152
16153
  import { existsSync as existsSync3, mkdirSync as mkdirSync3, readFileSync as readFileSync3, renameSync, rmSync, writeFileSync as writeFileSync3 } from "node:fs";
16153
16154
  import { homedir as homedir3 } from "node:os";
16154
16155
  import { dirname as dirname3, isAbsolute, join as join3, resolve as resolve3 } from "node:path";
16155
16156
  var HUB_BINDING_SCHEMA = "kxm.hub-binding.v1";
16156
16157
  var HUB_HEALTH_PROBE_MS = 300;
16158
+ var CloudTokenError = class extends Error {
16159
+ code;
16160
+ constructor(code, message) {
16161
+ super(message);
16162
+ this.name = "CloudTokenError";
16163
+ this.code = code;
16164
+ }
16165
+ };
16166
+ var TOKEN_ENV_NAME = /^[A-Za-z_][A-Za-z0-9_]{0,127}$/;
16167
+ var TOKEN_COMMAND_TIMEOUT_MS = 15e3;
16168
+ var TOKEN_COMMAND_MAX_BUFFER = 4096;
16157
16169
  var HubBindingError = class extends Error {
16158
16170
  constructor(message) {
16159
16171
  super(message);
@@ -16191,6 +16203,99 @@ function validateHubUrl(raw) {
16191
16203
  }
16192
16204
  return parsed.href.replace(/\/$/, "");
16193
16205
  }
16206
+ function splitTokenCommand(raw) {
16207
+ if (/[|&;<>$`\n\r]/.test(raw)) {
16208
+ throw new CloudTokenError(
16209
+ "cloud_token_command_invalid",
16210
+ "token command must be a program and arguments, not a shell pipeline"
16211
+ );
16212
+ }
16213
+ const args = [];
16214
+ let current = "";
16215
+ let quote;
16216
+ for (const ch of raw) {
16217
+ if (quote) {
16218
+ if (ch === quote) quote = void 0;
16219
+ else current += ch;
16220
+ continue;
16221
+ }
16222
+ if (ch === "'" || ch === '"') {
16223
+ quote = ch;
16224
+ continue;
16225
+ }
16226
+ if (ch === " " || ch === " ") {
16227
+ if (current.length > 0) {
16228
+ args.push(current);
16229
+ current = "";
16230
+ }
16231
+ continue;
16232
+ }
16233
+ current += ch;
16234
+ }
16235
+ if (quote) {
16236
+ throw new CloudTokenError("cloud_token_command_invalid", "token command has an unclosed quote");
16237
+ }
16238
+ if (current.length > 0) args.push(current);
16239
+ if (args.length === 0) {
16240
+ throw new CloudTokenError("cloud_token_command_invalid", "token command is empty");
16241
+ }
16242
+ return args;
16243
+ }
16244
+ function isCloudTokenEnvName(value) {
16245
+ return TOKEN_ENV_NAME.test(value);
16246
+ }
16247
+ function resolveHubServerUrl(env = process.env) {
16248
+ const fromEnv = env.KXM_SERVER_URL?.trim();
16249
+ if (fromEnv) return fromEnv.replace(/\/$/, "");
16250
+ try {
16251
+ const binding = readHubBinding(env);
16252
+ if (binding?.url) return binding.url;
16253
+ } catch (error2) {
16254
+ if (!(error2 instanceof HubBindingError)) throw error2;
16255
+ }
16256
+ return "http://127.0.0.1:7331";
16257
+ }
16258
+ function resolveCloudHubToken(binding, env = process.env) {
16259
+ if (!binding.cloud) {
16260
+ throw new CloudTokenError("cloud_token_missing", "cloud hub token is missing; the local hub-env token was not used");
16261
+ }
16262
+ if (binding.tokenEnv) {
16263
+ const value = env[binding.tokenEnv]?.trim();
16264
+ if (value) return value;
16265
+ }
16266
+ if (binding.tokenCommand) return runTokenCommand(binding.tokenCommand, env);
16267
+ const source = binding.tokenEnv ? `${binding.tokenEnv} is unset or empty` : "no token source is configured";
16268
+ throw new CloudTokenError(
16269
+ "cloud_token_missing",
16270
+ `cloud hub token is missing: ${source}; the local hub-env token was not used`
16271
+ );
16272
+ }
16273
+ function runTokenCommand(command, env) {
16274
+ const argv = splitTokenCommand(command);
16275
+ const [program, ...args] = argv;
16276
+ const result2 = spawnSync(program, args, {
16277
+ encoding: "utf8",
16278
+ shell: false,
16279
+ timeout: TOKEN_COMMAND_TIMEOUT_MS,
16280
+ maxBuffer: TOKEN_COMMAND_MAX_BUFFER,
16281
+ env,
16282
+ windowsHide: true
16283
+ });
16284
+ if (result2.error || result2.status !== 0) {
16285
+ throw new CloudTokenError(
16286
+ "cloud_token_command_failed",
16287
+ "token command failed; the local hub-env token was not used"
16288
+ );
16289
+ }
16290
+ const stdout = result2.stdout ?? "";
16291
+ if (stdout.trim().length === 0 || stdout.trim() !== stdout.trim().split(/\r?\n/)[0]) {
16292
+ throw new CloudTokenError(
16293
+ "cloud_token_command_failed",
16294
+ "token command did not print a single token; the local hub-env token was not used"
16295
+ );
16296
+ }
16297
+ return stdout.trim();
16298
+ }
16194
16299
  function isIsoTimestamp(value) {
16195
16300
  if (Number.isNaN(Date.parse(value))) return false;
16196
16301
  return value === new Date(value).toISOString();
@@ -16214,7 +16319,9 @@ function readHubBinding(env = process.env) {
16214
16319
  }
16215
16320
  const row = parsed;
16216
16321
  const keys = Object.keys(row);
16217
- if (keys.length !== 3 || row.schema !== HUB_BINDING_SCHEMA || typeof row.url !== "string" || typeof row.boundAt !== "string" || !isIsoTimestamp(row.boundAt)) {
16322
+ const allowed = /* @__PURE__ */ new Set(["schema", "url", "boundAt", "cloud", "tokenEnv", "tokenCommand"]);
16323
+ const cloudish = keys.some((key) => key === "cloud" || key === "tokenEnv" || key === "tokenCommand");
16324
+ if (keys.some((key) => !allowed.has(key)) || !cloudish && keys.length !== 3 || row.schema !== HUB_BINDING_SCHEMA || typeof row.url !== "string" || typeof row.boundAt !== "string" || !isIsoTimestamp(row.boundAt)) {
16218
16325
  throw new HubBindingError(`malformed hub binding at ${file}`);
16219
16326
  }
16220
16327
  let url;
@@ -16223,7 +16330,34 @@ function readHubBinding(env = process.env) {
16223
16330
  } catch {
16224
16331
  throw new HubBindingError(`malformed hub binding at ${file}`);
16225
16332
  }
16226
- return { schema: HUB_BINDING_SCHEMA, url, boundAt: row.boundAt };
16333
+ if (!cloudish) return { schema: HUB_BINDING_SCHEMA, url, boundAt: row.boundAt };
16334
+ if (row.cloud !== true) throw new HubBindingError(`malformed hub binding at ${file}`);
16335
+ let tokenEnv;
16336
+ let tokenCommand;
16337
+ if (row.tokenEnv !== void 0) {
16338
+ if (typeof row.tokenEnv !== "string" || !isCloudTokenEnvName(row.tokenEnv)) {
16339
+ throw new HubBindingError(`malformed hub binding at ${file}`);
16340
+ }
16341
+ tokenEnv = row.tokenEnv;
16342
+ }
16343
+ if (row.tokenCommand !== void 0) {
16344
+ if (typeof row.tokenCommand !== "string") throw new HubBindingError(`malformed hub binding at ${file}`);
16345
+ try {
16346
+ splitTokenCommand(row.tokenCommand);
16347
+ } catch {
16348
+ throw new HubBindingError(`malformed hub binding at ${file}`);
16349
+ }
16350
+ tokenCommand = row.tokenCommand;
16351
+ }
16352
+ if (!tokenEnv && !tokenCommand) throw new HubBindingError(`malformed hub binding at ${file}`);
16353
+ return {
16354
+ schema: HUB_BINDING_SCHEMA,
16355
+ url,
16356
+ boundAt: row.boundAt,
16357
+ cloud: true,
16358
+ ...tokenEnv ? { tokenEnv } : {},
16359
+ ...tokenCommand ? { tokenCommand } : {}
16360
+ };
16227
16361
  }
16228
16362
  async function probeHubHealth(url, fetchImpl, timeoutMs = HUB_HEALTH_PROBE_MS) {
16229
16363
  const started = Date.now();
@@ -16250,10 +16384,50 @@ async function probeHubHealth(url, fetchImpl, timeoutMs = HUB_HEALTH_PROBE_MS) {
16250
16384
  }
16251
16385
 
16252
16386
  // plugins/kxm/src/hub-env.ts
16253
- import { existsSync as existsSync4, mkdirSync as mkdirSync4, readFileSync as readFileSync4, renameSync as renameSync2, rmSync as rmSync2, writeFileSync as writeFileSync4 } from "node:fs";
16387
+ import { existsSync as existsSync5, mkdirSync as mkdirSync4, readFileSync as readFileSync5, renameSync as renameSync2, rmSync as rmSync2, writeFileSync as writeFileSync4 } from "node:fs";
16254
16388
  import { homedir as homedir4 } from "node:os";
16255
16389
  import { randomBytes } from "node:crypto";
16256
- import { dirname as dirname4, isAbsolute as isAbsolute2, join as join4, resolve as resolve4 } from "node:path";
16390
+ import { dirname as dirname5, isAbsolute as isAbsolute2, join as join5, resolve as resolve5 } from "node:path";
16391
+
16392
+ // plugins/kxm/src/project-name.ts
16393
+ var import_yaml2 = __toESM(require_dist(), 1);
16394
+ import { existsSync as existsSync4, readFileSync as readFileSync4 } from "node:fs";
16395
+ import { basename, dirname as dirname4, join as join4, resolve as resolve4 } from "node:path";
16396
+ function defaultProjectName(cwd, env = process.env, explicit) {
16397
+ const fromExplicit = explicit?.trim();
16398
+ if (fromExplicit) return fromExplicit;
16399
+ const fromEnv = env.KXM_PROJECT?.trim();
16400
+ if (fromEnv) return fromEnv;
16401
+ const fromProject = readProjectYamlId(cwd);
16402
+ if (fromProject) return fromProject;
16403
+ try {
16404
+ const pkg = JSON.parse(readFileSync4(join4(cwd, "package.json"), "utf8"));
16405
+ if (typeof pkg.name === "string" && pkg.name.trim().length > 0) return pkg.name.trim();
16406
+ } catch {
16407
+ }
16408
+ return basename(cwd);
16409
+ }
16410
+ function readProjectYamlId(start) {
16411
+ let dir = resolve4(start);
16412
+ for (; ; ) {
16413
+ const file = join4(dir, ".kxm", "project.yaml");
16414
+ if (existsSync4(file)) {
16415
+ try {
16416
+ const doc = (0, import_yaml2.parse)(readFileSync4(file, "utf8"));
16417
+ if (doc && typeof doc === "object" && !Array.isArray(doc) && typeof doc.id === "string" && doc.id.trim()) {
16418
+ return doc.id.trim();
16419
+ }
16420
+ } catch {
16421
+ }
16422
+ return void 0;
16423
+ }
16424
+ const parent = dirname4(dir);
16425
+ if (parent === dir) return void 0;
16426
+ dir = parent;
16427
+ }
16428
+ }
16429
+
16430
+ // plugins/kxm/src/hub-env.ts
16257
16431
  var HUB_ENV_SCHEMA = "kxm.hub-env.v1";
16258
16432
  var HubEnvError = class extends Error {
16259
16433
  constructor(message) {
@@ -16265,30 +16439,30 @@ function resolveUserStateRoot2(env) {
16265
16439
  const explicit = env.KXM_STATE_HOME?.trim();
16266
16440
  if (explicit) {
16267
16441
  if (!isAbsolute2(explicit)) throw new HubEnvError("local_state_root_not_absolute");
16268
- return resolve4(explicit);
16442
+ return resolve5(explicit);
16269
16443
  }
16270
16444
  if (process.platform === "win32") {
16271
16445
  const localAppData = env.LOCALAPPDATA?.trim();
16272
- const base2 = localAppData && isAbsolute2(localAppData) ? localAppData : join4(homedir4(), "AppData", "Local");
16273
- return resolve4(base2, "KXM");
16446
+ const base2 = localAppData && isAbsolute2(localAppData) ? localAppData : join5(homedir4(), "AppData", "Local");
16447
+ return resolve5(base2, "KXM");
16274
16448
  }
16275
- if (process.platform === "darwin") return resolve4(homedir4(), "Library", "Application Support", "KXM");
16449
+ if (process.platform === "darwin") return resolve5(homedir4(), "Library", "Application Support", "KXM");
16276
16450
  const xdgState = env.XDG_STATE_HOME?.trim();
16277
- const base = xdgState && isAbsolute2(xdgState) ? xdgState : join4(homedir4(), ".local", "state");
16278
- return resolve4(base, "kxm");
16451
+ const base = xdgState && isAbsolute2(xdgState) ? xdgState : join5(homedir4(), ".local", "state");
16452
+ return resolve5(base, "kxm");
16279
16453
  }
16280
16454
  function hubEnvFile(env = process.env) {
16281
- return join4(resolveUserStateRoot2(env), "hub-env.json");
16455
+ return join5(resolveUserStateRoot2(env), "hub-env.json");
16282
16456
  }
16283
16457
  function generateHubAuthToken() {
16284
16458
  return `kxm_admin_${randomBytes(24).toString("base64url")}`;
16285
16459
  }
16286
16460
  function readHubEnvRecord(env = process.env) {
16287
16461
  const file = hubEnvFile(env);
16288
- if (!existsSync4(file)) return void 0;
16462
+ if (!existsSync5(file)) return void 0;
16289
16463
  let parsed;
16290
16464
  try {
16291
- parsed = JSON.parse(readFileSync4(file, "utf8"));
16465
+ parsed = JSON.parse(readFileSync5(file, "utf8"));
16292
16466
  } catch (error2) {
16293
16467
  throw new HubEnvError(`hub env file is malformed at ${file}: ${error2 instanceof Error ? error2.message : String(error2)}`);
16294
16468
  }
@@ -16322,9 +16496,9 @@ function readHubEnvRecord(env = process.env) {
16322
16496
  }
16323
16497
  function writeHubEnvRecord(record2, env = process.env) {
16324
16498
  const file = hubEnvFile(env);
16325
- const directory = dirname4(file);
16499
+ const directory = dirname5(file);
16326
16500
  mkdirSync4(directory, { recursive: true });
16327
- const temporary = join4(directory, `.hub-env-${process.pid}.tmp`);
16501
+ const temporary = join5(directory, `.hub-env-${process.pid}.tmp`);
16328
16502
  writeFileSync4(temporary, `${JSON.stringify(record2, void 0, 2)}
16329
16503
  `, { encoding: "utf8", mode: 384 });
16330
16504
  try {
@@ -16393,7 +16567,22 @@ function resolveHubCredentials(options = {}) {
16393
16567
  written: needsPersist === true
16394
16568
  };
16395
16569
  }
16570
+ function activeCloudBinding(env) {
16571
+ try {
16572
+ const binding = readHubBinding(env);
16573
+ return binding?.cloud ? binding : void 0;
16574
+ } catch (error2) {
16575
+ if (error2 instanceof HubBindingError) {
16576
+ throw new HubEnvError(
16577
+ `${error2.message}; refusing to guess a credential \u2014 repair or remove ${hubBindingFile(env)}`
16578
+ );
16579
+ }
16580
+ throw error2;
16581
+ }
16582
+ }
16396
16583
  function resolveAgentHubAuthToken(env, project) {
16584
+ const cloud = activeCloudBinding(env);
16585
+ if (cloud) return resolveCloudHubToken(cloud, env);
16397
16586
  const envToken = env.KXM_AUTH_TOKEN?.trim();
16398
16587
  if (envToken) return envToken;
16399
16588
  const tokens = readHubEnvRecord(env)?.projectTokens;
@@ -16413,16 +16602,16 @@ var AgentProjectTokenMissingError = class extends Error {
16413
16602
  };
16414
16603
 
16415
16604
  // plugins/kxm/src/repo-root.ts
16416
- import { existsSync as existsSync5 } from "node:fs";
16417
- import { dirname as dirname5, join as join5 } from "node:path";
16605
+ import { existsSync as existsSync6 } from "node:fs";
16606
+ import { dirname as dirname6, join as join6 } from "node:path";
16418
16607
  import { fileURLToPath } from "node:url";
16419
16608
  var ROOT_MARKERS = ["scripts/kxm-hub.mjs", "scripts/kxm.mjs"];
16420
16609
  var MAX_WALK_DEPTH = 10;
16421
16610
  function tryFindKxmRepoRoot(fromUrl = import.meta.url) {
16422
- let dir = dirname5(fileURLToPath(fromUrl));
16611
+ let dir = dirname6(fileURLToPath(fromUrl));
16423
16612
  for (let depth = 0; depth < MAX_WALK_DEPTH; depth += 1) {
16424
- if (ROOT_MARKERS.some((marker) => existsSync5(join5(dir, marker)))) return dir;
16425
- const parent = dirname5(dir);
16613
+ if (ROOT_MARKERS.some((marker) => existsSync6(join6(dir, marker)))) return dir;
16614
+ const parent = dirname6(dir);
16426
16615
  if (parent === dir) break;
16427
16616
  dir = parent;
16428
16617
  }
@@ -16455,7 +16644,7 @@ function defaultProcessExists(pid) {
16455
16644
  function readLiveHubClaim(stateDir, processExists2 = defaultProcessExists) {
16456
16645
  let parsed;
16457
16646
  try {
16458
- parsed = JSON.parse(readFileSync5(join6(stateDir, "hub.pid"), "utf8"));
16647
+ parsed = JSON.parse(readFileSync6(join7(stateDir, "hub.pid"), "utf8"));
16459
16648
  } catch {
16460
16649
  return void 0;
16461
16650
  }
@@ -16470,7 +16659,7 @@ function readLiveHubClaim(stateDir, processExists2 = defaultProcessExists) {
16470
16659
  };
16471
16660
  }
16472
16661
  function defaultHubWrapperScriptPath(moduleUrl = import.meta.url) {
16473
- return join6(findKxmRepoRoot(moduleUrl), "scripts", "kxm-hub.mjs");
16662
+ return join7(findKxmRepoRoot(moduleUrl), "scripts", "kxm-hub.mjs");
16474
16663
  }
16475
16664
  function defaultHubSpawner(command, args, options) {
16476
16665
  const child = spawn(command, [...args], options);
@@ -16479,7 +16668,7 @@ function defaultHubSpawner(command, args, options) {
16479
16668
  }
16480
16669
  function logTail(logPath, maxChars = 2e3) {
16481
16670
  try {
16482
- return redactSecrets(readFileSync5(logPath, "utf8").trim().slice(-maxChars));
16671
+ return redactSecrets(readFileSync6(logPath, "utf8").trim().slice(-maxChars));
16483
16672
  } catch {
16484
16673
  return "";
16485
16674
  }
@@ -16492,11 +16681,12 @@ async function ensureHubRunning(options) {
16492
16681
  if (binding) {
16493
16682
  const { health } = await probeHubHealth(binding.url, fetchImpl);
16494
16683
  if (health === "on") return { status: "bound-healthy", url: binding.url };
16684
+ if (binding.cloud) return { status: "failed", reason: "cloud_hub_unreachable", logPath: "" };
16495
16685
  }
16496
- const workdir = resolve5(env.KXM_WORKDIR?.trim() || options.cwd);
16497
- const workspaceDir = resolve5(workdir, env.KXM_WORKSPACE_DIR?.trim() || ".kxm");
16498
- const stateDir = resolve5(workdir, env.KXM_STATE_DIR?.trim() || join6(workspaceDir, "state"));
16499
- const logsDir = resolve5(workdir, env.KXM_LOGS_DIR?.trim() || join6(workspaceDir, "logs"));
16686
+ const workdir = resolve6(env.KXM_WORKDIR?.trim() || options.cwd);
16687
+ const workspaceDir = resolve6(workdir, env.KXM_WORKSPACE_DIR?.trim() || ".kxm");
16688
+ const stateDir = resolve6(workdir, env.KXM_STATE_DIR?.trim() || join7(workspaceDir, "state"));
16689
+ const logsDir = resolve6(workdir, env.KXM_LOGS_DIR?.trim() || join7(workspaceDir, "logs"));
16500
16690
  const processExists2 = options.processExists ?? defaultProcessExists;
16501
16691
  const live = readLiveHubClaim(stateDir, processExists2);
16502
16692
  if (live) return { status: "claim-alive", pid: live.pid };
@@ -16506,7 +16696,7 @@ async function ensureHubRunning(options) {
16506
16696
  if (health === "on") return { status: "url-healthy", url: serverUrl };
16507
16697
  }
16508
16698
  const credentials = resolveHubCredentials({ env });
16509
- const logPath = join6(logsDir, HUB_AUTOSTART_LOG_NAME);
16699
+ const logPath = join7(logsDir, HUB_AUTOSTART_LOG_NAME);
16510
16700
  mkdirSync5(logsDir, { recursive: true });
16511
16701
  const logFd = openSync(logPath, "a");
16512
16702
  let child;
@@ -16553,20 +16743,6 @@ async function ensureHubRunning(options) {
16553
16743
  }
16554
16744
  }
16555
16745
 
16556
- // plugins/kxm/src/project-name.ts
16557
- import { readFileSync as readFileSync6 } from "node:fs";
16558
- import { basename, join as join7 } from "node:path";
16559
- function defaultProjectName(cwd, env = process.env) {
16560
- const fromEnv = env.KXM_PROJECT?.trim();
16561
- if (fromEnv) return fromEnv;
16562
- try {
16563
- const pkg = JSON.parse(readFileSync6(join7(cwd, "package.json"), "utf8"));
16564
- if (typeof pkg.name === "string" && pkg.name.trim().length > 0) return pkg.name.trim();
16565
- } catch {
16566
- }
16567
- return basename(cwd);
16568
- }
16569
-
16570
16746
  // plugins/kxm/src/nous-pi.ts
16571
16747
  import { readFile } from "node:fs/promises";
16572
16748
 
@@ -18437,7 +18613,7 @@ function closeServerGracefully(server) {
18437
18613
  server.close();
18438
18614
  }
18439
18615
  function startCallbackServer(expectedState) {
18440
- return new Promise((resolve8, reject) => {
18616
+ return new Promise((resolve9, reject) => {
18441
18617
  let settled = false;
18442
18618
  let timeout;
18443
18619
  let resolveCode;
@@ -18516,7 +18692,7 @@ function startCallbackServer(expectedState) {
18516
18692
  finish(() => rejectCode(new Error("OAuth callback timed out waiting for browser login")));
18517
18693
  close();
18518
18694
  }, OAUTH_CALLBACK_TIMEOUT_MS);
18519
- resolve8({ server, waitForCode: () => codePromise, cleanup });
18695
+ resolve9({ server, waitForCode: () => codePromise, cleanup });
18520
18696
  });
18521
18697
  });
18522
18698
  }
@@ -19135,8 +19311,8 @@ var AssistantMessageEventStream = class {
19135
19311
  finalResultPromise;
19136
19312
  resolveFinalResult;
19137
19313
  constructor() {
19138
- this.finalResultPromise = new Promise((resolve8) => {
19139
- this.resolveFinalResult = resolve8;
19314
+ this.finalResultPromise = new Promise((resolve9) => {
19315
+ this.resolveFinalResult = resolve9;
19140
19316
  });
19141
19317
  }
19142
19318
  push(event) {
@@ -19166,8 +19342,8 @@ var AssistantMessageEventStream = class {
19166
19342
  } else if (this.done) {
19167
19343
  return;
19168
19344
  } else {
19169
- const next = await new Promise((resolve8) => {
19170
- this.waiting.push(resolve8);
19345
+ const next = await new Promise((resolve9) => {
19346
+ this.waiting.push(resolve9);
19171
19347
  });
19172
19348
  if (next.done) return;
19173
19349
  if (next.value) yield next.value;
@@ -20486,8 +20662,8 @@ var AssistantMessageEventStream2 = class {
20486
20662
  finalResultPromise;
20487
20663
  resolveFinalResult;
20488
20664
  constructor() {
20489
- this.finalResultPromise = new Promise((resolve8) => {
20490
- this.resolveFinalResult = resolve8;
20665
+ this.finalResultPromise = new Promise((resolve9) => {
20666
+ this.resolveFinalResult = resolve9;
20491
20667
  });
20492
20668
  }
20493
20669
  push(event) {
@@ -20517,8 +20693,8 @@ var AssistantMessageEventStream2 = class {
20517
20693
  } else if (this.done) {
20518
20694
  return;
20519
20695
  } else {
20520
- const next = await new Promise((resolve8) => {
20521
- this.waiting.push(resolve8);
20696
+ const next = await new Promise((resolve9) => {
20697
+ this.waiting.push(resolve9);
20522
20698
  });
20523
20699
  if (next.done) return;
20524
20700
  if (next.value) yield next.value;
@@ -20544,11 +20720,11 @@ function emptyUsage() {
20544
20720
  }
20545
20721
 
20546
20722
  // plugins/kxm/src/providers/claude-bridge/config.ts
20547
- import { existsSync as existsSync6, readFileSync as readFileSync7 } from "node:fs";
20723
+ import { existsSync as existsSync7, readFileSync as readFileSync7 } from "node:fs";
20548
20724
  import { homedir as homedir5 } from "node:os";
20549
20725
  import { join as join8 } from "node:path";
20550
20726
  function tryParseJson(path) {
20551
- if (!existsSync6(path)) return {};
20727
+ if (!existsSync7(path)) return {};
20552
20728
  try {
20553
20729
  return JSON.parse(readFileSync7(path, "utf-8"));
20554
20730
  } catch (error2) {
@@ -33576,7 +33752,7 @@ var Protocol = class {
33576
33752
  return;
33577
33753
  }
33578
33754
  const pollInterval = task2.pollInterval ?? this._options?.defaultTaskPollInterval ?? 1e3;
33579
- await new Promise((resolve8) => setTimeout(resolve8, pollInterval));
33755
+ await new Promise((resolve9) => setTimeout(resolve9, pollInterval));
33580
33756
  options?.signal?.throwIfAborted();
33581
33757
  }
33582
33758
  } catch (error2) {
@@ -33593,7 +33769,7 @@ var Protocol = class {
33593
33769
  */
33594
33770
  request(request, resultSchema, options) {
33595
33771
  const { relatedRequestId, resumptionToken, onresumptiontoken, task, relatedTask } = options ?? {};
33596
- return new Promise((resolve8, reject) => {
33772
+ return new Promise((resolve9, reject) => {
33597
33773
  const earlyReject = (error2) => {
33598
33774
  reject(error2);
33599
33775
  };
@@ -33671,7 +33847,7 @@ var Protocol = class {
33671
33847
  if (!parseResult.success) {
33672
33848
  reject(parseResult.error);
33673
33849
  } else {
33674
- resolve8(parseResult.data);
33850
+ resolve9(parseResult.data);
33675
33851
  }
33676
33852
  } catch (error2) {
33677
33853
  reject(error2);
@@ -33932,12 +34108,12 @@ var Protocol = class {
33932
34108
  }
33933
34109
  } catch {
33934
34110
  }
33935
- return new Promise((resolve8, reject) => {
34111
+ return new Promise((resolve9, reject) => {
33936
34112
  if (signal.aborted) {
33937
34113
  reject(new McpError(ErrorCode.InvalidRequest, "Request cancelled"));
33938
34114
  return;
33939
34115
  }
33940
- const timeoutId = setTimeout(resolve8, interval);
34116
+ const timeoutId = setTimeout(resolve9, interval);
33941
34117
  signal.addEventListener("abort", () => {
33942
34118
  clearTimeout(timeoutId);
33943
34119
  reject(new McpError(ErrorCode.InvalidRequest, "Request cancelled"));
@@ -35028,7 +35204,7 @@ var McpServer = class {
35028
35204
  let task = createTaskResult.task;
35029
35205
  const pollInterval = task.pollInterval ?? 5e3;
35030
35206
  while (task.status !== "completed" && task.status !== "failed" && task.status !== "cancelled") {
35031
- await new Promise((resolve8) => setTimeout(resolve8, pollInterval));
35207
+ await new Promise((resolve9) => setTimeout(resolve9, pollInterval));
35032
35208
  const updatedTask = await extra.taskStore.getTask(taskId);
35033
35209
  if (!updatedTask) {
35034
35210
  throw new McpError(ErrorCode.InternalError, `Task ${taskId} not found during polling`);
@@ -35646,8 +35822,8 @@ function makePromptStream() {
35646
35822
  try {
35647
35823
  while (true) {
35648
35824
  while (queue.length === 0 && !done && !failure) {
35649
- await new Promise((resolve8) => {
35650
- wake = resolve8;
35825
+ await new Promise((resolve9) => {
35826
+ wake = resolve9;
35651
35827
  });
35652
35828
  }
35653
35829
  if (failure) throw failure;
@@ -35668,8 +35844,8 @@ function makePromptStream() {
35668
35844
  }
35669
35845
  return {
35670
35846
  stream: gen(),
35671
- push: (msg) => failure || done ? Promise.reject(failure ?? new Error("prompt stream closed")) : new Promise((resolve8, reject) => {
35672
- queue.push({ msg, resolve: resolve8, reject });
35847
+ push: (msg) => failure || done ? Promise.reject(failure ?? new Error("prompt stream closed")) : new Promise((resolve9, reject) => {
35848
+ queue.push({ msg, resolve: resolve9, reject });
35673
35849
  kick();
35674
35850
  }),
35675
35851
  end: () => {
@@ -36080,8 +36256,8 @@ function buildMcpServers(tools, queryCtx) {
36080
36256
  queryCtx.pendingResults.delete(toolCallId);
36081
36257
  return result2;
36082
36258
  }
36083
- return new Promise((resolve8) => {
36084
- queryCtx.pendingToolCalls.set(toolCallId, { toolName: tool.name, resolve: resolve8 });
36259
+ return new Promise((resolve9) => {
36260
+ queryCtx.pendingToolCalls.set(toolCallId, { toolName: tool.name, resolve: resolve9 });
36085
36261
  });
36086
36262
  }
36087
36263
  }));
@@ -36601,20 +36777,20 @@ async function consumeWorkerRecoveryEnvelope(client, stateDir, agentName, projec
36601
36777
  }
36602
36778
 
36603
36779
  // plugins/kxm/src/session-work.ts
36604
- import { spawnSync } from "node:child_process";
36780
+ import { spawnSync as spawnSync2 } from "node:child_process";
36605
36781
  import { randomUUID } from "node:crypto";
36606
- import { existsSync as existsSync10, mkdirSync as mkdirSync8, readFileSync as readFileSync12, renameSync as renameSync4, writeFileSync as writeFileSync6 } from "node:fs";
36782
+ import { existsSync as existsSync11, mkdirSync as mkdirSync8, readFileSync as readFileSync12, renameSync as renameSync4, writeFileSync as writeFileSync6 } from "node:fs";
36607
36783
  import { join as join13 } from "node:path";
36608
36784
 
36609
36785
  // plugins/kxm/src/local-snapshot.ts
36610
- import { existsSync as existsSync8, readdirSync, readFileSync as readFileSync10 } from "node:fs";
36786
+ import { existsSync as existsSync9, readdirSync, readFileSync as readFileSync10 } from "node:fs";
36611
36787
  import { homedir as homedir6 } from "node:os";
36612
- import { isAbsolute as isAbsolute3, join as join11, resolve as resolve7 } from "node:path";
36788
+ import { isAbsolute as isAbsolute3, join as join11, resolve as resolve8 } from "node:path";
36613
36789
 
36614
36790
  // plugins/kxm/src/sqlite.ts
36615
- import { existsSync as existsSync7 } from "node:fs";
36791
+ import { existsSync as existsSync8 } from "node:fs";
36616
36792
  import { createRequire as createRequire2 } from "node:module";
36617
- import { resolve as resolve6 } from "node:path";
36793
+ import { resolve as resolve7 } from "node:path";
36618
36794
  import { pathToFileURL } from "node:url";
36619
36795
  var requireFromHere = createRequire2(import.meta.url);
36620
36796
  function loadNative() {
@@ -36653,15 +36829,15 @@ var DatabaseSync = class {
36653
36829
  }
36654
36830
  };
36655
36831
  function openReadOnlyDatabase(path) {
36656
- if (existsSync7(`${path}-wal`)) return new DatabaseSync(path, { readOnly: true });
36657
- const uri = pathToFileURL(resolve6(path));
36832
+ if (existsSync8(`${path}-wal`)) return new DatabaseSync(path, { readOnly: true });
36833
+ const uri = pathToFileURL(resolve7(path));
36658
36834
  uri.searchParams.set("immutable", "1");
36659
36835
  return new DatabaseSync(uri.href, { readOnly: true });
36660
36836
  }
36661
36837
 
36662
36838
  // plugins/kxm/src/telemetry.ts
36663
36839
  import { appendFileSync, mkdirSync as mkdirSync6, readFileSync as readFileSync9 } from "node:fs";
36664
- import { dirname as dirname6, join as join10 } from "node:path";
36840
+ import { dirname as dirname7, join as join10 } from "node:path";
36665
36841
  function telemetryPath(logsDir) {
36666
36842
  return join10(logsDir, "telemetry.jsonl");
36667
36843
  }
@@ -36825,34 +37001,34 @@ function readOpenMessageMetadata(database, where = OPEN_MESSAGE_WHERE, params =
36825
37001
  function resolveKxmSnapshotPaths(cwd, env = process.env) {
36826
37002
  const stateDir = env.KXM_STATE_DIR?.trim() || join11(cwd, ".kxm", "state");
36827
37003
  const configured = env.KXM_DATA_PATH?.trim();
36828
- const dataPath = configured ? resolve7(cwd, configured) : join11(stateDir, "kxm.db");
37004
+ const dataPath = configured ? resolve8(cwd, configured) : join11(stateDir, "kxm.db");
36829
37005
  return { dataPath, stateDir };
36830
37006
  }
36831
37007
  function resolveKxmStateRoot(stateDir, options) {
36832
- if (options?.kxmStateRoot && existsSync8(options.kxmStateRoot)) {
36833
- return resolve7(options.kxmStateRoot);
37008
+ if (options?.kxmStateRoot && existsSync9(options.kxmStateRoot)) {
37009
+ return resolve8(options.kxmStateRoot);
36834
37010
  }
36835
- if (existsSync8(join11(stateDir, "runtime", "registry.db")) || existsSync8(join11(stateDir, "runtime", "projects"))) {
37011
+ if (existsSync9(join11(stateDir, "runtime", "registry.db")) || existsSync9(join11(stateDir, "runtime", "projects"))) {
36836
37012
  return stateDir;
36837
37013
  }
36838
37014
  const env = options?.env ?? process.env;
36839
37015
  const explicit = env.KXM_STATE_HOME?.trim() || env.KXM_USER_STATE_DIR?.trim() || env.KXM_STATE_ROOT?.trim();
36840
- if (explicit && isAbsolute3(explicit) && existsSync8(resolve7(explicit))) {
36841
- return resolve7(explicit);
37016
+ if (explicit && isAbsolute3(explicit) && existsSync9(resolve8(explicit))) {
37017
+ return resolve8(explicit);
36842
37018
  }
36843
37019
  let base;
36844
37020
  if (process.platform === "win32") {
36845
37021
  const localAppData = env.LOCALAPPDATA?.trim();
36846
37022
  base = localAppData && isAbsolute3(localAppData) ? localAppData : join11(homedir6(), "AppData", "Local");
36847
- base = resolve7(base, "KXM");
37023
+ base = resolve8(base, "KXM");
36848
37024
  } else if (process.platform === "darwin") {
36849
- base = resolve7(homedir6(), "Library", "Application Support", "KXM");
37025
+ base = resolve8(homedir6(), "Library", "Application Support", "KXM");
36850
37026
  } else {
36851
37027
  const xdgState = env.XDG_STATE_HOME?.trim();
36852
37028
  base = xdgState && isAbsolute3(xdgState) ? xdgState : join11(homedir6(), ".local", "state");
36853
- base = resolve7(base, "kxm");
37029
+ base = resolve8(base, "kxm");
36854
37030
  }
36855
- if (existsSync8(base)) return base;
37031
+ if (existsSync9(base)) return base;
36856
37032
  return void 0;
36857
37033
  }
36858
37034
  function readRuntimeRuns(eventDb, projectId) {
@@ -36885,7 +37061,7 @@ function loadLocalMeshSnapshot(dataPath, stateDir, options) {
36885
37061
  let legacyRuns = [];
36886
37062
  let legacyRunTotal = 0;
36887
37063
  let plans = [];
36888
- if (existsSync8(dataPath)) {
37064
+ if (existsSync9(dataPath)) {
36889
37065
  hasLegacy = true;
36890
37066
  const database = openReadOnlyDatabase(dataPath);
36891
37067
  try {
@@ -36920,7 +37096,7 @@ function loadLocalMeshSnapshot(dataPath, stateDir, options) {
36920
37096
  const registryDbPath = join11(runtimeDir, "registry.db");
36921
37097
  const projectsDir = join11(runtimeDir, "projects");
36922
37098
  const projectKeys = /* @__PURE__ */ new Set();
36923
- if (existsSync8(registryDbPath)) {
37099
+ if (existsSync9(registryDbPath)) {
36924
37100
  hasKxm = true;
36925
37101
  try {
36926
37102
  const regDb = openReadOnlyDatabase(registryDbPath);
@@ -36936,7 +37112,7 @@ function loadLocalMeshSnapshot(dataPath, stateDir, options) {
36936
37112
  } catch {
36937
37113
  }
36938
37114
  }
36939
- if (!scope && existsSync8(projectsDir)) {
37115
+ if (!scope && existsSync9(projectsDir)) {
36940
37116
  try {
36941
37117
  for (const entry of readdirSync(projectsDir, { withFileTypes: true })) {
36942
37118
  if (entry.isDirectory()) {
@@ -36949,7 +37125,7 @@ function loadLocalMeshSnapshot(dataPath, stateDir, options) {
36949
37125
  for (const key of projectKeys) {
36950
37126
  if (scope && !RUNTIME_PROJECT_KEY.test(key)) continue;
36951
37127
  const eventDbPath = join11(projectsDir, key, "run-events.db");
36952
- if (existsSync8(eventDbPath)) {
37128
+ if (existsSync9(eventDbPath)) {
36953
37129
  hasKxm = true;
36954
37130
  try {
36955
37131
  const eventDb = openReadOnlyDatabase(eventDbPath);
@@ -36967,7 +37143,7 @@ function loadLocalMeshSnapshot(dataPath, stateDir, options) {
36967
37143
  }
36968
37144
  }
36969
37145
  const pids = [];
36970
- if (existsSync8(stateDir)) {
37146
+ if (existsSync9(stateDir)) {
36971
37147
  for (const file of readdirSync(stateDir).filter((name) => name.endsWith(".pid"))) {
36972
37148
  try {
36973
37149
  const record2 = JSON.parse(readFileSync10(join11(stateDir, file), "utf8"));
@@ -37010,7 +37186,7 @@ function loadLocalMeshSnapshot(dataPath, stateDir, options) {
37010
37186
  source = "legacy";
37011
37187
  }
37012
37188
  const telemetryFile = join11(stateDir, "telemetry.jsonl");
37013
- const spend = existsSync8(telemetryFile) ? readRoutingRecords(telemetryFile) : [];
37189
+ const spend = existsSync9(telemetryFile) ? readRoutingRecords(telemetryFile) : [];
37014
37190
  return {
37015
37191
  source,
37016
37192
  agents: agents.sort((a, b) => Number(b.online) - Number(a.online) || a.name.localeCompare(b.name)),
@@ -37025,13 +37201,13 @@ function loadLocalMeshSnapshot(dataPath, stateDir, options) {
37025
37201
  }
37026
37202
 
37027
37203
  // plugins/kxm/src/kxm-update.ts
37028
- import { existsSync as existsSync9, readFileSync as readFileSync11, writeFileSync as writeFileSync5, mkdirSync as mkdirSync7 } from "node:fs";
37204
+ import { existsSync as existsSync10, readFileSync as readFileSync11, writeFileSync as writeFileSync5, mkdirSync as mkdirSync7 } from "node:fs";
37029
37205
  import { join as join12 } from "node:path";
37030
37206
  var KXM_UPDATE_CACHE = "update-check.json";
37031
37207
  var CACHE_TTL_MS = 6 * 60 * 60 * 1e3;
37032
37208
  function readUpdateCache(stateDir, now = Date.now()) {
37033
37209
  const path = join12(stateDir, KXM_UPDATE_CACHE);
37034
- if (!existsSync9(path)) return void 0;
37210
+ if (!existsSync10(path)) return void 0;
37035
37211
  try {
37036
37212
  const row = JSON.parse(readFileSync11(path, "utf8"));
37037
37213
  if (typeof row.checkedAt !== "number" || !row.notice || now - row.checkedAt > CACHE_TTL_MS) return void 0;
@@ -37099,10 +37275,10 @@ function formatShipLine(ship) {
37099
37275
  }
37100
37276
  function readGitShip(cwd) {
37101
37277
  try {
37102
- const dirty = spawnSync("git", ["--no-optional-locks", "-C", cwd, "status", "--porcelain"], { encoding: "utf8", windowsHide: true });
37278
+ const dirty = spawnSync2("git", ["--no-optional-locks", "-C", cwd, "status", "--porcelain"], { encoding: "utf8", windowsHide: true });
37103
37279
  if (dirty.status !== 0) return void 0;
37104
37280
  const isDirty2 = dirty.stdout.trim().length > 0;
37105
- const upstream = spawnSync("git", ["-C", cwd, "rev-list", "--count", "@{u}..HEAD"], { encoding: "utf8", windowsHide: true });
37281
+ const upstream = spawnSync2("git", ["-C", cwd, "rev-list", "--count", "@{u}..HEAD"], { encoding: "utf8", windowsHide: true });
37106
37282
  if (upstream.status === 0) {
37107
37283
  return {
37108
37284
  dirty: isDirty2,
@@ -37110,9 +37286,9 @@ function readGitShip(cwd) {
37110
37286
  };
37111
37287
  }
37112
37288
  for (const baseRef of ["origin/HEAD", "main", "origin/main", "master", "origin/master"]) {
37113
- const mb = spawnSync("git", ["-C", cwd, "merge-base", baseRef, "HEAD"], { encoding: "utf8", windowsHide: true });
37289
+ const mb = spawnSync2("git", ["-C", cwd, "merge-base", baseRef, "HEAD"], { encoding: "utf8", windowsHide: true });
37114
37290
  if (mb.status === 0 && mb.stdout.trim()) {
37115
- const count = spawnSync("git", ["-C", cwd, "rev-list", "--count", `${mb.stdout.trim()}..HEAD`], { encoding: "utf8", windowsHide: true });
37291
+ const count = spawnSync2("git", ["-C", cwd, "rev-list", "--count", `${mb.stdout.trim()}..HEAD`], { encoding: "utf8", windowsHide: true });
37116
37292
  if (count.status === 0) {
37117
37293
  return {
37118
37294
  dirty: isDirty2,
@@ -37202,7 +37378,7 @@ function buildSessionBrief(snapshot, current, hub, ship, updateLatest, cost, ses
37202
37378
  function readCachedSessionBrief(stateDir) {
37203
37379
  const file = join13(stateDir, "session-brief.json");
37204
37380
  try {
37205
- if (!existsSync10(file)) return void 0;
37381
+ if (!existsSync11(file)) return void 0;
37206
37382
  const raw = readFileSync12(file, "utf8");
37207
37383
  const parsed = JSON.parse(raw);
37208
37384
  if (parsed && parsed.schema === "kxm.session-brief.v1" && typeof parsed.generatedAt === "string") {
@@ -37229,7 +37405,7 @@ function writeCachedSessionBrief(stateDir, brief) {
37229
37405
  function estimateSessionCost(stateDir) {
37230
37406
  try {
37231
37407
  const telemetryFile = join13(stateDir, "telemetry.jsonl");
37232
- if (!existsSync10(telemetryFile)) return void 0;
37408
+ if (!existsSync11(telemetryFile)) return void 0;
37233
37409
  const records = readRoutingRecords(telemetryFile);
37234
37410
  if (records.length === 0) return void 0;
37235
37411
  let totalCost = 0;
@@ -37404,11 +37580,11 @@ function kxmSlashCompletions(prefix) {
37404
37580
  }
37405
37581
 
37406
37582
  // plugins/kxm/src/workflow-tui.ts
37407
- import { existsSync as existsSync11, readFileSync as readFileSync13 } from "node:fs";
37583
+ import { existsSync as existsSync12, readFileSync as readFileSync13 } from "node:fs";
37408
37584
  import { join as join14 } from "node:path";
37409
37585
  function loadActiveWorkflowProgress(repoRoot = process.cwd(), targetRunId) {
37410
37586
  const dbPath = join14(repoConfigDirectory(repoRoot), "state", "kxm.db");
37411
- if (!existsSync11(dbPath)) return void 0;
37587
+ if (!existsSync12(dbPath)) return void 0;
37412
37588
  let db;
37413
37589
  try {
37414
37590
  db = new DatabaseSync(dbPath, { readOnly: true });
@@ -37445,7 +37621,7 @@ function loadActiveWorkflowProgress(repoRoot = process.cwd(), targetRunId) {
37445
37621
  try {
37446
37622
  const logsDir = join14(repoConfigDirectory(repoRoot), "logs");
37447
37623
  const telemFile = telemetryPath(logsDir);
37448
- if (existsSync11(telemFile)) {
37624
+ if (existsSync12(telemFile)) {
37449
37625
  const records = readRoutingRecords(telemFile);
37450
37626
  const routingRunId = (routing) => "runId" in routing ? routing.runId : routing.workflowRunId;
37451
37627
  let matching = records.filter((r) => routingRunId(r.routing) === runId);
@@ -37737,7 +37913,7 @@ function piMeshExtension(pi) {
37737
37913
  messageId: message.id,
37738
37914
  createdAt: (/* @__PURE__ */ new Date()).toISOString()
37739
37915
  };
37740
- mkdirSync9(dirname7(path), { recursive: true });
37916
+ mkdirSync9(dirname8(path), { recursive: true });
37741
37917
  const tmp = `${path}.${process.pid}.tmp`;
37742
37918
  writeFileSync7(tmp, `${JSON.stringify(request)}
37743
37919
  `, { encoding: "utf8", mode: 384 });
@@ -37768,7 +37944,7 @@ function piMeshExtension(pi) {
37768
37944
  removeMatchingLegacyRecoveryContext();
37769
37945
  return;
37770
37946
  }
37771
- mkdirSync9(dirname7(path), { recursive: true });
37947
+ mkdirSync9(dirname8(path), { recursive: true });
37772
37948
  const tmp = `${path}.${process.pid}.tmp`;
37773
37949
  writeFileSync7(tmp, `${JSON.stringify({ version: 1, agentName, project: projectName, runId: runId ?? null, stageId: recoveryStageId ?? null, activeMessageIds, pendingMessageIds, artifactPointers: recoveryArtifacts.slice(0, 16), updatedAt: (/* @__PURE__ */ new Date()).toISOString() })}
37774
37950
  `, { encoding: "utf8", mode: 384 });
@@ -37818,7 +37994,7 @@ function piMeshExtension(pi) {
37818
37994
  ctx2.ui.setEditorText?.(item.prompt);
37819
37995
  }
37820
37996
  async function showKxmHub(ctx2) {
37821
- const url = (process.env.KXM_SERVER_URL ?? "http://127.0.0.1:7331").replace(/\/$/, "");
37997
+ const url = resolveHubServerUrl(process.env);
37822
37998
  let health = "unreachable";
37823
37999
  try {
37824
38000
  const response = await fetch(`${url}/health`);
@@ -38108,7 +38284,7 @@ function piMeshExtension(pi) {
38108
38284
  return;
38109
38285
  }
38110
38286
  currentPiSessionId = ctx2.sessionManager?.getSessionId();
38111
- const serverUrl = process.env.KXM_SERVER_URL ?? "http://127.0.0.1:7331";
38287
+ const serverUrl = resolveHubServerUrl(process.env);
38112
38288
  const project = defaultProjectName(ctx2.cwd, process.env);
38113
38289
  const name = process.env.KXM_AGENT_NAME ?? pi.getSessionName() ?? `pi-${process.pid}`;
38114
38290
  agentName = name;
@@ -38137,7 +38313,8 @@ function piMeshExtension(pi) {
38137
38313
  try {
38138
38314
  hubAuthToken = resolveAgentHubAuthToken(process.env, project);
38139
38315
  } catch (error2) {
38140
- ctx2.ui.notify(`kxm could not read persisted hub credentials: ${error2 instanceof Error ? error2.message : String(error2)}`, "error");
38316
+ const detail = error2 instanceof CloudTokenError ? error2.message : `kxm could not read persisted hub credentials: ${error2 instanceof Error ? error2.message : String(error2)}`;
38317
+ ctx2.ui.notify(detail, "error");
38141
38318
  await applySessionChrome(ctx2, event, true);
38142
38319
  return;
38143
38320
  }
@@ -38356,12 +38533,12 @@ function piMeshExtension(pi) {
38356
38533
  if (command === "memory") {
38357
38534
  const cwd = typeof ctx2.cwd === "string" ? ctx2.cwd : process.cwd();
38358
38535
  const kxmBin = process.env.KXM_BIN || "kxm";
38359
- const res = spawnSync2(kxmBin, ["memory", "brief"], { cwd, encoding: "utf8", windowsHide: true });
38536
+ const res = spawnSync3(kxmBin, ["memory", "brief"], { cwd, encoding: "utf8", windowsHide: true });
38360
38537
  let memText = res.status === 0 && res.stdout ? res.stdout.trim() : "";
38361
38538
  if (!memText) {
38362
38539
  const script = join15(cwd, "scripts", "kxm.mjs");
38363
- if (existsSync12(script)) {
38364
- const scriptRes = spawnSync2(process.execPath, [script, "memory", "brief"], { cwd, encoding: "utf8", windowsHide: true });
38540
+ if (existsSync13(script)) {
38541
+ const scriptRes = spawnSync3(process.execPath, [script, "memory", "brief"], { cwd, encoding: "utf8", windowsHide: true });
38365
38542
  if (scriptRes.status === 0 && scriptRes.stdout) memText = scriptRes.stdout.trim();
38366
38543
  }
38367
38544
  }