@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.
- package/.claude-plugin/marketplace.json +1 -1
- package/CHANGELOG.md +39 -8
- package/docs/concepts/data-and-storage.md +1 -1
- package/docs/contributing/test-matrix.md +11 -6
- package/docs/operations/backup-and-restore.md +59 -27
- package/docs/operations/deploy.md +1 -1
- package/docs/reference/cli-reference.md +73 -55
- package/docs/reference/config-reference.md +1 -1
- package/docs/reference/workflow-definitions.md +4 -4
- package/docs/start/first-workflow.md +6 -2
- package/docs/start/quickstart-claude-code.md +11 -1
- package/docs/templates/runbook.md +2 -1
- package/package.json +1 -1
- package/plugins/kxm/.claude-plugin/plugin.json +1 -1
- package/plugins/kxm/dist/cli.js +1802 -1011
- package/plugins/kxm/dist/mcp-server.js +1 -1
- package/plugins/kxm/dist/runtime-supervisor.js +322 -292
- package/plugins/kxm/dist/runtime.js +427 -351
- package/plugins/kxm/dist/server.js +78 -78
- package/plugins/kxm/package.json +1 -1
- package/plugins/kxm/skills/kxm-hub-ops/SKILL.md +14 -7
- package/plugins/kxm/src/cli/project.ts +132 -30
- package/plugins/kxm/src/cli/system.ts +19 -1
- package/plugins/kxm/src/cli/tasks.ts +55 -31
- package/plugins/kxm/src/cli/workflows.ts +52 -54
- package/plugins/kxm/src/cli.ts +8 -6
- package/plugins/kxm/src/database.ts +193 -65
- package/plugins/kxm/src/engine.ts +79 -3
- package/plugins/kxm/src/harness.ts +6 -5
- package/plugins/kxm/src/mcp-server.ts +1 -1
- package/plugins/kxm/src/runtime-paths.ts +50 -0
- package/plugins/kxm/src/runtime-store.ts +22 -53
- package/plugins/kxm/src/runtime-supervisor.ts +38 -17
- package/plugins/kxm/src/suggest.ts +132 -79
- package/plugins/kxm/src/workflow-manager.ts +42 -19
- 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 =
|
|
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
|
|
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
|
|
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,
|
|
3874
|
+
function resolveComponent(base, relative6, options, skipNormalization) {
|
|
3875
3875
|
const target = {};
|
|
3876
3876
|
if (!skipNormalization) {
|
|
3877
3877
|
base = parse8(serialize(base, options), options);
|
|
3878
|
-
|
|
3878
|
+
relative6 = parse8(serialize(relative6, options), options);
|
|
3879
3879
|
}
|
|
3880
3880
|
options = options || {};
|
|
3881
|
-
if (!options.tolerant &&
|
|
3882
|
-
target.scheme =
|
|
3883
|
-
target.userinfo =
|
|
3884
|
-
target.host =
|
|
3885
|
-
target.port =
|
|
3886
|
-
target.path = removeDotSegments(
|
|
3887
|
-
target.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 (
|
|
3890
|
-
target.userinfo =
|
|
3891
|
-
target.host =
|
|
3892
|
-
target.port =
|
|
3893
|
-
target.path = removeDotSegments(
|
|
3894
|
-
target.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 (!
|
|
3896
|
+
if (!relative6.path) {
|
|
3897
3897
|
target.path = base.path;
|
|
3898
|
-
if (
|
|
3899
|
-
target.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 (
|
|
3905
|
-
target.path = removeDotSegments(
|
|
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 = "/" +
|
|
3908
|
+
target.path = "/" + relative6.path;
|
|
3909
3909
|
} else if (!base.path) {
|
|
3910
|
-
target.path =
|
|
3910
|
+
target.path = relative6.path;
|
|
3911
3911
|
} else {
|
|
3912
|
-
target.path = base.path.slice(0, base.path.lastIndexOf("/") + 1) +
|
|
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 =
|
|
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 =
|
|
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:
|
|
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:
|
|
11413
|
+
const { start, key, sep: sep4, value } = collItem;
|
|
11414
11414
|
const keyProps = resolveProps.resolveProps(start, {
|
|
11415
11415
|
indicator: "explicit-key-ind",
|
|
11416
|
-
next: key ??
|
|
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 && !
|
|
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(
|
|
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,
|
|
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
|
|
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 +=
|
|
11576
|
-
|
|
11575
|
+
comment += sep4 + cb;
|
|
11576
|
+
sep4 = "";
|
|
11577
11577
|
break;
|
|
11578
11578
|
}
|
|
11579
11579
|
case "newline":
|
|
11580
11580
|
if (comment)
|
|
11581
|
-
|
|
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:
|
|
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 ??
|
|
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 && !
|
|
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 && !
|
|
11690
|
-
const valueNode = value ? composeNode(ctx, value, props, onError) : composeEmptyNode(ctx, props.end,
|
|
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(
|
|
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 (
|
|
11714
|
-
for (const st of
|
|
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,
|
|
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
|
|
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 +=
|
|
11929
|
-
|
|
11928
|
+
value += sep4 + indent.slice(trimIndent) + content;
|
|
11929
|
+
sep4 = "\n";
|
|
11930
11930
|
} else if (indent.length > trimIndent || content[0] === " ") {
|
|
11931
|
-
if (
|
|
11932
|
-
|
|
11933
|
-
else if (!prevMoreIndented &&
|
|
11934
|
-
|
|
11935
|
-
value +=
|
|
11936
|
-
|
|
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 (
|
|
11939
|
+
if (sep4 === "\n")
|
|
11940
11940
|
value += "\n";
|
|
11941
11941
|
else
|
|
11942
|
-
|
|
11942
|
+
sep4 = "\n";
|
|
11943
11943
|
} else {
|
|
11944
|
-
value +=
|
|
11945
|
-
|
|
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
|
|
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 (
|
|
12134
|
-
res +=
|
|
12133
|
+
if (sep4 === "\n")
|
|
12134
|
+
res += sep4;
|
|
12135
12135
|
else
|
|
12136
|
-
|
|
12136
|
+
sep4 = "\n";
|
|
12137
12137
|
} else {
|
|
12138
|
-
res +=
|
|
12139
|
-
|
|
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 +
|
|
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:
|
|
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 (
|
|
12963
|
-
for (const st of
|
|
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
|
|
14130
|
+
let sep4;
|
|
14131
14131
|
if (scalar.end) {
|
|
14132
|
-
|
|
14133
|
-
|
|
14132
|
+
sep4 = scalar.end;
|
|
14133
|
+
sep4.push(this.sourceToken);
|
|
14134
14134
|
delete scalar.end;
|
|
14135
14135
|
} else
|
|
14136
|
-
|
|
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:
|
|
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
|
|
14295
|
-
|
|
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:
|
|
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
|
|
14497
|
-
|
|
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:
|
|
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
|
|
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
|
|
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((
|
|
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
|
-
|
|
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.
|
|
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} (
|
|
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
|
|
17179
|
-
const minimumPassed =
|
|
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
|
|
17664
|
-
import { existsSync as existsSync6, lstatSync as lstatSync3, mkdirSync as mkdirSync2, readFileSync as readFileSync3,
|
|
17665
|
-
import { dirname as dirname5,
|
|
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
|
|
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:${
|
|
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
|
|
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
|
|
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:${
|
|
18346
|
+
return `sha256:${createHash5("sha256").update(bytes).digest("hex")}`;
|
|
18317
18347
|
}
|
|
18318
18348
|
function backupDatabaseFile(sourcePath, targetPath, storeId) {
|
|
18319
|
-
const resolvedSource =
|
|
18320
|
-
const resolvedTarget =
|
|
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 =
|
|
18371
|
-
const resolvedTarget =
|
|
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
|
|
18449
|
-
|
|
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
|
-
|
|
18496
|
+
paths = kxmRuntimePaths(options.env ? { env: options.env } : {});
|
|
18452
18497
|
} catch {
|
|
18453
|
-
return;
|
|
18498
|
+
return void 0;
|
|
18454
18499
|
}
|
|
18455
|
-
|
|
18456
|
-
|
|
18457
|
-
|
|
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,
|
|
18506
|
+
pushStore(stores, storeId, paths.registryDb);
|
|
18460
18507
|
}
|
|
18461
|
-
|
|
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 (
|
|
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 =
|
|
18521
|
+
const root = resolve5(projectRoot);
|
|
18488
18522
|
const stores = [];
|
|
18489
18523
|
const files = [];
|
|
18490
|
-
const hubPath = options.hubDataPath ?
|
|
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 =
|
|
18526
|
+
const registryPath = join5(root, ".kxm", "runtime", "registry.db");
|
|
18493
18527
|
if (existsSync5(registryPath)) pushStore(stores, "registry", registryPath);
|
|
18494
|
-
const bindingsPath =
|
|
18528
|
+
const bindingsPath = join5(root, ".kxm", "runtime", "bindings.db");
|
|
18495
18529
|
if (existsSync5(bindingsPath)) pushStore(stores, "binding-store", bindingsPath);
|
|
18496
|
-
const eventsDir =
|
|
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}`,
|
|
18536
|
+
pushStore(stores, `events:${key}`, join5(eventsDir, entry.name));
|
|
18503
18537
|
}
|
|
18504
18538
|
}
|
|
18505
18539
|
}
|
|
18506
|
-
|
|
18507
|
-
|
|
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 =
|
|
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 ?
|
|
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 ?
|
|
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 {
|
|
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,
|
|
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,
|
|
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:${
|
|
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 =
|
|
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 =
|
|
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 =
|
|
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 =
|
|
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
|
-
|
|
18682
|
-
if (
|
|
18683
|
-
|
|
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 =
|
|
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
|
-
|
|
18703
|
-
if (
|
|
18704
|
-
|
|
18705
|
-
|
|
18706
|
-
|
|
18707
|
-
|
|
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 {
|
|
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
|
|
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 =
|
|
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
|
-
|
|
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 =
|
|
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:${
|
|
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 =
|
|
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:${
|
|
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
|
|
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
|
|
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:
|
|
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
|
|
21869
|
-
if (!
|
|
21870
|
-
const declared = stringValue2(
|
|
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(
|
|
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
|
|
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:${
|
|
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((
|
|
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(
|
|
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:${
|
|
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 =
|
|
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 =
|
|
23305
|
-
const memoryDir = options.memoryDir ??
|
|
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 ??
|
|
23313
|
-
const promotedSkillsDir =
|
|
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(
|
|
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:${
|
|
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
|
|
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
|
|
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
|
|
23815
|
+
import { join as join16 } from "node:path";
|
|
23753
23816
|
|
|
23754
23817
|
// plugins/kxm/src/oneshot-evidence.ts
|
|
23755
|
-
import { createHash as
|
|
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
|
|
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:${
|
|
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 =
|
|
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 =
|
|
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
|
|
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
|
|
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
|
|
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(
|
|
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
|
|
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
|
|
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
|
|
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(
|
|
24061
|
-
const path =
|
|
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 =
|
|
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(
|
|
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
|
|
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
|
|
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 =
|
|
25133
|
-
const memoryDir =
|
|
25134
|
-
const candidatesDir =
|
|
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 =
|
|
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
|
|
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
|
|
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
|
|
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
|
|
25332
|
+
return join12(this.root, state === "candidate" ? "candidates" : `${state}s`.replace("rejecteds", "rejected").replace("promoteds", "promoted"));
|
|
25270
25333
|
}
|
|
25271
25334
|
historyFile(id) {
|
|
25272
|
-
return
|
|
25335
|
+
return join12(this.root, "history", `${id}.jsonl`);
|
|
25273
25336
|
}
|
|
25274
25337
|
paths(state, id) {
|
|
25275
|
-
const dir =
|
|
25276
|
-
return { dir, metadata:
|
|
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 =
|
|
25303
|
-
const toDir =
|
|
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 =
|
|
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(
|
|
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(
|
|
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(
|
|
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
|
|
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
|
|
25809
|
+
import { isAbsolute as isAbsolute4, relative as relative4, resolve as resolve8 } from "node:path";
|
|
25747
25810
|
function staysUnder(root, candidate) {
|
|
25748
|
-
const child =
|
|
25749
|
-
return child === "" || !
|
|
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 =
|
|
25753
|
-
const lexicalPath =
|
|
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 =
|
|
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,
|
|
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
|
|
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 =
|
|
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((
|
|
25953
|
-
this.resolveOutcome =
|
|
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
|
|
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
|
|
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:${
|
|
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_${
|
|
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((
|
|
27280
|
-
pending.resolve =
|
|
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 =
|
|
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 =
|
|
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(
|
|
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(
|
|
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 =
|
|
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 ??
|
|
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
|
|
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 (!
|
|
29822
|
-
return
|
|
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 &&
|
|
29827
|
-
return
|
|
29889
|
+
const base2 = localAppData && isAbsolute5(localAppData) ? localAppData : join17(homedir2(), "AppData", "Local");
|
|
29890
|
+
return resolve9(base2, "KXM");
|
|
29828
29891
|
}
|
|
29829
|
-
if (process.platform === "darwin") return
|
|
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 &&
|
|
29832
|
-
return
|
|
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
|
|
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
|
|
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 (!
|
|
29894
|
-
return
|
|
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 &&
|
|
29899
|
-
return
|
|
29961
|
+
const base2 = localAppData && isAbsolute6(localAppData) ? localAppData : join18(homedir3(), "AppData", "Local");
|
|
29962
|
+
return resolve10(base2, "KXM");
|
|
29900
29963
|
}
|
|
29901
|
-
if (process.platform === "darwin") return
|
|
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 &&
|
|
29904
|
-
return
|
|
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
|
|
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
|
|
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:${
|
|
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
|
|
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
|
|
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
|
-
|
|
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 =
|
|
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((
|
|
30329
|
-
timeout = setTimeout(
|
|
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
|
|
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_${
|
|
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 (!
|
|
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
|
|
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((
|
|
31282
|
-
this.pendingCommands.set(id, { resolve:
|
|
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((
|
|
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:
|
|
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",
|
|
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
|
|
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
|
|
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 =
|
|
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 ?
|
|
31826
|
-
const candidatesDir = options.candidatesDir ?
|
|
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 =
|
|
31841
|
-
const relDiffPath =
|
|
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 =
|
|
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 =
|
|
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
|
|
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 =
|
|
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 =
|
|
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
|
|
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 ??
|
|
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 =
|
|
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 =
|
|
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 =
|
|
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 =
|
|
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 =
|
|
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,
|