@kontextmind/kxm 0.7.103 → 0.7.105

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (36) hide show
  1. package/.claude-plugin/marketplace.json +1 -1
  2. package/CHANGELOG.md +39 -8
  3. package/docs/concepts/data-and-storage.md +1 -1
  4. package/docs/contributing/test-matrix.md +11 -6
  5. package/docs/operations/backup-and-restore.md +59 -27
  6. package/docs/operations/deploy.md +1 -1
  7. package/docs/reference/cli-reference.md +73 -55
  8. package/docs/reference/config-reference.md +1 -1
  9. package/docs/reference/workflow-definitions.md +4 -4
  10. package/docs/start/first-workflow.md +6 -2
  11. package/docs/start/quickstart-claude-code.md +11 -1
  12. package/docs/templates/runbook.md +2 -1
  13. package/package.json +1 -1
  14. package/plugins/kxm/.claude-plugin/plugin.json +1 -1
  15. package/plugins/kxm/dist/cli.js +1802 -1011
  16. package/plugins/kxm/dist/mcp-server.js +1 -1
  17. package/plugins/kxm/dist/runtime-supervisor.js +322 -292
  18. package/plugins/kxm/dist/runtime.js +427 -351
  19. package/plugins/kxm/dist/server.js +78 -78
  20. package/plugins/kxm/package.json +1 -1
  21. package/plugins/kxm/skills/kxm-hub-ops/SKILL.md +14 -7
  22. package/plugins/kxm/src/cli/project.ts +132 -30
  23. package/plugins/kxm/src/cli/system.ts +19 -1
  24. package/plugins/kxm/src/cli/tasks.ts +55 -31
  25. package/plugins/kxm/src/cli/workflows.ts +52 -54
  26. package/plugins/kxm/src/cli.ts +8 -6
  27. package/plugins/kxm/src/database.ts +193 -65
  28. package/plugins/kxm/src/engine.ts +79 -3
  29. package/plugins/kxm/src/harness.ts +6 -5
  30. package/plugins/kxm/src/mcp-server.ts +1 -1
  31. package/plugins/kxm/src/runtime-paths.ts +50 -0
  32. package/plugins/kxm/src/runtime-store.ts +22 -53
  33. package/plugins/kxm/src/runtime-supervisor.ts +38 -17
  34. package/plugins/kxm/src/suggest.ts +132 -79
  35. package/plugins/kxm/src/workflow-manager.ts +42 -19
  36. package/schemas/backup-manifest.schema.json +15 -0
