@kontextmind/kxm 0.7.7 → 0.7.9

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.
@@ -11,7 +11,7 @@
11
11
  "name": "kxm",
12
12
  "source": "./plugins/kxm",
13
13
  "description": "Durable workflows, peer agents, and kxm tui",
14
- "version": "0.7.7",
14
+ "version": "0.7.9",
15
15
  "category": "development",
16
16
  "tags": ["kxm", "multi-agent", "workflows", "mcp"]
17
17
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kontextmind/kxm",
3
- "version": "0.7.7",
3
+ "version": "0.7.9",
4
4
  "description": "KXM local-first multi-agent orchestration and operator dashboard",
5
5
  "type": "module",
6
6
  "author": "KontextMind",
@@ -2,7 +2,7 @@
2
2
  "$schema": "https://json.schemastore.org/claude-code-plugin-manifest.json",
3
3
  "name": "kxm",
4
4
  "displayName": "KXM",
5
- "version": "0.7.7",
5
+ "version": "0.7.9",
6
6
  "description": "Headless multi-agent orchestration, durable workflows, and a live operator dashboard for Pi and Claude Code",
7
7
  "author": {
8
8
  "name": "KontextMind",
@@ -20814,7 +20814,157 @@ import { existsSync as existsSync3 } from "node:fs";
20814
20814
  import { win32 as win32Path } from "node:path";
20815
20815
 
20816
20816
  // plugins/kxm/src/vnext-oneshot-process.ts
20817
+ import { spawn } from "node:child_process";
20817
20818
  var OUTPUT_LIMIT = 8 * 1024 * 1024;
20819
+ var KILL_GRACE_MS = 250;
20820
+ var DRAIN_GRACE_MS = 500;
20821
+ var REAP_GRACE_MS = 1e3;
20822
+ function killProcessTree(child, signal = "SIGKILL") {
20823
+ if (process.platform !== "win32" && child.pid) {
20824
+ try {
20825
+ process.kill(-child.pid, signal);
20826
+ return;
20827
+ } catch {
20828
+ }
20829
+ }
20830
+ try {
20831
+ child.kill(signal);
20832
+ } catch {
20833
+ }
20834
+ }
20835
+ function defaultSpawn(command, args, options) {
20836
+ if (options.signal?.aborted) {
20837
+ return Promise.resolve({ stdout: "", stderr: "", code: null, started: false, observedChildExit: false, error: new Error("process_aborted") });
20838
+ }
20839
+ return new Promise((resolve31) => {
20840
+ const stdout = [];
20841
+ const stderr = [];
20842
+ let outputBytes = 0;
20843
+ let outputChunks = 0;
20844
+ let code = null;
20845
+ let signal = null;
20846
+ let observedChildExit = false;
20847
+ let finished = false;
20848
+ let stopping = false;
20849
+ let closed = false;
20850
+ let killSent = false;
20851
+ let error;
20852
+ let wallTimer;
20853
+ let killTimer;
20854
+ let drainTimer;
20855
+ let reapTimer;
20856
+ let child;
20857
+ const finish = () => {
20858
+ if (finished) return;
20859
+ if (stopping && !killSent) return;
20860
+ finished = true;
20861
+ for (const timer of [wallTimer, killTimer, drainTimer, reapTimer]) clearTimeout(timer);
20862
+ options.signal?.removeEventListener("abort", onAbort);
20863
+ child?.stdin?.destroy();
20864
+ child?.stdout?.destroy();
20865
+ child?.stderr?.destroy();
20866
+ child?.unref();
20867
+ const started = Boolean(child?.pid);
20868
+ if (started && !observedChildExit) error ??= new Error("process_exit_unobserved");
20869
+ const unverifiedDescendants = stopping || started && !observedChildExit;
20870
+ resolve31({
20871
+ stdout: Buffer.concat(stdout).toString("utf8"),
20872
+ stderr: Buffer.concat(stderr).toString("utf8"),
20873
+ code,
20874
+ signal,
20875
+ started,
20876
+ observedChildExit,
20877
+ terminationRequested: stopping,
20878
+ ...unverifiedDescendants ? { unverifiedDescendants: true } : {},
20879
+ ...error ? { error } : {}
20880
+ });
20881
+ };
20882
+ const kill = (requested) => {
20883
+ killProcessTree(child, requested);
20884
+ };
20885
+ const stop = (reason) => {
20886
+ if (finished) return;
20887
+ error ??= new Error(reason);
20888
+ if (stopping) return;
20889
+ stopping = true;
20890
+ clearTimeout(wallTimer);
20891
+ kill("SIGTERM");
20892
+ killTimer = setTimeout(() => {
20893
+ kill("SIGKILL");
20894
+ killSent = true;
20895
+ if (closed) {
20896
+ finish();
20897
+ return;
20898
+ }
20899
+ reapTimer = setTimeout(() => {
20900
+ if (!observedChildExit) error ??= new Error("process_exit_unobserved");
20901
+ finish();
20902
+ }, REAP_GRACE_MS);
20903
+ }, KILL_GRACE_MS);
20904
+ };
20905
+ const onAbort = () => stop("process_aborted");
20906
+ try {
20907
+ child = spawn(command, [...args], {
20908
+ cwd: options.cwd,
20909
+ env: options.env ?? process.env,
20910
+ stdio: ["pipe", "pipe", "pipe"],
20911
+ shell: options.shell === true,
20912
+ windowsHide: true,
20913
+ detached: process.platform !== "win32"
20914
+ });
20915
+ } catch (cause) {
20916
+ error = cause instanceof Error ? cause : new Error("process_spawn_failed");
20917
+ finish();
20918
+ return;
20919
+ }
20920
+ const collect = (target, chunk) => {
20921
+ if (finished) return;
20922
+ const bytes = Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk);
20923
+ const remaining = Math.max(0, OUTPUT_LIMIT - outputBytes);
20924
+ if (remaining && outputChunks < 16384) {
20925
+ const kept = bytes.subarray(0, remaining);
20926
+ target.push(kept);
20927
+ outputBytes += kept.length;
20928
+ outputChunks++;
20929
+ }
20930
+ if (bytes.length > remaining || outputChunks >= 16384) stop("process_output_limit");
20931
+ };
20932
+ child.stdout.on("data", (chunk) => collect(stdout, chunk));
20933
+ child.stderr.on("data", (chunk) => collect(stderr, chunk));
20934
+ child.stdin.on("error", () => stop("process_stdin_error"));
20935
+ child.stdout.on("error", () => stop("process_stdio_error"));
20936
+ child.stderr.on("error", () => stop("process_stdio_error"));
20937
+ child.on("error", (cause) => {
20938
+ error ??= cause;
20939
+ if (!child.pid) finish();
20940
+ else stop("process_error");
20941
+ });
20942
+ child.on("exit", (exitCode, exitSignal) => {
20943
+ if (finished) return;
20944
+ observedChildExit = true;
20945
+ code = exitCode;
20946
+ signal = exitSignal;
20947
+ clearTimeout(wallTimer);
20948
+ drainTimer = setTimeout(() => stop("process_stdio_unclosed"), DRAIN_GRACE_MS);
20949
+ });
20950
+ child.on("close", (exitCode, exitSignal) => {
20951
+ if (finished) return;
20952
+ closed = true;
20953
+ code = exitCode;
20954
+ signal = exitSignal;
20955
+ finish();
20956
+ });
20957
+ options.signal?.addEventListener("abort", onAbort, { once: true });
20958
+ if (options.signal?.aborted) onAbort();
20959
+ const timeoutMs = options.timeoutMs ?? 12e4;
20960
+ if (!stopping) wallTimer = setTimeout(() => stop("process_timeout"), timeoutMs > 0 && Number.isFinite(timeoutMs) ? timeoutMs : 12e4);
20961
+ try {
20962
+ child.stdin.end(options.input);
20963
+ } catch {
20964
+ stop("process_stdin_error");
20965
+ }
20966
+ });
20967
+ }
20818
20968
 
