@kontextmind/kxm 0.7.149 → 0.7.151

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.
@@ -3834,7 +3834,7 @@ var require_fast_uri = __commonJS({
3834
3834
  normalizeString(uri, options);
3835
3835
  } else if (typeof uri === "object") {
3836
3836
  uri = /** @type {T} */
3837
- parse10(serialize(uri, options), options);
3837
+ parse11(serialize(uri, options), options);
3838
3838
  }
3839
3839
  return uri;
3840
3840
  }
@@ -3874,8 +3874,8 @@ var require_fast_uri = __commonJS({
3874
3874
  function resolveComponent(base, relative6, options, skipNormalization) {
3875
3875
  const target = {};
3876
3876
  if (!skipNormalization) {
3877
- base = parse10(serialize(base, options), options);
3878
- relative6 = parse10(serialize(relative6, options), options);
3877
+ base = parse11(serialize(base, options), options);
3878
+ relative6 = parse11(serialize(relative6, options), options);
3879
3879
  }
3880
3880
  options = options || {};
3881
3881
  if (!options.tolerant && relative6.scheme) {
@@ -4167,7 +4167,7 @@ var require_fast_uri = __commonJS({
4167
4167
  }
4168
4168
  return { parsed, malformedAuthorityOrPort, malformedPercentEncoding, malformedSchemeSpecific, malformedHost, malformedScheme };
4169
4169
  }
4170
- function parse10(uri, opts) {
4170
+ function parse11(uri, opts) {
4171
4171
  return parseWithStatus(uri, opts).parsed;
4172
4172
  }
4173
4173
  function normalizeString(uri, opts) {
@@ -4204,7 +4204,7 @@ var require_fast_uri = __commonJS({
4204
4204
  resolveComponent,
4205
4205
  equal,
4206
4206
  serialize,
4207
- parse: parse10
4207
+ parse: parse11
4208
4208
  };
4209
4209
  module.exports = fastUri;
4210
4210
  module.exports.default = fastUri;
@@ -14677,7 +14677,7 @@ var require_public_api = __commonJS({
14677
14677
  }
14678
14678
  return doc;
14679
14679
  }
14680
- function parse10(src, reviver, options) {
14680
+ function parse11(src, reviver, options) {
14681
14681
  let _reviver = void 0;
14682
14682
  if (typeof reviver === "function") {
14683
14683
  _reviver = reviver;
@@ -14718,7 +14718,7 @@ var require_public_api = __commonJS({
14718
14718
  return value.toString(options);
14719
14719
  return new Document.Document(value, _replacer, options).toString(options);
14720
14720
  }
14721
- exports.parse = parse10;
14721
+ exports.parse = parse11;
14722
14722
  exports.parseAllDocuments = parseAllDocuments;
14723
14723
  exports.parseDocument = parseDocument3;
14724
14724
  exports.stringify = stringify7;
@@ -14973,7 +14973,7 @@ var TOOL_KEYS = Object.freeze(["preset", "allow", "deny"]);
14973
14973
  var TEMPLATE_KEYS = Object.freeze(["template", "schema"]);
14974
14974
  var POLICY_KEYS = Object.freeze(["vendorIndependenceRequired", "maxTransitions", "requiresGateVerification", "fallback"]);
14975
14975
  var FALLBACK_KEYS = Object.freeze(["onError", "maxSwitches", "revert"]);
14976
- var FALLBACK_ERRORS = Object.freeze(["rate_limit", "transport", "provider_unavailable"]);
14976
+ var FALLBACK_ERRORS = Object.freeze(["rate_limit", "transport", "provider_unavailable", "context_overflow"]);
14977
14977
  var FALLBACK_REVERT = Object.freeze(["next_run", "never"]);
14978
14978
  var ROSTER_ENTRY_KEYS = Object.freeze(["route", "effort", "mode"]);
14979
14979
  var CRITIC_PURPOSES = Object.freeze(["reviewer-arch", "reviewer-cli"]);
@@ -15302,7 +15302,7 @@ function validateRoleShape(document, id, label, issues) {
15302
15302
  if (!closedObject(fallback, FALLBACK_KEYS, path, issues)) return;
15303
15303
  if (fallback.onError !== void 0) {
15304
15304
  if (!Array.isArray(fallback.onError) || new Set(fallback.onError).size !== fallback.onError.length || fallback.onError.some((item) => !FALLBACK_ERRORS.includes(item))) {
15305
- issues.push(issue2("schema", "schema_enum", path, "onError must be unique rate_limit, transport, or provider_unavailable values"));
15305
+ issues.push(issue2("schema", "schema_enum", path, "onError must be unique rate_limit, transport, provider_unavailable, or context_overflow values"));
15306
15306
  }
15307
15307
  }
15308
15308
  if (fallback.maxSwitches !== void 0 && (!Number.isInteger(fallback.maxSwitches) || fallback.maxSwitches < 0)) {
@@ -16982,9 +16982,9 @@ async function probeHarnessesAsync(options = {}) {
16982
16982
  );
16983
16983
  }
16984
16984
  function eligibleHarnesses(inventory) {
16985
- const eligible = inventory.harnesses.filter((entry) => entry !== void 0 && entry.detected && entry.authenticated === true).map((entry) => entry.id);
16986
- if (eligible.length === 0) throw new Error("no_authenticated_harness");
16987
- return eligible;
16985
+ const eligible2 = inventory.harnesses.filter((entry) => entry !== void 0 && entry.detected && entry.authenticated === true).map((entry) => entry.id);
16986
+ if (eligible2.length === 0) throw new Error("no_authenticated_harness");
16987
+ return eligible2;
16988
16988
  }
16989
16989
  function validateHarnessModelPair(harnessId, modelSpec) {
16990
16990
  if (!isKnownHarnessId(harnessId)) {
@@ -18139,8 +18139,8 @@ function validateWorkflow(workflow, agents, models, repositories, gates, issues)
18139
18139
  const writable = Object.values(objectValue(step.repositories) ?? {}).filter((access) => access === "write").length;
18140
18140
  if (maxWriteRepositories > writable) issues.push(issue3("semantic", "write_repository_bound_invalid", file, `${stepId} maxWriteRepositories exceeds writable repository scope`));
18141
18141
  }
18142
- const join24 = objectValue(step.join);
18143
- const minimumPassed = join24 && typeof join24.minimumPassed === "number" ? join24.minimumPassed : void 0;
18142
+ const join25 = objectValue(step.join);
18143
+ const minimumPassed = join25 && typeof join25.minimumPassed === "number" ? join25.minimumPassed : void 0;
18144
18144
  if (minimumPassed !== void 0 && minimumPassed > maximum) issues.push(issue3("semantic", "join_impossible", file, `${stepId} minimumPassed exceeds assignment maximum`));
18145
18145
  const distinctBy = names(assignment?.distinctBy);
18146
18146
  if (distinctBy.length > 0) {
@@ -18161,10 +18161,10 @@ function validateWorkflow(workflow, agents, models, repositories, gates, issues)
18161
18161
  }
18162
18162
  const policy = objectValue(requirement.producerPolicy);
18163
18163
  if (!policy) continue;
18164
- const eligible = names(policy.eligibleAgents);
18164
+ const eligible2 = names(policy.eligibleAgents);
18165
18165
  const producerMinimum = numberValue(policy.minimumProducers, 1);
18166
- if (producerMinimum > target || producerMinimum > eligible.length) issues.push(issue3("semantic", "producer_minimum_impossible", file, `${stepId}.${String(key)} producer minimum exceeds its eligible or target pool`));
18167
- for (const agentId of eligible) {
18166
+ if (producerMinimum > target || producerMinimum > eligible2.length) issues.push(issue3("semantic", "producer_minimum_impossible", file, `${stepId}.${String(key)} producer minimum exceeds its eligible or target pool`));
18167
+ for (const agentId of eligible2) {
18168
18168
  if (!lookupKxmResource(agents.values(), agentId, "agent")) issues.push(issue3("reference", "producer_agent_unknown", file, `${stepId}.${String(key)} references unknown producer ${agentId}`));
18169
18169
  if (allowedAgents.length > 0 && !allowedAgents.includes(agentId)) issues.push(issue3("semantic", "producer_agent_ineligible", file, `${stepId}.${String(key)} producer ${agentId} is outside allowedAgents`));
18170
18170
  }
@@ -22191,6 +22191,7 @@ function foldKxmRunState(run, plan, events, options = {}) {
22191
22191
  foldEffectUncertain(state, plan, event);
22192
22192
  break;
22193
22193
  case "routing.attempt.recorded":
22194
+ case "routing.route_switched":
22194
22195
  break;
22195
22196
  default:
22196
22197
  throw runtimeError("run_events_illegal", run.runId, `event type ${event.eventType} is not legal in this engine slice`);
@@ -23210,7 +23211,7 @@ function compileStep(step, index, stepIndex, requirePlanHash, sink) {
23210
23211
  const maxAttempts = compileCountField(step.maxAttempts, 1, `${id}.maxAttempts`, id, sink);
23211
23212
  const timeoutMs = compileOptionalDuration(step.timeoutMs, `${id}.timeoutMs`, id, sink);
23212
23213
  const assignments = compileAssignments(step, id, agent, sink);
23213
- const join24 = compileJoin(step, id, sink);
23214
+ const join25 = compileJoin(step, id, sink);
23214
23215
  const requiredEvidence = compileEvidence(step, id, sink);
23215
23216
  const transitions = compileTransitions(step, id, index, stepIndex, sink);
23216
23217
  const outcomes = Object.keys(transitions).sort(compareCodeUnits5);
@@ -23238,7 +23239,7 @@ function compileStep(step, index, stepIndex, requirePlanHash, sink) {
23238
23239
  transitions: orderedTransitions,
23239
23240
  requiresPlanHash: requirePlanHash.includes(id),
23240
23241
  assignments,
23241
- join: join24
23242
+ join: join25
23242
23243
  };
23243
23244
  if (kind === "agent" || kind === "moa") {
23244
23245
  if (!agent) return void 0;
@@ -23288,15 +23289,15 @@ function compileAssignments(step, stepId, primaryAgentId, sink) {
23288
23289
  };
23289
23290
  }
23290
23291
  function compileJoin(step, stepId, sink) {
23291
- const join24 = objectValue2(step.join);
23292
- if (!join24) return { strategy: "all" };
23293
- const declared = stringValue2(join24.strategy);
23292
+ const join25 = objectValue2(step.join);
23293
+ if (!join25) return { strategy: "all" };
23294
+ const declared = stringValue2(join25.strategy);
23294
23295
  const strategy = declared && JOIN_STRATEGIES.has(declared) ? declared : "all";
23295
- const minimumPassed = compileOptionalCount(join24.minimumPassed, `${stepId}.join.minimumPassed`, stepId, sink);
23296
+ const minimumPassed = compileOptionalCount(join25.minimumPassed, `${stepId}.join.minimumPassed`, stepId, sink);
23296
23297
  const compiled = {
23297
23298
  strategy,
23298
23299
  ...minimumPassed !== void 0 ? { minimumPassed } : {},
23299
- ...typeof join24.cancelRemaining === "boolean" ? { cancelRemaining: join24.cancelRemaining } : {}
23300
+ ...typeof join25.cancelRemaining === "boolean" ? { cancelRemaining: join25.cancelRemaining } : {}
23300
23301
  };
23301
23302
  return compiled;
23302
23303
  }
@@ -25180,9 +25181,9 @@ function assertKxmConfigError(error) {
25180
25181
  // plugins/kxm/src/runtime-supervisor.ts
25181
25182
  import { spawn as spawn3 } from "node:child_process";
25182
25183
  import { createHash as createHash16, createHmac, randomBytes as randomBytes3, timingSafeEqual as timingSafeEqual2 } from "node:crypto";
25183
- import { chmodSync as chmodSync2, existsSync as existsSync17, lstatSync as lstatSync6, mkdirSync as mkdirSync9, readFileSync as readFileSync14, renameSync as renameSync5, rmSync as rmSync4, writeFileSync as writeFileSync9 } from "node:fs";
25184
+ import { chmodSync as chmodSync2, existsSync as existsSync18, lstatSync as lstatSync6, mkdirSync as mkdirSync9, readFileSync as readFileSync15, renameSync as renameSync5, rmSync as rmSync4, writeFileSync as writeFileSync9 } from "node:fs";
25184
25185
  import { createServer } from "node:http";
25185
- import { dirname as dirname11, isAbsolute as isAbsolute8, join as join19 } from "node:path";
25186
+ import { dirname as dirname11, isAbsolute as isAbsolute8, join as join20 } from "node:path";
25186
25187
 
25187
25188
  // plugins/kxm/src/oneshot-evidence.ts
25188
25189
  import { createHash as createHash10, randomUUID as randomUUID3 } from "node:crypto";
@@ -25511,10 +25512,10 @@ function loadPriceCatalogForEstimate(options) {
25511
25512
  }
25512
25513
 
25513
25514
  // plugins/kxm/src/engine.ts
25514
- var import_yaml10 = __toESM(require_dist(), 1);
25515
+ var import_yaml11 = __toESM(require_dist(), 1);
25515
25516
  import { createHash as createHash15, randomBytes as randomBytes2, timingSafeEqual } from "node:crypto";
25516
- import { existsSync as existsSync13, readFileSync as readFileSync11 } from "node:fs";
25517
- import { join as join16 } from "node:path";
25517
+ import { existsSync as existsSync14, readFileSync as readFileSync12 } from "node:fs";
25518
+ import { join as join17 } from "node:path";
25518
25519
 
25519
25520
  // plugins/kxm/src/routes.ts
25520
25521
  var import_yaml7 = __toESM(require_dist(), 1);
@@ -25550,6 +25551,363 @@ function listRoleBindings(root) {
25550
25551
  return result;
25551
25552
  }
25552
25553
 
25554
+ // plugins/kxm/src/route-fallback.ts
25555
+ var import_yaml8 = __toESM(require_dist(), 1);
25556
+ import { existsSync as existsSync11, readdirSync as readdirSync7, readFileSync as readFileSync9 } from "node:fs";
25557
+ import { join as join12 } from "node:path";
25558
+
25559
+ // plugins/kxm/src/route-switch.ts
25560
+ var WALKABLE_CLASSES = ["rate_limit", "transport", "provider_unavailable", "context_overflow"];
25561
+ var EFFORTS2 = /* @__PURE__ */ new Set(["off", "minimal", "low", "medium", "high", "xhigh", "max"]);
25562
+
25563
+ // plugins/kxm/src/route-fallback.ts
25564
+ var CARRY_ROLES = /* @__PURE__ */ new Set(["user", "assistant", "tool"]);
25565
+ var MAX_CARRY_MESSAGES = 8;
25566
+ var MAX_CARRY_TEXT = 2e3;
25567
+ var MAX_CARRY_TOTAL = 8e3;
25568
+ var DEFAULT_MAX_SWITCHES = 1;
25569
+ function classifyRouteFailure(input) {
25570
+ const code = (input.code ?? "").toLowerCase();
25571
+ const text = `${code} ${input.text ?? ""}`.toLowerCase();
25572
+ const name = (input.name ?? "").toLowerCase();
25573
+ const status = input.httpStatus;
25574
+ const result = (failureClass) => ({
25575
+ class: failureClass,
25576
+ walkable: WALKABLE_CLASSES.includes(failureClass)
25577
+ });
25578
+ if (name === "aborterror" || /\b(?:user_cancelled|cancelled|cancellation)\b/.test(text) || code === "process_aborted" || text.includes("abort")) {
25579
+ return result("cancelled");
25580
+ }
25581
+ if (/policy_refusal|content_policy|tool_policy|usage policy|safety/.test(text) || text.includes("policy refusal")) {
25582
+ return result("policy_refusal");
25583
+ }
25584
+ if (code.includes("not_authenticated") || /unauthori[sz]ed|authentication|invalid api key|auth_failed|\bauth\b/.test(text) || status === 401 || status === 403) {
25585
+ return result("auth");
25586
+ }
25587
+ if (/permission_profile_unaudited|writer_profile_unaudited|tool_policy/.test(text)) {
25588
+ return result("tool_policy");
25589
+ }
25590
+ if (/harness_unhosted_model|unhosted|does not host/.test(text)) {
25591
+ return result("unhosted_model");
25592
+ }
25593
+ if (code.startsWith("gate_") || text.includes("gate_unsupported") || text.includes("gate_failed")) {
25594
+ return result("gate");
25595
+ }
25596
+ if (code === "producer_route_not_admitted" || text.includes("not_admitted") || text.includes("not admitted")) {
25597
+ return result("admission");
25598
+ }
25599
+ if (status === 413 || /context_overflow|context length|context window|maximum context|token limit|prompt too long|context overflow/.test(text)) {
25600
+ return result("context_overflow");
25601
+ }
25602
+ if (status === 429 || /rate_limit|rate limit|ratelimit|too many requests/.test(text)) {
25603
+ return result("rate_limit");
25604
+ }
25605
+ if (status === 408 || status === 502 || status === 504 || code === "process_timeout" || /etimedout|econnreset|econnrefused|enotfound|eai_again|socket hang up|\btimeout\b|timed out|\btransport\b/.test(text)) {
25606
+ return result("transport");
25607
+ }
25608
+ if (status === 500 || status === 503 || /provider_unavailable|model unavailable|service unavailable|overloaded|model_not_found|no available model/.test(text)) {
25609
+ return result("provider_unavailable");
25610
+ }
25611
+ return result("unknown");
25612
+ }
25613
+ function parseFallbackPolicy(value) {
25614
+ if (!value || typeof value !== "object" || Array.isArray(value)) return void 0;
25615
+ const record2 = value;
25616
+ const onErrorRaw = record2.onError;
25617
+ if (!Array.isArray(onErrorRaw) || onErrorRaw.length === 0) return void 0;
25618
+ if (new Set(onErrorRaw).size !== onErrorRaw.length) return void 0;
25619
+ const onError = [];
25620
+ for (const item of onErrorRaw) {
25621
+ if (typeof item !== "string" || !WALKABLE_CLASSES.includes(item)) return void 0;
25622
+ onError.push(item);
25623
+ }
25624
+ let maxSwitches = DEFAULT_MAX_SWITCHES;
25625
+ if (record2.maxSwitches !== void 0) {
25626
+ if (!Number.isInteger(record2.maxSwitches) || record2.maxSwitches < 0) return void 0;
25627
+ maxSwitches = record2.maxSwitches;
25628
+ }
25629
+ let revert = "next_run";
25630
+ if (record2.revert !== void 0) {
25631
+ if (record2.revert !== "next_run" && record2.revert !== "never") return void 0;
25632
+ revert = record2.revert;
25633
+ }
25634
+ return { onError, maxSwitches, revert };
25635
+ }
25636
+ function admittedSelector(model, admitted, disabled) {
25637
+ const candidates = [model.model, `${model.vendor}/${model.model}`, `${model.harness}/${model.model}`];
25638
+ const selector = candidates.find((candidate) => admitted.has(candidate));
25639
+ if (!selector || disabled.has(selector)) return void 0;
25640
+ return selector;
25641
+ }
25642
+ function splitSelector(selector) {
25643
+ const slash = selector.indexOf("/");
25644
+ if (slash <= 0 || slash === selector.length - 1) return void 0;
25645
+ return { provider: selector.slice(0, slash), model: selector.slice(slash + 1) };
25646
+ }
25647
+ function eligible(model, admitted, disabled, liveWrite) {
25648
+ if (model.status !== "admitted" || !model.hosted) return void 0;
25649
+ if (liveWrite && (!model.permissions.includes("edit") || !model.writerReady || !model.onWriterRoster)) return void 0;
25650
+ const selector = admittedSelector(model, admitted, disabled);
25651
+ if (!selector) return void 0;
25652
+ const parts = splitSelector(selector);
25653
+ if (!parts) return void 0;
25654
+ return {
25655
+ routeId: model.routeId,
25656
+ harness: model.harness,
25657
+ provider: parts.provider,
25658
+ model: parts.model,
25659
+ selector,
25660
+ vendor: model.vendor,
25661
+ permissions: model.permissions,
25662
+ priority: model.priority
25663
+ };
25664
+ }
25665
+ function selectorsFor2(fallback, models) {
25666
+ if (fallback.profile) {
25667
+ const model = models.find((item) => item.routeId === fallback.profile);
25668
+ return model ? [model] : [];
25669
+ }
25670
+ if (fallback.tag) {
25671
+ const required2 = new Set(fallback.capabilities ?? []);
25672
+ return models.filter((item) => item.tags.includes(fallback.tag) && [...required2].every((capability) => item.capabilities.includes(capability))).slice().sort((left, right) => right.priority - left.priority || left.routeId.localeCompare(right.routeId));
25673
+ }
25674
+ if (fallback.provider && fallback.model) {
25675
+ return models.filter((item) => item.vendor === fallback.provider && item.model === fallback.model);
25676
+ }
25677
+ return [];
25678
+ }
25679
+ function buildFallbackChain(input) {
25680
+ const admitted = new Set(input.admitted);
25681
+ const disabled = new Set(input.disabled);
25682
+ const critics = new Set(input.criticVendors ?? []);
25683
+ const byId = new Map(input.models.map((model) => [model.routeId, model]));
25684
+ const chain = [];
25685
+ const seen = /* @__PURE__ */ new Set();
25686
+ const entries = [...input.roster, ...input.extendsRoster ?? []];
25687
+ const push2 = (model, effort) => {
25688
+ if (!model || seen.has(model.routeId)) return;
25689
+ const candidate = eligible(model, admitted, disabled, input.liveWrite);
25690
+ if (!candidate) return;
25691
+ if (input.vendorIndependenceRequired && chain.length > 0 && critics.has(candidate.vendor)) return;
25692
+ seen.add(model.routeId);
25693
+ const resolvedEffort = effort && EFFORTS2.has(effort) ? effort : void 0;
25694
+ chain.push(resolvedEffort ? { ...candidate, effort: resolvedEffort } : candidate);
25695
+ };
25696
+ for (const entry of entries) {
25697
+ const model = byId.get(entry.route);
25698
+ push2(model, entry.effort);
25699
+ if (!model) continue;
25700
+ for (const fallback of model.fallbacks) {
25701
+ for (const resolved of selectorsFor2(fallback, input.models)) push2(resolved, entry.effort);
25702
+ }
25703
+ }
25704
+ return chain;
25705
+ }
25706
+ function decideRouteSwitch(input) {
25707
+ if (!input.policy || input.policy.onError.length === 0) return { action: "continue", cause: "disabled" };
25708
+ if (!input.failure.walkable) return { action: "continue", cause: "not_walkable" };
25709
+ if (!input.policy.onError.includes(input.failure.class)) {
25710
+ return { action: "continue", cause: "class_not_opted_in" };
25711
+ }
25712
+ if (input.switchesUsed >= input.policy.maxSwitches) return { action: "continue", cause: "budget" };
25713
+ const index = input.chain.findIndex((candidate) => candidate.routeId === input.currentRouteId);
25714
+ const next = index >= 0 ? input.chain[index + 1] : void 0;
25715
+ if (!next) return { action: "continue", cause: "no_candidate" };
25716
+ const effort = next.effort ?? (input.currentEffort && EFFORTS2.has(input.currentEffort) ? input.currentEffort : void 0);
25717
+ return {
25718
+ action: "switch",
25719
+ to: next,
25720
+ reason: input.failure.class,
25721
+ ...effort ? { effort } : {}
25722
+ };
25723
+ }
25724
+ function parseSessionCarry(value) {
25725
+ if (!value || typeof value !== "object" || Array.isArray(value)) return void 0;
25726
+ const transcript = value.transcript;
25727
+ if (!Array.isArray(transcript) || transcript.length === 0) return void 0;
25728
+ const messages = [];
25729
+ let total = 0;
25730
+ for (const item of transcript) {
25731
+ if (messages.length >= MAX_CARRY_MESSAGES) break;
25732
+ if (!item || typeof item !== "object" || Array.isArray(item)) continue;
25733
+ const role = item.role;
25734
+ const text = item.text;
25735
+ if (typeof role !== "string" || !CARRY_ROLES.has(role) || typeof text !== "string" || text.length === 0) continue;
25736
+ const clipped = text.slice(0, MAX_CARRY_TEXT);
25737
+ if (total + clipped.length > MAX_CARRY_TOTAL) break;
25738
+ total += clipped.length;
25739
+ messages.push({ role, text: clipped });
25740
+ }
25741
+ return messages.length > 0 ? { transcript: messages } : void 0;
25742
+ }
25743
+ function mergeSessionCarry(left, right) {
25744
+ return parseSessionCarry({ transcript: [...left?.transcript ?? [], ...right?.transcript ?? []] });
25745
+ }
25746
+ function carryForwardPrompt(prompt, carry) {
25747
+ if (!carry || carry.transcript.length === 0) return prompt;
25748
+ const lines = carry.transcript.map((message) => `${message.role}: ${message.text}`);
25749
+ const block = `Prior attempt transcript:
25750
+ ${lines.join("\n")}`;
25751
+ if (!prompt || prompt.length === 0) return block;
25752
+ return `${prompt}
25753
+
25754
+ ${block}`;
25755
+ }
25756
+ function readYaml(file) {
25757
+ if (!existsSync11(file)) return void 0;
25758
+ try {
25759
+ const parsed = (0, import_yaml8.parse)(readFileSync9(file, "utf8"));
25760
+ if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) return void 0;
25761
+ return parsed;
25762
+ } catch {
25763
+ return void 0;
25764
+ }
25765
+ }
25766
+ function stringList(value) {
25767
+ return Array.isArray(value) ? value.filter((item) => typeof item === "string") : [];
25768
+ }
25769
+ function readSelectors(projectRoot, value) {
25770
+ if (!Array.isArray(value)) return [];
25771
+ const modelsDir = join12(projectRoot, ".kxm", "models");
25772
+ const selectors = [];
25773
+ for (const item of value) {
25774
+ if (!item || typeof item !== "object" || Array.isArray(item)) continue;
25775
+ const record2 = item;
25776
+ if (typeof record2.profile === "string") {
25777
+ selectors.push({ profile: findYamlBasename(modelsDir, record2.profile, "route") ?? record2.profile });
25778
+ } else if (typeof record2.tag === "string") {
25779
+ selectors.push({
25780
+ tag: record2.tag,
25781
+ ...Array.isArray(record2.capabilities) ? { capabilities: stringList(record2.capabilities) } : {}
25782
+ });
25783
+ } else if (typeof record2.provider === "string" && typeof record2.model === "string") {
25784
+ selectors.push({ provider: record2.provider, model: record2.model });
25785
+ }
25786
+ }
25787
+ return selectors;
25788
+ }
25789
+ function loadChainModel(projectRoot, routeId2, writerIds) {
25790
+ const modelsDir = join12(projectRoot, ".kxm", "models");
25791
+ const fileId = findYamlBasename(modelsDir, routeId2, "route") ?? routeId2;
25792
+ const doc = readYaml(join12(modelsDir, `${fileId}.yaml`));
25793
+ if (!doc || doc.schema !== "kxm.model.v2") return void 0;
25794
+ const harness = typeof doc.harness === "string" ? doc.harness : "";
25795
+ const model = typeof doc.model === "string" ? doc.model : "";
25796
+ const vendor = typeof doc.vendor === "string" ? doc.vendor : "";
25797
+ if (!harness || !model || !vendor) return void 0;
25798
+ const permissions = stringList(doc.permissions);
25799
+ const selector = [model, `${vendor}/${model}`, `${harness}/${model}`].find((candidate) => candidate.includes("/")) ?? `${vendor}/${model}`;
25800
+ const parts = splitSelector(selector);
25801
+ const hosted = parts ? validateHarnessModelPair(harness, { provider: parts.provider, model: parts.model }).valid : false;
25802
+ return {
25803
+ routeId: fileId,
25804
+ harness,
25805
+ model,
25806
+ vendor,
25807
+ status: typeof doc.status === "string" ? doc.status : "",
25808
+ permissions,
25809
+ tags: stringList(doc.tags),
25810
+ capabilities: stringList(doc.capabilities),
25811
+ priority: typeof doc.priority === "number" ? doc.priority : 0,
25812
+ fallbacks: readSelectors(projectRoot, doc.fallbacks),
25813
+ hosted,
25814
+ writerReady: oneShotWriterArgs(harness) !== void 0,
25815
+ onWriterRoster: writerIds.has(fileId) || writerIds.has(routeId2)
25816
+ };
25817
+ }
25818
+ function canonicalRoster(projectRoot, entries) {
25819
+ const modelsDir = join12(projectRoot, ".kxm", "models");
25820
+ return entries.map((entry) => {
25821
+ const route = findYamlBasename(modelsDir, entry.route, "route") ?? entry.route;
25822
+ return entry.effort ? { route, effort: entry.effort } : { route };
25823
+ });
25824
+ }
25825
+ function rosterEntries(doc) {
25826
+ if (!Array.isArray(doc?.roster)) return [];
25827
+ const entries = [];
25828
+ for (const item of doc.roster) {
25829
+ if (!item || typeof item !== "object" || Array.isArray(item)) continue;
25830
+ const route = item.route;
25831
+ const effort = item.effort;
25832
+ if (typeof route !== "string" || route.length === 0) continue;
25833
+ entries.push(typeof effort === "string" ? { route, effort } : { route });
25834
+ }
25835
+ return entries;
25836
+ }
25837
+ function loadModelsFor(projectRoot, roster, writerIds) {
25838
+ const modelsDir = join12(projectRoot, ".kxm", "models");
25839
+ const wanted = /* @__PURE__ */ new Set();
25840
+ for (const entry of roster) wanted.add(entry.route);
25841
+ if (existsSync11(modelsDir)) {
25842
+ for (const name of readdirSync7(modelsDir)) {
25843
+ if (!name.endsWith(".yaml") || name === "inventory.yaml") continue;
25844
+ wanted.add(name.slice(0, -5));
25845
+ }
25846
+ }
25847
+ const models = [];
25848
+ const seen = /* @__PURE__ */ new Set();
25849
+ for (const routeId2 of wanted) {
25850
+ const model = loadChainModel(projectRoot, routeId2, writerIds);
25851
+ if (!model || seen.has(model.routeId)) continue;
25852
+ seen.add(model.routeId);
25853
+ models.push(model);
25854
+ }
25855
+ return models;
25856
+ }
25857
+ function criticVendors(projectRoot, writerIds) {
25858
+ const dir = join12(projectRoot, ".kxm", "roles");
25859
+ if (!existsSync11(dir)) return [];
25860
+ const vendors = [];
25861
+ for (const name of readdirSync7(dir)) {
25862
+ if (!name.endsWith(".yaml")) continue;
25863
+ const doc = readYaml(join12(dir, name));
25864
+ const purpose = doc?.purpose;
25865
+ if (purpose !== "reviewer-arch" && purpose !== "reviewer-cli") continue;
25866
+ const first = rosterEntries(doc)[0];
25867
+ if (!first) continue;
25868
+ const model = loadChainModel(projectRoot, first.route, writerIds);
25869
+ if (model?.status === "admitted") vendors.push(model.vendor);
25870
+ }
25871
+ return vendors;
25872
+ }
25873
+ function loadAgentFallback(projectRoot, agentId, options) {
25874
+ const agentsDir = join12(projectRoot, ".kxm", "agents");
25875
+ const agentFile = findYamlBasename(agentsDir, agentId, "agent") ?? agentId;
25876
+ const agent = readYaml(join12(agentsDir, `${agentFile}.yaml`));
25877
+ const roleId = typeof agent?.role === "string" ? agent.role : "";
25878
+ if (!roleId) return void 0;
25879
+ const role = readYaml(join12(projectRoot, ".kxm", "roles", `${roleId}.yaml`));
25880
+ if (!role) return void 0;
25881
+ const policyRecord = role.policy && typeof role.policy === "object" ? role.policy.fallback : void 0;
25882
+ const policy = parseFallbackPolicy(policyRecord);
25883
+ if (!policy) return void 0;
25884
+ const own2 = canonicalRoster(projectRoot, rosterEntries(role));
25885
+ const seenRoles = /* @__PURE__ */ new Set([roleId]);
25886
+ let extendsRoster = [];
25887
+ let cursor = typeof role.extends === "string" ? role.extends : "";
25888
+ while (cursor && !seenRoles.has(cursor)) {
25889
+ seenRoles.add(cursor);
25890
+ const parent = readYaml(join12(projectRoot, ".kxm", "roles", `${cursor}.yaml`));
25891
+ extendsRoster = extendsRoster.concat(canonicalRoster(projectRoot, rosterEntries(parent)));
25892
+ cursor = typeof parent?.extends === "string" ? parent.extends : "";
25893
+ }
25894
+ const writerIds = new Set(listRoleBindings(projectRoot).writer ?? []);
25895
+ const models = loadModelsFor(projectRoot, [...own2, ...extendsRoster], writerIds);
25896
+ const routePolicy = loadRoutePolicy(projectRoot);
25897
+ const independence = Boolean(role.policy && typeof role.policy === "object" && role.policy.vendorIndependenceRequired);
25898
+ const chain = buildFallbackChain({
25899
+ roster: own2,
25900
+ extendsRoster,
25901
+ models,
25902
+ admitted: routePolicy.admitted,
25903
+ disabled: routePolicy.disabled,
25904
+ liveWrite: options.liveWrite,
25905
+ criticVendors: independence ? criticVendors(projectRoot, writerIds) : [],
25906
+ vendorIndependenceRequired: independence
25907
+ });
25908
+ return { policy, chain, roleId };
25909
+ }
25910
+
25553
25911
  // plugins/kxm/src/worktree-witness.ts
25554
25912
  import { spawnSync as spawnSync4 } from "node:child_process";
25555
25913
  function gitText(cwd, args) {
@@ -25876,8 +26234,8 @@ function pruneContextPacket(packet, tokenBudget) {
25876
26234
 
25877
26235
  // plugins/kxm/src/dispatch-context.ts
25878
26236
  import { spawnSync as spawnSync5 } from "node:child_process";
25879
- import { readdirSync as readdirSync9 } from "node:fs";
25880
- import { extname as extname3, join as join14 } from "node:path";
26237
+ import { readdirSync as readdirSync10 } from "node:fs";
26238
+ import { extname as extname3, join as join15 } from "node:path";
25881
26239
 
25882
26240
  // plugins/kxm/src/protocol.ts
25883
26241
  var DEFAULT_MESSAGE_TTL_MS = 24 * 60 * 6e4;
@@ -26409,16 +26767,16 @@ function arbitrate(requestInput, pool, options = {}) {
26409
26767
  };
26410
26768
  const allowedKinds = new Set(requestedKinds);
26411
26769
  const inertProposal = (item) => item.kind === "state" && item.status !== void 0 && item.status !== "current" || item.kind === "skill" && item.status === "proposed";
26412
- const eligible = candidates.filter((item) => contradictions.has(item.id) || allowedKinds.has(item.kind) && !inertProposal(item));
26413
- const scoreList = scoreRelevance(request.task, eligible.map(contextItemRelevanceText));
26770
+ const eligible2 = candidates.filter((item) => contradictions.has(item.id) || allowedKinds.has(item.kind) && !inertProposal(item));
26771
+ const scoreList = scoreRelevance(request.task, eligible2.map(contextItemRelevanceText));
26414
26772
  const scores = /* @__PURE__ */ new Map();
26415
- eligible.forEach((item, index) => scores.set(item, scoreList[index] ?? 0));
26773
+ eligible2.forEach((item, index) => scores.set(item, scoreList[index] ?? 0));
26416
26774
  const scoreOf = (item) => scores.get(item) ?? 0;
26417
26775
  const when = (item) => {
26418
26776
  const parsed = Date.parse(item.observedAt ?? item.validFrom ?? "");
26419
26777
  return Number.isFinite(parsed) ? parsed : 0;
26420
26778
  };
26421
- const ordered = [...eligible].sort(
26779
+ const ordered = [...eligible2].sort(
26422
26780
  (left, right) => (contradictions.has(right.id) ? 1 : 0) - (contradictions.has(left.id) ? 1 : 0) || (left.project === request.project ? 0 : 1) - (right.project === request.project ? 0 : 1) || (scoreOf(right) > 0 ? 1 : 0) - (scoreOf(left) > 0 ? 1 : 0) || kindPreference(left) - kindPreference(right) || scoreOf(right) - scoreOf(left) || CONFIDENCE_RANK[right.confidence] - CONFIDENCE_RANK[left.confidence] || AUTHORITY_WEIGHT[right.authority] - AUTHORITY_WEIGHT[left.authority] || when(right) - when(left) || compareCodeUnitIds(left.id, right.id)
26423
26781
  );
26424
26782
  const selected = [];
@@ -26508,9 +26866,9 @@ function memoryRecordToContextItem(record2, project) {
26508
26866
  }
26509
26867
 
26510
26868
  // plugins/kxm/src/memory.ts
26511
- var import_yaml8 = __toESM(require_dist(), 1);
26512
- import { existsSync as existsSync11, mkdirSync as mkdirSync4, readdirSync as readdirSync7, readFileSync as readFileSync9, writeFileSync as writeFileSync5 } from "node:fs";
26513
- import { extname as extname2, join as join12, resolve as resolve7 } from "node:path";
26869
+ var import_yaml9 = __toESM(require_dist(), 1);
26870
+ import { existsSync as existsSync12, mkdirSync as mkdirSync4, readdirSync as readdirSync8, readFileSync as readFileSync10, writeFileSync as writeFileSync5 } from "node:fs";
26871
+ import { extname as extname2, join as join13, resolve as resolve7 } from "node:path";
26514
26872
  var MEMORY_SCHEMA = "kxm.memory.v1";
26515
26873
  var VALID_SCOPES = /* @__PURE__ */ new Set(["agent", "project", "run", "operator"]);
26516
26874
  var VALID_AUTHORITIES = /* @__PURE__ */ new Set(["instruction", "evidence", "promoted"]);
@@ -26540,7 +26898,7 @@ function parseFrontmatter(content) {
26540
26898
  }
26541
26899
  function parseMemoryRecord(raw, filename = "memory.md") {
26542
26900
  const { frontmatter, body } = parseFrontmatter(raw);
26543
- const data = (0, import_yaml8.parse)(frontmatter);
26901
+ const data = (0, import_yaml9.parse)(frontmatter);
26544
26902
  if (!data || typeof data !== "object" || Array.isArray(data)) {
26545
26903
  throw new Error(`invalid YAML frontmatter in ${filename}`);
26546
26904
  }
@@ -26609,20 +26967,20 @@ function parseMemoryRecord(raw, filename = "memory.md") {
26609
26967
  }
26610
26968
  function memoryDirectories(repoRoot) {
26611
26969
  const root = resolve7(repoRoot);
26612
- const memoryDir = join12(root, ".kxm", "memory");
26613
- const candidatesDir = join12(memoryDir, "candidates");
26970
+ const memoryDir = join13(root, ".kxm", "memory");
26971
+ const candidatesDir = join13(memoryDir, "candidates");
26614
26972
  return { memoryDir, candidatesDir };
26615
26973
  }
26616
26974
  function loadAuthoredMemory(repoRoot) {
26617
26975
  const { memoryDir } = memoryDirectories(repoRoot);
26618
- if (!existsSync11(memoryDir)) return [];
26976
+ if (!existsSync12(memoryDir)) return [];
26619
26977
  const records = [];
26620
- const entries = readdirSync7(memoryDir, { withFileTypes: true });
26978
+ const entries = readdirSync8(memoryDir, { withFileTypes: true });
26621
26979
  for (const entry of entries) {
26622
26980
  if (entry.isFile() && extname2(entry.name) === ".md") {
26623
- const fullPath = join12(memoryDir, entry.name);
26981
+ const fullPath = join13(memoryDir, entry.name);
26624
26982
  try {
26625
- const text = readFileSync9(fullPath, "utf8");
26983
+ const text = readFileSync10(fullPath, "utf8");
26626
26984
  const record2 = parseMemoryRecord(text, entry.name);
26627
26985
  if (record2.lifecycle === "active") {
26628
26986
  records.push(record2);
@@ -26636,10 +26994,10 @@ function loadAuthoredMemory(repoRoot) {
26636
26994
  }
26637
26995
 
26638
26996
  // plugins/kxm/src/skills.ts
26639
- var import_yaml9 = __toESM(require_dist(), 1);
26997
+ var import_yaml10 = __toESM(require_dist(), 1);
26640
26998
  import { createHash as createHash12 } from "node:crypto";
26641
- import { existsSync as existsSync12, mkdirSync as mkdirSync5, readdirSync as readdirSync8, readFileSync as readFileSync10, renameSync, rmSync, statSync as statSync3, writeFileSync as writeFileSync6 } from "node:fs";
26642
- import { dirname as dirname7, join as join13 } from "node:path";
26999
+ import { existsSync as existsSync13, mkdirSync as mkdirSync5, readdirSync as readdirSync9, readFileSync as readFileSync11, renameSync, rmSync, statSync as statSync3, writeFileSync as writeFileSync6 } from "node:fs";
27000
+ import { dirname as dirname7, join as join14 } from "node:path";
26643
27001
  var SKILL_CANDIDATE_SCHEMA = "kxm.skill-candidate.v1";
26644
27002
  var SKILL_EVALUATION_SCHEMA = "kxm.skill-evaluation.v1";
26645
27003
  var SKILL_DECISION_SCHEMA = "kxm.skill-decision.v1";
@@ -26680,7 +27038,7 @@ function parseSkillFrontmatter(content) {
26680
27038
  return { frontmatter: null, body: content };
26681
27039
  }
26682
27040
  try {
26683
- const parsed = (0, import_yaml9.parse)(rawFm);
27041
+ const parsed = (0, import_yaml10.parse)(rawFm);
26684
27042
  if (parsed && typeof parsed === "object" && !Array.isArray(parsed)) {
26685
27043
  return { frontmatter: parsed, body: rawBody };
26686
27044
  }
@@ -26745,20 +27103,20 @@ var SkillLifecycle = class {
26745
27103
  writeFileSync6(file, content);
26746
27104
  }
26747
27105
  dir(state) {
26748
- return join13(this.root, state === "candidate" ? "candidates" : `${state}s`.replace("rejecteds", "rejected").replace("promoteds", "promoted"));
27106
+ return join14(this.root, state === "candidate" ? "candidates" : `${state}s`.replace("rejecteds", "rejected").replace("promoteds", "promoted"));
26749
27107
  }
26750
27108
  historyFile(id) {
26751
- return join13(this.root, "history", `${id}.jsonl`);
27109
+ return join14(this.root, "history", `${id}.jsonl`);
26752
27110
  }
26753
27111
  paths(state, id) {
26754
- const dir = join13(this.dir(state), id);
26755
- return { dir, metadata: join13(dir, "metadata.json"), skill: join13(dir, "SKILL.md") };
27112
+ const dir = join14(this.dir(state), id);
27113
+ return { dir, metadata: join14(dir, "metadata.json"), skill: join14(dir, "SKILL.md") };
26756
27114
  }
26757
27115
  appendHistory(id, record2) {
26758
27116
  const line = `${JSON.stringify(record2)}
26759
27117
  `;
26760
- if (existsSync12(this.historyFile(id))) {
26761
- const existing = readFileSync10(this.historyFile(id), "utf8");
27118
+ if (existsSync13(this.historyFile(id))) {
27119
+ const existing = readFileSync11(this.historyFile(id), "utf8");
26762
27120
  const lines = existing.split("\n").filter((entry) => entry.trim());
26763
27121
  this.write(this.historyFile(id), [...lines.slice(-499), line.trim()].join("\n") + "\n");
26764
27122
  } else {
@@ -26767,20 +27125,20 @@ var SkillLifecycle = class {
26767
27125
  }
26768
27126
  history(id) {
26769
27127
  const file = this.historyFile(id);
26770
- if (!existsSync12(file)) return [];
26771
- return readFileSync10(file, "utf8").split("\n").filter((line) => line.trim()).map((line) => JSON.parse(line));
27128
+ if (!existsSync13(file)) return [];
27129
+ return readFileSync11(file, "utf8").split("\n").filter((line) => line.trim()).map((line) => JSON.parse(line));
26772
27130
  }
26773
27131
  readMetadata(state, id) {
26774
27132
  const { metadata } = this.paths(state, id);
26775
- if (!existsSync12(metadata)) {
27133
+ if (!existsSync13(metadata)) {
26776
27134
  throw new SkillLifecycleError("skill_not_found", `skill ${id} not found in ${state}`);
26777
27135
  }
26778
- return JSON.parse(readFileSync10(metadata, "utf8"));
27136
+ return JSON.parse(readFileSync11(metadata, "utf8"));
26779
27137
  }
26780
27138
  move(from, to, id) {
26781
- const fromDir = join13(this.dir(from), id);
26782
- const toDir = join13(this.dir(to), id);
26783
- if (!existsSync12(fromDir)) {
27139
+ const fromDir = join14(this.dir(from), id);
27140
+ const toDir = join14(this.dir(to), id);
27141
+ if (!existsSync13(fromDir)) {
26784
27142
  throw new SkillLifecycleError("skill_not_found", `skill ${id} not found in ${from}`);
26785
27143
  }
26786
27144
  if (this.dryRun) {
@@ -26788,7 +27146,7 @@ var SkillLifecycle = class {
26788
27146
  return;
26789
27147
  }
26790
27148
  mkdirSync5(this.dir(to), { recursive: true });
26791
- if (existsSync12(toDir)) rmSync(toDir, { recursive: true, force: true });
27149
+ if (existsSync13(toDir)) rmSync(toDir, { recursive: true, force: true });
26792
27150
  renameSync(fromDir, toDir);
26793
27151
  }
26794
27152
  /** Submit a new skill candidate. Content is redacted of secret material at
@@ -26831,7 +27189,7 @@ var SkillLifecycle = class {
26831
27189
  const contentSha256 = skillContentSha256(content);
26832
27190
  const id = skillIdFor(name, contentSha256);
26833
27191
  const { metadata, skill } = this.paths("candidate", id);
26834
- if (existsSync12(metadata)) {
27192
+ if (existsSync13(metadata)) {
26835
27193
  throw new SkillLifecycleError(
26836
27194
  "skill_candidate_exists",
26837
27195
  `identical candidate ${id} already exists; changed behavior requires changed content`
@@ -26940,11 +27298,11 @@ var SkillLifecycle = class {
26940
27298
  };
26941
27299
  const candidatePaths = this.paths("candidate", candidateId);
26942
27300
  const promotedPaths = this.paths("promoted", candidateId);
26943
- const skillContent = readFileSync10(candidatePaths.skill, "utf8");
26944
- const metadataContent = readFileSync10(candidatePaths.metadata, "utf8");
27301
+ const skillContent = readFileSync11(candidatePaths.skill, "utf8");
27302
+ const metadataContent = readFileSync11(candidatePaths.metadata, "utf8");
26945
27303
  this.write(promotedPaths.skill, skillContent);
26946
27304
  this.write(promotedPaths.metadata, metadataContent);
26947
- const patchPath = join13(this.root, "patches", `${candidateId}.patch`);
27305
+ const patchPath = join14(this.root, "patches", `${candidateId}.patch`);
26948
27306
  const relSkillPath = `.kxm/skills/promoted/${candidateId}/SKILL.md`;
26949
27307
  const relMetaPath = `.kxm/skills/promoted/${candidateId}/metadata.json`;
26950
27308
  const patch = `${createUnifiedPatch(relSkillPath, skillContent)}${createUnifiedPatch(relMetaPath, metadataContent)}`;
@@ -26972,7 +27330,7 @@ var SkillLifecycle = class {
26972
27330
  verify(state, id) {
26973
27331
  const metadata = this.readMetadata(state, id);
26974
27332
  const { skill } = this.paths(state, id);
26975
- const content = readFileSync10(skill, "utf8");
27333
+ const content = readFileSync11(skill, "utf8");
26976
27334
  if (skillContentSha256(content) !== metadata.contentSha256) {
26977
27335
  throw new SkillLifecycleError(
26978
27336
  "skill_integrity_violation",
@@ -26990,7 +27348,7 @@ var SkillLifecycle = class {
26990
27348
  }
26991
27349
  list(state) {
26992
27350
  const dir = this.dir(state);
26993
- if (!existsSync12(dir)) return [];
27351
+ if (!existsSync13(dir)) return [];
26994
27352
  const ids = readdirSorted(dir);
26995
27353
  return ids.map((id) => {
26996
27354
  try {
@@ -27003,7 +27361,7 @@ var SkillLifecycle = class {
27003
27361
  read(state, id) {
27004
27362
  const metadata = this.readMetadata(state, id);
27005
27363
  const { skill } = this.paths(state, id);
27006
- return { metadata, content: readFileSync10(skill, "utf8") };
27364
+ return { metadata, content: readFileSync11(skill, "utf8") };
27007
27365
  }
27008
27366
  };
27009
27367
  function boundedList(value, field) {
@@ -27018,7 +27376,7 @@ function boundedList(value, field) {
27018
27376
  return [...new Set(refs)];
27019
27377
  }
27020
27378
  function readdirSorted(dir) {
27021
- return readdirSync8(dir).filter((entry) => statSync3(join13(dir, entry)).isDirectory()).sort();
27379
+ return readdirSync9(dir).filter((entry) => statSync3(join14(dir, entry)).isDirectory()).sort();
27022
27380
  }
27023
27381
 
27024
27382
  // plugins/kxm/src/dispatch-context.ts
@@ -27059,18 +27417,18 @@ function contextRoleForAgent(agentId) {
27059
27417
  return agentId;
27060
27418
  }
27061
27419
  function dispatchContextPresent(projectRoot) {
27062
- return hasTopLevelMarkdown(join14(projectRoot, ".kxm", "memory")) || hasAnyEntry(join14(projectRoot, ".kxm", "skills", "promoted"));
27420
+ return hasTopLevelMarkdown(join15(projectRoot, ".kxm", "memory")) || hasAnyEntry(join15(projectRoot, ".kxm", "skills", "promoted"));
27063
27421
  }
27064
27422
  function hasTopLevelMarkdown(dir) {
27065
27423
  try {
27066
- return readdirSync9(dir, { withFileTypes: true }).some((entry) => entry.isFile() && extname3(entry.name) === ".md");
27424
+ return readdirSync10(dir, { withFileTypes: true }).some((entry) => entry.isFile() && extname3(entry.name) === ".md");
27067
27425
  } catch {
27068
27426
  return false;
27069
27427
  }
27070
27428
  }
27071
27429
  function hasAnyEntry(dir) {
27072
27430
  try {
27073
- return readdirSync9(dir).length > 0;
27431
+ return readdirSync10(dir).length > 0;
27074
27432
  } catch {
27075
27433
  return false;
27076
27434
  }
@@ -27135,7 +27493,7 @@ function loadDispatchContextSources(input) {
27135
27493
  }
27136
27494
  const promoted = [];
27137
27495
  try {
27138
- const lifecycle = new SkillLifecycle(join14(projectRoot, ".kxm", "skills"));
27496
+ const lifecycle = new SkillLifecycle(join15(projectRoot, ".kxm", "skills"));
27139
27497
  for (const metadata of lifecycle.list("promoted")) {
27140
27498
  try {
27141
27499
  promoted.push(lifecycle.verify("promoted", metadata.id));
@@ -27218,7 +27576,7 @@ function assembleDispatchContext(sources, input) {
27218
27576
  }
27219
27577
 
27220
27578
  // plugins/kxm/src/engine-artifacts.ts
27221
- import { join as join15 } from "node:path";
27579
+ import { join as join16 } from "node:path";
27222
27580
 
27223
27581
  // plugins/kxm/src/artifacts-exist.ts
27224
27582
  import { lstatSync as lstatSync5, realpathSync as realpathSync4, statSync as statSync4 } from "node:fs";
@@ -27265,14 +27623,14 @@ function verifyArtifactExists(rootInput, pathInput) {
27265
27623
  // plugins/kxm/src/engine-artifacts.ts
27266
27624
  var kxmArtifactsGateSeams = {};
27267
27625
  function evaluateArtifactsGate(context, definition) {
27268
- const root = join15(context.projectRoot, ".kxm", "assets");
27626
+ const root = join16(context.projectRoot, ".kxm", "assets");
27269
27627
  const startedAt = (/* @__PURE__ */ new Date()).toISOString();
27270
27628
  const startTime = process.hrtime.bigint();
27271
27629
  let checkedCount = 0;
27272
27630
  let failedCount = 0;
27273
27631
  for (const [index, path] of definition.paths.entries()) {
27274
27632
  checkedCount += 1;
27275
- const result = verifyArtifactExists(root, join15(root, path));
27633
+ const result = verifyArtifactExists(root, join16(root, path));
27276
27634
  if (!result.ok) failedCount += 1;
27277
27635
  kxmArtifactsGateSeams.afterPathChecked?.({ path, index, checkedCount, failedCount });
27278
27636
  }
@@ -28851,32 +29209,185 @@ var KxmRunScheduler = class _KxmRunScheduler {
28851
29209
  });
28852
29210
  }
28853
29211
  };
29212
+ var attemptFallback = /* @__PURE__ */ new Map();
29213
+ var runStickyRoute = /* @__PURE__ */ new Map();
29214
+ function observeProducerFailure(error, capability) {
29215
+ try {
29216
+ const raw = error instanceof Error ? error.message : error;
29217
+ const message = typeof raw === "string" ? raw : "";
29218
+ let text = message;
29219
+ if (capability) text = text.split(capability).join("[redacted]");
29220
+ text = text.replace(/kxmcap_[A-Za-z0-9_-]+/g, "[redacted]");
29221
+ const match = /^[a-z][a-z0-9]*(?:_[a-z0-9]+){1,3}/.exec(text);
29222
+ const extracted = match?.[0] ?? "";
29223
+ const code = extracted.length > 0 && extracted.length <= 64 ? extracted : "producer_error";
29224
+ const record2 = error && typeof error === "object" ? error : void 0;
29225
+ const statusValue = record2?.statusCode ?? record2?.status ?? record2?.httpStatus;
29226
+ const httpStatus = typeof statusValue === "number" && Number.isInteger(statusValue) ? statusValue : void 0;
29227
+ const name = error instanceof Error ? error.name : void 0;
29228
+ const sessionCarry = parseSessionCarry(record2?.sessionCarry);
29229
+ return {
29230
+ code,
29231
+ failure: {
29232
+ classified: classifyRouteFailure({ code, text: text.slice(0, 500), httpStatus, name }),
29233
+ ...sessionCarry ? { sessionCarry } : {}
29234
+ }
29235
+ };
29236
+ } catch {
29237
+ return { code: "producer_error", failure: { classified: classifyRouteFailure({ code: "producer_error" }) } };
29238
+ }
29239
+ }
28854
29240
  function invokeProducer(producer, request) {
28855
- const reason = (error) => {
28856
- try {
28857
- const raw = error instanceof Error ? error.message : error;
28858
- const message = typeof raw === "string" ? raw : "";
28859
- let text = message;
28860
- if (request.capability) text = text.split(request.capability).join("[redacted]");
28861
- text = text.replace(/kxmcap_[A-Za-z0-9_-]+/g, "[redacted]");
28862
- const match = /^[a-z][a-z0-9]*(?:_[a-z0-9]+){1,3}/.exec(text);
28863
- const code = match?.[0] ?? "";
28864
- return code.length > 0 && code.length <= 64 ? code : "producer_error";
28865
- } catch {
28866
- return "producer_error";
28867
- }
28868
- };
28869
29241
  let pending;
28870
29242
  try {
28871
29243
  pending = Promise.resolve(producer.produce(request));
28872
29244
  } catch (error) {
28873
- return Promise.resolve({ error: true, errorCode: reason(error) });
29245
+ const observed = observeProducerFailure(error, request.capability);
29246
+ return Promise.resolve({ error: true, errorCode: observed.code, failure: observed.failure });
28874
29247
  }
28875
29248
  return pending.then(
28876
29249
  (result) => ({ result, error: false }),
28877
- (error) => ({ error: true, errorCode: reason(error) })
29250
+ (error) => {
29251
+ const observed = observeProducerFailure(error, request.capability);
29252
+ return { error: true, errorCode: observed.code, failure: observed.failure };
29253
+ }
28878
29254
  );
28879
29255
  }
29256
+ function stickyRouteFromEvents(context, runId) {
29257
+ const remembered = runStickyRoute.get(runId);
29258
+ if (remembered) return remembered;
29259
+ let found;
29260
+ for (const event of context.eventStore.events(runId, 0, 1e5)) {
29261
+ if (event.eventType !== "routing.attempt.recorded") continue;
29262
+ const routing = event.payload.routing;
29263
+ const route = routing?.providerMetadata?.fallbackRoute;
29264
+ if (typeof route === "string" && route.length > 0) found = route;
29265
+ }
29266
+ return found;
29267
+ }
29268
+ function stickyWalkRoute(context, step, agentId, runId, liveWrite) {
29269
+ const loaded = loadAgentFallback(context.projectRoot, agentId, { liveWrite });
29270
+ if (!loaded || loaded.policy.revert !== "never") return void 0;
29271
+ const sticky = stickyRouteFromEvents(context, runId);
29272
+ if (!sticky) return void 0;
29273
+ const candidate = loaded.chain.find((item) => item.routeId === sticky);
29274
+ if (!candidate) return void 0;
29275
+ return candidateToRoute(candidate, loaded.roleId);
29276
+ }
29277
+ function candidateToRoute(candidate, role) {
29278
+ return {
29279
+ provider: candidate.provider,
29280
+ model: candidate.model,
29281
+ selector: candidate.selector,
29282
+ harness: candidate.harness,
29283
+ routeId: candidate.routeId,
29284
+ role,
29285
+ permissions: [...candidate.permissions],
29286
+ ...candidate.effort ? { effort: candidate.effort } : {}
29287
+ };
29288
+ }
29289
+ function rememberAttemptFallback(attemptId, loaded, index, basePrompt) {
29290
+ if (loaded.chain.length < 2 || loaded.policy.onError.length === 0 || loaded.policy.maxSwitches <= 0) return;
29291
+ if (index < 0 || index >= loaded.chain.length) return;
29292
+ attemptFallback.set(attemptId, {
29293
+ policy: loaded.policy,
29294
+ chain: loaded.chain,
29295
+ index,
29296
+ switches: 0,
29297
+ basePrompt
29298
+ });
29299
+ }
29300
+ function appendRouteSwitch(context, member, routeSwitch) {
29301
+ const run = requireRun(context, member.run.runId);
29302
+ const now = (/* @__PURE__ */ new Date()).toISOString();
29303
+ const sequence = context.eventStore.nextSequence(run.runId);
29304
+ const event = {
29305
+ ...kxmEventBase(context, run, now, kxmMonotonicNs()),
29306
+ eventId: newKxmEventId(),
29307
+ eventType: "routing.route_switched",
29308
+ sequence,
29309
+ payload: {
29310
+ attemptId: member.attemptId,
29311
+ stepId: member.stepId,
29312
+ routeSwitch: {
29313
+ from: routeSwitch.from,
29314
+ to: routeSwitch.to,
29315
+ reason: routeSwitch.reason,
29316
+ ...routeSwitch.effort ? { effort: routeSwitch.effort } : {}
29317
+ }
29318
+ }
29319
+ };
29320
+ context.eventStore.appendEvent(event);
29321
+ const next = foldStoredKxmRun(context, run);
29322
+ persistKxmRunState(context, run.runId, next, sequence);
29323
+ try {
29324
+ context.logger?.({
29325
+ event: "route_switch",
29326
+ runId: run.runId,
29327
+ attemptId: member.attemptId,
29328
+ stepId: member.stepId,
29329
+ from: routeSwitch.from,
29330
+ to: routeSwitch.to,
29331
+ reason: routeSwitch.reason,
29332
+ ...routeSwitch.effort ? { effort: routeSwitch.effort } : {}
29333
+ });
29334
+ } catch {
29335
+ }
29336
+ }
29337
+ async function produceWithRouteFallback(context, member, producer) {
29338
+ const session = attemptFallback.get(member.attemptId);
29339
+ let request = member.request;
29340
+ let produced = await invokeProducer(producer, request);
29341
+ if (!session) return producerOutcome(produced);
29342
+ let carry;
29343
+ while (produced.error) {
29344
+ const current = session.chain[session.index];
29345
+ if (!current) break;
29346
+ const failure = produced.failure?.classified ?? classifyRouteFailure({ code: produced.errorCode, text: produced.errorCode });
29347
+ const decision = decideRouteSwitch({
29348
+ policy: session.policy,
29349
+ chain: session.chain,
29350
+ currentRouteId: current.routeId,
29351
+ switchesUsed: session.switches,
29352
+ failure,
29353
+ ...current.effort || member.request.thinking ? { currentEffort: current.effort ?? member.request.thinking } : {}
29354
+ });
29355
+ if (decision.action !== "switch") break;
29356
+ appendRouteSwitch(context, member, {
29357
+ from: current.routeId,
29358
+ to: decision.to.routeId,
29359
+ reason: decision.reason,
29360
+ ...decision.effort ? { effort: decision.effort } : {}
29361
+ });
29362
+ session.switches += 1;
29363
+ session.index = session.chain.findIndex((candidate) => candidate.routeId === decision.to.routeId);
29364
+ carry = mergeSessionCarry(carry, produced.failure?.sessionCarry);
29365
+ request = {
29366
+ ...member.request,
29367
+ prompt: carryForwardPrompt(session.basePrompt, carry),
29368
+ model: decision.to.model,
29369
+ provider: decision.to.provider,
29370
+ harness: decision.to.harness,
29371
+ ...decision.effort ? { thinking: decision.effort } : {}
29372
+ };
29373
+ produced = await invokeProducer(producer, request);
29374
+ }
29375
+ if (!produced.error && session.switches > 0 && session.policy.revert === "never") {
29376
+ const route = session.chain[session.index];
29377
+ if (route) {
29378
+ session.stickyRouteId = route.routeId;
29379
+ runStickyRoute.set(member.run.runId, route.routeId);
29380
+ }
29381
+ }
29382
+ return producerOutcome(produced);
29383
+ }
29384
+ function producerOutcome(produced) {
29385
+ return {
29386
+ error: produced.error,
29387
+ ...produced.result !== void 0 ? { result: produced.result } : {},
29388
+ ...produced.errorCode !== void 0 ? { errorCode: produced.errorCode } : {}
29389
+ };
29390
+ }
28880
29391
  var kxmGateDispatchSeams = {};
28881
29392
  function peekDispatchContextSources(context, runId) {
28882
29393
  if (!dispatchContextPresent(context.projectRoot)) return EMPTY_DISPATCH_SOURCES;
@@ -29150,9 +29661,9 @@ function readYamlFile(file) {
29150
29661
  return readModelDocument(file);
29151
29662
  }
29152
29663
  function readModelDocument(file) {
29153
- if (!existsSync13(file)) return void 0;
29664
+ if (!existsSync14(file)) return void 0;
29154
29665
  try {
29155
- const parsed = (0, import_yaml10.parse)(readFileSync11(file, "utf8"));
29666
+ const parsed = (0, import_yaml11.parse)(readFileSync12(file, "utf8"));
29156
29667
  if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) return void 0;
29157
29668
  return parsed;
29158
29669
  } catch {
@@ -29183,8 +29694,8 @@ function resolveProducerRoute(projectRoot, step, agentId) {
29183
29694
  }
29184
29695
  };
29185
29696
  }
29186
- const agentFile = findYamlBasename(join16(projectRoot, ".kxm", "agents"), agentId, "agent") ?? agentId;
29187
- const agent = readYamlFile(join16(projectRoot, ".kxm", "agents", `${agentFile}.yaml`));
29697
+ const agentFile = findYamlBasename(join17(projectRoot, ".kxm", "agents"), agentId, "agent") ?? agentId;
29698
+ const agent = readYamlFile(join17(projectRoot, ".kxm", "agents", `${agentFile}.yaml`));
29188
29699
  const role = typeof agent?.role === "string" ? agent.role : "";
29189
29700
  if (!role) {
29190
29701
  return {
@@ -29195,7 +29706,7 @@ function resolveProducerRoute(projectRoot, step, agentId) {
29195
29706
  }
29196
29707
  };
29197
29708
  }
29198
- const roleDoc = readYamlFile(join16(projectRoot, ".kxm", "roles", `${role}.yaml`));
29709
+ const roleDoc = readYamlFile(join17(projectRoot, ".kxm", "roles", `${role}.yaml`));
29199
29710
  const roster = Array.isArray(roleDoc?.roster) ? roleDoc.roster : void 0;
29200
29711
  if (!roster) {
29201
29712
  return {
@@ -29211,8 +29722,8 @@ function resolveProducerRoute(projectRoot, step, agentId) {
29211
29722
  if (!entry || typeof entry !== "object" || Array.isArray(entry)) continue;
29212
29723
  const record2 = entry;
29213
29724
  if (typeof record2.route !== "string" || record2.route.length === 0) continue;
29214
- const routeFile = findYamlBasename(join16(projectRoot, ".kxm", "models"), record2.route, "route") ?? record2.route;
29215
- const modelPath = join16(projectRoot, ".kxm", "models", `${routeFile}.yaml`);
29725
+ const routeFile = findYamlBasename(join17(projectRoot, ".kxm", "models"), record2.route, "route") ?? record2.route;
29726
+ const modelPath = join17(projectRoot, ".kxm", "models", `${routeFile}.yaml`);
29216
29727
  const doc = readModelDocument(modelPath);
29217
29728
  if (!doc) {
29218
29729
  return {
@@ -29229,9 +29740,9 @@ function resolveProducerRoute(projectRoot, step, agentId) {
29229
29740
  const harness = typeof doc.harness === "string" ? doc.harness : "";
29230
29741
  if (!modelName || !vendor || !harness) continue;
29231
29742
  const candidates = [modelName, `${vendor}/${modelName}`, `${harness}/${modelName}`];
29232
- const admittedSelector = candidates.find((candidate) => policy.admitted.includes(candidate));
29743
+ const admittedSelector2 = candidates.find((candidate) => policy.admitted.includes(candidate));
29233
29744
  const disabledSelector = candidates.find((candidate) => policy.disabled.includes(candidate));
29234
- if (!admittedSelector && disabledSelector) {
29745
+ if (!admittedSelector2 && disabledSelector) {
29235
29746
  return {
29236
29747
  error: {
29237
29748
  reason: "step_unsupported",
@@ -29240,7 +29751,7 @@ function resolveProducerRoute(projectRoot, step, agentId) {
29240
29751
  }
29241
29752
  };
29242
29753
  }
29243
- const selector = admittedSelector ?? (modelName.includes("/") ? modelName : `${vendor}/${modelName}`);
29754
+ const selector = admittedSelector2 ?? (modelName.includes("/") ? modelName : `${vendor}/${modelName}`);
29244
29755
  if (policy.disabled.includes(selector)) {
29245
29756
  return {
29246
29757
  error: {
@@ -29502,6 +30013,14 @@ function prepareDispatch(context, runId, producerId, dispatchSources) {
29502
30013
  return { kind: "return", state, handoff: { ...routeResult.error, stepId } };
29503
30014
  }
29504
30015
  resolvedRoute = routeResult;
30016
+ const stickyRoute = stickyWalkRoute(
30017
+ context,
30018
+ step,
30019
+ agentId,
30020
+ run.runId,
30021
+ Object.values(step.repositories).some((access) => access === "write")
30022
+ );
30023
+ if (stickyRoute && stickyRoute.routeId !== resolvedRoute.routeId) resolvedRoute = stickyRoute;
29505
30024
  const writeRefusal = unsupportedLiveWrite(
29506
30025
  context.projectRoot,
29507
30026
  step,
@@ -29616,6 +30135,27 @@ function birthMember(context, input) {
29616
30135
  }
29617
30136
  resolvedRoute = routeResult;
29618
30137
  }
30138
+ const liveProducer = Boolean(input.producerId && input.producerId !== "driver-simulated");
30139
+ const liveWrite = liveProducer && Object.values(input.step.repositories).some((access) => access === "write");
30140
+ const loadedFallback = loadAgentFallback(context.projectRoot, agentId, { liveWrite });
30141
+ let fallbackIndex = -1;
30142
+ if (loadedFallback && loadedFallback.chain.length > 1 && loadedFallback.policy.maxSwitches > 0) {
30143
+ const sticky = loadedFallback.policy.revert === "never" ? stickyRouteFromEvents(context, run.runId) : void 0;
30144
+ const stickyIndex = sticky ? loadedFallback.chain.findIndex((candidate) => candidate.routeId === sticky) : -1;
30145
+ if (!resolvedRoute) {
30146
+ fallbackIndex = stickyIndex > 0 ? stickyIndex : 0;
30147
+ const start = loadedFallback.chain[fallbackIndex];
30148
+ if (start) resolvedRoute = candidateToRoute(start, loadedFallback.roleId);
30149
+ } else if (stickyIndex > 0 && resolvedRoute.routeId !== loadedFallback.chain[stickyIndex]?.routeId) {
30150
+ const start = loadedFallback.chain[stickyIndex];
30151
+ if (start) {
30152
+ resolvedRoute = candidateToRoute(start, loadedFallback.roleId);
30153
+ fallbackIndex = stickyIndex;
30154
+ }
30155
+ } else {
30156
+ fallbackIndex = loadedFallback.chain.findIndex((candidate) => candidate.routeId === resolvedRoute?.routeId);
30157
+ }
30158
+ }
29619
30159
  const dispatchContext = assembleDispatchContext(input.dispatchSources, {
29620
30160
  projectId: run.projectId,
29621
30161
  runId: run.runId,
@@ -29750,6 +30290,9 @@ ${generatedPrompt}` : generatedPrompt,
29750
30290
  } catch {
29751
30291
  }
29752
30292
  }
30293
+ if (loadedFallback && fallbackIndex >= 0) {
30294
+ rememberAttemptFallback(attemptId, loadedFallback, fallbackIndex, member.request.prompt ?? "");
30295
+ }
29753
30296
  kxmPanelDispatchSeams.afterBirth?.(member);
29754
30297
  return member;
29755
30298
  }
@@ -29853,7 +30396,7 @@ async function drivePanel(context, panel, producer) {
29853
30396
  const live = member.producerId !== "driver-simulated";
29854
30397
  const writes = Object.values(member.step.repositories).some((access) => access === "write");
29855
30398
  const before = live ? captureWorktreeWitness(context.projectRoot) : void 0;
29856
- const produced = await invokeProducer(producer, member.request);
30399
+ const produced = await produceWithRouteFallback(context, member, producer);
29857
30400
  if (live && produced.result && before) {
29858
30401
  const after = captureWorktreeWitness(context.projectRoot);
29859
30402
  return {
@@ -30048,6 +30591,8 @@ function engineRoutingMetadata(dispatch, producer) {
30048
30591
  metadata.askSha256 = kxmStepAskSha256(dispatch.plan, dispatch.stepId, dispatch.agentId);
30049
30592
  metadata.objectiveSha256 = dispatch.run.promptSha256;
30050
30593
  metadata.stepWrites = Object.values(dispatch.step.repositories).some((access) => access === "write");
30594
+ const stickyRouteId = attemptFallback.get(dispatch.attemptId)?.stickyRouteId;
30595
+ if (stickyRouteId && Object.keys(metadata).length < MAX_PROVIDER_METADATA_FIELDS) metadata.fallbackRoute = stickyRouteId;
30051
30596
  return metadata;
30052
30597
  }
30053
30598
  function producerRoutingRecord(context, dispatch, result, now, finalOutcome) {
@@ -30206,6 +30751,7 @@ function settleMember(context, dispatch, result, produceError, produceErrorCode)
30206
30751
  }
30207
30752
  }
30208
30753
  context.eventStore.settleCapability(dispatch.attemptId, "settled");
30754
+ attemptFallback.delete(dispatch.attemptId);
30209
30755
  for (const event of events) context.eventStore.appendEvent(event);
30210
30756
  const next = foldStoredKxmRun(context, run);
30211
30757
  persistKxmRunState(context, run.runId, next, events[events.length - 1].sequence);
@@ -31466,9 +32012,9 @@ var RuntimeHubClient = class {
31466
32012
  };
31467
32013
 
31468
32014
  // plugins/kxm/src/hub-binding.ts
31469
- import { existsSync as existsSync14, mkdirSync as mkdirSync6, readFileSync as readFileSync12, renameSync as renameSync2, rmSync as rmSync2, writeFileSync as writeFileSync7 } from "node:fs";
32015
+ import { existsSync as existsSync15, mkdirSync as mkdirSync6, readFileSync as readFileSync13, renameSync as renameSync2, rmSync as rmSync2, writeFileSync as writeFileSync7 } from "node:fs";
31470
32016
  import { homedir as homedir2 } from "node:os";
31471
- import { dirname as dirname8, isAbsolute as isAbsolute6, join as join17, resolve as resolve9 } from "node:path";
32017
+ import { dirname as dirname8, isAbsolute as isAbsolute6, join as join18, resolve as resolve9 } from "node:path";
31472
32018
  var HUB_BINDING_SCHEMA = "kxm.hub-binding.v1";
31473
32019
  var HubBindingError = class extends Error {
31474
32020
  constructor(message) {
@@ -31484,16 +32030,16 @@ function resolveUserStateRoot(env) {
31484
32030
  }
31485
32031
  if (process.platform === "win32") {
31486
32032
  const localAppData = env.LOCALAPPDATA?.trim();
31487
- const base2 = localAppData && isAbsolute6(localAppData) ? localAppData : join17(homedir2(), "AppData", "Local");
32033
+ const base2 = localAppData && isAbsolute6(localAppData) ? localAppData : join18(homedir2(), "AppData", "Local");
31488
32034
  return resolve9(base2, "KXM");
31489
32035
  }
31490
32036
  if (process.platform === "darwin") return resolve9(homedir2(), "Library", "Application Support", "KXM");
31491
32037
  const xdgState = env.XDG_STATE_HOME?.trim();
31492
- const base = xdgState && isAbsolute6(xdgState) ? xdgState : join17(homedir2(), ".local", "state");
32038
+ const base = xdgState && isAbsolute6(xdgState) ? xdgState : join18(homedir2(), ".local", "state");
31493
32039
  return resolve9(base, "kxm");
31494
32040
  }
31495
32041
  function hubBindingFile(env = process.env) {
31496
- return join17(resolveUserStateRoot(env), "hub-binding.json");
32042
+ return join18(resolveUserStateRoot(env), "hub-binding.json");
31497
32043
  }
31498
32044
  function validateHubUrl(raw) {
31499
32045
  let parsed;
@@ -31513,10 +32059,10 @@ function isIsoTimestamp(value) {
31513
32059
  }
31514
32060
  function readHubBinding(env = process.env) {
31515
32061
  const file = hubBindingFile(env);
31516
- if (!existsSync14(file)) return void 0;
32062
+ if (!existsSync15(file)) return void 0;
31517
32063
  let parsed;
31518
32064
  try {
31519
- parsed = JSON.parse(readFileSync12(file, "utf8"));
32065
+ parsed = JSON.parse(readFileSync13(file, "utf8"));
31520
32066
  } catch {
31521
32067
  throw new HubBindingError(`malformed hub binding at ${file}`);
31522
32068
  }
@@ -31538,9 +32084,9 @@ function readHubBinding(env = process.env) {
31538
32084
  }
31539
32085
 
31540
32086
  // plugins/kxm/src/hub-env.ts
31541
- import { existsSync as existsSync15, mkdirSync as mkdirSync7, readFileSync as readFileSync13, renameSync as renameSync3, rmSync as rmSync3, writeFileSync as writeFileSync8 } from "node:fs";
32087
+ import { existsSync as existsSync16, mkdirSync as mkdirSync7, readFileSync as readFileSync14, renameSync as renameSync3, rmSync as rmSync3, writeFileSync as writeFileSync8 } from "node:fs";
31542
32088
  import { homedir as homedir3 } from "node:os";
31543
- import { dirname as dirname9, isAbsolute as isAbsolute7, join as join18, resolve as resolve10 } from "node:path";
32089
+ import { dirname as dirname9, isAbsolute as isAbsolute7, join as join19, resolve as resolve10 } from "node:path";
31544
32090
  var HUB_ENV_SCHEMA = "kxm.hub-env.v1";
31545
32091
  var HubEnvError = class extends Error {
31546
32092
  constructor(message) {
@@ -31556,23 +32102,23 @@ function resolveUserStateRoot2(env) {
31556
32102
  }
31557
32103
  if (process.platform === "win32") {
31558
32104
  const localAppData = env.LOCALAPPDATA?.trim();
31559
- const base2 = localAppData && isAbsolute7(localAppData) ? localAppData : join18(homedir3(), "AppData", "Local");
32105
+ const base2 = localAppData && isAbsolute7(localAppData) ? localAppData : join19(homedir3(), "AppData", "Local");
31560
32106
  return resolve10(base2, "KXM");
31561
32107
  }
31562
32108
  if (process.platform === "darwin") return resolve10(homedir3(), "Library", "Application Support", "KXM");
31563
32109
  const xdgState = env.XDG_STATE_HOME?.trim();
31564
- const base = xdgState && isAbsolute7(xdgState) ? xdgState : join18(homedir3(), ".local", "state");
32110
+ const base = xdgState && isAbsolute7(xdgState) ? xdgState : join19(homedir3(), ".local", "state");
31565
32111
  return resolve10(base, "kxm");
31566
32112
  }
31567
32113
  function hubEnvFile(env = process.env) {
31568
- return join18(resolveUserStateRoot2(env), "hub-env.json");
32114
+ return join19(resolveUserStateRoot2(env), "hub-env.json");
31569
32115
  }
31570
32116
  function readHubEnvRecord(env = process.env) {
31571
32117
  const file = hubEnvFile(env);
31572
- if (!existsSync15(file)) return void 0;
32118
+ if (!existsSync16(file)) return void 0;
31573
32119
  let parsed;
31574
32120
  try {
31575
- parsed = JSON.parse(readFileSync13(file, "utf8"));
32121
+ parsed = JSON.parse(readFileSync14(file, "utf8"));
31576
32122
  } catch (error) {
31577
32123
  throw new HubEnvError(`hub env file is malformed at ${file}: ${error instanceof Error ? error.message : String(error)}`);
31578
32124
  }
@@ -31612,7 +32158,7 @@ function resolveClientHubAuthToken(env, project) {
31612
32158
  }
31613
32159
 
31614
32160
  // plugins/kxm/src/logger.ts
31615
- import { appendFileSync, existsSync as existsSync16, mkdirSync as mkdirSync8, renameSync as renameSync4, statSync as statSync5, unlinkSync as unlinkSync2 } from "node:fs";
32161
+ import { appendFileSync, existsSync as existsSync17, mkdirSync as mkdirSync8, renameSync as renameSync4, statSync as statSync5, unlinkSync as unlinkSync2 } from "node:fs";
31616
32162
  import { dirname as dirname10 } from "node:path";
31617
32163
  var LOG_LEVEL_PRIORITY = {
31618
32164
  debug: 10,
@@ -31650,7 +32196,7 @@ function redactLogValue(val, key) {
31650
32196
  function rotateLogFiles(filePath, maxFiles) {
31651
32197
  for (let i = maxFiles; i >= 1; i--) {
31652
32198
  const current = `${filePath}.${i}`;
31653
- if (existsSync16(current)) {
32199
+ if (existsSync17(current)) {
31654
32200
  if (i >= maxFiles) {
31655
32201
  try {
31656
32202
  unlinkSync2(current);
@@ -31664,7 +32210,7 @@ function rotateLogFiles(filePath, maxFiles) {
31664
32210
  }
31665
32211
  }
31666
32212
  }
31667
- if (existsSync16(filePath)) {
32213
+ if (existsSync17(filePath)) {
31668
32214
  try {
31669
32215
  renameSync4(filePath, `${filePath}.1`);
31670
32216
  } catch {
@@ -31681,7 +32227,7 @@ function createLogger(options) {
31681
32227
  const shouldStdout = options.stdout ?? !isDaemon;
31682
32228
  const correlationDefaults = options.correlation ?? {};
31683
32229
  let currentSize = 0;
31684
- if (filePath && existsSync16(filePath)) {
32230
+ if (filePath && existsSync17(filePath)) {
31685
32231
  try {
31686
32232
  currentSize = statSync5(filePath).size;
31687
32233
  } catch {
@@ -31762,7 +32308,7 @@ function createLogger(options) {
31762
32308
 
31763
32309
  // plugins/kxm/src/runtime-supervisor.ts
31764
32310
  function kxmSupervisorTokenFile(paths) {
31765
- return join19(paths.runtimeDir, "supervisor.token");
32311
+ return join20(paths.runtimeDir, "supervisor.token");
31766
32312
  }
31767
32313
  function publishKxmSupervisorToken(paths, token) {
31768
32314
  const file = kxmSupervisorTokenFile(paths);
@@ -31790,7 +32336,7 @@ function readKxmSupervisorToken(paths) {
31790
32336
  if (stat.isSymbolicLink() || !stat.isFile()) {
31791
32337
  throw runtimeError("runtime_path_invalid", file, "supervisor token file must be a regular file, not a link");
31792
32338
  }
31793
- const token = readFileSync14(file, "utf8").trim();
32339
+ const token = readFileSync15(file, "utf8").trim();
31794
32340
  return token.length >= 32 ? token : void 0;
31795
32341
  }
31796
32342
  function processAlive(pid) {
@@ -31804,11 +32350,11 @@ function processAlive(pid) {
31804
32350
  var HEARTBEAT_STALE_MS = 15e3;
31805
32351
  var SUPERVISOR_ERROR_MAX_AGE_MS = 3e4;
31806
32352
  function supervisorErrorFile(paths) {
31807
- return join19(paths.runtimeDir, "supervisor.error");
32353
+ return join20(paths.runtimeDir, "supervisor.error");
31808
32354
  }
31809
32355
  function clearSupervisorError(paths) {
31810
32356
  const file = supervisorErrorFile(paths);
31811
- if (existsSync17(file)) rmSync4(file, { force: true });
32357
+ if (existsSync18(file)) rmSync4(file, { force: true });
31812
32358
  }
31813
32359
  function recordSupervisorError(paths, message) {
31814
32360
  try {
@@ -31825,7 +32371,7 @@ function readRecentSupervisorError(paths) {
31825
32371
  const ageMs = Date.now() - stat.mtimeMs;
31826
32372
  if (ageMs > SUPERVISOR_ERROR_MAX_AGE_MS) return void 0;
31827
32373
  try {
31828
- return readFileSync14(file, "utf8").trim();
32374
+ return readFileSync15(file, "utf8").trim();
31829
32375
  } catch {
31830
32376
  return void 0;
31831
32377
  }
@@ -31864,7 +32410,7 @@ function supervisorStatusOf(record2) {
31864
32410
  };
31865
32411
  }
31866
32412
  function kxmSupervisorStatus(paths, options = {}) {
31867
- if (!existsSync17(paths.registryDb)) return { running: false };
32413
+ if (!existsSync18(paths.registryDb)) return { running: false };
31868
32414
  if (options.readOnly) {
31869
32415
  const database = openReadOnlyDatabase(paths.registryDb);
31870
32416
  try {
@@ -31930,7 +32476,7 @@ async function ensureKxmSupervisor(options = {}) {
31930
32476
  throw runtimeError("runtime_supervisor_unreachable", paths.registryDb, `runtime supervisor pid ${status.pid} is registered as running but cannot be probed`);
31931
32477
  }
31932
32478
  clearSupervisorError(paths);
31933
- const scriptPath = join19(findKxmRepoRoot(import.meta.url), "scripts", "kxm-runtime-supervisor.mjs");
32479
+ const scriptPath = join20(findKxmRepoRoot(import.meta.url), "scripts", "kxm-runtime-supervisor.mjs");
31934
32480
  const spawnImpl = options.spawnImpl ?? ((script, env) => {
31935
32481
  const child = spawn3(process.execPath, [script], {
31936
32482
  detached: true,
@@ -32153,7 +32699,7 @@ function syncFailureText(error) {
32153
32699
  return `${code ? `${code}: ` : ""}${message}`.replace(/(kxm_[A-Za-z0-9_]+|[A-Za-z0-9._-]{40,})/g, "[redacted]").slice(0, 300);
32154
32700
  }
32155
32701
  function runtimeSupervisorLogFile(paths) {
32156
- return join19(paths.runtimeDir, "logs", "kxm-runtime.jsonl");
32702
+ return join20(paths.runtimeDir, "logs", "kxm-runtime.jsonl");
32157
32703
  }
32158
32704
  async function startKxmRuntimeSupervisor(options = {}) {
32159
32705
  const now = options.now ?? (() => (/* @__PURE__ */ new Date()).toISOString());
@@ -32278,8 +32824,8 @@ async function startKxmRuntimeSupervisorInner(paths, requestedPortOption, now, e
32278
32824
  openRunIds = unsettledRunIds(existing2);
32279
32825
  } else {
32280
32826
  const registration = registry.projectByRoot(projectRoot);
32281
- const eventsPath = join19(paths.projectsDir, registration?.projectKey ?? projectRuntimeKey(projectRoot), "run-events.db");
32282
- if (registration && existsSync17(eventsPath)) {
32827
+ const eventsPath = join20(paths.projectsDir, registration?.projectKey ?? projectRuntimeKey(projectRoot), "run-events.db");
32828
+ if (registration && existsSync18(eventsPath)) {
32283
32829
  const store = new KxmRunEventStore(eventsPath);
32284
32830
  try {
32285
32831
  openRunIds = store.runsForProject(registration.projectId, 1e4).filter((run) => !SETTLED_RUN_STATUS.has(run.status)).map((run) => run.runId);
@@ -32795,7 +33341,7 @@ function handoffSuffix(handoff) {
32795
33341
 
32796
33342
  // plugins/kxm/src/pi-producer.ts
32797
33343
  import { spawn as spawn4 } from "node:child_process";
32798
- import { join as join20 } from "node:path";
33344
+ import { join as join21 } from "node:path";
32799
33345
  import { StringDecoder } from "node:string_decoder";
32800
33346
  function formatPiSessionKey(params) {
32801
33347
  if (params.agentId === "coordinator") {
@@ -33169,7 +33715,7 @@ function createKxmPiProducer(options = {}) {
33169
33715
  const args = ["--mode", "rpc", "--name", displayName];
33170
33716
  if (options.sessionDir) {
33171
33717
  const safeDirName = key.replace(/[^a-zA-Z0-9_-]/g, "_");
33172
- args.push("--session-dir", join20(options.sessionDir, request.runId, safeDirName));
33718
+ args.push("--session-dir", join21(options.sessionDir, request.runId, safeDirName));
33173
33719
  }
33174
33720
  if (model) {
33175
33721
  args.push("--model", model);
@@ -33298,8 +33844,8 @@ function createKxmPiProducer(options = {}) {
33298
33844
 
33299
33845
  // plugins/kxm/src/improve.ts
33300
33846
  import { createHash as createHash17 } from "node:crypto";
33301
- import { existsSync as existsSync18, mkdirSync as mkdirSync10, writeFileSync as writeFileSync10 } from "node:fs";
33302
- import { join as join21, relative as relative5, resolve as resolve11 } from "node:path";
33847
+ import { existsSync as existsSync19, mkdirSync as mkdirSync10, writeFileSync as writeFileSync10 } from "node:fs";
33848
+ import { join as join22, relative as relative5, resolve as resolve11 } from "node:path";
33303
33849
  var CANDIDATE_SCHEMA = "kxm.candidate.v1";
33304
33850
  var IMPROVEMENT_REPORT_SCHEMA = "kxm.improvement-report.v2";
33305
33851
  var IMPROVEMENT_REPORT_V1_SCHEMA = "kxm.improvement-report.v1";
@@ -33556,7 +34102,7 @@ function groupRoutingRecords(records, options = {}) {
33556
34102
  }
33557
34103
  function buildImprovementReport(records, options = {}) {
33558
34104
  const projectRoot = options.projectRoot ? resolve11(options.projectRoot) : process.cwd();
33559
- const candidatesDir = options.candidatesDir ? resolve11(options.candidatesDir) : join21(projectRoot, ".kxm", "candidates");
34105
+ const candidatesDir = options.candidatesDir ? resolve11(options.candidatesDir) : join22(projectRoot, ".kxm", "candidates");
33560
34106
  const promotionPolicy = options.promotionPolicy ?? "manual_pr";
33561
34107
  const groups = groupRoutingRecords(records, options);
33562
34108
  const candidates = [];
@@ -33570,7 +34116,7 @@ function buildImprovementReport(records, options = {}) {
33570
34116
  group.workflowId
33571
34117
  );
33572
34118
  const diffFileName = `${group.candidateId}.diff`;
33573
- const diffFilePath = join21(candidatesDir, diffFileName);
34119
+ const diffFilePath = join22(candidatesDir, diffFileName);
33574
34120
  const relDiffPath = relative5(projectRoot, diffFilePath).replace(/\\/g, "/");
33575
34121
  const candidate = {
33576
34122
  schema: CANDIDATE_SCHEMA,
@@ -33592,11 +34138,11 @@ function buildImprovementReport(records, options = {}) {
33592
34138
  createdAt: nowIso()
33593
34139
  };
33594
34140
  if (!options.dryRun) {
33595
- if (!existsSync18(candidatesDir)) {
34141
+ if (!existsSync19(candidatesDir)) {
33596
34142
  mkdirSync10(candidatesDir, { recursive: true });
33597
34143
  }
33598
34144
  writeFileSync10(diffFilePath, diff, "utf8");
33599
- const jsonFilePath = join21(candidatesDir, `${group.candidateId}.json`);
34145
+ const jsonFilePath = join22(candidatesDir, `${group.candidateId}.json`);
33600
34146
  writeFileSync10(jsonFilePath, JSON.stringify(candidate, null, 2) + "\n", "utf8");
33601
34147
  }
33602
34148
  candidates.push(candidate);
@@ -33612,6 +34158,7 @@ function buildImprovementReport(records, options = {}) {
33612
34158
  })
33613
34159
  });
33614
34160
  }
34161
+ const routeSwitches = options.routeSwitches?.filter((item) => item.from && item.to) ?? [];
33615
34162
  return {
33616
34163
  schema: IMPROVEMENT_REPORT_SCHEMA,
33617
34164
  createdAt: nowIso(),
@@ -33620,12 +34167,13 @@ function buildImprovementReport(records, options = {}) {
33620
34167
  groups,
33621
34168
  candidates,
33622
34169
  promotionPolicy,
33623
- promotion
34170
+ promotion,
34171
+ ...routeSwitches.length > 0 ? { routeSwitches: [...routeSwitches] } : {}
33624
34172
  };
33625
34173
  }
33626
34174
  function writeImprovementReport(improvementsDir, report, dryRun = false) {
33627
34175
  const stamp = report.createdAt.replace(/[:.]/g, "-");
33628
- const path = join21(improvementsDir, `${stamp}.json`);
34176
+ const path = join22(improvementsDir, `${stamp}.json`);
33629
34177
  if (!dryRun) {
33630
34178
  mkdirSync10(improvementsDir, { recursive: true });
33631
34179
  writeFileSync10(path, `${JSON.stringify(report, null, 2)}
@@ -33656,6 +34204,14 @@ function formatImprovementReport(report) {
33656
34204
  const cand = g.isCandidate ? `yes (${g.candidateKind})` : g.excludedReason !== void 0 ? `no (${g.excludedReason})` : "no";
33657
34205
  lines.push(`${wf} ${step} ${role} ${prompt} ${rec} ${runs} ${asks} ${weighted} ${cost} ${lat} ${accepted} ${rework} ${cand}`);
33658
34206
  }
34207
+ if (report.routeSwitches && report.routeSwitches.length > 0) {
34208
+ lines.push("");
34209
+ lines.push(`Route switches (${report.routeSwitches.length}):`);
34210
+ for (const item of report.routeSwitches) {
34211
+ const effort = item.effort ? ` effort ${item.effort}` : "";
34212
+ lines.push(` - ${item.from} -> ${item.to} (${item.reason}${effort}) on ${item.stepId}`);
34213
+ }
34214
+ }
33659
34215
  if (report.candidates.length > 0) {
33660
34216
  const readiness = new Map(report.promotion.map((entry) => [entry.candidateId, entry]));
33661
34217
  lines.push("");
@@ -34286,9 +34842,9 @@ Instructions for Operator:
34286
34842
  };
34287
34843
 
34288
34844
  // plugins/kxm/src/modes.ts
34289
- var import_yaml11 = __toESM(require_dist(), 1);
34290
- import { existsSync as existsSync19, readFileSync as readFileSync16 } from "node:fs";
34291
- import { join as join22 } from "node:path";
34845
+ var import_yaml12 = __toESM(require_dist(), 1);
34846
+ import { existsSync as existsSync20, readFileSync as readFileSync17 } from "node:fs";
34847
+ import { join as join23 } from "node:path";
34292
34848
  var DEFAULT_MODES_CONFIG = Object.freeze({
34293
34849
  schema: "kxm.modes.v1",
34294
34850
  majorModes: {
@@ -34351,13 +34907,13 @@ function loadModesConfig(projectRoot) {
34351
34907
  if (!projectRoot) {
34352
34908
  return DEFAULT_MODES_CONFIG;
34353
34909
  }
34354
- const modesPath = join22(projectRoot, ".kxm", "modes.yaml");
34355
- if (!existsSync19(modesPath)) {
34910
+ const modesPath = join23(projectRoot, ".kxm", "modes.yaml");
34911
+ if (!existsSync20(modesPath)) {
34356
34912
  return DEFAULT_MODES_CONFIG;
34357
34913
  }
34358
34914
  try {
34359
- const raw = readFileSync16(modesPath, "utf8");
34360
- const parsed = (0, import_yaml11.parse)(raw);
34915
+ const raw = readFileSync17(modesPath, "utf8");
34916
+ const parsed = (0, import_yaml12.parse)(raw);
34361
34917
  if (parsed && parsed.schema === "kxm.modes.v1" && parsed.majorModes) {
34362
34918
  return {
34363
34919
  schema: "kxm.modes.v1",
@@ -34442,11 +34998,11 @@ function calculatePromptFootprint(resolved, projectRoot = process.cwd(), catalog
34442
34998
  estimatedTokens: estimateTokens(baseSystemPromptChars)
34443
34999
  });
34444
35000
  for (const relPath of resolved.contextFiles) {
34445
- const fullPath = join22(projectRoot, relPath);
35001
+ const fullPath = join23(projectRoot, relPath);
34446
35002
  let chars = 0;
34447
- if (existsSync19(fullPath)) {
35003
+ if (existsSync20(fullPath)) {
34448
35004
  try {
34449
- chars = readFileSync16(fullPath, "utf8").length;
35005
+ chars = readFileSync17(fullPath, "utf8").length;
34450
35006
  } catch {
34451
35007
  chars = 0;
34452
35008
  }
@@ -34578,9 +35134,9 @@ ${divider}
34578
35134
 
34579
35135
  // plugins/kxm/src/ssh-remote.ts
34580
35136
  import { spawnSync as spawnSync6 } from "node:child_process";
34581
- import { existsSync as existsSync20, mkdirSync as mkdirSync11, readFileSync as readFileSync17, readdirSync as readdirSync10, rmSync as rmSync5, statSync as statSync6 } from "node:fs";
35137
+ import { existsSync as existsSync21, mkdirSync as mkdirSync11, readFileSync as readFileSync18, readdirSync as readdirSync11, rmSync as rmSync5, statSync as statSync6 } from "node:fs";
34582
35138
  import { homedir as homedir4 } from "node:os";
34583
- import { join as join23, resolve as resolve12 } from "node:path";
35139
+ import { join as join24, resolve as resolve12 } from "node:path";
34584
35140
  var MAX_SSH_OUTPUT_BYTES = 50 * 1024;
34585
35141
  var MAX_SSH_OUTPUT_LINES = 2e3;
34586
35142
  var DEFAULT_SOCKET_DIR = ".kxm/run/ssh-sockets";
@@ -34606,12 +35162,12 @@ function truncateSshOutput(raw) {
34606
35162
  return { text, truncated };
34607
35163
  }
34608
35164
  function parseSshConfig(configPath) {
34609
- const targetPath = configPath ?? join23(homedir4(), ".ssh", "config");
34610
- if (!existsSync20(targetPath)) {
35165
+ const targetPath = configPath ?? join24(homedir4(), ".ssh", "config");
35166
+ if (!existsSync21(targetPath)) {
34611
35167
  return [];
34612
35168
  }
34613
35169
  try {
34614
- const content = readFileSync17(targetPath, "utf-8");
35170
+ const content = readFileSync18(targetPath, "utf-8");
34615
35171
  const lines = content.split("\n");
34616
35172
  const hosts = [];
34617
35173
  let currentHosts = [];
@@ -34689,14 +35245,14 @@ function resolveSshHostG(host, execFn = spawnSync6) {
34689
35245
  }
34690
35246
  function ensureSocketDir(socketDir = DEFAULT_SOCKET_DIR) {
34691
35247
  const resolved = resolve12(socketDir);
34692
- if (!existsSync20(resolved)) {
35248
+ if (!existsSync21(resolved)) {
34693
35249
  mkdirSync11(resolved, { recursive: true, mode: 448 });
34694
35250
  }
34695
35251
  return resolved;
34696
35252
  }
34697
35253
  function buildSshArgs(options) {
34698
35254
  const socketDir = ensureSocketDir(options.socketDir ?? DEFAULT_SOCKET_DIR);
34699
- const controlPath = join23(socketDir, "%C");
35255
+ const controlPath = join24(socketDir, "%C");
34700
35256
  const persist2 = options.controlPersist ?? DEFAULT_CONTROL_PERSIST;
34701
35257
  const args = [
34702
35258
  "-o",
@@ -34721,7 +35277,7 @@ function buildSshArgs(options) {
34721
35277
  }
34722
35278
  function checkControlSocket(host, socketDir = DEFAULT_SOCKET_DIR, execFn = spawnSync6) {
34723
35279
  const resolvedDir = ensureSocketDir(socketDir);
34724
- const controlPath = join23(resolvedDir, "%C");
35280
+ const controlPath = join24(resolvedDir, "%C");
34725
35281
  try {
34726
35282
  const result = execFn("ssh", ["-O", "check", "-o", `ControlPath=${controlPath}`, host], {
34727
35283
  encoding: "utf-8"
@@ -34733,7 +35289,7 @@ function checkControlSocket(host, socketDir = DEFAULT_SOCKET_DIR, execFn = spawn
34733
35289
  }
34734
35290
  function closeControlSocket(host, socketDir = DEFAULT_SOCKET_DIR, execFn = spawnSync6) {
34735
35291
  const resolvedDir = ensureSocketDir(socketDir);
34736
- const controlPath = join23(resolvedDir, "%C");
35292
+ const controlPath = join24(resolvedDir, "%C");
34737
35293
  try {
34738
35294
  const result = execFn("ssh", ["-O", "stop", "-o", `ControlPath=${controlPath}`, host], {
34739
35295
  encoding: "utf-8"
@@ -34747,9 +35303,9 @@ function pruneSocketDir(socketDir = DEFAULT_SOCKET_DIR) {
34747
35303
  const resolvedDir = ensureSocketDir(socketDir);
34748
35304
  let removed = 0;
34749
35305
  try {
34750
- const entries = readdirSync10(resolvedDir);
35306
+ const entries = readdirSync11(resolvedDir);
34751
35307
  for (const entry of entries) {
34752
- const fullPath = join23(resolvedDir, entry);
35308
+ const fullPath = join24(resolvedDir, entry);
34753
35309
  try {
34754
35310
  const stat = statSync6(fullPath);
34755
35311
  if (stat.isSocket()) {