@@ -2986,7 +2986,7 @@ var require_compile = __commonJS({
2986
2986
  const schOrFunc = root.refs[ref];
2987
2987
  if (schOrFunc)
2988
2988
  return schOrFunc;
2989
- let _sch = resolve12.call(this, root, ref);
2989
+ let _sch = resolve13.call(this, root, ref);
2990
2990
  if (_sch === void 0) {
2991
2991
  const schema = (_a = root.localRefs) === null || _a === void 0 ? void 0 : _a[ref];
2992
2992
  const { schemaId } = this.opts;
@@ -3013,7 +3013,7 @@ var require_compile = __commonJS({
3013
3013
  function sameSchemaEnv(s1, s2) {
3014
3014
  return s1.schema === s2.schema && s1.root === s2.root && s1.baseId === s2.baseId;
3015
3015
  }
3016
- function resolve12(root, ref) {
3016
+ function resolve13(root, ref) {
3017
3017
  let sch;
3018
3018
  while (typeof (sch = this.refs[ref]) == "string")
3019
3019
  ref = sch;
@@ -3838,7 +3838,7 @@ var require_fast_uri = __commonJS({
3838
3838
  }
3839
3839
  return uri;
3840
3840
  }
3841
- function resolve12(baseURI, relativeURI, options) {
3841
+ function resolve13(baseURI, relativeURI, options) {
3842
3842
  const schemelessOptions = options ? Object.assign({ scheme: "null" }, options) : { scheme: "null" };
3843
3843
  const {
3844
3844
  parsed: baseParsed,
@@ -3871,49 +3871,49 @@ var require_fast_uri = __commonJS({
3871
3871
  schemelessOptions.skipEscape = true;
3872
3872
  return serialize(resolved, schemelessOptions);
3873
3873
  }
3874
- function resolveComponent(base, relative5, options, skipNormalization) {
3874
+ function resolveComponent(base, relative6, options, skipNormalization) {
3875
3875
  const target = {};
3876
3876
  if (!skipNormalization) {
3877
3877
  base = parse8(serialize(base, options), options);
3878
- relative5 = parse8(serialize(relative5, options), options);
3878
+ relative6 = parse8(serialize(relative6, options), options);
3879
3879
  }
3880
3880
  options = options || {};
3881
- if (!options.tolerant && relative5.scheme) {
3882
- target.scheme = relative5.scheme;
3883
- target.userinfo = relative5.userinfo;
3884
- target.host = relative5.host;
3885
- target.port = relative5.port;
3886
- target.path = removeDotSegments(relative5.path || "");
3887
- target.query = relative5.query;
3881
+ if (!options.tolerant && relative6.scheme) {
3882
+ target.scheme = relative6.scheme;
3883
+ target.userinfo = relative6.userinfo;
3884
+ target.host = relative6.host;
3885
+ target.port = relative6.port;
3886
+ target.path = removeDotSegments(relative6.path || "");
3887
+ target.query = relative6.query;
3888
3888
  } else {
3889
- if (relative5.userinfo !== void 0 || relative5.host !== void 0 || relative5.port !== void 0) {
3890
- target.userinfo = relative5.userinfo;
3891
- target.host = relative5.host;
3892
- target.port = relative5.port;
3893
- target.path = removeDotSegments(relative5.path || "");
3894
- target.query = relative5.query;
3889
+ if (relative6.userinfo !== void 0 || relative6.host !== void 0 || relative6.port !== void 0) {
3890
+ target.userinfo = relative6.userinfo;
3891
+ target.host = relative6.host;
3892
+ target.port = relative6.port;
3893
+ target.path = removeDotSegments(relative6.path || "");
3894
+ target.query = relative6.query;
3895
3895
  } else {
3896
- if (!relative5.path) {
3896
+ if (!relative6.path) {
3897
3897
  target.path = base.path;
3898
- if (relative5.query !== void 0) {
3899
- target.query = relative5.query;
3898
+ if (relative6.query !== void 0) {
3899
+ target.query = relative6.query;
3900
3900
  } else {
3901
3901
  target.query = base.query;
3902
3902
  }
3903
3903
  } else {
3904
- if (relative5.path[0] === "/") {
3905
- target.path = removeDotSegments(relative5.path);
3904
+ if (relative6.path[0] === "/") {
3905
+ target.path = removeDotSegments(relative6.path);
3906
3906
  } else {
3907
3907
  if ((base.userinfo !== void 0 || base.host !== void 0 || base.port !== void 0) && !base.path) {
3908
- target.path = "/" + relative5.path;
3908
+ target.path = "/" + relative6.path;
3909
3909
  } else if (!base.path) {
3910
- target.path = relative5.path;
3910
+ target.path = relative6.path;
3911
3911
  } else {
3912
- target.path = base.path.slice(0, base.path.lastIndexOf("/") + 1) + relative5.path;
3912
+ target.path = base.path.slice(0, base.path.lastIndexOf("/") + 1) + relative6.path;
3913
3913
  }
3914
3914
  target.path = removeDotSegments(target.path);
3915
3915
  }
3916
- target.query = relative5.query;
3916
+ target.query = relative6.query;
3917
3917
  }
3918
3918
  target.userinfo = base.userinfo;
3919
3919
  target.host = base.host;
@@ -3921,7 +3921,7 @@ var require_fast_uri = __commonJS({
3921
3921
  }
3922
3922
  target.scheme = base.scheme;
3923
3923
  }
3924
- target.fragment = relative5.fragment;
3924
+ target.fragment = relative6.fragment;
3925
3925
  return target;
3926
3926
  }
3927
3927
  function equal(uriA, uriB, options) {
@@ -4200,7 +4200,7 @@ var require_fast_uri = __commonJS({
4200
4200
  var fastUri = {
4201
4201
  SCHEMES,
4202
4202
  normalize,
4203
- resolve: resolve12,
4203
+ resolve: resolve13,
4204
4204
  resolveComponent,
4205
4205
  equal,
4206
4206
  serialize,
@@ -11410,10 +11410,10 @@ var require_resolve_block_map = __commonJS({
11410
11410
  let offset = bm.offset;
11411
11411
  let commentEnd = null;
11412
11412
  for (const collItem of bm.items) {
11413
- const { start, key, sep: sep3, value } = collItem;
11413
+ const { start, key, sep: sep4, value } = collItem;
11414
11414
  const keyProps = resolveProps.resolveProps(start, {
11415
11415
  indicator: "explicit-key-ind",
11416
- next: key ?? sep3?.[0],
11416
+ next: key ?? sep4?.[0],
11417
11417
  offset,
11418
11418
  onError,
11419
11419
  parentIndent: bm.indent,
@@ -11427,7 +11427,7 @@ var require_resolve_block_map = __commonJS({
11427
11427
  else if ("indent" in key && key.indent !== bm.indent)
11428
11428
  onError(offset, "BAD_INDENT", startColMsg);
11429
11429
  }
11430
- if (!keyProps.anchor && !keyProps.tag && !sep3) {
11430
+ if (!keyProps.anchor && !keyProps.tag && !sep4) {
11431
11431
  commentEnd = keyProps.end;
11432
11432
  if (keyProps.comment) {
11433
11433
  if (map.comment)
@@ -11451,7 +11451,7 @@ var require_resolve_block_map = __commonJS({
11451
11451
  ctx.atKey = false;
11452
11452
  if (utilMapIncludes.mapIncludes(ctx, map.items, keyNode))
11453
11453
  onError(keyStart, "DUPLICATE_KEY", "Map keys must be unique");
11454
- const valueProps = resolveProps.resolveProps(sep3 ?? [], {
11454
+ const valueProps = resolveProps.resolveProps(sep4 ?? [], {
11455
11455
  indicator: "map-value-ind",
11456
11456
  next: value,
11457
11457
  offset: keyNode.range[2],
@@ -11467,7 +11467,7 @@ var require_resolve_block_map = __commonJS({
11467
11467
  if (ctx.options.strict && keyProps.start < valueProps.found.offset - 1024)
11468
11468
  onError(keyNode.range, "KEY_OVER_1024_CHARS", "The : indicator must be at most 1024 chars after the start of an implicit block mapping key");
11469
11469
  }
11470
- const valueNode = value ? composeNode(ctx, value, valueProps, onError) : composeEmptyNode(ctx, offset, sep3, null, valueProps, onError);
11470
+ const valueNode = value ? composeNode(ctx, value, valueProps, onError) : composeEmptyNode(ctx, offset, sep4, null, valueProps, onError);
11471
11471
  if (ctx.schema.compat)
11472
11472
  utilFlowIndentCheck.flowIndentCheck(bm.indent, value, onError);
11473
11473
  offset = valueNode.range[2];
@@ -11558,7 +11558,7 @@ var require_resolve_end = __commonJS({
11558
11558
  let comment = "";
11559
11559
  if (end) {
11560
11560
  let hasSpace = false;
11561
- let sep3 = "";
11561
+ let sep4 = "";
11562
11562
  for (const token of end) {
11563
11563
  const { source, type } = token;
11564
11564
  switch (type) {
@@ -11572,13 +11572,13 @@ var require_resolve_end = __commonJS({
11572
11572
  if (!comment)
11573
11573
  comment = cb;
11574
11574
  else
11575
- comment += sep3 + cb;
11576
- sep3 = "";
11575
+ comment += sep4 + cb;
11576
+ sep4 = "";
11577
11577
  break;
11578
11578
  }
11579
11579
  case "newline":
11580
11580
  if (comment)
11581
- sep3 += source;
11581
+ sep4 += source;
11582
11582
  hasSpace = true;
11583
11583
  break;
11584
11584
  default:
@@ -11621,18 +11621,18 @@ var require_resolve_flow_collection = __commonJS({
11621
11621
  let offset = fc.offset + fc.start.source.length;
11622
11622
  for (let i = 0; i < fc.items.length; ++i) {
11623
11623
  const collItem = fc.items[i];
11624
- const { start, key, sep: sep3, value } = collItem;
11624
+ const { start, key, sep: sep4, value } = collItem;
11625
11625
  const props = resolveProps.resolveProps(start, {
11626
11626
  flow: fcName,
11627
11627
  indicator: "explicit-key-ind",
11628
- next: key ?? sep3?.[0],
11628
+ next: key ?? sep4?.[0],
11629
11629
  offset,
11630
11630
  onError,
11631
11631
  parentIndent: fc.indent,
11632
11632
  startOnNewline: false
11633
11633
  });
11634
11634
  if (!props.found) {
11635
- if (!props.anchor && !props.tag && !sep3 && !value) {
11635
+ if (!props.anchor && !props.tag && !sep4 && !value) {
11636
11636
  if (i === 0 && props.comma)
11637
11637
  onError(props.comma, "UNEXPECTED_TOKEN", `Unexpected , in ${fcName}`);
11638
11638
  else if (i < fc.items.length - 1)
@@ -11686,8 +11686,8 @@ var require_resolve_flow_collection = __commonJS({
11686
11686
  }
11687
11687
  }
11688
11688
  }
11689
- if (!isMap2 && !sep3 && !props.found) {
11690
- const valueNode = value ? composeNode(ctx, value, props, onError) : composeEmptyNode(ctx, props.end, sep3, null, props, onError);
11689
+ if (!isMap2 && !sep4 && !props.found) {
11690
+ const valueNode = value ? composeNode(ctx, value, props, onError) : composeEmptyNode(ctx, props.end, sep4, null, props, onError);
11691
11691
  coll.items.push(valueNode);
11692
11692
  offset = valueNode.range[2];
11693
11693
  if (isBlock(value))
@@ -11699,7 +11699,7 @@ var require_resolve_flow_collection = __commonJS({
11699
11699
  if (isBlock(key))
11700
11700
  onError(keyNode.range, "BLOCK_IN_FLOW", blockMsg);
11701
11701
  ctx.atKey = false;
11702
- const valueProps = resolveProps.resolveProps(sep3 ?? [], {
11702
+ const valueProps = resolveProps.resolveProps(sep4 ?? [], {
11703
11703
  flow: fcName,
11704
11704
  indicator: "map-value-ind",
11705
11705
  next: value,
@@ -11710,8 +11710,8 @@ var require_resolve_flow_collection = __commonJS({
11710
11710
  });
11711
11711
  if (valueProps.found) {
11712
11712
  if (!isMap2 && !props.found && ctx.options.strict) {
11713
- if (sep3)
11714
- for (const st of sep3) {
11713
+ if (sep4)
11714
+ for (const st of sep4) {
11715
11715
  if (st === valueProps.found)
11716
11716
  break;
11717
11717
  if (st.type === "newline") {
@@ -11728,7 +11728,7 @@ var require_resolve_flow_collection = __commonJS({
11728
11728
  else
11729
11729
  onError(valueProps.start, "MISSING_CHAR", `Missing , or : between ${fcName} items`);
11730
11730
  }
11731
- const valueNode = value ? composeNode(ctx, value, valueProps, onError) : valueProps.found ? composeEmptyNode(ctx, valueProps.end, sep3, null, valueProps, onError) : null;
11731
+ const valueNode = value ? composeNode(ctx, value, valueProps, onError) : valueProps.found ? composeEmptyNode(ctx, valueProps.end, sep4, null, valueProps, onError) : null;
11732
11732
  if (valueNode) {
11733
11733
  if (isBlock(value))
11734
11734
  onError(valueNode.range, "BLOCK_IN_FLOW", blockMsg);
@@ -11908,7 +11908,7 @@ var require_resolve_block_scalar = __commonJS({
11908
11908
  chompStart = i + 1;
11909
11909
  }
11910
11910
  let value = "";
11911
- let sep3 = "";
11911
+ let sep4 = "";
11912
11912
  let prevMoreIndented = false;
11913
11913
  for (let i = 0; i < contentStart; ++i)
11914
11914
  value += lines[i][0].slice(trimIndent) + "\n";
@@ -11925,24 +11925,24 @@ var require_resolve_block_scalar = __commonJS({
11925
11925
  indent = "";
11926
11926
  }
11927
11927
  if (type === Scalar.Scalar.BLOCK_LITERAL) {
11928
- value += sep3 + indent.slice(trimIndent) + content;
11929
- sep3 = "\n";
11928
+ value += sep4 + indent.slice(trimIndent) + content;
11929
+ sep4 = "\n";
11930
11930
  } else if (indent.length > trimIndent || content[0] === " ") {
11931
- if (sep3 === " ")
11932
- sep3 = "\n";
11933
- else if (!prevMoreIndented && sep3 === "\n")
11934
- sep3 = "\n\n";
11935
- value += sep3 + indent.slice(trimIndent) + content;
11936
- sep3 = "\n";
11931
+ if (sep4 === " ")
11932
+ sep4 = "\n";
11933
+ else if (!prevMoreIndented && sep4 === "\n")
11934
+ sep4 = "\n\n";
11935
+ value += sep4 + indent.slice(trimIndent) + content;
11936
+ sep4 = "\n";
11937
11937
  prevMoreIndented = true;
11938
11938
  } else if (content === "") {
11939
- if (sep3 === "\n")
11939
+ if (sep4 === "\n")
11940
11940
  value += "\n";
11941
11941
  else
11942
- sep3 = "\n";
11942
+ sep4 = "\n";
11943
11943
  } else {
11944
- value += sep3 + content;
11945
- sep3 = " ";
11944
+ value += sep4 + content;
11945
+ sep4 = " ";
11946
11946
  prevMoreIndented = false;
11947
11947
  }
11948
11948
  }
@@ -12125,25 +12125,25 @@ var require_resolve_flow_scalar = __commonJS({
12125
12125
  trimBoth = /^[ \t]+|[ \t]+$/g;
12126
12126
  }
12127
12127
  let res = match[1].replace(trimEnd, "");
12128
- let sep3 = " ";
12128
+ let sep4 = " ";
12129
12129
  let pos = line.lastIndex;
12130
12130
  while (match = line.exec(source)) {
12131
12131
  const lm = match[1].replace(trimBoth, "");
12132
12132
  if (lm === "") {
12133
- if (sep3 === "\n")
12134
- res += sep3;
12133
+ if (sep4 === "\n")
12134
+ res += sep4;
12135
12135
  else
12136
- sep3 = "\n";
12136
+ sep4 = "\n";
12137
12137
  } else {
12138
- res += sep3 + lm;
12139
- sep3 = " ";
12138
+ res += sep4 + lm;
12139
+ sep4 = " ";
12140
12140
  }
12141
12141
  pos = line.lastIndex;
12142
12142
  }
12143
12143
  const last = /[ \t]*(.*)/sy;
12144
12144
  last.lastIndex = pos;
12145
12145
  match = last.exec(source);
12146
- return res + sep3 + (match?.[1] ?? "");
12146
+ return res + sep4 + (match?.[1] ?? "");
12147
12147
  }
12148
12148
  function doubleQuotedValue(source, onError) {
12149
12149
  let res = "";
@@ -12953,14 +12953,14 @@ var require_cst_stringify = __commonJS({
12953
12953
  }
12954
12954
  }
12955
12955
  }
12956
- function stringifyItem({ start, key, sep: sep3, value }) {
12956
+ function stringifyItem({ start, key, sep: sep4, value }) {
12957
12957
  let res = "";
12958
12958
  for (const st of start)
12959
12959
  res += st.source;
12960
12960
  if (key)
12961
12961
  res += stringifyToken(key);
12962
- if (sep3)
12963
- for (const st of sep3)
12962
+ if (sep4)
12963
+ for (const st of sep4)
12964
12964
  res += st.source;
12965
12965
  if (value)
12966
12966
  res += stringifyToken(value);
@@ -14127,18 +14127,18 @@ var require_parser = __commonJS({
14127
14127
  if (this.type === "map-value-ind") {
14128
14128
  const prev = getPrevProps(this.peek(2));
14129
14129
  const start = getFirstKeyStartProps(prev);
14130
- let sep3;
14130
+ let sep4;
14131
14131
  if (scalar.end) {
14132
- sep3 = scalar.end;
14133
- sep3.push(this.sourceToken);
14132
+ sep4 = scalar.end;
14133
+ sep4.push(this.sourceToken);
14134
14134
  delete scalar.end;
14135
14135
  } else
14136
- sep3 = [this.sourceToken];
14136
+ sep4 = [this.sourceToken];
14137
14137
  const map = {
14138
14138
  type: "block-map",
14139
14139
  offset: scalar.offset,
14140
14140
  indent: scalar.indent,
14141
- items: [{ start, key: scalar, sep: sep3 }]
14141
+ items: [{ start, key: scalar, sep: sep4 }]
14142
14142
  };
14143
14143
  this.onKeyLine = true;
14144
14144
  this.stack[this.stack.length - 1] = map;
@@ -14291,15 +14291,15 @@ var require_parser = __commonJS({
14291
14291
  } else if (isFlowToken(it.key) && !includesToken(it.sep, "newline")) {
14292
14292
  const start2 = getFirstKeyStartProps(it.start);
14293
14293
  const key = it.key;
14294
- const sep3 = it.sep;
14295
- sep3.push(this.sourceToken);
14294
+ const sep4 = it.sep;
14295
+ sep4.push(this.sourceToken);
14296
14296
  delete it.key;
14297
14297
  delete it.sep;
14298
14298
  this.stack.push({
14299
14299
  type: "block-map",
14300
14300
  offset: this.offset,
14301
14301
  indent: this.indent,
14302
- items: [{ start: start2, key, sep: sep3 }]
14302
+ items: [{ start: start2, key, sep: sep4 }]
14303
14303
  });
14304
14304
  } else if (start.length > 0) {
14305
14305
  it.sep = it.sep.concat(start, this.sourceToken);
@@ -14493,13 +14493,13 @@ var require_parser = __commonJS({
14493
14493
  const prev = getPrevProps(parent);
14494
14494
  const start = getFirstKeyStartProps(prev);
14495
14495
  fixFlowSeqItems(fc);
14496
- const sep3 = fc.end.splice(1, fc.end.length);
14497
- sep3.push(this.sourceToken);
14496
+ const sep4 = fc.end.splice(1, fc.end.length);
14497
+ sep4.push(this.sourceToken);
14498
14498
  const map = {
14499
14499
  type: "block-map",
14500
14500
  offset: fc.offset,
14501
14501
  indent: fc.indent,
14502
- items: [{ start, key: fc, sep: sep3 }]
14502
+ items: [{ start, key: fc, sep: sep4 }]
14503
14503
  };
14504
14504
  this.onKeyLine = true;
14505
14505
  this.stack[this.stack.length - 1] = map;
@@ -14778,9 +14778,9 @@ var require_dist = __commonJS({
14778
14778
  });
14779
14779
 
14780
14780
  // plugins/kxm/src/runtime-service.ts
14781
- import { createHash as createHash7 } from "node:crypto";
14781
+ import { createHash as createHash8 } from "node:crypto";
14782
14782
  import { existsSync as existsSync7, readdirSync as readdirSync3, readFileSync as readFileSync4 } from "node:fs";
14783
- import { join as join6 } from "node:path";
14783
+ import { join as join7 } from "node:path";
14784
14784
 
14785
14785
  // plugins/kxm/src/project-config.ts
14786
14786
  var import__ = __toESM(require__(), 1);
@@ -15194,7 +15194,7 @@ function defaultSpawn(command, args, options) {
15194
15194
  if (options.signal?.aborted) {
15195
15195
  return Promise.resolve({ stdout: "", stderr: "", code: null, started: false, observedChildExit: false, error: new Error("process_aborted") });
15196
15196
  }
15197
- return new Promise((resolve12) => {
15197
+ return new Promise((resolve13) => {
15198
15198
  const stdout = [];
15199
15199
  const stderr = [];
15200
15200
  let outputBytes = 0;
@@ -15225,7 +15225,7 @@ function defaultSpawn(command, args, options) {
15225
15225
  const started = Boolean(child?.pid);
15226
15226
  if (started && !observedChildExit) error ??= new Error("process_exit_unobserved");
15227
15227
  const unverifiedDescendants = stopping || started && !observedChildExit;
15228
- resolve12({
15228
+ resolve13({
15229
15229
  stdout: Buffer.concat(stdout).toString("utf8"),
15230
15230
  stderr: Buffer.concat(stderr).toString("utf8"),
15231
15231
  code,
@@ -16017,7 +16017,7 @@ function probeEntry(entry, runCommand, timeoutMs, platform, probe = {}) {
16017
16017
  return {
16018
16018
  id: entry.id,
16019
16019
  label: entry.label,
16020
- default: entry.default,
16020
+ default: entry.id === (probe.defaultHarness ?? DEFAULT_HARNESS),
16021
16021
  mode: entry.mode,
16022
16022
  detected,
16023
16023
  authenticated,
@@ -16038,7 +16038,7 @@ function probeHarnesses(options = {}) {
16038
16038
  const runCommand = options.runCommand ?? defaultRunner(options.env ?? process.env);
16039
16039
  const platform = options.platform ?? process.platform;
16040
16040
  return {
16041
- defaultHarness: DEFAULT_HARNESS,
16041
+ defaultHarness: options.defaultHarness ?? DEFAULT_HARNESS,
16042
16042
  harnesses: BUILTIN_HARNESSES.map((entry) => probeEntry(entry, runCommand, timeoutMs, platform, options))
16043
16043
  };
16044
16044
  }
@@ -16449,7 +16449,7 @@ function formatHarnessInventory(inventory) {
16449
16449
  ].join(" ");
16450
16450
  });
16451
16451
  return [
16452
- `default harness: ${inventory.defaultHarness} (omit agent harness: to use headless Pi)`,
16452
+ `default harness: ${inventory.defaultHarness} (used when an agent omits harness:)`,
16453
16453
  "enable/disable = Git YAML (.kxm/agents, .kxm/models) or the harness's own plugin CLI",
16454
16454
  "governed kxm skills are not auto-updated",
16455
16455
  header,
@@ -17175,8 +17175,8 @@ function validateWorkflow(workflow, agents, models, repositories, gates, issues)
17175
17175
  const writable = Object.values(objectValue(step.repositories) ?? {}).filter((access) => access === "write").length;
17176
17176
  if (maxWriteRepositories > writable) issues.push(issue2("semantic", "write_repository_bound_invalid", file, `${stepId} maxWriteRepositories exceeds writable repository scope`));
17177
17177
  }
17178
- const join23 = objectValue(step.join);
17179
- const minimumPassed = join23 && typeof join23.minimumPassed === "number" ? join23.minimumPassed : void 0;
17178
+ const join24 = objectValue(step.join);
17179
+ const minimumPassed = join24 && typeof join24.minimumPassed === "number" ? join24.minimumPassed : void 0;
17180
17180
  if (minimumPassed !== void 0 && minimumPassed > maximum) issues.push(issue2("semantic", "join_impossible", file, `${stepId} minimumPassed exceeds assignment maximum`));
17181
17181
  const distinctBy = names(assignment?.distinctBy);
17182
17182
  if (distinctBy.length > 0) {
@@ -17660,9 +17660,9 @@ function legacyConfigFilesAt(root) {
17660
17660
  }
17661
17661
 
17662
17662
  // plugins/kxm/src/runtime-store.ts
17663
- import { createHash as createHash5, randomUUID } from "node:crypto";
17664
- import { existsSync as existsSync6, lstatSync as lstatSync3, mkdirSync as mkdirSync2, readFileSync as readFileSync3, realpathSync as realpathSync2, writeFileSync as writeFileSync2 } from "node:fs";
17665
- import { dirname as dirname5, join as join5, resolve as resolve5 } from "node:path";
17663
+ import { createHash as createHash6, randomUUID } from "node:crypto";
17664
+ import { existsSync as existsSync6, lstatSync as lstatSync3, mkdirSync as mkdirSync2, readFileSync as readFileSync3, writeFileSync as writeFileSync2 } from "node:fs";
17665
+ import { dirname as dirname5, resolve as resolve6 } from "node:path";
17666
17666
 
17667
17667
  // plugins/kxm/src/sqlite.ts
17668
17668
  import { existsSync as existsSync4 } from "node:fs";
@@ -17712,6 +17712,11 @@ function openReadOnlyDatabase(path) {
17712
17712
  return new DatabaseSync(uri.href, { readOnly: true });
17713
17713
  }
17714
17714
 
17715
+ // plugins/kxm/src/runtime-paths.ts
17716
+ import { createHash as createHash3 } from "node:crypto";
17717
+ import { realpathSync as realpathSync2 } from "node:fs";
17718
+ import { join as join4, resolve as resolve4 } from "node:path";
17719
+
17715
17720
  // plugins/kxm/src/bindings.ts
17716
17721
  import { homedir } from "node:os";
17717
17722
  import { dirname as dirname3, isAbsolute as isAbsolute2, join as join3, parse, relative as relative2, resolve as resolve3, sep as sep2 } from "node:path";
@@ -17743,8 +17748,33 @@ function kxmUserStateRoot(options = {}) {
17743
17748
  return resolve3(base, "kxm");
17744
17749
  }
17745
17750
 
17751
+ // plugins/kxm/src/runtime-paths.ts
17752
+ function kxmRuntimePaths(options = {}) {
17753
+ const stateRoot = options.stateRoot ? resolve4(options.stateRoot) : kxmUserStateRoot({ ...options.env ? { env: options.env } : {}, ...options.homeDir ? { homeDir: options.homeDir } : {} });
17754
+ const runtimeDir = join4(stateRoot, "runtime");
17755
+ return {
17756
+ stateRoot,
17757
+ runtimeDir,
17758
+ registryDb: join4(runtimeDir, "registry.db"),
17759
+ projectsDir: join4(runtimeDir, "projects")
17760
+ };
17761
+ }
17762
+ function projectRuntimeKey(projectRoot) {
17763
+ let canonical;
17764
+ try {
17765
+ canonical = realpathSync2.native(resolve4(projectRoot));
17766
+ } catch {
17767
+ canonical = resolve4(projectRoot);
17768
+ }
17769
+ const folded = process.platform === "win32" ? canonical.toLocaleLowerCase("en-US") : canonical;
17770
+ return createHash3("sha256").update(folded, "utf8").digest("hex").slice(0, 24);
17771
+ }
17772
+ function kxmProjectRunEventsPath(projectRoot, env) {
17773
+ return join4(kxmRuntimePaths({ env }).projectsDir, projectRuntimeKey(projectRoot), "run-events.db");
17774
+ }
17775
+
17746
17776
  // plugins/kxm/src/sync-transform.ts
17747
- import { createHash as createHash3 } from "node:crypto";
17777
+ import { createHash as createHash4 } from "node:crypto";
17748
17778
 
17749
17779
  // plugins/kxm/src/redact.ts
17750
17780
  var SECRET_PATTERNS = [
@@ -17783,7 +17813,7 @@ var KXM_DEFAULT_SYNC_POLICY = Object.freeze({
17783
17813
  diffs: false,
17784
17814
  environmentValues: false
17785
17815
  });
17786
- var KXM_DEFAULT_SYNC_POLICY_REVISION = `sha256:${createHash3("sha256").update(kxmCanonicalJson(KXM_DEFAULT_SYNC_POLICY), "utf8").digest("hex")}`;
17816
+ var KXM_DEFAULT_SYNC_POLICY_REVISION = `sha256:${createHash4("sha256").update(kxmCanonicalJson(KXM_DEFAULT_SYNC_POLICY), "utf8").digest("hex")}`;
17787
17817
  var MIN_REGISTERED_SECRET_CHARS = 4;
17788
17818
  var REDACTED = "[redacted]";
17789
17819
  var PATH_REDACTED = "[path]";
@@ -18075,7 +18105,7 @@ function kxmSyncEventBytes(event) {
18075
18105
  }
18076
18106
 
18077
18107
  // plugins/kxm/src/database.ts
18078
- import { createHash as createHash4, randomBytes } from "node:crypto";
18108
+ import { createHash as createHash5, randomBytes } from "node:crypto";
18079
18109
  import {
18080
18110
  chmodSync,
18081
18111
  copyFileSync,
@@ -18087,7 +18117,7 @@ import {
18087
18117
  unlinkSync,
18088
18118
  writeFileSync
18089
18119
  } from "node:fs";
18090
- import { basename as basename2, dirname as dirname4, join as join4, resolve as resolve4 } from "node:path";
18120
+ import { basename as basename2, dirname as dirname4, isAbsolute as isAbsolute3, join as join5, relative as relative3, resolve as resolve5, sep as sep3 } from "node:path";
18091
18121
  function databaseError(code, file, message) {
18092
18122
  const issue3 = { phase: "semantic", code, file, message };
18093
18123
  return new KxmConfigError([issue3]);
@@ -18313,11 +18343,11 @@ function checkIntegrity(database) {
18313
18343
  }
18314
18344
  function fileSha256(filePath) {
18315
18345
  const bytes = readFileSync2(filePath);
18316
- return `sha256:${createHash4("sha256").update(bytes).digest("hex")}`;
18346
+ return `sha256:${createHash5("sha256").update(bytes).digest("hex")}`;
18317
18347
  }
18318
18348
  function backupDatabaseFile(sourcePath, targetPath, storeId) {
18319
- const resolvedSource = resolve4(sourcePath);
18320
- const resolvedTarget = resolve4(targetPath);
18349
+ const resolvedSource = resolve5(sourcePath);
18350
+ const resolvedTarget = resolve5(targetPath);
18321
18351
  const sourceStat = lstatSync2(resolvedSource, { throwIfNoEntry: false });
18322
18352
  if (!sourceStat || !sourceStat.isFile() || sourceStat.isSymbolicLink()) {
18323
18353
  throw databaseError("runtime_path_invalid", resolvedSource, `source database ${resolvedSource} must be a regular file, not a link or directory`);
@@ -18367,8 +18397,8 @@ function backupDatabaseFile(sourcePath, targetPath, storeId) {
18367
18397
  };
18368
18398
  }
18369
18399
  function restoreDatabaseFile(backupPath, targetPath, storeId, expectedSchemaVersion, maxSupportedVersion) {
18370
- const resolvedBackup = resolve4(backupPath);
18371
- const resolvedTarget = resolve4(targetPath);
18400
+ const resolvedBackup = resolve5(backupPath);
18401
+ const resolvedTarget = resolve5(targetPath);
18372
18402
  const backupStat = lstatSync2(resolvedBackup, { throwIfNoEntry: false });
18373
18403
  if (!backupStat || !backupStat.isFile() || backupStat.isSymbolicLink()) {
18374
18404
  throw databaseError("runtime_path_invalid", resolvedBackup, `backup database ${resolvedBackup} must be a regular file, not a link or directory`);
@@ -18445,69 +18475,74 @@ function pushStore(stores, storeId, sourcePath) {
18445
18475
  if (stores.some((store) => store.storeId === storeId || store.sourcePath === sourcePath)) return;
18446
18476
  stores.push({ storeId, sourcePath, maxSupportedVersion: kxmBackupCeiling(storeId) });
18447
18477
  }
18448
- function discoverUserRuntime(env, stores, files) {
18449
- let stateRoot;
18478
+ function pushEventStore(stores, files, paths, key) {
18479
+ const dbPath = join5(paths.projectsDir, key, "run-events.db");
18480
+ if (!existsSync5(dbPath)) return;
18481
+ const safe = key.replace(/[^a-zA-Z0-9_.-]/g, "_");
18482
+ let storeId = `events:${safe}`;
18483
+ if (stores.some((store) => store.storeId === storeId)) storeId = `events:runtime:${safe}`;
18484
+ pushStore(stores, storeId, dbPath);
18485
+ const sidecar = `${dbPath}.run-prompts.json`;
18486
+ if (existsSync5(sidecar)) {
18487
+ const id = `${storeId}:run-prompts`;
18488
+ if (!files.some((file) => file.id === id || file.sourcePath === sidecar)) {
18489
+ files.push({ id, sourcePath: sidecar });
18490
+ }
18491
+ }
18492
+ }
18493
+ function discoverUserRuntime(runtimeProjectKey, options, stores, files) {
18494
+ let paths;
18450
18495
  try {
18451
- stateRoot = kxmUserStateRoot(env ? { env } : {});
18496
+ paths = kxmRuntimePaths(options.env ? { env: options.env } : {});
18452
18497
  } catch {
18453
- return;
18498
+ return void 0;
18454
18499
  }
18455
- const runtimeDir = join4(stateRoot, "runtime");
18456
- const registryPath = join4(runtimeDir, "registry.db");
18457
- if (existsSync5(registryPath)) {
18500
+ if (!options.allProjects) {
18501
+ pushEventStore(stores, files, paths, runtimeProjectKey);
18502
+ return paths.stateRoot;
18503
+ }
18504
+ if (existsSync5(paths.registryDb)) {
18458
18505
  const storeId = stores.some((store) => store.storeId === "registry") ? "runtime-registry" : "registry";
18459
- pushStore(stores, storeId, registryPath);
18506
+ pushStore(stores, storeId, paths.registryDb);
18460
18507
  }
18461
- const projectsDir = join4(runtimeDir, "projects");
18462
- if (!existsSync5(projectsDir)) return;
18508
+ if (!existsSync5(paths.projectsDir)) return paths.stateRoot;
18463
18509
  let entries;
18464
18510
  try {
18465
- entries = readdirSync2(projectsDir, { withFileTypes: true });
18511
+ entries = readdirSync2(paths.projectsDir, { withFileTypes: true });
18466
18512
  } catch {
18467
- return;
18513
+ return paths.stateRoot;
18468
18514
  }
18469
18515
  for (const entry of entries) {
18470
- if (!entry.isDirectory()) continue;
18471
- const dbPath = join4(projectsDir, entry.name, "run-events.db");
18472
- if (!existsSync5(dbPath)) continue;
18473
- const safe = entry.name.replace(/[^a-zA-Z0-9_.-]/g, "_");
18474
- let storeId = `events:${safe}`;
18475
- if (stores.some((store) => store.storeId === storeId)) storeId = `events:runtime:${safe}`;
18476
- pushStore(stores, storeId, dbPath);
18477
- const sidecar = `${dbPath}.run-prompts.json`;
18478
- if (existsSync5(sidecar)) {
18479
- const id = `${storeId}:run-prompts`;
18480
- if (!files.some((file) => file.id === id || file.sourcePath === sidecar)) {
18481
- files.push({ id, sourcePath: sidecar });
18482
- }
18483
- }
18516
+ if (entry.isDirectory()) pushEventStore(stores, files, paths, entry.name);
18484
18517
  }
18518
+ return paths.stateRoot;
18485
18519
  }
18486
18520
  function discoverBackupSources(projectRoot, options = {}) {
18487
- const root = resolve4(projectRoot);
18521
+ const root = resolve5(projectRoot);
18488
18522
  const stores = [];
18489
18523
  const files = [];
18490
- const hubPath = options.hubDataPath ? resolve4(options.hubDataPath) : join4(root, ".kxm", "state", "kxm.db");
18524
+ const hubPath = options.hubDataPath ? resolve5(options.hubDataPath) : join5(root, ".kxm", "state", "kxm.db");
18491
18525
  if (existsSync5(hubPath)) pushStore(stores, "hub-store", hubPath);
18492
- const registryPath = join4(root, ".kxm", "runtime", "registry.db");
18526
+ const registryPath = join5(root, ".kxm", "runtime", "registry.db");
18493
18527
  if (existsSync5(registryPath)) pushStore(stores, "registry", registryPath);
18494
- const bindingsPath = join4(root, ".kxm", "runtime", "bindings.db");
18528
+ const bindingsPath = join5(root, ".kxm", "runtime", "bindings.db");
18495
18529
  if (existsSync5(bindingsPath)) pushStore(stores, "binding-store", bindingsPath);
18496
- const eventsDir = join4(root, ".kxm", "runtime", "events");
18530
+ const eventsDir = join5(root, ".kxm", "runtime", "events");
18497
18531
  if (existsSync5(eventsDir)) {
18498
18532
  const entries = readdirSync2(eventsDir, { withFileTypes: true });
18499
18533
  for (const entry of entries) {
18500
18534
  if (entry.isFile() && entry.name.endsWith(".db")) {
18501
18535
  const key = entry.name.replace(/\.db$/, "").replace(/[^a-zA-Z0-9_.-]/g, "_");
18502
- pushStore(stores, `events:${key}`, join4(eventsDir, entry.name));
18536
+ pushStore(stores, `events:${key}`, join5(eventsDir, entry.name));
18503
18537
  }
18504
18538
  }
18505
18539
  }
18506
- discoverUserRuntime(options.env, stores, files);
18507
- return { stores, files };
18540
+ const runtimeProjectKey = projectRuntimeKey(root);
18541
+ const stateRoot = discoverUserRuntime(runtimeProjectKey, options, stores, files);
18542
+ return { stores, files, runtimeProjectKey, ...stateRoot !== void 0 ? { stateRoot } : {} };
18508
18543
  }
18509
18544
  function backupPlainFile(sourcePath, targetPath, id) {
18510
- const resolvedSource = resolve4(sourcePath);
18545
+ const resolvedSource = resolve5(sourcePath);
18511
18546
  const sourceStat = lstatSync2(resolvedSource, { throwIfNoEntry: false });
18512
18547
  if (!sourceStat || !sourceStat.isFile() || sourceStat.isSymbolicLink()) {
18513
18548
  throw databaseError("runtime_path_invalid", resolvedSource, `backup file ${resolvedSource} must be a regular file, not a link or directory`);
@@ -18550,18 +18585,19 @@ function discoverProjectStores(projectRoot, options = {}) {
18550
18585
  function backupDiscoverOptions(options) {
18551
18586
  return {
18552
18587
  ...options.hubDataPath !== void 0 ? { hubDataPath: options.hubDataPath } : {},
18553
- ...options.env !== void 0 ? { env: options.env } : {}
18588
+ ...options.env !== void 0 ? { env: options.env } : {},
18589
+ ...options.allProjects === true ? { allProjects: true } : {}
18554
18590
  };
18555
18591
  }
18556
18592
  function planBackup(options = {}) {
18557
- const projectRoot = options.projectRoot ? resolve4(options.projectRoot) : process.cwd();
18593
+ const projectRoot = options.projectRoot ? resolve5(options.projectRoot) : process.cwd();
18558
18594
  const discovered = discoverBackupSources(projectRoot, backupDiscoverOptions(options));
18559
18595
  if (discovered.stores.length === 0) {
18560
18596
  throw databaseError("backup_no_stores", projectRoot, "no existing SQLite stores found to backup");
18561
18597
  }
18562
18598
  const createdAt = (/* @__PURE__ */ new Date()).toISOString();
18563
18599
  const timestamp = createdAt.replace(/[:.]/g, "-");
18564
- const outDir = options.outDir ? resolve4(options.outDir) : join4(projectRoot, ".kxm", "backups", `backup-${timestamp}`);
18600
+ const outDir = options.outDir ? resolve5(options.outDir) : join5(projectRoot, ".kxm", "backups", `backup-${timestamp}`);
18565
18601
  const usedFilenames = /* @__PURE__ */ new Set();
18566
18602
  const stores = discovered.stores.map((store) => ({
18567
18603
  storeId: store.storeId,
@@ -18573,10 +18609,19 @@ function planBackup(options = {}) {
18573
18609
  sourcePath: file.sourcePath,
18574
18610
  backupFile: backupFilename(file.sourcePath, file.id, usedFilenames)
18575
18611
  }));
18576
- return { projectRoot, outDir, createdAt, stores, files };
18612
+ return {
18613
+ projectRoot,
18614
+ outDir,
18615
+ createdAt,
18616
+ scope: options.allProjects === true ? "all-projects" : "project",
18617
+ ...discovered.stateRoot !== void 0 ? { stateRoot: discovered.stateRoot } : {},
18618
+ runtimeProjectKey: discovered.runtimeProjectKey,
18619
+ stores,
18620
+ files
18621
+ };
18577
18622
  }
18578
18623
  function createBackup(options = {}) {
18579
- const { projectRoot, outDir, createdAt, stores, files } = planBackup(options);
18624
+ const { projectRoot, outDir, createdAt, scope, stateRoot, runtimeProjectKey, stores, files } = planBackup(options);
18580
18625
  const backupId = `bk_${randomBytes(8).toString("hex")}`;
18581
18626
  if (!existsSync5(outDir)) {
18582
18627
  mkdirSync(outDir, { recursive: true, mode: 448 });
@@ -18586,14 +18631,14 @@ function createBackup(options = {}) {
18586
18631
  const omitted = [];
18587
18632
  for (const store of stores) {
18588
18633
  try {
18589
- backedUpStores.push(backupDatabaseFile(store.sourcePath, join4(outDir, store.backupFile), store.storeId));
18634
+ backedUpStores.push(backupDatabaseFile(store.sourcePath, join5(outDir, store.backupFile), store.storeId));
18590
18635
  } catch {
18591
18636
  omitted.push(store.storeId);
18592
18637
  }
18593
18638
  }
18594
18639
  for (const file of files) {
18595
18640
  try {
18596
- backedUpFiles.push(backupPlainFile(file.sourcePath, join4(outDir, file.backupFile), file.id));
18641
+ backedUpFiles.push(backupPlainFile(file.sourcePath, join5(outDir, file.backupFile), file.id));
18597
18642
  } catch {
18598
18643
  omitted.push(file.id);
18599
18644
  }
@@ -18617,27 +18662,53 @@ function createBackup(options = {}) {
18617
18662
  backupId,
18618
18663
  createdAt,
18619
18664
  projectRoot,
18665
+ scope,
18666
+ ...stateRoot !== void 0 ? { stateRoot } : {},
18667
+ runtimeProjectKey,
18620
18668
  stores: backedUpStores,
18621
18669
  ...backedUpFiles.length > 0 ? { files: backedUpFiles } : {},
18622
18670
  complete: omitted.length === 0,
18623
18671
  ...omitted.length > 0 ? { omitted } : {}
18624
18672
  };
18625
18673
  const manifestJson = JSON.stringify(manifest, null, 2) + "\n";
18626
- const manifestSha256 = `sha256:${createHash4("sha256").update(manifestJson, "utf8").digest("hex")}`;
18674
+ const manifestSha256 = `sha256:${createHash5("sha256").update(manifestJson, "utf8").digest("hex")}`;
18627
18675
  manifest.manifestSha256 = manifestSha256;
18628
18676
  const finalJson = JSON.stringify(manifest, null, 2) + "\n";
18629
- const manifestPath = join4(outDir, "manifest.json");
18677
+ const manifestPath = join5(outDir, "manifest.json");
18630
18678
  writeFileSync(manifestPath, finalJson, "utf8");
18631
18679
  return { manifest, outDir };
18632
18680
  }
18681
+ function pathUnder(root, path) {
18682
+ if (!root) return void 0;
18683
+ const rel = relative3(root, path);
18684
+ if (rel === "" || rel === ".." || rel.startsWith(`..${sep3}`) || isAbsolute3(rel)) return void 0;
18685
+ return rel;
18686
+ }
18687
+ function restoreTarget(manifest, sourcePath, id, options, currentStateRoot) {
18688
+ const stateRel = pathUnder(manifest.stateRoot, sourcePath);
18689
+ const projectRel = pathUnder(manifest.projectRoot, sourcePath);
18690
+ if (stateRel !== void 0 && (projectRel === void 0 || stateRel.length <= projectRel.length)) {
18691
+ const ownEvents = manifest.runtimeProjectKey !== void 0 ? join5("runtime", "projects", manifest.runtimeProjectKey, "run-events.db") : void 0;
18692
+ const own = ownEvents !== void 0 && (stateRel === ownEvents || stateRel === `${ownEvents}.run-prompts.json`);
18693
+ if (own && !options.allProjects && options.projectRoot !== void 0) {
18694
+ const eventsPath = kxmProjectRunEventsPath(resolve5(options.projectRoot), options.env ?? process.env);
18695
+ return { targetPath: stateRel === ownEvents ? eventsPath : `${eventsPath}.run-prompts.json`, machineWide: false };
18696
+ }
18697
+ return { targetPath: join5(currentStateRoot(), stateRel), machineWide: !own };
18698
+ }
18699
+ if (projectRel !== void 0) {
18700
+ return { targetPath: options.projectRoot ? join5(resolve5(options.projectRoot), projectRel) : sourcePath, machineWide: false };
18701
+ }
18702
+ return { targetPath: sourcePath, machineWide: id !== "hub-store" };
18703
+ }
18633
18704
  function planRestore(manifestPathOrDir, options = {}) {
18634
- let manifestPath = resolve4(manifestPathOrDir);
18705
+ let manifestPath = resolve5(manifestPathOrDir);
18635
18706
  const stat = lstatSync2(manifestPath, { throwIfNoEntry: false });
18636
18707
  if (!stat) {
18637
18708
  throw databaseError("runtime_path_invalid", manifestPath, `manifest path ${manifestPath} does not exist`);
18638
18709
  }
18639
18710
  if (stat.isDirectory()) {
18640
- manifestPath = join4(manifestPath, "manifest.json");
18711
+ manifestPath = join5(manifestPath, "manifest.json");
18641
18712
  }
18642
18713
  if (!existsSync5(manifestPath)) {
18643
18714
  throw databaseError("runtime_path_invalid", manifestPath, `backup manifest ${manifestPath} not found`);
@@ -18656,9 +18727,12 @@ function planRestore(manifestPathOrDir, options = {}) {
18656
18727
  if (manifest.complete === false) {
18657
18728
  throw databaseError("restore_incomplete", manifestPath, "backup manifest is incomplete; refusing to restore a partial copy");
18658
18729
  }
18730
+ let stateRoot;
18731
+ const currentStateRoot = () => stateRoot ??= kxmRuntimePaths({ env: options.env ?? process.env }).stateRoot;
18732
+ const machineWide = [];
18659
18733
  const stores = [];
18660
18734
  for (const store of manifest.stores) {
18661
- const backupFilePath = join4(manifestDir, store.backupFile);
18735
+ const backupFilePath = join5(manifestDir, store.backupFile);
18662
18736
  if (!existsSync5(backupFilePath)) {
18663
18737
  throw databaseError("restore_file_missing", backupFilePath, `backup file ${store.backupFile} missing from ${manifestDir}`);
18664
18738
  }
@@ -18678,16 +18752,13 @@ function planRestore(manifestPathOrDir, options = {}) {
18678
18752
  `backup store ${store.storeId} schema version ${store.schemaVersion} is newer than supported maximum ${maxSupportedVersion}`
18679
18753
  );
18680
18754
  }
18681
- let targetPath = store.sourcePath;
18682
- if (options.projectRoot && manifest.projectRoot && targetPath.startsWith(manifest.projectRoot)) {
18683
- const rel = targetPath.slice(manifest.projectRoot.length).replace(/^[\\/]+/, "");
18684
- targetPath = join4(resolve4(options.projectRoot), rel);
18685
- }
18686
- stores.push({ storeId: store.storeId, backupFilePath, targetPath, schemaVersion: store.schemaVersion, maxSupportedVersion });
18755
+ const target = restoreTarget(manifest, store.sourcePath, store.storeId, options, currentStateRoot);
18756
+ if (target.machineWide) machineWide.push(store.storeId);
18757
+ stores.push({ storeId: store.storeId, backupFilePath, targetPath: target.targetPath, schemaVersion: store.schemaVersion, maxSupportedVersion });
18687
18758
  }
18688
18759
  const files = [];
18689
18760
  for (const file of manifest.files ?? []) {
18690
- const backupFilePath = join4(manifestDir, file.backupFile);
18761
+ const backupFilePath = join5(manifestDir, file.backupFile);
18691
18762
  if (!existsSync5(backupFilePath)) {
18692
18763
  throw databaseError("restore_file_missing", backupFilePath, `backup file ${file.backupFile} missing from ${manifestDir}`);
18693
18764
  }
@@ -18699,17 +18770,26 @@ function planRestore(manifestPathOrDir, options = {}) {
18699
18770
  `backup file ${file.backupFile} sha256 ${actualSha256} does not match manifest hash ${file.sha256}`
18700
18771
  );
18701
18772
  }
18702
- let targetPath = file.sourcePath;
18703
- if (options.projectRoot && manifest.projectRoot && targetPath.startsWith(manifest.projectRoot)) {
18704
- const rel = targetPath.slice(manifest.projectRoot.length).replace(/^[\\/]+/, "");
18705
- targetPath = join4(resolve4(options.projectRoot), rel);
18706
- }
18707
- files.push({ id: file.id, backupFilePath, targetPath });
18773
+ const target = restoreTarget(manifest, file.sourcePath, file.id, options, currentStateRoot);
18774
+ if (target.machineWide) machineWide.push(file.id);
18775
+ files.push({ id: file.id, backupFilePath, targetPath: target.targetPath });
18776
+ }
18777
+ if (machineWide.length > 0 && !options.allProjects) {
18778
+ throw databaseError(
18779
+ "restore_requires_all_projects",
18780
+ manifestPath,
18781
+ `backup ${manifest.backupId} holds Runtime state shared by every project on this machine (${machineWide.join(", ")}); restoring it rolls back the registry or other projects' runs. Pass --all-projects to restore all of it, or restore a backup taken without --all-projects`
18782
+ );
18708
18783
  }
18709
- return { manifestPath, backupId: manifest.backupId, stores, files };
18784
+ return {
18785
+ manifestPath,
18786
+ backupId: manifest.backupId,
18787
+ ...manifest.scope !== void 0 ? { scope: manifest.scope } : {},
18788
+ stores,
18789
+ files
18790
+ };
18710
18791
  }
18711
- function restoreBackup(manifestPathOrDir, options = {}) {
18712
- const plan = planRestore(manifestPathOrDir, options);
18792
+ function applyRestorePlan(plan) {
18713
18793
  const restoredStores = plan.stores.map((store) => restoreDatabaseFile(
18714
18794
  store.backupFilePath,
18715
18795
  store.targetPath,
@@ -18726,37 +18806,17 @@ function restoreBackup(manifestPathOrDir, options = {}) {
18726
18806
  restoredStores
18727
18807
  };
18728
18808
  }
18809
+ function restoreBackup(manifestPathOrDir, options = {}) {
18810
+ return applyRestorePlan(planRestore(manifestPathOrDir, options));
18811
+ }
18729
18812
 
18730
18813
  // plugins/kxm/src/runtime-store.ts
18731
- function kxmRuntimePaths(options = {}) {
18732
- const stateRoot = options.stateRoot ? resolve5(options.stateRoot) : kxmUserStateRoot({ ...options.env ? { env: options.env } : {}, ...options.homeDir ? { homeDir: options.homeDir } : {} });
18733
- const runtimeDir = join5(stateRoot, "runtime");
18734
- return {
18735
- stateRoot,
18736
- runtimeDir,
18737
- registryDb: join5(runtimeDir, "registry.db"),
18738
- projectsDir: join5(runtimeDir, "projects")
18739
- };
18740
- }
18741
18814
  function runtimeIssue(phase, code, file, message) {
18742
18815
  return { phase, code, file, message };
18743
18816
  }
18744
18817
  function runtimeError(code, file, message) {
18745
18818
  return new KxmConfigError([runtimeIssue("semantic", code, file, message)]);
18746
18819
  }
18747
- function projectRuntimeKey(projectRoot) {
18748
- let canonical;
18749
- try {
18750
- canonical = realpathSync2.native(resolve5(projectRoot));
18751
- } catch {
18752
- canonical = resolve5(projectRoot);
18753
- }
18754
- const folded = process.platform === "win32" ? canonical.toLocaleLowerCase("en-US") : canonical;
18755
- return createHash5("sha256").update(folded, "utf8").digest("hex").slice(0, 24);
18756
- }
18757
- function kxmProjectRunEventsPath(projectRoot, env) {
18758
- return join5(kxmRuntimePaths({ env }).projectsDir, projectRuntimeKey(projectRoot), "run-events.db");
18759
- }
18760
18820
  function projectRuntimeOwnsRun(projectRoot, runId, env) {
18761
18821
  const path = kxmProjectRunEventsPath(projectRoot, env);
18762
18822
  if (!existsSync6(path)) return false;
@@ -18793,11 +18853,23 @@ CREATE TABLE projects (
18793
18853
  registered_at TEXT NOT NULL
18794
18854
  ) STRICT;
18795
18855
  `;
18856
+ function readKxmSupervisorRecord(database) {
18857
+ const row = database.prepare("SELECT runtime_id, pid, port, token_hash, started_at, heartbeat_at, state FROM supervisor WHERE singleton_id = 1").get();
18858
+ return row ? {
18859
+ runtimeId: row.runtime_id,
18860
+ pid: row.pid,
18861
+ port: row.port,
18862
+ tokenHash: row.token_hash,
18863
+ startedAt: row.started_at,
18864
+ heartbeatAt: row.heartbeat_at,
18865
+ state: row.state
18866
+ } : void 0;
18867
+ }
18796
18868
  var KxmRuntimeRegistry = class {
18797
18869
  path;
18798
18870
  database;
18799
18871
  constructor(path) {
18800
- this.path = resolve5(path);
18872
+ this.path = resolve6(path);
18801
18873
  this.database = openDatabase(this.path, "runtime registry", {
18802
18874
  schema: REGISTRY_SCHEMA,
18803
18875
  version: KXM_REGISTRY_SCHEMA_VERSION,
@@ -18871,16 +18943,7 @@ var KxmRuntimeRegistry = class {
18871
18943
  return Number(result.changes);
18872
18944
  }
18873
18945
  readSupervisorRow() {
18874
- const row = this.database.prepare("SELECT runtime_id, pid, port, token_hash, started_at, heartbeat_at, state FROM supervisor WHERE singleton_id = 1").get();
18875
- return row ? {
18876
- runtimeId: row.runtime_id,
18877
- pid: row.pid,
18878
- port: row.port,
18879
- tokenHash: row.token_hash,
18880
- startedAt: row.started_at,
18881
- heartbeatAt: row.heartbeat_at,
18882
- state: row.state
18883
- } : void 0;
18946
+ return readKxmSupervisorRecord(this.database);
18884
18947
  }
18885
18948
  supervisor() {
18886
18949
  return this.readSupervisorRow();
@@ -18896,7 +18959,7 @@ var KxmRuntimeRegistry = class {
18896
18959
  return rows.map((row) => ({ projectRoot: row.project_root, projectId: row.project_id }));
18897
18960
  }
18898
18961
  registerProject(registration) {
18899
- const projectRoot = resolve5(registration.projectRoot);
18962
+ const projectRoot = resolve6(registration.projectRoot);
18900
18963
  const projectKey = projectRuntimeKey(projectRoot);
18901
18964
  this.database.exec("BEGIN IMMEDIATE");
18902
18965
  try {
@@ -18972,7 +19035,7 @@ var KXM_RUN_EVENT_SCHEMA = "kxm.run-event.v1";
18972
19035
  var KXM_ABSENT_MEMORY_REVISION = "ctxrev_absent";
18973
19036
  function hashKxmDriveLog(events) {
18974
19037
  const body = events.map((event) => `${event.eventId}:${event.sequence}`).join("\n");
18975
- return `sha256:${createHash5("sha256").update(body, "utf8").digest("hex")}`;
19038
+ return `sha256:${createHash6("sha256").update(body, "utf8").digest("hex")}`;
18976
19039
  }
18977
19040
  function verifyKxmDriveReceipt(receipt, events, foldedStatus, binding) {
18978
19041
  const reasons = [];
@@ -19323,7 +19386,7 @@ var KxmRunEventStore = class {
19323
19386
  syncRedactor = new KxmSyncRedactor();
19324
19387
  database;
19325
19388
  constructor(path) {
19326
- this.path = resolve5(path);
19389
+ this.path = resolve6(path);
19327
19390
  this.database = openDatabase(this.path, "run event store", {
19328
19391
  schema: EVENT_STORE_SCHEMA,
19329
19392
  version: KXM_EVENT_STORE_SCHEMA_VERSION,
@@ -20206,7 +20269,7 @@ function gateRowContentHash(table, row) {
20206
20269
  const copy = { ...row };
20207
20270
  delete copy.contentHash;
20208
20271
  void table;
20209
- return `sha256:${createHash5("sha256").update(kxmCanonicalJson(copy), "utf8").digest("hex")}`;
20272
+ return `sha256:${createHash6("sha256").update(kxmCanonicalJson(copy), "utf8").digest("hex")}`;
20210
20273
  }
20211
20274
  function assertClosedGateObservation(kind, row, id = "observation") {
20212
20275
  if (row.completeness === "incomplete") return;
@@ -21637,7 +21700,7 @@ function isTerminalRunStatus(status) {
21637
21700
  }
21638
21701
 
21639
21702
  // plugins/kxm/src/engine-plan.ts
21640
- import { createHash as createHash6 } from "node:crypto";
21703
+ import { createHash as createHash7 } from "node:crypto";
21641
21704
 
21642
21705
  // plugins/kxm/src/engine-compile.ts
21643
21706
  var KXM_COMPILED_WORKFLOW_SCHEMA = "kxm.compiled-workflow.v1";
@@ -21787,7 +21850,7 @@ function compileStep(step, index, stepIndex, requirePlanHash, sink) {
21787
21850
  const maxAttempts = compileCountField(step.maxAttempts, 1, `${id}.maxAttempts`, id, sink);
21788
21851
  const timeoutMs = compileOptionalDuration(step.timeoutMs, `${id}.timeoutMs`, id, sink);
21789
21852
  const assignments = compileAssignments(step, id, agent, sink);
21790
- const join23 = compileJoin(step, id, sink);
21853
+ const join24 = compileJoin(step, id, sink);
21791
21854
  const requiredEvidence = compileEvidence(step, id, sink);
21792
21855
  const transitions = compileTransitions(step, id, index, stepIndex, sink);
21793
21856
  const outcomes = Object.keys(transitions).sort(compareCodeUnits4);
@@ -21815,7 +21878,7 @@ function compileStep(step, index, stepIndex, requirePlanHash, sink) {
21815
21878
  transitions: orderedTransitions,
21816
21879
  requiresPlanHash: requirePlanHash.includes(id),
21817
21880
  assignments,
21818
- join: join23
21881
+ join: join24
21819
21882
  };
21820
21883
  if (kind === "agent" || kind === "moa") {
21821
21884
  if (!agent) return void 0;
@@ -21865,15 +21928,15 @@ function compileAssignments(step, stepId, primaryAgentId, sink) {
21865
21928
  };
21866
21929
  }
21867
21930
  function compileJoin(step, stepId, sink) {
21868
- const join23 = objectValue2(step.join);
21869
- if (!join23) return { strategy: "all" };
21870
- const declared = stringValue2(join23.strategy);
21931
+ const join24 = objectValue2(step.join);
21932
+ if (!join24) return { strategy: "all" };
21933
+ const declared = stringValue2(join24.strategy);
21871
21934
  const strategy = declared && JOIN_STRATEGIES.has(declared) ? declared : "all";
21872
- const minimumPassed = compileOptionalCount(join23.minimumPassed, `${stepId}.join.minimumPassed`, stepId, sink);
21935
+ const minimumPassed = compileOptionalCount(join24.minimumPassed, `${stepId}.join.minimumPassed`, stepId, sink);
21873
21936
  const compiled = {
21874
21937
  strategy,
21875
21938
  ...minimumPassed !== void 0 ? { minimumPassed } : {},
21876
- ...typeof join23.cancelRemaining === "boolean" ? { cancelRemaining: join23.cancelRemaining } : {}
21939
+ ...typeof join24.cancelRemaining === "boolean" ? { cancelRemaining: join24.cancelRemaining } : {}
21877
21940
  };
21878
21941
  return compiled;
21879
21942
  }
@@ -22184,7 +22247,7 @@ var JOIN_OPTIONAL = ["minimumPassed", "cancelRemaining"];
22184
22247
  var EVIDENCE_REQUIRED = ["key", "kind", "minimum", "reusableAcrossAttempts"];
22185
22248
  var EVIDENCE_OPTIONAL = ["producerPolicy"];
22186
22249
  function kxmSha256(input) {
22187
- return `sha256:${createHash6("sha256").update(input, "utf8").digest("hex")}`;
22250
+ return `sha256:${createHash7("sha256").update(input, "utf8").digest("hex")}`;
22188
22251
  }
22189
22252
  function kxmStepAskSha256(plan, stepId, agentId) {
22190
22253
  const step = Object.hasOwn(plan.steps, stepId) ? plan.steps[stepId] : void 0;
@@ -23219,12 +23282,12 @@ function enqueueKxmScheduledRun(storePath, runId, configRevision, bound, start)
23219
23282
  if (owner.admitted.has(runId) || owner.queue.some((item) => item.runId === runId)) {
23220
23283
  return Promise.reject(runtimeError("run_busy", runId, `run ${runId} is already admitted or queued`));
23221
23284
  }
23222
- return new Promise((resolve12, reject) => {
23285
+ return new Promise((resolve13, reject) => {
23223
23286
  owner.queue.push({
23224
23287
  runId,
23225
23288
  configRevision,
23226
23289
  bound,
23227
- start: (token) => start(token).then(resolve12, reject),
23290
+ start: (token) => start(token).then(resolve13, reject),
23228
23291
  fail: (error) => reject(error)
23229
23292
  });
23230
23293
  pump(storePath, owner);
@@ -23253,7 +23316,7 @@ function compareCodeUnits5(left, right) {
23253
23316
  return left < right ? -1 : left > right ? 1 : 0;
23254
23317
  }
23255
23318
  function sha256Of(input) {
23256
- return `sha256:${createHash7("sha256").update(input, "utf8").digest("hex")}`;
23319
+ return `sha256:${createHash8("sha256").update(input, "utf8").digest("hex")}`;
23257
23320
  }
23258
23321
  function objectValue3(value) {
23259
23322
  return value !== null && typeof value === "object" && !Array.isArray(value) ? value : void 0;
@@ -23289,7 +23352,7 @@ function collectMemoryFiles(dir, baseDir, ignoreSubdirs = /* @__PURE__ */ new Se
23289
23352
  const entries = readdirSync3(dir, { withFileTypes: true });
23290
23353
  const results = [];
23291
23354
  for (const entry of entries) {
23292
- const fullPath = join6(dir, entry.name);
23355
+ const fullPath = join7(dir, entry.name);
23293
23356
  if (entry.isDirectory()) {
23294
23357
  if (ignoreSubdirs.has(entry.name)) continue;
23295
23358
  results.push(...collectMemoryFiles(fullPath, baseDir, ignoreSubdirs));
@@ -23301,16 +23364,16 @@ function collectMemoryFiles(dir, baseDir, ignoreSubdirs = /* @__PURE__ */ new Se
23301
23364
  return results;
23302
23365
  }
23303
23366
  function computeKxmMemoryRevision(bundle, options = {}) {
23304
- const hash = createHash7("sha256");
23305
- const memoryDir = options.memoryDir ?? join6(bundle.projectRoot, ".kxm", "memory");
23367
+ const hash = createHash8("sha256");
23368
+ const memoryDir = options.memoryDir ?? join7(bundle.projectRoot, ".kxm", "memory");
23306
23369
  const memoryFiles = collectMemoryFiles(memoryDir, memoryDir, /* @__PURE__ */ new Set(["candidates"])).sort((left, right) => compareCodeUnits5(left.relPath, right.relPath));
23307
23370
  for (const file of memoryFiles) {
23308
23371
  hash.update(`memory:${file.relPath}\0`, "utf8");
23309
23372
  hash.update(readFileSync4(file.fullPath));
23310
23373
  hash.update("\0", "utf8");
23311
23374
  }
23312
- const skillsDir = options.skillsDir ?? join6(bundle.projectRoot, ".kxm", "skills");
23313
- const promotedSkillsDir = join6(skillsDir, "promoted");
23375
+ const skillsDir = options.skillsDir ?? join7(bundle.projectRoot, ".kxm", "skills");
23376
+ const promotedSkillsDir = join7(skillsDir, "promoted");
23314
23377
  const skillFiles = collectMemoryFiles(promotedSkillsDir, promotedSkillsDir).sort((left, right) => compareCodeUnits5(left.relPath, right.relPath));
23315
23378
  for (const file of skillFiles) {
23316
23379
  hash.update(`skill:${file.relPath}\0`, "utf8");
@@ -23394,7 +23457,7 @@ function openKxmRuntimeContext(projectRoot, options) {
23394
23457
  configRevision: bundle.configRevision,
23395
23458
  now: options.now ?? (/* @__PURE__ */ new Date()).toISOString()
23396
23459
  });
23397
- const eventStore = new KxmRunEventStore(join6(paths.projectsDir, registration.projectKey, "run-events.db"));
23460
+ const eventStore = new KxmRunEventStore(join7(paths.projectsDir, registration.projectKey, "run-events.db"));
23398
23461
  registerKxmRuntimeHandle(eventStore.path);
23399
23462
  return {
23400
23463
  registry,
@@ -23461,7 +23524,7 @@ function acceptKxmRun(context, bundle, request, options = {}) {
23461
23524
  }
23462
23525
  const revisions = kxmPolicyRevisions(bundle, options);
23463
23526
  const memoryRevision = options.memoryRevision ?? revisions.memoryRevision;
23464
- const promptSha256 = `sha256:${createHash7("sha256").update(request.prompt, "utf8").digest("hex")}`;
23527
+ const promptSha256 = `sha256:${createHash8("sha256").update(request.prompt, "utf8").digest("hex")}`;
23465
23528
  return context.eventStore.transaction(() => {
23466
23529
  const prior = context.eventStore.command(commandId);
23467
23530
  if (prior) {
@@ -23743,24 +23806,24 @@ function assertKxmConfigError(error) {
23743
23806
 
23744
23807
  // plugins/kxm/src/runtime-supervisor.ts
23745
23808
  import { spawn as spawn3 } from "node:child_process";
23746
- import { createHash as createHash14, createHmac, randomBytes as randomBytes3, timingSafeEqual as timingSafeEqual2 } from "node:crypto";
23809
+ import { createHash as createHash15, createHmac, randomBytes as randomBytes3, timingSafeEqual as timingSafeEqual2 } from "node:crypto";
23747
23810
  import { chmodSync as chmodSync2, existsSync as existsSync16, lstatSync as lstatSync5, mkdirSync as mkdirSync9, readFileSync as readFileSync12, renameSync as renameSync5, rmSync as rmSync4, writeFileSync as writeFileSync9 } from "node:fs";
23748
23811
  import { createServer } from "node:http";
23749
- import { dirname as dirname11, isAbsolute as isAbsolute6, join as join18 } from "node:path";
23812
+ import { dirname as dirname11, isAbsolute as isAbsolute7, join as join19 } from "node:path";
23750
23813
 
23751
23814
  // plugins/kxm/src/oneshot-producer.ts
23752
- import { join as join15 } from "node:path";
23815
+ import { join as join16 } from "node:path";
23753
23816
 
23754
23817
  // plugins/kxm/src/oneshot-evidence.ts
23755
- import { createHash as createHash8, randomUUID as randomUUID3 } from "node:crypto";
23818
+ import { createHash as createHash9, randomUUID as randomUUID3 } from "node:crypto";
23756
23819
  import { lstat, mkdir, open, rename } from "node:fs/promises";
23757
- import { join as join7 } from "node:path";
23820
+ import { join as join8 } from "node:path";
23758
23821
  var ONESHOT_EVIDENCE_SCHEMA = "kxm.oneshot-evidence.v2";
23759
23822
  var RETIRED_ONESHOT_EVIDENCE_SCHEMAS = /* @__PURE__ */ new Set(["kxm.oneshot-evidence.v1"]);
23760
23823
  var TEXT_LIMIT = 4 * 1024 * 1024;
23761
23824
  var ARGV_LIMIT = 64 * 1024;
23762
23825
  var RECORD_LIMIT = 16 * 1024 * 1024;
23763
- var digest = (value) => `sha256:${createHash8("sha256").update(value).digest("hex")}`;
23826
+ var digest = (value) => `sha256:${createHash9("sha256").update(value).digest("hex")}`;
23764
23827
  function parseOneShotEvidenceRecord(bytes) {
23765
23828
  let parsed;
23766
23829
  try {
@@ -23784,7 +23847,7 @@ async function beginOneShotEvidence(root, intent, sensitive) {
23784
23847
  throw new Error("oneshot_evidence_root_not_private");
23785
23848
  }
23786
23849
  const id = `evd_${randomUUID3().replaceAll("-", "")}`;
23787
- const dir = join7(root, id);
23850
+ const dir = join8(root, id);
23788
23851
  await mkdir(dir, { mode: 448 });
23789
23852
  const secrets = [...new Set(sensitive.filter((value) => value.length >= 8))].sort((a, b) => b.length - a.length);
23790
23853
  const redact = (value) => {
@@ -23804,7 +23867,7 @@ async function beginOneShotEvidence(root, intent, sensitive) {
23804
23867
  const bytes = JSON.stringify(value);
23805
23868
  if (Buffer.byteLength(bytes) > RECORD_LIMIT) throw new Error("oneshot_evidence_record_limit");
23806
23869
  parseOneShotEvidenceRecord(bytes);
23807
- const target = join7(dir, name);
23870
+ const target = join8(dir, name);
23808
23871
  const partial = `${target}.partial`;
23809
23872
  const file = await open(partial, "wx", 384);
23810
23873
  try {
@@ -23870,9 +23933,9 @@ async function beginOneShotEvidence(root, intent, sensitive) {
23870
23933
 
23871
23934
  // plugins/kxm/src/prices.ts
23872
23935
  var import_yaml3 = __toESM(require_dist(), 1);
23873
- import { createHash as createHash9 } from "node:crypto";
23936
+ import { createHash as createHash10 } from "node:crypto";
23874
23937
  import { existsSync as existsSync8, readFileSync as readFileSync5, statSync, writeFileSync as writeFileSync3 } from "node:fs";
23875
- import { join as join8 } from "node:path";
23938
+ import { join as join9 } from "node:path";
23876
23939
 
23877
23940
  // plugins/kxm/src/price-calc.ts
23878
23941
  var PRICES_SCHEMA = "kxm.prices.v1";
@@ -23933,7 +23996,7 @@ function hashPriceCatalog(catalog) {
23933
23996
  }))
23934
23997
  })).sort((a, b) => a.id.localeCompare(b.id))
23935
23998
  };
23936
- return createHash9("sha256").update(JSON.stringify(canonical), "utf8").digest("hex");
23999
+ return createHash10("sha256").update(JSON.stringify(canonical), "utf8").digest("hex");
23937
24000
  }
23938
24001
  function parsePriceCatalog(text) {
23939
24002
  const parsed = (0, import_yaml3.parse)(text);
@@ -24024,7 +24087,7 @@ function parsePriceCatalog(text) {
24024
24087
  return catalog;
24025
24088
  }
24026
24089
  function loadPriceCatalog(rootOrPath) {
24027
- const candidatePath = existsSync8(join8(rootOrPath, ".kxm", "prices.yaml")) ? join8(rootOrPath, ".kxm", "prices.yaml") : existsSync8(join8(rootOrPath, "prices.yaml")) ? join8(rootOrPath, "prices.yaml") : existsSync8(rootOrPath) && statSync(rootOrPath).isFile() ? rootOrPath : void 0;
24090
+ const candidatePath = existsSync8(join9(rootOrPath, ".kxm", "prices.yaml")) ? join9(rootOrPath, ".kxm", "prices.yaml") : existsSync8(join9(rootOrPath, "prices.yaml")) ? join9(rootOrPath, "prices.yaml") : existsSync8(rootOrPath) && statSync(rootOrPath).isFile() ? rootOrPath : void 0;
24028
24091
  if (!candidatePath || !existsSync8(candidatePath)) {
24029
24092
  return void 0;
24030
24093
  }
@@ -24046,31 +24109,31 @@ function loadPriceCatalogForEstimate(options) {
24046
24109
 
24047
24110
  // plugins/kxm/src/engine.ts
24048
24111
  var import_yaml7 = __toESM(require_dist(), 1);
24049
- import { createHash as createHash13, randomBytes as randomBytes2, timingSafeEqual } from "node:crypto";
24112
+ import { createHash as createHash14, randomBytes as randomBytes2, timingSafeEqual } from "node:crypto";
24050
24113
  import { existsSync as existsSync12, readFileSync as readFileSync9 } from "node:fs";
24051
- import { join as join14 } from "node:path";
24114
+ import { join as join15 } from "node:path";
24052
24115
 
24053
24116
  // plugins/kxm/src/routes.ts
24054
24117
  var import_yaml4 = __toESM(require_dist(), 1);
24055
24118
  import { existsSync as existsSync9, readFileSync as readFileSync6, mkdirSync as mkdirSync3, writeFileSync as writeFileSync4, readdirSync as readdirSync4 } from "node:fs";
24056
- import { join as join9 } from "node:path";
24119
+ import { join as join10 } from "node:path";
24057
24120
  var RETIRED_POLICY = ".kxm/producers.yaml";
24058
24121
  var empty = () => ({ schema: "kxm.routes.v2", updatedAt: (/* @__PURE__ */ new Date()).toISOString(), admitted: [], disabled: [], roles: {} });
24059
24122
  function loadRoutePolicy(root) {
24060
- if (existsSync9(join9(root, RETIRED_POLICY))) throw new Error(`retired ${RETIRED_POLICY} present; use .kxm/routes.yaml (kxm.routes.v2)`);
24061
- const path = join9(root, ".kxm", "routes.yaml");
24123
+ if (existsSync9(join10(root, RETIRED_POLICY))) throw new Error(`retired ${RETIRED_POLICY} present; use .kxm/routes.yaml (kxm.routes.v2)`);
24124
+ const path = join10(root, ".kxm", "routes.yaml");
24062
24125
  if (!existsSync9(path)) return empty();
24063
24126
  const value = (0, import_yaml4.parse)(readFileSync6(path, "utf8"));
24064
24127
  if (value?.schema !== "kxm.routes.v2" || !Array.isArray(value.admitted)) throw new Error("invalid .kxm/routes.yaml");
24065
24128
  return { schema: "kxm.routes.v2", updatedAt: typeof value.updatedAt === "string" ? value.updatedAt : (/* @__PURE__ */ new Date()).toISOString(), admitted: value.admitted.filter((x) => typeof x === "string"), disabled: Array.isArray(value.disabled) ? value.disabled.filter((x) => typeof x === "string") : [], roles: value.roles && typeof value.roles === "object" ? Object.fromEntries(Object.entries(value.roles).filter(([, v]) => Array.isArray(v)).map(([k, v]) => [k, v.filter((x) => typeof x === "string")])) : {} };
24066
24129
  }
24067
24130
  function listRoleBindings(root) {
24068
- const dir = join9(root, ".kxm", "roles");
24131
+ const dir = join10(root, ".kxm", "roles");
24069
24132
  const result = {};
24070
24133
  if (!existsSync9(dir)) return result;
24071
24134
  for (const file of readdirSync4(dir).filter((name) => name.endsWith(".yaml"))) {
24072
24135
  const role = file.slice(0, -5);
24073
- const value = (0, import_yaml4.parse)(readFileSync6(join9(dir, file), "utf8"));
24136
+ const value = (0, import_yaml4.parse)(readFileSync6(join10(dir, file), "utf8"));
24074
24137
  result[role] = (value.roster ?? []).map((entry) => entry.model).filter((model) => typeof model === "string");
24075
24138
  }
24076
24139
  return result;
@@ -24398,7 +24461,7 @@ function pruneContextPacket(packet, tokenBudget) {
24398
24461
  // plugins/kxm/src/dispatch-context.ts
24399
24462
  import { spawnSync as spawnSync4 } from "node:child_process";
24400
24463
  import { readdirSync as readdirSync7 } from "node:fs";
24401
- import { extname as extname3, join as join12 } from "node:path";
24464
+ import { extname as extname3, join as join13 } from "node:path";
24402
24465
 
24403
24466
  // plugins/kxm/src/protocol.ts
24404
24467
  var DEFAULT_MESSAGE_TTL_MS = 24 * 60 * 6e4;
@@ -25031,7 +25094,7 @@ function memoryRecordToContextItem(record2, project) {
25031
25094
  // plugins/kxm/src/memory.ts
25032
25095
  var import_yaml5 = __toESM(require_dist(), 1);
25033
25096
  import { existsSync as existsSync10, mkdirSync as mkdirSync4, readdirSync as readdirSync5, readFileSync as readFileSync7, writeFileSync as writeFileSync5 } from "node:fs";
25034
- import { extname as extname2, join as join10, resolve as resolve6 } from "node:path";
25097
+ import { extname as extname2, join as join11, resolve as resolve7 } from "node:path";
25035
25098
  var MEMORY_SCHEMA = "kxm.memory.v1";
25036
25099
  var VALID_SCOPES = /* @__PURE__ */ new Set(["agent", "project", "run", "operator"]);
25037
25100
  var VALID_AUTHORITIES = /* @__PURE__ */ new Set(["instruction", "evidence", "promoted"]);
@@ -25129,9 +25192,9 @@ function parseMemoryRecord(raw, filename = "memory.md") {
25129
25192
  };
25130
25193
  }
25131
25194
  function memoryDirectories(repoRoot) {
25132
- const root = resolve6(repoRoot);
25133
- const memoryDir = join10(root, ".kxm", "memory");
25134
- const candidatesDir = join10(memoryDir, "candidates");
25195
+ const root = resolve7(repoRoot);
25196
+ const memoryDir = join11(root, ".kxm", "memory");
25197
+ const candidatesDir = join11(memoryDir, "candidates");
25135
25198
  return { memoryDir, candidatesDir };
25136
25199
  }
25137
25200
  function loadAuthoredMemory(repoRoot) {
@@ -25141,7 +25204,7 @@ function loadAuthoredMemory(repoRoot) {
25141
25204
  const entries = readdirSync5(memoryDir, { withFileTypes: true });
25142
25205
  for (const entry of entries) {
25143
25206
  if (entry.isFile() && extname2(entry.name) === ".md") {
25144
- const fullPath = join10(memoryDir, entry.name);
25207
+ const fullPath = join11(memoryDir, entry.name);
25145
25208
  try {
25146
25209
  const text = readFileSync7(fullPath, "utf8");
25147
25210
  const record2 = parseMemoryRecord(text, entry.name);
@@ -25158,9 +25221,9 @@ function loadAuthoredMemory(repoRoot) {
25158
25221
 
25159
25222
  // plugins/kxm/src/skills.ts
25160
25223
  var import_yaml6 = __toESM(require_dist(), 1);
25161
- import { createHash as createHash10 } from "node:crypto";
25224
+ import { createHash as createHash11 } from "node:crypto";
25162
25225
  import { existsSync as existsSync11, mkdirSync as mkdirSync5, readdirSync as readdirSync6, readFileSync as readFileSync8, renameSync, rmSync, statSync as statSync2, writeFileSync as writeFileSync6 } from "node:fs";
25163
- import { dirname as dirname7, join as join11 } from "node:path";
25226
+ import { dirname as dirname7, join as join12 } from "node:path";
25164
25227
  var SKILL_CANDIDATE_SCHEMA = "kxm.skill-candidate.v1";
25165
25228
  var SKILL_EVALUATION_SCHEMA = "kxm.skill-evaluation.v1";
25166
25229
  var SKILL_DECISION_SCHEMA = "kxm.skill-decision.v1";
@@ -25183,7 +25246,7 @@ var SkillLifecycleError = class extends Error {
25183
25246
  }
25184
25247
  };
25185
25248
  function skillContentSha256(content) {
25186
- return createHash10("sha256").update(content, "utf8").digest("hex");
25249
+ return createHash11("sha256").update(content, "utf8").digest("hex");
25187
25250
  }
25188
25251
  function skillIdFor(name, contentSha256) {
25189
25252
  const slug = name.toLowerCase().replaceAll(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "").slice(0, 40);
@@ -25266,14 +25329,14 @@ var SkillLifecycle = class {
25266
25329
  writeFileSync6(file, content);
25267
25330
  }
25268
25331
  dir(state) {
25269
- return join11(this.root, state === "candidate" ? "candidates" : `${state}s`.replace("rejecteds", "rejected").replace("promoteds", "promoted"));
25332
+ return join12(this.root, state === "candidate" ? "candidates" : `${state}s`.replace("rejecteds", "rejected").replace("promoteds", "promoted"));
25270
25333
  }
25271
25334
  historyFile(id) {
25272
- return join11(this.root, "history", `${id}.jsonl`);
25335
+ return join12(this.root, "history", `${id}.jsonl`);
25273
25336
  }
25274
25337
  paths(state, id) {
25275
- const dir = join11(this.dir(state), id);
25276
- return { dir, metadata: join11(dir, "metadata.json"), skill: join11(dir, "SKILL.md") };
25338
+ const dir = join12(this.dir(state), id);
25339
+ return { dir, metadata: join12(dir, "metadata.json"), skill: join12(dir, "SKILL.md") };
25277
25340
  }
25278
25341
  appendHistory(id, record2) {
25279
25342
  const line = `${JSON.stringify(record2)}
@@ -25299,8 +25362,8 @@ var SkillLifecycle = class {
25299
25362
  return JSON.parse(readFileSync8(metadata, "utf8"));
25300
25363
  }
25301
25364
  move(from, to, id) {
25302
- const fromDir = join11(this.dir(from), id);
25303
- const toDir = join11(this.dir(to), id);
25365
+ const fromDir = join12(this.dir(from), id);
25366
+ const toDir = join12(this.dir(to), id);
25304
25367
  if (!existsSync11(fromDir)) {
25305
25368
  throw new SkillLifecycleError("skill_not_found", `skill ${id} not found in ${from}`);
25306
25369
  }
@@ -25465,7 +25528,7 @@ var SkillLifecycle = class {
25465
25528
  const metadataContent = readFileSync8(candidatePaths.metadata, "utf8");
25466
25529
  this.write(promotedPaths.skill, skillContent);
25467
25530
  this.write(promotedPaths.metadata, metadataContent);
25468
- const patchPath = join11(this.root, "patches", `${candidateId}.patch`);
25531
+ const patchPath = join12(this.root, "patches", `${candidateId}.patch`);
25469
25532
  const relSkillPath = `.kxm/skills/promoted/${candidateId}/SKILL.md`;
25470
25533
  const relMetaPath = `.kxm/skills/promoted/${candidateId}/metadata.json`;
25471
25534
  const patch = `${createUnifiedPatch(relSkillPath, skillContent)}${createUnifiedPatch(relMetaPath, metadataContent)}`;
@@ -25539,7 +25602,7 @@ function boundedList(value, field) {
25539
25602
  return [...new Set(refs)];
25540
25603
  }
25541
25604
  function readdirSorted(dir) {
25542
- return readdirSync6(dir).filter((entry) => statSync2(join11(dir, entry)).isDirectory()).sort();
25605
+ return readdirSync6(dir).filter((entry) => statSync2(join12(dir, entry)).isDirectory()).sort();
25543
25606
  }
25544
25607
 
25545
25608
  // plugins/kxm/src/dispatch-context.ts
@@ -25580,7 +25643,7 @@ function contextRoleForAgent(agentId) {
25580
25643
  return agentId;
25581
25644
  }
25582
25645
  function dispatchContextPresent(projectRoot) {
25583
- return hasTopLevelMarkdown(join12(projectRoot, ".kxm", "memory")) || hasAnyEntry(join12(projectRoot, ".kxm", "skills", "promoted"));
25646
+ return hasTopLevelMarkdown(join13(projectRoot, ".kxm", "memory")) || hasAnyEntry(join13(projectRoot, ".kxm", "skills", "promoted"));
25584
25647
  }
25585
25648
  function hasTopLevelMarkdown(dir) {
25586
25649
  try {
@@ -25656,7 +25719,7 @@ function loadDispatchContextSources(input) {
25656
25719
  }
25657
25720
  const promoted = [];
25658
25721
  try {
25659
- const lifecycle = new SkillLifecycle(join12(projectRoot, ".kxm", "skills"));
25722
+ const lifecycle = new SkillLifecycle(join13(projectRoot, ".kxm", "skills"));
25660
25723
  for (const metadata of lifecycle.list("promoted")) {
25661
25724
  try {
25662
25725
  promoted.push(lifecycle.verify("promoted", metadata.id));
@@ -25739,18 +25802,18 @@ function assembleDispatchContext(sources, input) {
25739
25802
  }
25740
25803
 
25741
25804
  // plugins/kxm/src/engine-artifacts.ts
25742
- import { join as join13 } from "node:path";
25805
+ import { join as join14 } from "node:path";
25743
25806
 
25744
25807
  // plugins/kxm/src/artifacts-exist.ts
25745
25808
  import { lstatSync as lstatSync4, realpathSync as realpathSync3, statSync as statSync3 } from "node:fs";
25746
- import { isAbsolute as isAbsolute3, relative as relative3, resolve as resolve7 } from "node:path";
25809
+ import { isAbsolute as isAbsolute4, relative as relative4, resolve as resolve8 } from "node:path";
25747
25810
  function staysUnder(root, candidate) {
25748
- const child = relative3(root, candidate);
25749
- return child === "" || !isAbsolute3(child) && child !== ".." && !child.startsWith(`..${process.platform === "win32" ? "\\" : "/"}`);
25811
+ const child = relative4(root, candidate);
25812
+ return child === "" || !isAbsolute4(child) && child !== ".." && !child.startsWith(`..${process.platform === "win32" ? "\\" : "/"}`);
25750
25813
  }
25751
25814
  function verifyArtifactExists(rootInput, pathInput) {
25752
- const lexicalRoot = resolve7(rootInput);
25753
- const lexicalPath = resolve7(pathInput);
25815
+ const lexicalRoot = resolve8(rootInput);
25816
+ const lexicalPath = resolve8(pathInput);
25754
25817
  if (!staysUnder(lexicalRoot, lexicalPath)) {
25755
25818
  return { ok: false, error: "artifact_outside_workspace_assets", path: lexicalPath };
25756
25819
  }
@@ -25786,14 +25849,14 @@ function verifyArtifactExists(rootInput, pathInput) {
25786
25849
  // plugins/kxm/src/engine-artifacts.ts
25787
25850
  var kxmArtifactsGateSeams = {};
25788
25851
  function evaluateArtifactsGate(context, definition) {
25789
- const root = join13(context.projectRoot, ".kxm", "assets");
25852
+ const root = join14(context.projectRoot, ".kxm", "assets");
25790
25853
  const startedAt = (/* @__PURE__ */ new Date()).toISOString();
25791
25854
  const startTime = process.hrtime.bigint();
25792
25855
  let checkedCount = 0;
25793
25856
  let failedCount = 0;
25794
25857
  for (const [index, path] of definition.paths.entries()) {
25795
25858
  checkedCount += 1;
25796
- const result = verifyArtifactExists(root, join13(root, path));
25859
+ const result = verifyArtifactExists(root, join14(root, path));
25797
25860
  if (!result.ok) failedCount += 1;
25798
25861
  kxmArtifactsGateSeams.afterPathChecked?.({ path, index, checkedCount, failedCount });
25799
25862
  }
@@ -25826,7 +25889,7 @@ function evaluateArtifactsGate(context, definition) {
25826
25889
 
25827
25890
  // plugins/kxm/src/engine-command.ts
25828
25891
  import { spawn as spawn2 } from "node:child_process";
25829
- import { createHash as createHash11 } from "node:crypto";
25892
+ import { createHash as createHash12 } from "node:crypto";
25830
25893
 
25831
25894
  // plugins/kxm/src/safety-integrity.ts
25832
25895
  var DESTRUCTIVE_COMMAND_PATTERNS = Object.freeze([
@@ -25874,7 +25937,7 @@ function createCommandObserver(input) {
25874
25937
  return new CommandObserver(input);
25875
25938
  }
25876
25939
  var StreamDigest = class {
25877
- hash = createHash11("sha256");
25940
+ hash = createHash12("sha256");
25878
25941
  bytes = 0;
25879
25942
  complete = 0;
25880
25943
  digest() {
@@ -25949,8 +26012,8 @@ var CommandObserver = class {
25949
26012
  this.requestStop("error", "lost-close");
25950
26013
  }
25951
26014
  run() {
25952
- return new Promise((resolve12) => {
25953
- this.resolveOutcome = resolve12;
26015
+ return new Promise((resolve13) => {
26016
+ this.resolveOutcome = resolve13;
25954
26017
  try {
25955
26018
  this.start();
25956
26019
  } catch (error) {
@@ -26721,7 +26784,7 @@ function hashFromStore(context, runId) {
26721
26784
  }
26722
26785
 
26723
26786
  // plugins/kxm/src/routing.ts
26724
- import { createHash as createHash12 } from "node:crypto";
26787
+ import { createHash as createHash13 } from "node:crypto";
26725
26788
  var ROUTING_RECORD_V2_SCHEMA = "kxm.routing-record.v2";
26726
26789
  var BEHAVIORAL_HASH_VERSION = 1;
26727
26790
  var MAX_PROVIDER_METADATA_FIELDS = 32;
@@ -26744,7 +26807,7 @@ function behavioralConfigHash(input) {
26744
26807
  workflowDefinitionSha256: input.workflowDefinitionSha256?.trim() ?? null,
26745
26808
  verifierConfigSha256: input.verifierConfigSha256?.trim() ?? null
26746
26809
  };
26747
- return createHash12("sha256").update(JSON.stringify(canonical), "utf8").digest("hex");
26810
+ return createHash13("sha256").update(JSON.stringify(canonical), "utf8").digest("hex");
26748
26811
  }
26749
26812
  function boundedInt(value, field) {
26750
26813
  if (value === void 0 || value === null) return void 0;
@@ -26920,7 +26983,7 @@ function requireTrustedProducer(producer) {
26920
26983
  }
26921
26984
  }
26922
26985
  function hashCapabilitySecret(secret) {
26923
- return `sha256:${createHash13("sha256").update(`${CAPABILITY_PREFIX}${secret}`, "utf8").digest("hex")}`;
26986
+ return `sha256:${createHash14("sha256").update(`${CAPABILITY_PREFIX}${secret}`, "utf8").digest("hex")}`;
26924
26987
  }
26925
26988
  function mintKxmCapabilitySecret() {
26926
26989
  const secret = `kxmcap_${randomBytes2(32).toString("base64url")}`;
@@ -27049,7 +27112,7 @@ async function driveAdmitted(context, runId, producer, token, options = {}) {
27049
27112
  return latest;
27050
27113
  }
27051
27114
  function newDriveId(runId, token, runtimeId, monotonicNs) {
27052
- return `drv_${createHash13("sha256").update(`${runId}\0${token}\0${runtimeId}\0${monotonicNs}`, "utf8").digest("hex").slice(0, 24)}`;
27115
+ return `drv_${createHash14("sha256").update(`${runId}\0${token}\0${runtimeId}\0${monotonicNs}`, "utf8").digest("hex").slice(0, 24)}`;
27053
27116
  }
27054
27117
  function driveErrorSummary(error) {
27055
27118
  const raw = error instanceof KxmConfigError ? error.issues[0]?.code : void 0;
@@ -27276,8 +27339,8 @@ var KxmRunScheduler = class _KxmRunScheduler {
27276
27339
  resolve: (_value) => void 0,
27277
27340
  reject: (_error) => void 0
27278
27341
  };
27279
- const settled = new Promise((resolve12, reject) => {
27280
- pending.resolve = resolve12;
27342
+ const settled = new Promise((resolve13, reject) => {
27343
+ pending.resolve = resolve13;
27281
27344
  pending.reject = reject;
27282
27345
  });
27283
27346
  void settled.then(void 0, () => void 0);
@@ -27675,7 +27738,7 @@ function unreconciledPanelAttemptId(state) {
27675
27738
  }
27676
27739
  function resolveProducerRoute(projectRoot, step, agentId) {
27677
27740
  let agentModel;
27678
- const agentFile = join14(projectRoot, ".kxm", "agents", `${agentId}.yaml`);
27741
+ const agentFile = join15(projectRoot, ".kxm", "agents", `${agentId}.yaml`);
27679
27742
  if (existsSync12(agentFile)) {
27680
27743
  try {
27681
27744
  const parsed = (0, import_yaml7.parse)(readFileSync9(agentFile, "utf8"));
@@ -27982,7 +28045,7 @@ function birthMember(context, input) {
27982
28045
  if (promptText === void 0) {
27983
28046
  throw runtimeError("run_prompt_mismatch", run.runId, "prompt text missing from accepted run prompt store");
27984
28047
  }
27985
- const promptHash = createHash13("sha256").update(promptText, "utf8").digest("hex");
28048
+ const promptHash = createHash14("sha256").update(promptText, "utf8").digest("hex");
27986
28049
  const expectedHash = run.promptSha256.replace(/^sha256:/, "");
27987
28050
  if (promptHash !== expectedHash) {
27988
28051
  throw runtimeError("run_prompt_mismatch", run.runId, "prompt text does not match accepted promptSha256");
@@ -28892,11 +28955,11 @@ function readYamlRecord(path) {
28892
28955
  return void 0;
28893
28956
  }
28894
28957
  function agentHarness(projectRoot, agentId) {
28895
- const harness = readYamlRecord(join14(projectRoot, ".kxm", "agents", `${agentId}.yaml`))?.harness;
28958
+ const harness = readYamlRecord(join15(projectRoot, ".kxm", "agents", `${agentId}.yaml`))?.harness;
28896
28959
  return typeof harness === "string" && harness.length > 0 ? harness : void 0;
28897
28960
  }
28898
28961
  function projectDefaultHarness(projectRoot) {
28899
- const harness = readYamlRecord(join14(projectRoot, ".kxm", "project.yaml"))?.defaultHarness;
28962
+ const harness = readYamlRecord(join15(projectRoot, ".kxm", "project.yaml"))?.defaultHarness;
28900
28963
  return typeof harness === "string" && harness.length > 0 ? harness : "pi";
28901
28964
  }
28902
28965
  function unsupportedLiveWrite(projectRoot, step, agentId, selector, maxConcurrentRuns) {
@@ -28923,7 +28986,7 @@ function unsupportedLiveWrite(projectRoot, step, agentId, selector, maxConcurren
28923
28986
  detail: `live write steps require an audited writer profile; ${harness} has none`
28924
28987
  };
28925
28988
  }
28926
- const rosterPath = join14(projectRoot, ".kxm", "roster.yaml");
28989
+ const rosterPath = join15(projectRoot, ".kxm", "roster.yaml");
28927
28990
  if (!existsSync12(rosterPath)) return void 0;
28928
28991
  const roster = readYamlRecord(rosterPath);
28929
28992
  if (!roster || roster.schema !== "kxm.developer-roster.v1") {
@@ -29567,7 +29630,7 @@ Return a final JSON object with an "outcome" field chosen from ${JSON.stringify(
29567
29630
  }
29568
29631
  const spawnFn = options.spawnProcess ?? defaultSpawn;
29569
29632
  const cwd = options.projectRoot ?? process.cwd();
29570
- const evidence = await beginOneShotEvidence(options.evidenceRoot ?? join15(kxmUserStateRoot(), "runtime", "oneshot-evidence"), {
29633
+ const evidence = await beginOneShotEvidence(options.evidenceRoot ?? join16(kxmUserStateRoot(), "runtime", "oneshot-evidence"), {
29571
29634
  runId: request.runId,
29572
29635
  stepId: request.stepId,
29573
29636
  attemptId: request.attemptId,
@@ -29807,7 +29870,7 @@ var RuntimeHubClient = class {
29807
29870
  // plugins/kxm/src/hub-binding.ts
29808
29871
  import { existsSync as existsSync13, mkdirSync as mkdirSync6, readFileSync as readFileSync10, renameSync as renameSync2, rmSync as rmSync2, writeFileSync as writeFileSync7 } from "node:fs";
29809
29872
  import { homedir as homedir2 } from "node:os";
29810
- import { dirname as dirname8, isAbsolute as isAbsolute4, join as join16, resolve as resolve8 } from "node:path";
29873
+ import { dirname as dirname8, isAbsolute as isAbsolute5, join as join17, resolve as resolve9 } from "node:path";
29811
29874
  var HUB_BINDING_SCHEMA = "kxm.hub-binding.v1";
29812
29875
  var HubBindingError = class extends Error {
29813
29876
  constructor(message) {
@@ -29818,21 +29881,21 @@ var HubBindingError = class extends Error {
29818
29881
  function resolveUserStateRoot(env) {
29819
29882
  const explicit = env.KXM_STATE_HOME?.trim();
29820
29883
  if (explicit) {
29821
- if (!isAbsolute4(explicit)) throw new HubBindingError("local_state_root_not_absolute");
29822
- return resolve8(explicit);
29884
+ if (!isAbsolute5(explicit)) throw new HubBindingError("local_state_root_not_absolute");
29885
+ return resolve9(explicit);
29823
29886
  }
29824
29887
  if (process.platform === "win32") {
29825
29888
  const localAppData = env.LOCALAPPDATA?.trim();
29826
- const base2 = localAppData && isAbsolute4(localAppData) ? localAppData : join16(homedir2(), "AppData", "Local");
29827
- return resolve8(base2, "KXM");
29889
+ const base2 = localAppData && isAbsolute5(localAppData) ? localAppData : join17(homedir2(), "AppData", "Local");
29890
+ return resolve9(base2, "KXM");
29828
29891
  }
29829
- if (process.platform === "darwin") return resolve8(homedir2(), "Library", "Application Support", "KXM");
29892
+ if (process.platform === "darwin") return resolve9(homedir2(), "Library", "Application Support", "KXM");
29830
29893
  const xdgState = env.XDG_STATE_HOME?.trim();
29831
- const base = xdgState && isAbsolute4(xdgState) ? xdgState : join16(homedir2(), ".local", "state");
29832
- return resolve8(base, "kxm");
29894
+ const base = xdgState && isAbsolute5(xdgState) ? xdgState : join17(homedir2(), ".local", "state");
29895
+ return resolve9(base, "kxm");
29833
29896
  }
29834
29897
  function hubBindingFile(env = process.env) {
29835
- return join16(resolveUserStateRoot(env), "hub-binding.json");
29898
+ return join17(resolveUserStateRoot(env), "hub-binding.json");
29836
29899
  }
29837
29900
  function validateHubUrl(raw) {
29838
29901
  let parsed;
@@ -29879,7 +29942,7 @@ function readHubBinding(env = process.env) {
29879
29942
  // plugins/kxm/src/hub-env.ts
29880
29943
  import { existsSync as existsSync14, mkdirSync as mkdirSync7, readFileSync as readFileSync11, renameSync as renameSync3, rmSync as rmSync3, writeFileSync as writeFileSync8 } from "node:fs";
29881
29944
  import { homedir as homedir3 } from "node:os";
29882
- import { dirname as dirname9, isAbsolute as isAbsolute5, join as join17, resolve as resolve9 } from "node:path";
29945
+ import { dirname as dirname9, isAbsolute as isAbsolute6, join as join18, resolve as resolve10 } from "node:path";
29883
29946
  var HUB_ENV_SCHEMA = "kxm.hub-env.v1";
29884
29947
  var HubEnvError = class extends Error {
29885
29948
  constructor(message) {
@@ -29890,21 +29953,21 @@ var HubEnvError = class extends Error {
29890
29953
  function resolveUserStateRoot2(env) {
29891
29954
  const explicit = env.KXM_STATE_HOME?.trim();
29892
29955
  if (explicit) {
29893
- if (!isAbsolute5(explicit)) throw new HubEnvError("local_state_root_not_absolute");
29894
- return resolve9(explicit);
29956
+ if (!isAbsolute6(explicit)) throw new HubEnvError("local_state_root_not_absolute");
29957
+ return resolve10(explicit);
29895
29958
  }
29896
29959
  if (process.platform === "win32") {
29897
29960
  const localAppData = env.LOCALAPPDATA?.trim();
29898
- const base2 = localAppData && isAbsolute5(localAppData) ? localAppData : join17(homedir3(), "AppData", "Local");
29899
- return resolve9(base2, "KXM");
29961
+ const base2 = localAppData && isAbsolute6(localAppData) ? localAppData : join18(homedir3(), "AppData", "Local");
29962
+ return resolve10(base2, "KXM");
29900
29963
  }
29901
- if (process.platform === "darwin") return resolve9(homedir3(), "Library", "Application Support", "KXM");
29964
+ if (process.platform === "darwin") return resolve10(homedir3(), "Library", "Application Support", "KXM");
29902
29965
  const xdgState = env.XDG_STATE_HOME?.trim();
29903
- const base = xdgState && isAbsolute5(xdgState) ? xdgState : join17(homedir3(), ".local", "state");
29904
- return resolve9(base, "kxm");
29966
+ const base = xdgState && isAbsolute6(xdgState) ? xdgState : join18(homedir3(), ".local", "state");
29967
+ return resolve10(base, "kxm");
29905
29968
  }
29906
29969
  function hubEnvFile(env = process.env) {
29907
- return join17(resolveUserStateRoot2(env), "hub-env.json");
29970
+ return join18(resolveUserStateRoot2(env), "hub-env.json");
29908
29971
  }
29909
29972
  function readHubEnvRecord(env = process.env) {
29910
29973
  const file = hubEnvFile(env);
@@ -30101,7 +30164,7 @@ function createLogger(options) {
30101
30164
 
30102
30165
  // plugins/kxm/src/runtime-supervisor.ts
30103
30166
  function kxmSupervisorTokenFile(paths) {
30104
- return join18(paths.runtimeDir, "supervisor.token");
30167
+ return join19(paths.runtimeDir, "supervisor.token");
30105
30168
  }
30106
30169
  function publishKxmSupervisorToken(paths, token) {
30107
30170
  const file = kxmSupervisorTokenFile(paths);
@@ -30120,7 +30183,7 @@ function publishKxmSupervisorToken(paths, token) {
30120
30183
  }
30121
30184
  }
30122
30185
  function hashKxmSupervisorToken(token) {
30123
- return `sha256:${createHash14("sha256").update(`kxm-runtime-supervisor\0${token}`, "utf8").digest("hex")}`;
30186
+ return `sha256:${createHash15("sha256").update(`kxm-runtime-supervisor\0${token}`, "utf8").digest("hex")}`;
30124
30187
  }
30125
30188
  function readKxmSupervisorToken(paths) {
30126
30189
  const file = kxmSupervisorTokenFile(paths);
@@ -30143,7 +30206,7 @@ function processAlive(pid) {
30143
30206
  var HEARTBEAT_STALE_MS = 15e3;
30144
30207
  var SUPERVISOR_ERROR_MAX_AGE_MS = 3e4;
30145
30208
  function supervisorErrorFile(paths) {
30146
- return join18(paths.runtimeDir, "supervisor.error");
30209
+ return join19(paths.runtimeDir, "supervisor.error");
30147
30210
  }
30148
30211
  function clearSupervisorError(paths) {
30149
30212
  const file = supervisorErrorFile(paths);
@@ -30169,24 +30232,35 @@ function readRecentSupervisorError(paths) {
30169
30232
  return void 0;
30170
30233
  }
30171
30234
  }
30172
- function kxmSupervisorStatus(paths) {
30235
+ function supervisorStatusOf(record2) {
30236
+ if (!record2) return { running: false };
30237
+ const heartbeatAgeMs = Date.now() - Date.parse(record2.heartbeatAt);
30238
+ const fresh = Number.isFinite(heartbeatAgeMs) && heartbeatAgeMs < HEARTBEAT_STALE_MS;
30239
+ const alive = record2.state === "running" && fresh && processAlive(record2.pid);
30240
+ return {
30241
+ running: alive,
30242
+ runtimeId: record2.runtimeId,
30243
+ pid: record2.pid,
30244
+ port: record2.port,
30245
+ state: alive ? record2.state : "dead",
30246
+ heartbeatAt: record2.heartbeatAt,
30247
+ startedAt: record2.startedAt
30248
+ };
30249
+ }
30250
+ function kxmSupervisorStatus(paths, options = {}) {
30173
30251
  if (!existsSync16(paths.registryDb)) return { running: false };
30252
+ if (options.readOnly) {
30253
+ const database = openReadOnlyDatabase(paths.registryDb);
30254
+ try {
30255
+ database.exec("PRAGMA busy_timeout = 5000");
30256
+ return supervisorStatusOf(readKxmSupervisorRecord(database));
30257
+ } finally {
30258
+ database.close();
30259
+ }
30260
+ }
30174
30261
  const registry = new KxmRuntimeRegistry(paths.registryDb);
30175
30262
  try {
30176
- const record2 = registry.supervisor();
30177
- if (!record2) return { running: false };
30178
- const heartbeatAgeMs = Date.now() - Date.parse(record2.heartbeatAt);
30179
- const fresh = Number.isFinite(heartbeatAgeMs) && heartbeatAgeMs < HEARTBEAT_STALE_MS;
30180
- const alive = record2.state === "running" && fresh && processAlive(record2.pid);
30181
- return {
30182
- running: alive,
30183
- runtimeId: record2.runtimeId,
30184
- pid: record2.pid,
30185
- port: record2.port,
30186
- state: alive ? record2.state : "dead",
30187
- heartbeatAt: record2.heartbeatAt,
30188
- startedAt: record2.startedAt
30189
- };
30263
+ return supervisorStatusOf(registry.supervisor());
30190
30264
  } finally {
30191
30265
  registry.close();
30192
30266
  }
@@ -30240,7 +30314,7 @@ async function ensureKxmSupervisor(options = {}) {
30240
30314
  throw runtimeError("runtime_supervisor_unreachable", paths.registryDb, `runtime supervisor pid ${status.pid} is registered as running but cannot be probed`);
30241
30315
  }
30242
30316
  clearSupervisorError(paths);
30243
- const scriptPath = join18(findKxmRepoRoot(import.meta.url), "scripts", "kxm-runtime-supervisor.mjs");
30317
+ const scriptPath = join19(findKxmRepoRoot(import.meta.url), "scripts", "kxm-runtime-supervisor.mjs");
30244
30318
  const spawnImpl = options.spawnImpl ?? ((script, env) => {
30245
30319
  const child = spawn3(process.execPath, [script], {
30246
30320
  detached: true,
@@ -30325,8 +30399,8 @@ async function waitForDriveSessions(settled, graceMs) {
30325
30399
  try {
30326
30400
  await Promise.race([
30327
30401
  Promise.allSettled(settled),
30328
- new Promise((resolve12) => {
30329
- timeout = setTimeout(resolve12, graceMs);
30402
+ new Promise((resolve13) => {
30403
+ timeout = setTimeout(resolve13, graceMs);
30330
30404
  timeout.unref?.();
30331
30405
  })
30332
30406
  ]);
@@ -30463,7 +30537,7 @@ function syncFailureText(error) {
30463
30537
  return `${code ? `${code}: ` : ""}${message}`.replace(/(kxm_[A-Za-z0-9_]+|[A-Za-z0-9._-]{40,})/g, "[redacted]").slice(0, 300);
30464
30538
  }
30465
30539
  function runtimeSupervisorLogFile(paths) {
30466
- return join18(paths.runtimeDir, "logs", "kxm-runtime.jsonl");
30540
+ return join19(paths.runtimeDir, "logs", "kxm-runtime.jsonl");
30467
30541
  }
30468
30542
  async function startKxmRuntimeSupervisor(options = {}) {
30469
30543
  const now = options.now ?? (() => (/* @__PURE__ */ new Date()).toISOString());
@@ -30490,7 +30564,7 @@ async function startKxmRuntimeSupervisorInner(paths, requestedPortOption, now, e
30490
30564
  const token = randomBytes3(32).toString("hex");
30491
30565
  const tokenHash = hashKxmSupervisorToken(token);
30492
30566
  const registry = new KxmRuntimeRegistry(paths.registryDb);
30493
- const runtimeId = `rtm_${createHash14("sha256").update(`${paths.stateRoot}\0${process.pid}\0${now()}\0${randomBytes3(16).toString("hex")}`, "utf8").digest("hex").slice(0, 24)}`;
30567
+ const runtimeId = `rtm_${createHash15("sha256").update(`${paths.stateRoot}\0${process.pid}\0${now()}\0${randomBytes3(16).toString("hex")}`, "utf8").digest("hex").slice(0, 24)}`;
30494
30568
  const requestedPort = requestedPortOption ?? 0;
30495
30569
  let activeRuntimeId = runtimeId;
30496
30570
  const contexts = /* @__PURE__ */ new Map();
@@ -30506,7 +30580,7 @@ async function startKxmRuntimeSupervisorInner(paths, requestedPortOption, now, e
30506
30580
  }
30507
30581
  };
30508
30582
  const contextFor = (projectRoot) => {
30509
- if (!isAbsolute6(projectRoot)) {
30583
+ if (!isAbsolute7(projectRoot)) {
30510
30584
  throw runtimeError("runtime_request_invalid", "projectRoot", "projectRoot must be an absolute path");
30511
30585
  }
30512
30586
  const key = projectRuntimeKey(projectRoot);
@@ -31062,7 +31136,7 @@ function handoffSuffix(handoff) {
31062
31136
 
31063
31137
  // plugins/kxm/src/pi-producer.ts
31064
31138
  import { spawn as spawn4 } from "node:child_process";
31065
- import { join as join19 } from "node:path";
31139
+ import { join as join20 } from "node:path";
31066
31140
  import { StringDecoder } from "node:string_decoder";
31067
31141
  function formatPiSessionKey(params) {
31068
31142
  if (params.agentId === "coordinator") {
@@ -31278,8 +31352,8 @@ var PiSession = class {
31278
31352
  }
31279
31353
  const id = `cmd_${++this.commandCounter}`;
31280
31354
  const payload = { ...command, id };
31281
- return new Promise((resolve12, reject) => {
31282
- this.pendingCommands.set(id, { resolve: resolve12, reject });
31355
+ return new Promise((resolve13, reject) => {
31356
+ this.pendingCommands.set(id, { resolve: resolve13, reject });
31283
31357
  try {
31284
31358
  this.process.stdin.write(JSON.stringify(payload) + "\n");
31285
31359
  } catch (err) {
@@ -31299,7 +31373,7 @@ var PiSession = class {
31299
31373
  return { outcome: "cancelled", text: "aborted", usage: {} };
31300
31374
  }
31301
31375
  this.status = "busy";
31302
- return new Promise((resolve12, reject) => {
31376
+ return new Promise((resolve13, reject) => {
31303
31377
  let signalCleanup;
31304
31378
  if (signal) {
31305
31379
  const onAbort = () => {
@@ -31313,7 +31387,7 @@ var PiSession = class {
31313
31387
  signalCleanup = () => signal.removeEventListener("abort", onAbort);
31314
31388
  }
31315
31389
  this.activePrompt = {
31316
- resolve: resolve12,
31390
+ resolve: resolve13,
31317
31391
  reject,
31318
31392
  allowedOutcomes,
31319
31393
  text: "",
@@ -31436,7 +31510,7 @@ function createKxmPiProducer(options = {}) {
31436
31510
  const args = ["--mode", "rpc", "--name", displayName];
31437
31511
  if (options.sessionDir) {
31438
31512
  const safeDirName = key.replace(/[^a-zA-Z0-9_-]/g, "_");
31439
- args.push("--session-dir", join19(options.sessionDir, request.runId, safeDirName));
31513
+ args.push("--session-dir", join20(options.sessionDir, request.runId, safeDirName));
31440
31514
  }
31441
31515
  if (model) {
31442
31516
  args.push("--model", model);
@@ -31564,9 +31638,9 @@ function createKxmPiProducer(options = {}) {
31564
31638
  }
31565
31639
 
31566
31640
  // plugins/kxm/src/improve.ts
31567
- import { createHash as createHash15 } from "node:crypto";
31641
+ import { createHash as createHash16 } from "node:crypto";
31568
31642
  import { existsSync as existsSync17, mkdirSync as mkdirSync10, writeFileSync as writeFileSync10 } from "node:fs";
31569
- import { join as join20, relative as relative4, resolve as resolve10 } from "node:path";
31643
+ import { join as join21, relative as relative5, resolve as resolve11 } from "node:path";
31570
31644
  var CANDIDATE_SCHEMA = "kxm.candidate.v1";
31571
31645
  var IMPROVEMENT_REPORT_SCHEMA = "kxm.improvement-report.v2";
31572
31646
  var IMPROVEMENT_REPORT_V1_SCHEMA = "kxm.improvement-report.v1";
@@ -31782,7 +31856,7 @@ function groupRoutingRecords(records, options = {}) {
31782
31856
  }
31783
31857
  const candidateKind = isCandidate ? classifyCandidateKind(group.stepId, group.agentRole) : void 0;
31784
31858
  const safeSlug = group.stepId.toLowerCase().replace(/[^a-z0-9]+/g, "_").replace(/^_+|_+$/g, "").slice(0, 16) || "step";
31785
- const keyHash = createHash15("sha256").update(`${group.workflowHash}:${group.stepId}:${group.agentRole}:${group.promptHash}`).digest("hex").slice(0, 10);
31859
+ const keyHash = createHash16("sha256").update(`${group.workflowHash}:${group.stepId}:${group.agentRole}:${group.promptHash}`).digest("hex").slice(0, 10);
31786
31860
  const candidateId = isCandidate && candidateKind ? `cand_${candidateKind.replace(/-/g, "_")}_${safeSlug}_${keyHash}` : void 0;
31787
31861
  keyed.push({
31788
31862
  key: group.key,
@@ -31822,8 +31896,8 @@ function groupRoutingRecords(records, options = {}) {
31822
31896
  }).map((entry) => entry.row);
31823
31897
  }
31824
31898
  function buildImprovementReport(records, options = {}) {
31825
- const projectRoot = options.projectRoot ? resolve10(options.projectRoot) : process.cwd();
31826
- const candidatesDir = options.candidatesDir ? resolve10(options.candidatesDir) : join20(projectRoot, ".kxm", "candidates");
31899
+ const projectRoot = options.projectRoot ? resolve11(options.projectRoot) : process.cwd();
31900
+ const candidatesDir = options.candidatesDir ? resolve11(options.candidatesDir) : join21(projectRoot, ".kxm", "candidates");
31827
31901
  const promotionPolicy = options.promotionPolicy ?? "manual_pr";
31828
31902
  const groups = groupRoutingRecords(records, options);
31829
31903
  const candidates = [];
@@ -31837,8 +31911,8 @@ function buildImprovementReport(records, options = {}) {
31837
31911
  group.workflowId
31838
31912
  );
31839
31913
  const diffFileName = `${group.candidateId}.diff`;
31840
- const diffFilePath = join20(candidatesDir, diffFileName);
31841
- const relDiffPath = relative4(projectRoot, diffFilePath).replace(/\\/g, "/");
31914
+ const diffFilePath = join21(candidatesDir, diffFileName);
31915
+ const relDiffPath = relative5(projectRoot, diffFilePath).replace(/\\/g, "/");
31842
31916
  const candidate = {
31843
31917
  schema: CANDIDATE_SCHEMA,
31844
31918
  id: group.candidateId,
@@ -31863,7 +31937,7 @@ function buildImprovementReport(records, options = {}) {
31863
31937
  mkdirSync10(candidatesDir, { recursive: true });
31864
31938
  }
31865
31939
  writeFileSync10(diffFilePath, diff, "utf8");
31866
- const jsonFilePath = join20(candidatesDir, `${group.candidateId}.json`);
31940
+ const jsonFilePath = join21(candidatesDir, `${group.candidateId}.json`);
31867
31941
  writeFileSync10(jsonFilePath, JSON.stringify(candidate, null, 2) + "\n", "utf8");
31868
31942
  }
31869
31943
  candidates.push(candidate);
@@ -31892,7 +31966,7 @@ function buildImprovementReport(records, options = {}) {
31892
31966
  }
31893
31967
  function writeImprovementReport(improvementsDir, report, dryRun = false) {
31894
31968
  const stamp = report.createdAt.replace(/[:.]/g, "-");
31895
- const path = join20(improvementsDir, `${stamp}.json`);
31969
+ const path = join21(improvementsDir, `${stamp}.json`);
31896
31970
  if (!dryRun) {
31897
31971
  mkdirSync10(improvementsDir, { recursive: true });
31898
31972
  writeFileSync10(path, `${JSON.stringify(report, null, 2)}
@@ -32396,7 +32470,7 @@ Instructions for Operator:
32396
32470
  // plugins/kxm/src/modes.ts
32397
32471
  var import_yaml8 = __toESM(require_dist(), 1);
32398
32472
  import { existsSync as existsSync18, readFileSync as readFileSync14 } from "node:fs";
32399
- import { join as join21 } from "node:path";
32473
+ import { join as join22 } from "node:path";
32400
32474
  var DEFAULT_MODES_CONFIG = Object.freeze({
32401
32475
  schema: "kxm.modes.v1",
32402
32476
  majorModes: {
@@ -32459,7 +32533,7 @@ function loadModesConfig(projectRoot) {
32459
32533
  if (!projectRoot) {
32460
32534
  return DEFAULT_MODES_CONFIG;
32461
32535
  }
32462
- const modesPath = join21(projectRoot, ".kxm", "modes.yaml");
32536
+ const modesPath = join22(projectRoot, ".kxm", "modes.yaml");
32463
32537
  if (!existsSync18(modesPath)) {
32464
32538
  return DEFAULT_MODES_CONFIG;
32465
32539
  }
@@ -32550,7 +32624,7 @@ function calculatePromptFootprint(resolved, projectRoot = process.cwd(), catalog
32550
32624
  estimatedTokens: estimateTokens(baseSystemPromptChars)
32551
32625
  });
32552
32626
  for (const relPath of resolved.contextFiles) {
32553
- const fullPath = join21(projectRoot, relPath);
32627
+ const fullPath = join22(projectRoot, relPath);
32554
32628
  let chars = 0;
32555
32629
  if (existsSync18(fullPath)) {
32556
32630
  try {
@@ -32688,7 +32762,7 @@ ${divider}
32688
32762
  import { spawnSync as spawnSync5 } from "node:child_process";
32689
32763
  import { existsSync as existsSync19, mkdirSync as mkdirSync11, readFileSync as readFileSync15, readdirSync as readdirSync8, rmSync as rmSync5, statSync as statSync5 } from "node:fs";
32690
32764
  import { homedir as homedir4 } from "node:os";
32691
- import { join as join22, resolve as resolve11 } from "node:path";
32765
+ import { join as join23, resolve as resolve12 } from "node:path";
32692
32766
  var MAX_SSH_OUTPUT_BYTES = 50 * 1024;
32693
32767
  var MAX_SSH_OUTPUT_LINES = 2e3;
32694
32768
  var DEFAULT_SOCKET_DIR = ".kxm/run/ssh-sockets";
@@ -32714,7 +32788,7 @@ function truncateSshOutput(raw) {
32714
32788
  return { text, truncated };
32715
32789
  }
32716
32790
  function parseSshConfig(configPath) {
32717
- const targetPath = configPath ?? join22(homedir4(), ".ssh", "config");
32791
+ const targetPath = configPath ?? join23(homedir4(), ".ssh", "config");
32718
32792
  if (!existsSync19(targetPath)) {
32719
32793
  return [];
32720
32794
  }
@@ -32796,7 +32870,7 @@ function resolveSshHostG(host, execFn = spawnSync5) {
32796
32870
  }
32797
32871
  }
32798
32872
  function ensureSocketDir(socketDir = DEFAULT_SOCKET_DIR) {
32799
- const resolved = resolve11(socketDir);
32873
+ const resolved = resolve12(socketDir);
32800
32874
  if (!existsSync19(resolved)) {
32801
32875
  mkdirSync11(resolved, { recursive: true, mode: 448 });
32802
32876
  }
@@ -32804,7 +32878,7 @@ function ensureSocketDir(socketDir = DEFAULT_SOCKET_DIR) {
32804
32878
  }
32805
32879
  function buildSshArgs(options) {
32806
32880
  const socketDir = ensureSocketDir(options.socketDir ?? DEFAULT_SOCKET_DIR);
32807
- const controlPath = join22(socketDir, "%C");
32881
+ const controlPath = join23(socketDir, "%C");
32808
32882
  const persist2 = options.controlPersist ?? DEFAULT_CONTROL_PERSIST;
32809
32883
  const args = [
32810
32884
  "-o",
@@ -32829,7 +32903,7 @@ function buildSshArgs(options) {
32829
32903
  }
32830
32904
  function checkControlSocket(host, socketDir = DEFAULT_SOCKET_DIR, execFn = spawnSync5) {
32831
32905
  const resolvedDir = ensureSocketDir(socketDir);
32832
- const controlPath = join22(resolvedDir, "%C");
32906
+ const controlPath = join23(resolvedDir, "%C");
32833
32907
  try {
32834
32908
  const result = execFn("ssh", ["-O", "check", "-o", `ControlPath=${controlPath}`, host], {
32835
32909
  encoding: "utf-8"
@@ -32841,7 +32915,7 @@ function checkControlSocket(host, socketDir = DEFAULT_SOCKET_DIR, execFn = spawn
32841
32915
  }
32842
32916
  function closeControlSocket(host, socketDir = DEFAULT_SOCKET_DIR, execFn = spawnSync5) {
32843
32917
  const resolvedDir = ensureSocketDir(socketDir);
32844
- const controlPath = join22(resolvedDir, "%C");
32918
+ const controlPath = join23(resolvedDir, "%C");
32845
32919
  try {
32846
32920
  const result = execFn("ssh", ["-O", "stop", "-o", `ControlPath=${controlPath}`, host], {
32847
32921
  encoding: "utf-8"
@@ -32857,7 +32931,7 @@ function pruneSocketDir(socketDir = DEFAULT_SOCKET_DIR) {
32857
32931
  try {
32858
32932
  const entries = readdirSync8(resolvedDir);
32859
32933
  for (const entry of entries) {
32860
- const fullPath = join22(resolvedDir, entry);
32934
+ const fullPath = join23(resolvedDir, entry);
32861
32935
  try {
32862
32936
  const stat = statSync5(fullPath);
32863
32937
  if (stat.isSocket()) {
@@ -33316,6 +33390,7 @@ export {
33316
33390
  VIEWPORT_PRESETS,
33317
33391
  WIN_NPM_INNER_EXE,
33318
33392
  acceptKxmRun,
33393
+ applyRestorePlan,
33319
33394
  assertClosedGateObservation,
33320
33395
  assertKxmConfigError,
33321
33396
  attachKxmSupervisor,
@@ -33425,6 +33500,7 @@ export {
33425
33500
  projectRuntimeOwnsRun,
33426
33501
  pruneSocketDir,
33427
33502
  readKxmRunStatus,
33503
+ readKxmSupervisorRecord,
33428
33504
  readKxmSupervisorToken,
33429
33505
  rebuildKxmRunProjection,
33430
33506
  redactLogValue,