20819
20969
  // plugins/kxm/src/vnext-harness.ts
20820
20970
  var DEFAULT_HARNESS = "pi";
@@ -21243,6 +21393,31 @@ function defaultRunner(env) {
21243
21393
  }
21244
21394
  };
21245
21395
  }
21396
+ function commandResultFromSpawn(result) {
21397
+ const errno = result.error && "code" in result.error ? result.error.code : void 0;
21398
+ const error = (typeof errno === "string" && errno ? errno : void 0) ?? result.error?.message ?? (result.observedChildExit !== true ? "auth_probe_exit_unobserved" : void 0);
21399
+ return {
21400
+ ok: result.code === 0 && !error,
21401
+ code: result.code,
21402
+ stdout: result.stdout,
21403
+ stderr: result.stderr,
21404
+ ...error ? { error } : {}
21405
+ };
21406
+ }
21407
+ function defaultAsyncRunner(env, signal) {
21408
+ return async (command, args, timeoutMs) => {
21409
+ try {
21410
+ return commandResultFromSpawn(await defaultSpawn(command, args, {
21411
+ env,
21412
+ timeoutMs,
21413
+ signal,
21414
+ shell: harnessSpawnUsesShell(command)
21415
+ }));
21416
+ } catch (error) {
21417
+ return { ok: false, code: null, stdout: "", stderr: "", error: error instanceof Error ? error.message : "spawn_failed" };
21418
+ }
21419
+ };
21420
+ }
21246
21421
  function firstLine(text) {
21247
21422
  const line = text.split(/\r?\n/).map((candidate) => candidate.trim()).find(Boolean);
21248
21423
  return line && line.length <= 200 ? line : void 0;
@@ -21441,6 +21616,13 @@ function probeHarnesses(options = {}) {
21441
21616
  harnesses: BUILTIN_HARNESSES.map((entry) => probeEntry(entry, runCommand, timeoutMs, platform, options))
21442
21617
  };
21443
21618
  }
21619
+ async function probeHarnessesAsync(options = {}) {
21620
+ return replayHarnessProbe(
21621
+ options.runCommand ?? defaultAsyncRunner(options.env ?? process.env, options.signal),
21622
+ (runCommand) => probeHarnesses({ ...options, runCommand }),
21623
+ 256
21624
+ );
21625
+ }
21444
21626
  function validateHarnessModelPair(harnessId, modelSpec) {
21445
21627
  if (!isKnownHarnessId(harnessId)) {
21446
21628
  return { valid: false, issue: "harness_unknown", message: `unknown harness: ${harnessId}` };
@@ -21533,6 +21715,36 @@ function validateHarnessModelPair(harnessId, modelSpec) {
21533
21715
  }
21534
21716
  return { valid: true };
21535
21717
  }
21718
+ var PendingHarnessCommand = class {
21719
+ command;
21720
+ args;
21721
+ timeoutMs;
21722
+ key;
21723
+ constructor(command, args, timeoutMs, key) {
21724
+ this.command = command;
21725
+ this.args = [...args];
21726
+ this.timeoutMs = timeoutMs;
21727
+ this.key = key;
21728
+ }
21729
+ };
21730
+ async function replayHarnessProbe(run, execute, limit) {
21731
+ const observed = /* @__PURE__ */ new Map();
21732
+ for (let commands = 0; commands <= limit; commands++) {
21733
+ try {
21734
+ return execute((command, args, timeoutMs) => {
21735
+ const key = JSON.stringify([command, args, timeoutMs]);
21736
+ const result = observed.get(key);
21737
+ if (result) return result;
21738
+ throw new PendingHarnessCommand(command, args, timeoutMs, key);
21739
+ });
21740
+ } catch (pending) {
21741
+ if (!(pending instanceof PendingHarnessCommand)) throw pending;
21742
+ if (commands === limit) throw new Error("auth_probe_command_limit");
21743
+ observed.set(pending.key, await run(pending.command, pending.args, pending.timeoutMs));
21744
+ }
21745
+ }
21746
+ throw new Error("auth_probe_command_limit");
21747
+ }
21536
21748
  function scopesFor(scope, entry) {
21537
21749
  if (scope === "self") return ["self"];
21538
21750
  if (scope === "extensions") return entry.update.extensions ? ["extensions"] : [];
@@ -22928,7 +23140,7 @@ function planVnextInitialization(start = process.cwd(), options = {}) {
22928
23140
  }
22929
23141
 
22930
23142
  // plugins/kxm/src/vnext-runtime-supervisor.ts
22931
- import { spawn } from "node:child_process";
23143
+ import { spawn as spawn2 } from "node:child_process";
22932
23144
  import { createHash as createHash11, createHmac, randomBytes as randomBytes2, timingSafeEqual as timingSafeEqual2 } from "node:crypto";
22933
23145
  import { chmodSync as chmodSync4, existsSync as existsSync10, lstatSync as lstatSync6, mkdirSync as mkdirSync7, readFileSync as readFileSync9, renameSync as renameSync2, rmSync as rmSync2, writeFileSync as writeFileSync7 } from "node:fs";
22934
23146
  import { dirname as dirname6, isAbsolute as isAbsolute4, join as join9, resolve as resolve7 } from "node:path";
@@ -24435,6 +24647,7 @@ var RUNTIME_EPOCH_NS = process.hrtime.bigint();
24435
24647
 
24436
24648
  // plugins/kxm/src/vnext-oneshot-evidence.ts
24437
24649
  var TEXT_LIMIT = 4 * 1024 * 1024;
24650
+ var ARGV_LIMIT = 64 * 1024;
24438
24651
  var RECORD_LIMIT = 16 * 1024 * 1024;
24439
24652
 
24440
24653
  // plugins/kxm/src/prices.ts
@@ -25408,7 +25621,7 @@ async function ensureVnextSupervisor(options = {}) {
25408
25621
  clearSupervisorError(paths);
25409
25622
  const scriptPath = join9(repoRoot, "scripts", "kxm-runtime-supervisor.mjs");
25410
25623
  const spawnImpl = options.spawnImpl ?? ((script, env) => {
25411
- const child = spawn(process.execPath, [script], {
25624
+ const child = spawn2(process.execPath, [script], {
25412
25625
  detached: true,
25413
25626
  stdio: "ignore",
25414
25627
  env,
@@ -25458,7 +25671,7 @@ async function vnextRuntimeRequest(handle, method, path4, body) {
25458
25671
  }
25459
25672
 
25460
25673
  // plugins/kxm/src/cli/types.ts
25461
- import { spawn as spawn2 } from "node:child_process";
25674
+ import { spawn as spawn3 } from "node:child_process";
25462
25675
  import { join as join12, resolve as resolve9 } from "node:path";
25463
25676
  import { fileURLToPath as fileURLToPath3 } from "node:url";
25464
25677
 
@@ -25720,7 +25933,7 @@ async function probeHubHealth(url, fetchImpl, timeoutMs = HUB_HEALTH_PROBE_MS) {
25720
25933
  var repoRoot2 = resolve9(fileURLToPath3(new URL("../../../../", import.meta.url)));
25721
25934
  function spawnScript(scriptName, extraEnv = {}) {
25722
25935
  return new Promise((resolveExit) => {
25723
- const child = spawn2(process.execPath, [join12(repoRoot2, "scripts", scriptName)], {
25936
+ const child = spawn3(process.execPath, [join12(repoRoot2, "scripts", scriptName)], {
25724
25937
  stdio: "inherit",
25725
25938
  env: { ...process.env, ...extraEnv }
25726
25939
  });
@@ -29361,7 +29574,6 @@ import { fileURLToPath as fileURLToPath4 } from "node:url";
29361
29574
  // plugins/kxm/src/model-inventory.ts
29362
29575
  var import_yaml11 = __toESM(require_dist(), 1);
29363
29576
  import { mkdirSync as mkdirSync15, writeFileSync as writeFileSync14 } from "node:fs";
29364
- import { spawnSync as spawnSync4 } from "node:child_process";
29365
29577
  import { join as join19 } from "node:path";
29366
29578
  var OR_URL = "https://openrouter.ai/api/v1/models";
29367
29579
  var NOUS_URL = "https://inference-api.nousresearch.com/v1/models";
@@ -29422,10 +29634,10 @@ async function refreshModelInventory(options) {
29422
29634
  if (item.fast === true) current.capabilities.speed = { fast: true, tiers: ["fast"], source };
29423
29635
  byId.set(key, current);
29424
29636
  };
29425
- const native2 = (command, args, source) => {
29426
- const result = spawnSync4(command, args, { encoding: "utf8", timeout: 2e4, shell: false });
29427
- const ok = result.status === 0;
29428
- sources[source] = { url: `${command} ${args.join(" ")}`, ok, ...ok ? {} : { error: (result.stderr || "command failed").trim().slice(0, 240) } };
29637
+ const native2 = async (command, args, source) => {
29638
+ const result = await defaultSpawn(command, args, { env, timeoutMs: 2e4 });
29639
+ const ok = result.code === 0 && !result.error;
29640
+ sources[source] = { url: `${command} ${args.join(" ")}`, ok, ...ok ? {} : { error: (result.stderr || result.error?.message || "command failed").trim().slice(0, 240) } };
29429
29641
  if (!ok) return;
29430
29642
  for (const line of (result.stdout || "").split(/\r?\n/)) {
29431
29643
  const parts = line.trim().split(/\s+/);
@@ -29436,9 +29648,9 @@ async function refreshModelInventory(options) {
29436
29648
  }
29437
29649
  }
29438
29650
  };
29439
- native2("pi", ["--list-models"], "pi");
29440
- native2("grok", ["models"], "grok");
29441
- native2("agy", ["models"], "agy");
29651
+ await native2("pi", ["--list-models"], "pi");
29652
+ await native2("grok", ["models"], "grok");
29653
+ await native2("agy", ["models"], "agy");
29442
29654
  const openrouter = await fetchModels(env.KXM_OPENROUTER_MODELS_URL?.trim() || OR_URL, env.OPENROUTER_API_KEY);
29443
29655
  const openrouterUrl = env.KXM_OPENROUTER_MODELS_URL?.trim() || OR_URL;
29444
29656
  sources.openrouter = { url: openrouterUrl, ok: !openrouter.error, ...openrouter.error ? { error: openrouter.error } : {} };
@@ -29478,7 +29690,7 @@ import {
29478
29690
  import { dirname as dirname13, isAbsolute as isAbsolute6, join as join21, relative as relative4, resolve as resolve18 } from "node:path";
29479
29691
 
29480
29692
  // plugins/kxm/src/vnext-permission.ts
29481
- import { spawnSync as spawnSync5 } from "node:child_process";
29693
+ import { spawnSync as spawnSync4 } from "node:child_process";
29482
29694
  import { createHash as createHash12 } from "node:crypto";
29483
29695
  import { existsSync as existsSync18, mkdtempSync, mkdirSync as mkdirSync16, readFileSync as readFileSync18, rmSync as rmSync6, writeFileSync as writeFileSync15 } from "node:fs";
29484
29696
  import { tmpdir } from "node:os";
@@ -29954,7 +30166,7 @@ function gitEnvironment2() {
29954
30166
  return Object.fromEntries(Object.entries(process.env).filter(([name]) => !name.toUpperCase().startsWith("GIT_")));
29955
30167
  }
29956
30168
  function git(root, args) {
29957
- const result = spawnSync5("git", ["-C", root, ...args], {
30169
+ const result = spawnSync4("git", ["-C", root, ...args], {
29958
30170
  encoding: "utf8",
29959
30171
  env: gitEnvironment2(),
29960
30172
  timeout: 15e3,
@@ -29972,7 +30184,7 @@ function git(root, args) {
29972
30184
  return result.stdout;
29973
30185
  }
29974
30186
  function gitBuffer(root, args) {
29975
- const result = spawnSync5("git", ["-C", root, ...args], {
30187
+ const result = spawnSync4("git", ["-C", root, ...args], {
29976
30188
  env: gitEnvironment2(),
29977
30189
  timeout: 15e3,
29978
30190
  windowsHide: true,
@@ -30170,7 +30382,7 @@ function loadBaseProjectDeclarations(projectFile) {
30170
30382
  return members;
30171
30383
  }
30172
30384
  function initShadowGitRoot(directory) {
30173
- const result = spawnSync5("git", ["-c", "init.defaultBranch=main", "init", "--quiet", directory], {
30385
+ const result = spawnSync4("git", ["-c", "init.defaultBranch=main", "init", "--quiet", directory], {
30174
30386
  encoding: "utf8",
30175
30387
  env: gitEnvironment2(),
30176
30388
  timeout: 1e4,
@@ -33392,7 +33604,7 @@ async function cmdVnextRunList(runtime) {
33392
33604
  }
33393
33605
  }
33394
33606
  async function cmdHarnessList(runtime) {
33395
- const inventory = probeHarnesses({ env: runtime.env });
33607
+ const inventory = await probeHarnessesAsync({ env: runtime.env });
33396
33608
  print(runtime.io, runtime.json, { ok: true, command: "harness list", ...inventory }, formatHarnessInventory(inventory));
33397
33609
  return 0;
33398
33610
  }
@@ -33520,7 +33732,7 @@ async function cmdSuggest(runtime, promptParts) {
33520
33732
  runtime.io.stderr("prompt must be non-empty\n");
33521
33733
  return 2;
33522
33734
  }
33523
- const inventory = probeHarnesses({ env: runtime.env });
33735
+ const inventory = await probeHarnessesAsync({ env: runtime.env });
33524
33736
  const availableHarnesses = inventory.harnesses.map((h) => ({
33525
33737
  harness: h.id,
33526
33738
  auth: h.authenticated === true ? "authenticated" : "unauthenticated"
@@ -43259,7 +43471,7 @@ var MAX_RENDER_WRITE_CHARS = 1024 * 1024;
43259
43471
  // plugins/kxm/src/tui.ts
43260
43472
  import { mkdirSync as mkdirSync22 } from "node:fs";
43261
43473
  import { join as join34, resolve as resolve24, dirname as dirname17 } from "node:path";
43262
- import { spawnSync as spawnSync6 } from "node:child_process";
43474
+ import { spawnSync as spawnSync5 } from "node:child_process";
43263
43475
 
43264
43476
  // plugins/kxm/src/external-effects.ts
43265
43477
  function slugifyBranchPart(text, maxLength = 40) {
@@ -43656,16 +43868,16 @@ function applyMeshTuiKey(view, key, itemCount = 0) {
43656
43868
  function copyToClipboard(text) {
43657
43869
  try {
43658
43870
  if (process.platform === "darwin") {
43659
- const proc = spawnSync6("pbcopy", { input: text, encoding: "utf8", windowsHide: true });
43871
+ const proc = spawnSync5("pbcopy", { input: text, encoding: "utf8", windowsHide: true });
43660
43872
  return proc.status === 0;
43661
43873
  }
43662
43874
  if (process.platform === "win32") {
43663
- const proc = spawnSync6("clip", { input: text, encoding: "utf8", windowsHide: true });
43875
+ const proc = spawnSync5("clip", { input: text, encoding: "utf8", windowsHide: true });
43664
43876
  return proc.status === 0;
43665
43877
  }
43666
- const wl = spawnSync6("wl-copy", [text], { encoding: "utf8", windowsHide: true });
43878
+ const wl = spawnSync5("wl-copy", [text], { encoding: "utf8", windowsHide: true });
43667
43879
  if (wl.status === 0) return true;
43668
- const xclip = spawnSync6("xclip", ["-selection", "clipboard"], { input: text, encoding: "utf8", windowsHide: true });
43880
+ const xclip = spawnSync5("xclip", ["-selection", "clipboard"], { input: text, encoding: "utf8", windowsHide: true });
43669
43881
  return xclip.status === 0;
43670
43882
  } catch {
43671
43883
  return false;
@@ -43673,7 +43885,7 @@ function copyToClipboard(text) {
43673
43885
  }
43674
43886
  function spawnDegradeWorktree(repoRoot6, runId, options) {
43675
43887
  const runner = options?.execFn ?? ((cmd, args) => {
43676
- const res = spawnSync6(cmd, args, {
43888
+ const res = spawnSync5(cmd, args, {
43677
43889
  cwd: repoRoot6,
43678
43890
  encoding: "utf8",
43679
43891
  windowsHide: true,
@@ -44458,7 +44670,7 @@ async function runMeshTui(input) {
44458
44670
  }
44459
44671
 
44460
44672
  // plugins/kxm/src/session-work.ts
44461
- import { spawnSync as spawnSync7 } from "node:child_process";
44673
+ import { spawnSync as spawnSync6 } from "node:child_process";
44462
44674
  import { randomUUID as randomUUID13 } from "node:crypto";
44463
44675
  import { existsSync as existsSync26, mkdirSync as mkdirSync23, readFileSync as readFileSync26, renameSync as renameSync8, writeFileSync as writeFileSync21 } from "node:fs";
44464
44676
  import { join as join35 } from "node:path";
@@ -44516,10 +44728,10 @@ function formatShipLine(ship) {
44516
44728
  }
44517
44729
  function readGitShip(cwd) {
44518
44730
  try {
44519
- const dirty = spawnSync7("git", ["-C", cwd, "status", "--porcelain"], { encoding: "utf8", windowsHide: true });
44731
+ const dirty = spawnSync6("git", ["-C", cwd, "status", "--porcelain"], { encoding: "utf8", windowsHide: true });
44520
44732
  if (dirty.status !== 0) return void 0;
44521
44733
  const isDirty = dirty.stdout.trim().length > 0;
44522
- const upstream = spawnSync7("git", ["-C", cwd, "rev-list", "--count", "@{u}..HEAD"], { encoding: "utf8", windowsHide: true });
44734
+ const upstream = spawnSync6("git", ["-C", cwd, "rev-list", "--count", "@{u}..HEAD"], { encoding: "utf8", windowsHide: true });
44523
44735
  if (upstream.status === 0) {
44524
44736
  return {
44525
44737
  dirty: isDirty,
@@ -44527,9 +44739,9 @@ function readGitShip(cwd) {
44527
44739
  };
44528
44740
  }
44529
44741
  for (const baseRef of ["origin/HEAD", "main", "origin/main", "master", "origin/master"]) {
44530
- const mb = spawnSync7("git", ["-C", cwd, "merge-base", baseRef, "HEAD"], { encoding: "utf8", windowsHide: true });
44742
+ const mb = spawnSync6("git", ["-C", cwd, "merge-base", baseRef, "HEAD"], { encoding: "utf8", windowsHide: true });
44531
44743
  if (mb.status === 0 && mb.stdout.trim()) {
44532
- const count = spawnSync7("git", ["-C", cwd, "rev-list", "--count", `${mb.stdout.trim()}..HEAD`], { encoding: "utf8", windowsHide: true });
44744
+ const count = spawnSync6("git", ["-C", cwd, "rev-list", "--count", `${mb.stdout.trim()}..HEAD`], { encoding: "utf8", windowsHide: true });
44533
44745
  if (count.status === 0) {
44534
44746
  return {
44535
44747
  dirty: isDirty,
@@ -45602,7 +45814,7 @@ async function cmdSessionStart(runtime, options) {
45602
45814
  }
45603
45815
 
45604
45816
  // plugins/kxm/src/cli/system.ts
45605
- import { spawnSync as spawnSync9 } from "node:child_process";
45817
+ import { spawnSync as spawnSync8 } from "node:child_process";
45606
45818
  import { createHash as createHash16 } from "node:crypto";
45607
45819
  import { existsSync as existsSync36, mkdtempSync as mkdtempSync2, readFileSync as readFileSync35, rmSync as rmSync12 } from "node:fs";
45608
45820
  import { tmpdir as tmpdir2 } from "node:os";
@@ -46126,7 +46338,7 @@ ${divider}
46126
46338
  }
46127
46339
 
46128
46340
  // plugins/kxm/src/ssh-remote.ts
46129
- import { spawnSync as spawnSync8 } from "node:child_process";
46341
+ import { spawnSync as spawnSync7 } from "node:child_process";
46130
46342
  import { existsSync as existsSync33, mkdirSync as mkdirSync27, readFileSync as readFileSync33, readdirSync as readdirSync13, rmSync as rmSync11, statSync as statSync5 } from "node:fs";
46131
46343
  import { homedir as homedir7 } from "node:os";
46132
46344
  import { join as join42, resolve as resolve27 } from "node:path";
@@ -46202,7 +46414,7 @@ function parseSshConfig(configPath) {
46202
46414
  return [];
46203
46415
  }
46204
46416
  }
46205
- function resolveSshHostG(host, execFn = spawnSync8) {
46417
+ function resolveSshHostG(host, execFn = spawnSync7) {
46206
46418
  try {
46207
46419
  const result = execFn("ssh", ["-G", host], { encoding: "utf-8" });
46208
46420
  if (result.status !== 0 || !result.stdout) {
@@ -46268,7 +46480,7 @@ function buildSshArgs(options) {
46268
46480
  args.push(options.host);
46269
46481
  return args;
46270
46482
  }
46271
- function checkControlSocket(host, socketDir = DEFAULT_SOCKET_DIR, execFn = spawnSync8) {
46483
+ function checkControlSocket(host, socketDir = DEFAULT_SOCKET_DIR, execFn = spawnSync7) {
46272
46484
  const resolvedDir = ensureSocketDir(socketDir);
46273
46485
  const controlPath = join42(resolvedDir, "%C");
46274
46486
  try {
@@ -46280,7 +46492,7 @@ function checkControlSocket(host, socketDir = DEFAULT_SOCKET_DIR, execFn = spawn
46280
46492
  return false;
46281
46493
  }
46282
46494
  }
46283
- function closeControlSocket(host, socketDir = DEFAULT_SOCKET_DIR, execFn = spawnSync8) {
46495
+ function closeControlSocket(host, socketDir = DEFAULT_SOCKET_DIR, execFn = spawnSync7) {
46284
46496
  const resolvedDir = ensureSocketDir(socketDir);
46285
46497
  const controlPath = join42(resolvedDir, "%C");
46286
46498
  try {
@@ -46294,7 +46506,7 @@ function closeControlSocket(host, socketDir = DEFAULT_SOCKET_DIR, execFn = spawn
46294
46506
  }
46295
46507
  function executeSshRun(params) {
46296
46508
  const startTime = Date.now();
46297
- const execSyncFn = params.execFn ?? spawnSync8;
46509
+ const execSyncFn = params.execFn ?? spawnSync7;
46298
46510
  if (params.action === "info") {
46299
46511
  if (params.host) {
46300
46512
  const hostInfo = resolveSshHostG(params.host, execSyncFn);
@@ -47343,7 +47555,7 @@ function parseGuideSelection(input, catalog = GUIDE_WORKFLOWS) {
47343
47555
  var repoRoot4 = resolve29(fileURLToPath7(new URL("../../../../", import.meta.url)));
47344
47556
  function cliSpawn(runtime, command, args, extra) {
47345
47557
  if (runtime.io.spawnSync) return runtime.io.spawnSync(command, args);
47346
- const result = spawnSync9(command, [...args], {
47558
+ const result = spawnSync8(command, [...args], {
47347
47559
  encoding: "utf8",
47348
47560
  windowsHide: true,
47349
47561
  shell: process.platform === "win32",
@@ -47612,7 +47824,7 @@ async function cmdUpdate(runtime, harness, options) {
47612
47824
  return kxmApply?.ok === false ? 1 : 0;
47613
47825
  }
47614
47826
  const scope = options.self ? "self" : options.extensions ? "extensions" : options.models ? "models" : "all";
47615
- const inventory = probeHarnesses({ env: runtime.env });
47827
+ const inventory = await probeHarnessesAsync({ env: runtime.env });
47616
47828
  const planned = planHarnessUpdate(inventory, { ...harness ? { harness } : {}, scope });
47617
47829
  const steps = runHarnessUpdate(planned, { env: runtime.env, dryRun: runtime.dryRun });
47618
47830
  const failed = steps.some((step) => step.outcome === "failed") || kxmApply?.ok === false;
@@ -47928,7 +48140,7 @@ async function maybeOfferGuideSetup(runtime) {
47928
48140
  if (runtime.env[GUIDE_SETUP_OPT_OUT_ENV]?.trim()) return;
47929
48141
  let inventory;
47930
48142
  try {
47931
- inventory = probeHarnesses({ env: runtime.env });
48143
+ inventory = await probeHarnessesAsync({ env: runtime.env });
47932
48144
  } catch {
47933
48145
  return;
47934
48146
  }
@@ -17036,7 +17036,7 @@ async function deliverInboxNotification(messageId, delivered, notify) {
17036
17036
  }
17037
17037
 
17038
17038
  // plugins/kxm/src/mcp-server.ts
17039
- var VERSION = "0.7.7";
17039
+ var VERSION = "0.7.9";
17040
17040
  var inbox = /* @__PURE__ */ new Map();
17041
17041
  var notifiedInbox = /* @__PURE__ */ new Set();
17042
17042
  var meshClient;