@kontextmind/kxm 0.7.97 → 0.7.99
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/.kxm/workflows/default.yaml +2 -0
- package/CHANGELOG.md +46 -2
- package/docs/concepts/architecture.md +1 -1
- package/docs/concepts/data-and-storage.md +1 -1
- package/docs/contracts/routing.md +1 -1
- package/docs/contributing/test-matrix.md +6 -5
- package/docs/guides/peer-messaging.md +2 -2
- package/docs/operations/backup-and-restore.md +43 -24
- package/docs/operations/deploy.md +1 -1
- package/docs/reference/cli-reference.md +65 -28
- package/docs/reference/config-reference.md +24 -13
- package/docs/reference/harness-routing.md +3 -3
- package/docs/reference/http-api.md +2 -1
- package/docs/reference/tools.md +3 -3
- package/docs/start/first-workflow.md +4 -4
- package/docs/start/quickstart-claude-code.md +2 -2
- package/package.json +1 -1
- package/plugins/kxm/.claude-plugin/plugin.json +1 -1
- package/plugins/kxm/dist/claude-hook.js +4 -1
- package/plugins/kxm/dist/cli.js +407 -156
- package/plugins/kxm/dist/client.js +9 -0
- package/plugins/kxm/dist/core.js +9 -3
- package/plugins/kxm/dist/extension.js +13 -1
- package/plugins/kxm/dist/mcp-server.js +14 -2
- package/plugins/kxm/dist/runtime-supervisor.js +231 -48
- package/plugins/kxm/dist/runtime.js +415 -92
- package/plugins/kxm/dist/server.js +19 -1
- package/plugins/kxm/package.json +1 -1
- package/plugins/kxm/skills/kxm-hub-ops/SKILL.md +4 -3
- package/plugins/kxm/skills/kxm-peer/SKILL.md +5 -3
- package/plugins/kxm/skills/kxm-project-setup/SKILL.md +3 -2
- package/plugins/kxm/skills/kxm-routing-improve/SKILL.md +3 -0
- package/plugins/kxm/skills/kxm-runs/SKILL.md +8 -7
- package/plugins/kxm/src/cli/project.ts +22 -13
- package/plugins/kxm/src/cli/system.ts +22 -1
- package/plugins/kxm/src/cli.ts +14 -4
- package/plugins/kxm/src/client.ts +10 -0
- package/plugins/kxm/src/commands.ts +10 -1
- package/plugins/kxm/src/database.ts +210 -36
- package/plugins/kxm/src/engine.ts +117 -2
- package/plugins/kxm/src/extension.ts +1 -0
- package/plugins/kxm/src/harness.ts +29 -0
- package/plugins/kxm/src/hub.ts +12 -0
- package/plugins/kxm/src/init-guide-setup.ts +43 -28
- package/plugins/kxm/src/mcp-server.ts +1 -1
- package/plugins/kxm/src/oneshot-producer.ts +16 -8
- package/plugins/kxm/src/prices.ts +33 -2
- package/plugins/kxm/src/routing.ts +13 -7
- package/plugins/kxm/src/studio-layout.ts +5 -4
- package/plugins/kxm/src/template.ts +31 -0
- package/plugins/kxm/src/worktree-witness.ts +71 -0
- package/schemas/backup-manifest.schema.json +33 -0
|
@@ -164,10 +164,10 @@ var require_code = __commonJS({
|
|
|
164
164
|
function interpolate(x) {
|
|
165
165
|
return typeof x == "number" || typeof x == "boolean" || x === null ? x : safeStringify(Array.isArray(x) ? x.join(",") : x);
|
|
166
166
|
}
|
|
167
|
-
function
|
|
167
|
+
function stringify5(x) {
|
|
168
168
|
return new _Code(safeStringify(x));
|
|
169
169
|
}
|
|
170
|
-
exports.stringify =
|
|
170
|
+
exports.stringify = stringify5;
|
|
171
171
|
function safeStringify(x) {
|
|
172
172
|
return JSON.stringify(x).replace(/\u2028/g, "\\u2028").replace(/\u2029/g, "\\u2029");
|
|
173
173
|
}
|
|
@@ -8918,7 +8918,7 @@ var require_stringify = __commonJS({
|
|
|
8918
8918
|
props.push(doc.directives.tagString(tag));
|
|
8919
8919
|
return props.join(" ");
|
|
8920
8920
|
}
|
|
8921
|
-
function
|
|
8921
|
+
function stringify5(item, ctx, onComment, onChompKeep) {
|
|
8922
8922
|
if (identity.isPair(item))
|
|
8923
8923
|
return item.toString(ctx, onComment, onChompKeep);
|
|
8924
8924
|
if (identity.isAlias(item)) {
|
|
@@ -8947,7 +8947,7 @@ var require_stringify = __commonJS({
|
|
|
8947
8947
|
${ctx.indent}${str}`;
|
|
8948
8948
|
}
|
|
8949
8949
|
exports.createStringifyContext = createStringifyContext;
|
|
8950
|
-
exports.stringify =
|
|
8950
|
+
exports.stringify = stringify5;
|
|
8951
8951
|
}
|
|
8952
8952
|
});
|
|
8953
8953
|
|
|
@@ -8957,7 +8957,7 @@ var require_stringifyPair = __commonJS({
|
|
|
8957
8957
|
"use strict";
|
|
8958
8958
|
var identity = require_identity();
|
|
8959
8959
|
var Scalar = require_Scalar();
|
|
8960
|
-
var
|
|
8960
|
+
var stringify5 = require_stringify();
|
|
8961
8961
|
var stringifyComment = require_stringifyComment();
|
|
8962
8962
|
function stringifyPair({ key, value }, ctx, onComment, onChompKeep) {
|
|
8963
8963
|
const { allNullValues, doc, indent, indentStep, options: { commentString, indentSeq, simpleKeys } } = ctx;
|
|
@@ -8979,7 +8979,7 @@ var require_stringifyPair = __commonJS({
|
|
|
8979
8979
|
});
|
|
8980
8980
|
let keyCommentDone = false;
|
|
8981
8981
|
let chompKeep = false;
|
|
8982
|
-
let str =
|
|
8982
|
+
let str = stringify5.stringify(key, ctx, () => keyCommentDone = true, () => chompKeep = true);
|
|
8983
8983
|
if (!explicitKey && !ctx.inFlow && str.length > 1024) {
|
|
8984
8984
|
if (simpleKeys)
|
|
8985
8985
|
throw new Error("With simple keys, single line scalar must not span more than 1024 characters");
|
|
@@ -9031,7 +9031,7 @@ ${indent}:`;
|
|
|
9031
9031
|
ctx.indent = ctx.indent.substring(2);
|
|
9032
9032
|
}
|
|
9033
9033
|
let valueCommentDone = false;
|
|
9034
|
-
const valueStr =
|
|
9034
|
+
const valueStr = stringify5.stringify(value, ctx, () => valueCommentDone = true, () => chompKeep = true);
|
|
9035
9035
|
let ws = " ";
|
|
9036
9036
|
if (keyComment || vsb || vcb) {
|
|
9037
9037
|
ws = vsb ? "\n" : "";
|
|
@@ -9172,7 +9172,7 @@ var require_addPairToJSMap = __commonJS({
|
|
|
9172
9172
|
"use strict";
|
|
9173
9173
|
var log = require_log();
|
|
9174
9174
|
var merge = require_merge();
|
|
9175
|
-
var
|
|
9175
|
+
var stringify5 = require_stringify();
|
|
9176
9176
|
var identity = require_identity();
|
|
9177
9177
|
var toJS = require_toJS();
|
|
9178
9178
|
function addPairToJSMap(ctx, map, { key, value }) {
|
|
@@ -9208,7 +9208,7 @@ var require_addPairToJSMap = __commonJS({
|
|
|
9208
9208
|
if (typeof jsKey !== "object")
|
|
9209
9209
|
return String(jsKey);
|
|
9210
9210
|
if (identity.isNode(key) && ctx?.doc) {
|
|
9211
|
-
const strCtx =
|
|
9211
|
+
const strCtx = stringify5.createStringifyContext(ctx.doc, {});
|
|
9212
9212
|
strCtx.anchors = /* @__PURE__ */ new Set();
|
|
9213
9213
|
for (const node of ctx.anchors.keys())
|
|
9214
9214
|
strCtx.anchors.add(node.anchor);
|
|
@@ -9275,12 +9275,12 @@ var require_stringifyCollection = __commonJS({
|
|
|
9275
9275
|
"node_modules/yaml/dist/stringify/stringifyCollection.js"(exports) {
|
|
9276
9276
|
"use strict";
|
|
9277
9277
|
var identity = require_identity();
|
|
9278
|
-
var
|
|
9278
|
+
var stringify5 = require_stringify();
|
|
9279
9279
|
var stringifyComment = require_stringifyComment();
|
|
9280
9280
|
function stringifyCollection(collection, ctx, options) {
|
|
9281
9281
|
const flow = ctx.inFlow ?? collection.flow;
|
|
9282
|
-
const
|
|
9283
|
-
return
|
|
9282
|
+
const stringify6 = flow ? stringifyFlowCollection : stringifyBlockCollection;
|
|
9283
|
+
return stringify6(collection, ctx, options);
|
|
9284
9284
|
}
|
|
9285
9285
|
function stringifyBlockCollection({ comment, items }, ctx, { blockItemPrefix, flowChars, itemIndent, onChompKeep, onComment }) {
|
|
9286
9286
|
const { indent, options: { commentString } } = ctx;
|
|
@@ -9305,7 +9305,7 @@ var require_stringifyCollection = __commonJS({
|
|
|
9305
9305
|
}
|
|
9306
9306
|
}
|
|
9307
9307
|
chompKeep = false;
|
|
9308
|
-
let str2 =
|
|
9308
|
+
let str2 = stringify5.stringify(item, itemCtx, () => comment2 = null, () => chompKeep = true);
|
|
9309
9309
|
if (comment2)
|
|
9310
9310
|
str2 += stringifyComment.lineComment(str2, itemIndent, commentString(comment2));
|
|
9311
9311
|
if (chompKeep && comment2)
|
|
@@ -9372,7 +9372,7 @@ ${indent}${line}` : "\n";
|
|
|
9372
9372
|
}
|
|
9373
9373
|
if (comment)
|
|
9374
9374
|
reqNewline = true;
|
|
9375
|
-
let str =
|
|
9375
|
+
let str = stringify5.stringify(item, itemCtx, () => comment = null);
|
|
9376
9376
|
reqNewline || (reqNewline = lines.length > linesAtValue || str.includes("\n"));
|
|
9377
9377
|
if (i < items.length - 1) {
|
|
9378
9378
|
str += ",";
|
|
@@ -10733,7 +10733,7 @@ var require_stringifyDocument = __commonJS({
|
|
|
10733
10733
|
"node_modules/yaml/dist/stringify/stringifyDocument.js"(exports) {
|
|
10734
10734
|
"use strict";
|
|
10735
10735
|
var identity = require_identity();
|
|
10736
|
-
var
|
|
10736
|
+
var stringify5 = require_stringify();
|
|
10737
10737
|
var stringifyComment = require_stringifyComment();
|
|
10738
10738
|
function stringifyDocument(doc, options) {
|
|
10739
10739
|
const lines = [];
|
|
@@ -10748,7 +10748,7 @@ var require_stringifyDocument = __commonJS({
|
|
|
10748
10748
|
}
|
|
10749
10749
|
if (hasDirectives)
|
|
10750
10750
|
lines.push("---");
|
|
10751
|
-
const ctx =
|
|
10751
|
+
const ctx = stringify5.createStringifyContext(doc, options);
|
|
10752
10752
|
const { commentString } = ctx.options;
|
|
10753
10753
|
if (doc.commentBefore) {
|
|
10754
10754
|
if (lines.length !== 1)
|
|
@@ -10770,7 +10770,7 @@ var require_stringifyDocument = __commonJS({
|
|
|
10770
10770
|
contentComment = doc.contents.comment;
|
|
10771
10771
|
}
|
|
10772
10772
|
const onChompKeep = contentComment ? void 0 : () => chompKeep = true;
|
|
10773
|
-
let body =
|
|
10773
|
+
let body = stringify5.stringify(doc.contents, ctx, () => contentComment = null, onChompKeep);
|
|
10774
10774
|
if (contentComment)
|
|
10775
10775
|
body += stringifyComment.lineComment(body, "", commentString(contentComment));
|
|
10776
10776
|
if ((body[0] === "|" || body[0] === ">") && lines[lines.length - 1] === "---") {
|
|
@@ -10778,7 +10778,7 @@ var require_stringifyDocument = __commonJS({
|
|
|
10778
10778
|
} else
|
|
10779
10779
|
lines.push(body);
|
|
10780
10780
|
} else {
|
|
10781
|
-
lines.push(
|
|
10781
|
+
lines.push(stringify5.stringify(doc.contents, ctx));
|
|
10782
10782
|
}
|
|
10783
10783
|
if (doc.directives?.docEnd) {
|
|
10784
10784
|
if (doc.comment) {
|
|
@@ -12914,7 +12914,7 @@ var require_cst_scalar = __commonJS({
|
|
|
12914
12914
|
var require_cst_stringify = __commonJS({
|
|
12915
12915
|
"node_modules/yaml/dist/parse/cst-stringify.js"(exports) {
|
|
12916
12916
|
"use strict";
|
|
12917
|
-
var
|
|
12917
|
+
var stringify5 = (cst) => "type" in cst ? stringifyToken(cst) : stringifyItem(cst);
|
|
12918
12918
|
function stringifyToken(token) {
|
|
12919
12919
|
switch (token.type) {
|
|
12920
12920
|
case "block-scalar": {
|
|
@@ -12967,7 +12967,7 @@ var require_cst_stringify = __commonJS({
|
|
|
12967
12967
|
res += stringifyToken(value);
|
|
12968
12968
|
return res;
|
|
12969
12969
|
}
|
|
12970
|
-
exports.stringify =
|
|
12970
|
+
exports.stringify = stringify5;
|
|
12971
12971
|
}
|
|
12972
12972
|
});
|
|
12973
12973
|
|
|
@@ -14697,7 +14697,7 @@ var require_public_api = __commonJS({
|
|
|
14697
14697
|
}
|
|
14698
14698
|
return doc.toJS(Object.assign({ reviver: _reviver }, options));
|
|
14699
14699
|
}
|
|
14700
|
-
function
|
|
14700
|
+
function stringify5(value, replacer, options) {
|
|
14701
14701
|
let _replacer = null;
|
|
14702
14702
|
if (typeof replacer === "function" || Array.isArray(replacer)) {
|
|
14703
14703
|
_replacer = replacer;
|
|
@@ -14722,7 +14722,7 @@ var require_public_api = __commonJS({
|
|
|
14722
14722
|
exports.parse = parse7;
|
|
14723
14723
|
exports.parseAllDocuments = parseAllDocuments;
|
|
14724
14724
|
exports.parseDocument = parseDocument2;
|
|
14725
|
-
exports.stringify =
|
|
14725
|
+
exports.stringify = stringify5;
|
|
14726
14726
|
}
|
|
14727
14727
|
});
|
|
14728
14728
|
|
|
@@ -14781,7 +14781,7 @@ var require_dist = __commonJS({
|
|
|
14781
14781
|
// plugins/kxm/src/runtime-supervisor.ts
|
|
14782
14782
|
import { spawn as spawn3 } from "node:child_process";
|
|
14783
14783
|
import { createHash as createHash13, createHmac, randomBytes as randomBytes2, timingSafeEqual as timingSafeEqual2 } from "node:crypto";
|
|
14784
|
-
import { chmodSync as chmodSync2, existsSync as existsSync15, lstatSync as lstatSync5, mkdirSync as mkdirSync9, readFileSync as readFileSync12, renameSync as renameSync5, rmSync as rmSync4, writeFileSync as
|
|
14784
|
+
import { chmodSync as chmodSync2, existsSync as existsSync15, lstatSync as lstatSync5, mkdirSync as mkdirSync9, readFileSync as readFileSync12, renameSync as renameSync5, rmSync as rmSync4, writeFileSync as writeFileSync9 } from "node:fs";
|
|
14785
14785
|
import { createServer } from "node:http";
|
|
14786
14786
|
import { dirname as dirname11, isAbsolute as isAbsolute6, join as join18 } from "node:path";
|
|
14787
14787
|
|
|
@@ -15078,6 +15078,35 @@ function coreTemplate(projectId, projectName, variant) {
|
|
|
15078
15078
|
}]
|
|
15079
15079
|
]);
|
|
15080
15080
|
if (variant === "v4-registry") {
|
|
15081
|
+
const coordinator = files.get(".kxm/agents/coordinator.yaml");
|
|
15082
|
+
if (coordinator) {
|
|
15083
|
+
files.set(".kxm/agents/coordinator.yaml", {
|
|
15084
|
+
...coordinator,
|
|
15085
|
+
harness: "claude",
|
|
15086
|
+
model: { provider: "anthropic", model: "fable" }
|
|
15087
|
+
});
|
|
15088
|
+
}
|
|
15089
|
+
const implementer = files.get(".kxm/agents/implementer.yaml");
|
|
15090
|
+
if (implementer) {
|
|
15091
|
+
files.set(".kxm/agents/implementer.yaml", {
|
|
15092
|
+
...implementer,
|
|
15093
|
+
harness: "grok",
|
|
15094
|
+
model: { provider: "xai", model: "grok-4.6" }
|
|
15095
|
+
});
|
|
15096
|
+
}
|
|
15097
|
+
const workflow = files.get(".kxm/workflows/default.yaml");
|
|
15098
|
+
if (workflow) {
|
|
15099
|
+
const limits = { ...workflow.limits };
|
|
15100
|
+
delete limits.maxAgentTimeMs;
|
|
15101
|
+
files.set(".kxm/workflows/default.yaml", { ...workflow, limits });
|
|
15102
|
+
}
|
|
15103
|
+
files.set(".kxm/routes.yaml", {
|
|
15104
|
+
schema: "kxm.routes.v2",
|
|
15105
|
+
updatedAt: "2026-09-23T00:00:00.000Z",
|
|
15106
|
+
admitted: ["anthropic/fable", "xai/grok-4.6"],
|
|
15107
|
+
disabled: [],
|
|
15108
|
+
roles: { implementer: ["xai/grok-4.6"] }
|
|
15109
|
+
});
|
|
15081
15110
|
files.set(".kxm/gates.yaml", {
|
|
15082
15111
|
schema: "kxm.gate-registry.v1",
|
|
15083
15112
|
gates: { test: { kind: "command", argv: ["npm", "test"], timeoutMs: 36e5 } }
|
|
@@ -15604,6 +15633,16 @@ var READ_ONLY_ONESHOT_ARGS = Object.freeze({
|
|
|
15604
15633
|
function oneShotReadOnlyArgs(harness) {
|
|
15605
15634
|
return Object.hasOwn(READ_ONLY_ONESHOT_ARGS, harness) ? READ_ONLY_ONESHOT_ARGS[harness] : void 0;
|
|
15606
15635
|
}
|
|
15636
|
+
var WRITER_ONESHOT_ARGS = Object.freeze({
|
|
15637
|
+
pi: Object.freeze(["-a", "--no-extensions", "--no-skills", "--no-prompt-templates", "--no-session"]),
|
|
15638
|
+
grok: Object.freeze(["--always-approve", "--no-subagents", "--disable-web-search"])
|
|
15639
|
+
});
|
|
15640
|
+
function oneShotWriterArgs(harness) {
|
|
15641
|
+
return Object.hasOwn(WRITER_ONESHOT_ARGS, harness) ? WRITER_ONESHOT_ARGS[harness] : void 0;
|
|
15642
|
+
}
|
|
15643
|
+
function oneShotPermissionArgs(harness, permission) {
|
|
15644
|
+
return permission === "edit" ? oneShotWriterArgs(harness) : oneShotReadOnlyArgs(harness);
|
|
15645
|
+
}
|
|
15607
15646
|
var BUILTIN_HARNESSES = Object.freeze([
|
|
15608
15647
|
{
|
|
15609
15648
|
id: "pi",
|
|
@@ -23146,7 +23185,7 @@ async function beginOneShotEvidence(root, intent, sensitive) {
|
|
|
23146
23185
|
// plugins/kxm/src/prices.ts
|
|
23147
23186
|
var import_yaml3 = __toESM(require_dist(), 1);
|
|
23148
23187
|
import { createHash as createHash8 } from "node:crypto";
|
|
23149
|
-
import { existsSync as existsSync7, readFileSync as readFileSync5, statSync } from "node:fs";
|
|
23188
|
+
import { existsSync as existsSync7, readFileSync as readFileSync5, statSync, writeFileSync as writeFileSync3 } from "node:fs";
|
|
23150
23189
|
import { join as join8 } from "node:path";
|
|
23151
23190
|
|
|
23152
23191
|
// plugins/kxm/src/price-calc.ts
|
|
@@ -23315,7 +23354,7 @@ import { join as join14 } from "node:path";
|
|
|
23315
23354
|
|
|
23316
23355
|
// plugins/kxm/src/routes.ts
|
|
23317
23356
|
var import_yaml4 = __toESM(require_dist(), 1);
|
|
23318
|
-
import { existsSync as existsSync8, readFileSync as readFileSync6, mkdirSync as mkdirSync3, writeFileSync as
|
|
23357
|
+
import { existsSync as existsSync8, readFileSync as readFileSync6, mkdirSync as mkdirSync3, writeFileSync as writeFileSync4, readdirSync as readdirSync4 } from "node:fs";
|
|
23319
23358
|
import { join as join9 } from "node:path";
|
|
23320
23359
|
var RETIRED_POLICY = ".kxm/producers.yaml";
|
|
23321
23360
|
var empty = () => ({ schema: "kxm.routes.v2", updatedAt: (/* @__PURE__ */ new Date()).toISOString(), admitted: [], disabled: [], roles: {} });
|
|
@@ -23343,6 +23382,55 @@ function isRouteAdmitted(root, modelId) {
|
|
|
23343
23382
|
return policy.admitted.includes(modelId) && !policy.disabled.includes(modelId);
|
|
23344
23383
|
}
|
|
23345
23384
|
|
|
23385
|
+
// plugins/kxm/src/worktree-witness.ts
|
|
23386
|
+
import { spawnSync as spawnSync3 } from "node:child_process";
|
|
23387
|
+
function gitText(cwd, args) {
|
|
23388
|
+
const result = spawnSync3("git", ["-C", cwd, ...args], {
|
|
23389
|
+
encoding: "utf8",
|
|
23390
|
+
windowsHide: true,
|
|
23391
|
+
timeout: 15e3
|
|
23392
|
+
});
|
|
23393
|
+
if (result.error || result.status !== 0) return void 0;
|
|
23394
|
+
return result.stdout ?? "";
|
|
23395
|
+
}
|
|
23396
|
+
function captureWorktreeWitness(cwd) {
|
|
23397
|
+
const porcelain = gitText(cwd, ["status", "--porcelain=v1", "-uall"]);
|
|
23398
|
+
const diff = gitText(cwd, ["diff", "--no-ext-diff"]);
|
|
23399
|
+
const staged = gitText(cwd, ["diff", "--cached", "--no-ext-diff"]);
|
|
23400
|
+
if (porcelain === void 0 || diff === void 0 || staged === void 0) {
|
|
23401
|
+
return { unwitnessed: true, fingerprint: "" };
|
|
23402
|
+
}
|
|
23403
|
+
return { unwitnessed: false, fingerprint: `${porcelain}\0${diff}\0${staged}` };
|
|
23404
|
+
}
|
|
23405
|
+
function worktreeChanged(before, after) {
|
|
23406
|
+
if (before.unwitnessed || after.unwitnessed) return false;
|
|
23407
|
+
return before.fingerprint !== after.fingerprint;
|
|
23408
|
+
}
|
|
23409
|
+
function applyAuthoringWitness(result, input) {
|
|
23410
|
+
const changed = worktreeChanged(input.before, input.after);
|
|
23411
|
+
const unwitnessed = input.before.unwitnessed || input.after.unwitnessed;
|
|
23412
|
+
const providerMetadata = { ...result.providerMetadata ?? {} };
|
|
23413
|
+
if (input.writes) {
|
|
23414
|
+
if (unwitnessed || !changed) {
|
|
23415
|
+
providerMetadata.authored = false;
|
|
23416
|
+
providerMetadata.authoringWitness = unwitnessed ? "unwitnessed" : "unchanged";
|
|
23417
|
+
if (result.outcome === "passed") return { ...result, outcome: "failed", providerMetadata };
|
|
23418
|
+
} else {
|
|
23419
|
+
providerMetadata.authored = true;
|
|
23420
|
+
providerMetadata.authoringWitness = "changed";
|
|
23421
|
+
}
|
|
23422
|
+
} else {
|
|
23423
|
+
providerMetadata.authored = false;
|
|
23424
|
+
if (!unwitnessed && changed) {
|
|
23425
|
+
providerMetadata.authoringWitness = "readonly_mutated";
|
|
23426
|
+
if (result.outcome === "passed") return { ...result, outcome: "failed", providerMetadata };
|
|
23427
|
+
} else {
|
|
23428
|
+
providerMetadata.authoringWitness = unwitnessed ? "unwitnessed" : "read-only";
|
|
23429
|
+
}
|
|
23430
|
+
}
|
|
23431
|
+
return { ...result, providerMetadata };
|
|
23432
|
+
}
|
|
23433
|
+
|
|
23346
23434
|
// plugins/kxm/src/context-packet.ts
|
|
23347
23435
|
import { randomUUID as randomUUID4 } from "node:crypto";
|
|
23348
23436
|
var CONTEXT_PACKET_SCHEMA = "kxm.context-packet.v2";
|
|
@@ -23610,7 +23698,7 @@ function pruneContextPacket(packet, tokenBudget) {
|
|
|
23610
23698
|
}
|
|
23611
23699
|
|
|
23612
23700
|
// plugins/kxm/src/dispatch-context.ts
|
|
23613
|
-
import { spawnSync as
|
|
23701
|
+
import { spawnSync as spawnSync4 } from "node:child_process";
|
|
23614
23702
|
import { readdirSync as readdirSync7 } from "node:fs";
|
|
23615
23703
|
import { extname as extname3, join as join12 } from "node:path";
|
|
23616
23704
|
|
|
@@ -24241,7 +24329,7 @@ function memoryRecordToContextItem(record2, project) {
|
|
|
24241
24329
|
|
|
24242
24330
|
// plugins/kxm/src/memory.ts
|
|
24243
24331
|
var import_yaml5 = __toESM(require_dist(), 1);
|
|
24244
|
-
import { existsSync as existsSync9, mkdirSync as mkdirSync4, readdirSync as readdirSync5, readFileSync as readFileSync7, writeFileSync as
|
|
24332
|
+
import { existsSync as existsSync9, mkdirSync as mkdirSync4, readdirSync as readdirSync5, readFileSync as readFileSync7, writeFileSync as writeFileSync5 } from "node:fs";
|
|
24245
24333
|
import { extname as extname2, join as join10, resolve as resolve5 } from "node:path";
|
|
24246
24334
|
var MEMORY_SCHEMA = "kxm.memory.v1";
|
|
24247
24335
|
var VALID_SCOPES = /* @__PURE__ */ new Set(["agent", "project", "run", "operator"]);
|
|
@@ -24370,7 +24458,7 @@ function loadAuthoredMemory(repoRoot) {
|
|
|
24370
24458
|
// plugins/kxm/src/skills.ts
|
|
24371
24459
|
var import_yaml6 = __toESM(require_dist(), 1);
|
|
24372
24460
|
import { createHash as createHash9 } from "node:crypto";
|
|
24373
|
-
import { existsSync as existsSync10, mkdirSync as mkdirSync5, readdirSync as readdirSync6, readFileSync as readFileSync8, renameSync, rmSync, statSync as statSync2, writeFileSync as
|
|
24461
|
+
import { existsSync as existsSync10, mkdirSync as mkdirSync5, readdirSync as readdirSync6, readFileSync as readFileSync8, renameSync, rmSync, statSync as statSync2, writeFileSync as writeFileSync6 } from "node:fs";
|
|
24374
24462
|
import { dirname as dirname7, join as join11 } from "node:path";
|
|
24375
24463
|
var SKILL_CANDIDATE_SCHEMA = "kxm.skill-candidate.v1";
|
|
24376
24464
|
var SKILL_EVALUATION_SCHEMA = "kxm.skill-evaluation.v1";
|
|
@@ -24474,7 +24562,7 @@ var SkillLifecycle = class {
|
|
|
24474
24562
|
return;
|
|
24475
24563
|
}
|
|
24476
24564
|
mkdirSync5(dirname7(file), { recursive: true });
|
|
24477
|
-
|
|
24565
|
+
writeFileSync6(file, content);
|
|
24478
24566
|
}
|
|
24479
24567
|
dir(state) {
|
|
24480
24568
|
return join11(this.root, state === "candidate" ? "candidates" : `${state}s`.replace("rejecteds", "rejected").replace("promoteds", "promoted"));
|
|
@@ -24811,7 +24899,7 @@ function gitEnvironment2() {
|
|
|
24811
24899
|
return Object.fromEntries(Object.entries(process.env).filter(([name]) => !name.toUpperCase().startsWith("GIT_")));
|
|
24812
24900
|
}
|
|
24813
24901
|
function committedGateGap(projectRoot) {
|
|
24814
|
-
const result =
|
|
24902
|
+
const result = spawnSync4("git", [
|
|
24815
24903
|
"--no-optional-locks",
|
|
24816
24904
|
"-C",
|
|
24817
24905
|
projectRoot,
|
|
@@ -27080,6 +27168,14 @@ function prepareDispatch(context, runId, producerId, dispatchSources) {
|
|
|
27080
27168
|
return { kind: "return", state, handoff: { ...routeResult.error, stepId } };
|
|
27081
27169
|
}
|
|
27082
27170
|
resolvedRoute = routeResult;
|
|
27171
|
+
const writeRefusal = unsupportedLiveWrite(
|
|
27172
|
+
context.projectRoot,
|
|
27173
|
+
step,
|
|
27174
|
+
agentId,
|
|
27175
|
+
resolvedRoute.selector,
|
|
27176
|
+
loadKxmRunPlanEnvelope(context.eventStore, run).projectLimits.maxConcurrentRuns
|
|
27177
|
+
);
|
|
27178
|
+
if (writeRefusal) return { kind: "return", state, handoff: { ...writeRefusal, stepId } };
|
|
27083
27179
|
}
|
|
27084
27180
|
const used = state.stepAttempts[stepId] ?? 0;
|
|
27085
27181
|
if (used >= step.maxAttempts) {
|
|
@@ -27288,6 +27384,7 @@ function birthMember(context, input) {
|
|
|
27288
27384
|
|
|
27289
27385
|
${generatedPrompt}` : generatedPrompt,
|
|
27290
27386
|
thinking: input.stepAttempt <= 1 ? "low" : "medium",
|
|
27387
|
+
permission: Object.values(input.step.repositories).some((access) => access === "write") ? "edit" : "read-only",
|
|
27291
27388
|
contextPacket,
|
|
27292
27389
|
...resolvedRoute ? { provider: resolvedRoute.provider, model: resolvedRoute.model } : {}
|
|
27293
27390
|
},
|
|
@@ -27414,7 +27511,18 @@ async function drivePanel(context, panel, producer) {
|
|
|
27414
27511
|
if (!executingBound()) return { attemptId: member.attemptId, invoked: false, skipped: true };
|
|
27415
27512
|
kxmPanelDispatchSeams.beforeInvoke?.(member);
|
|
27416
27513
|
if (!executingBound()) return { attemptId: member.attemptId, invoked: false, skipped: true };
|
|
27514
|
+
const live = member.producerId !== "driver-simulated";
|
|
27515
|
+
const writes = Object.values(member.step.repositories).some((access) => access === "write");
|
|
27516
|
+
const before = live ? captureWorktreeWitness(context.projectRoot) : void 0;
|
|
27417
27517
|
const produced = await invokeProducer(producer, member.request);
|
|
27518
|
+
if (live && produced.result && before) {
|
|
27519
|
+
const after = captureWorktreeWitness(context.projectRoot);
|
|
27520
|
+
return {
|
|
27521
|
+
attemptId: member.attemptId,
|
|
27522
|
+
invoked: true,
|
|
27523
|
+
produced: { ...produced, result: applyAuthoringWitness(produced.result, { writes, before, after }) }
|
|
27524
|
+
};
|
|
27525
|
+
}
|
|
27418
27526
|
return { attemptId: member.attemptId, invoked: true, produced };
|
|
27419
27527
|
} catch (error) {
|
|
27420
27528
|
member.controller.abort();
|
|
@@ -28052,11 +28160,78 @@ function unsupportedStep(plan, step, producerId) {
|
|
|
28052
28160
|
return { reason: "step_unsupported", field: "repositories", detail: `invalid repository access '${access}' on ${repoId}` };
|
|
28053
28161
|
}
|
|
28054
28162
|
}
|
|
28055
|
-
|
|
28163
|
+
return void 0;
|
|
28164
|
+
}
|
|
28165
|
+
function readYamlRecord(path) {
|
|
28166
|
+
if (!existsSync11(path)) return void 0;
|
|
28167
|
+
try {
|
|
28168
|
+
const parsed = (0, import_yaml7.parse)(readFileSync9(path, "utf8"));
|
|
28169
|
+
if (parsed && typeof parsed === "object" && !Array.isArray(parsed)) return parsed;
|
|
28170
|
+
} catch {
|
|
28171
|
+
return void 0;
|
|
28172
|
+
}
|
|
28173
|
+
return void 0;
|
|
28174
|
+
}
|
|
28175
|
+
function agentHarness(projectRoot, agentId) {
|
|
28176
|
+
const harness = readYamlRecord(join14(projectRoot, ".kxm", "agents", `${agentId}.yaml`))?.harness;
|
|
28177
|
+
return typeof harness === "string" && harness.length > 0 ? harness : void 0;
|
|
28178
|
+
}
|
|
28179
|
+
function projectDefaultHarness(projectRoot) {
|
|
28180
|
+
const harness = readYamlRecord(join14(projectRoot, ".kxm", "project.yaml"))?.defaultHarness;
|
|
28181
|
+
return typeof harness === "string" && harness.length > 0 ? harness : "pi";
|
|
28182
|
+
}
|
|
28183
|
+
function unsupportedLiveWrite(projectRoot, step, agentId, selector, maxConcurrentRuns) {
|
|
28184
|
+
if (!Object.values(step.repositories).some((access) => access === "write")) return void 0;
|
|
28185
|
+
if (step.assignments.maximum !== 1) {
|
|
28186
|
+
return {
|
|
28187
|
+
reason: "step_unsupported",
|
|
28188
|
+
field: "assignments.maximum",
|
|
28189
|
+
detail: "live write steps run a single assignment; the checkout witness cannot attribute edits between writers"
|
|
28190
|
+
};
|
|
28191
|
+
}
|
|
28192
|
+
if (maxConcurrentRuns !== 1) {
|
|
28193
|
+
return {
|
|
28194
|
+
reason: "step_unsupported",
|
|
28195
|
+
field: "limits.maxConcurrentRuns",
|
|
28196
|
+
detail: "live write steps require limits.maxConcurrentRuns of 1; concurrent runs share one checkout"
|
|
28197
|
+
};
|
|
28198
|
+
}
|
|
28199
|
+
const harness = agentHarness(projectRoot, agentId) ?? projectDefaultHarness(projectRoot);
|
|
28200
|
+
if (!oneShotWriterArgs(harness)) {
|
|
28056
28201
|
return {
|
|
28057
28202
|
reason: "step_unsupported",
|
|
28058
28203
|
field: "repositories",
|
|
28059
|
-
detail:
|
|
28204
|
+
detail: `live write steps require an audited writer profile; ${harness} has none`
|
|
28205
|
+
};
|
|
28206
|
+
}
|
|
28207
|
+
const rosterPath = join14(projectRoot, ".kxm", "roster.yaml");
|
|
28208
|
+
if (!existsSync11(rosterPath)) return void 0;
|
|
28209
|
+
const roster = readYamlRecord(rosterPath);
|
|
28210
|
+
if (!roster || roster.schema !== "kxm.developer-roster.v1") {
|
|
28211
|
+
return { reason: "step_unsupported", field: "model", detail: "live write steps require a readable kxm.developer-roster.v1" };
|
|
28212
|
+
}
|
|
28213
|
+
const routes = roster.routes;
|
|
28214
|
+
const lineup = roster.lineup;
|
|
28215
|
+
const writerIds = lineup && typeof lineup === "object" && !Array.isArray(lineup) ? lineup.writer : void 0;
|
|
28216
|
+
if (!routes || typeof routes !== "object" || Array.isArray(routes) || !Array.isArray(writerIds)) {
|
|
28217
|
+
return { reason: "step_unsupported", field: "model", detail: "developer roster has no writer lineup" };
|
|
28218
|
+
}
|
|
28219
|
+
const allowed = writerIds.some((id) => {
|
|
28220
|
+
if (typeof id !== "string") return false;
|
|
28221
|
+
const route = routes[id];
|
|
28222
|
+
if (!route || typeof route !== "object" || Array.isArray(route)) return false;
|
|
28223
|
+
const record2 = route;
|
|
28224
|
+
if (record2.harness !== harness || record2.status !== "admitted") return false;
|
|
28225
|
+
if (!Array.isArray(record2.permissions) || !record2.permissions.includes("edit")) return false;
|
|
28226
|
+
const model = typeof record2.model === "string" ? record2.model : "";
|
|
28227
|
+
const vendor = typeof record2.vendor === "string" ? record2.vendor : "";
|
|
28228
|
+
return model === selector || vendor.length > 0 && `${vendor}/${model}` === selector;
|
|
28229
|
+
});
|
|
28230
|
+
if (!allowed) {
|
|
28231
|
+
return {
|
|
28232
|
+
reason: "step_unsupported",
|
|
28233
|
+
field: "model",
|
|
28234
|
+
detail: `live write route ${selector} on ${harness} is not on the developer roster writer lineup`
|
|
28060
28235
|
};
|
|
28061
28236
|
}
|
|
28062
28237
|
return void 0;
|
|
@@ -28522,10 +28697,10 @@ function createKxmOneShotProducer(options = {}) {
|
|
|
28522
28697
|
if (request.provider) {
|
|
28523
28698
|
return { provider: request.provider.toLowerCase(), model: request.model, thinking: request.thinking };
|
|
28524
28699
|
}
|
|
28525
|
-
const
|
|
28700
|
+
const parsed = parseModelString(request.model, harness);
|
|
28526
28701
|
return {
|
|
28527
|
-
provider: request.provider?.toLowerCase() ??
|
|
28528
|
-
model:
|
|
28702
|
+
provider: request.provider?.toLowerCase() ?? parsed.provider,
|
|
28703
|
+
model: parsed.model,
|
|
28529
28704
|
thinking: request.thinking
|
|
28530
28705
|
};
|
|
28531
28706
|
}
|
|
@@ -28535,17 +28710,19 @@ function createKxmOneShotProducer(options = {}) {
|
|
|
28535
28710
|
if (resolved.provider) {
|
|
28536
28711
|
return { provider: resolved.provider.toLowerCase(), model: resolved.model, thinking: resolved.thinking };
|
|
28537
28712
|
}
|
|
28538
|
-
const
|
|
28713
|
+
const parsed = parseModelString(resolved.model, harness);
|
|
28539
28714
|
return {
|
|
28540
|
-
provider: resolved.provider?.toLowerCase() ??
|
|
28541
|
-
model:
|
|
28715
|
+
provider: resolved.provider?.toLowerCase() ?? parsed.provider,
|
|
28716
|
+
model: parsed.model,
|
|
28542
28717
|
thinking: resolved.thinking
|
|
28543
28718
|
};
|
|
28544
28719
|
}
|
|
28545
28720
|
}
|
|
28546
|
-
|
|
28547
|
-
|
|
28548
|
-
|
|
28721
|
+
if (options.defaultModel) {
|
|
28722
|
+
const parsed = parseModelString(options.defaultModel, harness);
|
|
28723
|
+
return { provider: parsed.provider, model: parsed.model, thinking: request.thinking };
|
|
28724
|
+
}
|
|
28725
|
+
throw new Error("producer_route_not_admitted");
|
|
28549
28726
|
}
|
|
28550
28727
|
async function checkAuth(harness, provider, model, env, signal) {
|
|
28551
28728
|
if (options.inventory) {
|
|
@@ -28583,8 +28760,11 @@ function createKxmOneShotProducer(options = {}) {
|
|
|
28583
28760
|
if (request.signal.aborted) return cancelled();
|
|
28584
28761
|
const catalogEntry = (options.catalog ?? BUILTIN_HARNESSES).find((h) => h.id === harness);
|
|
28585
28762
|
if (!catalogEntry?.oneShot) throw new Error(`oneshot_harness_unsupported: ${harness}`);
|
|
28586
|
-
const
|
|
28587
|
-
|
|
28763
|
+
const permission = request.permission === "edit" || request.contextPacket?.task.permissionCeiling === "edit" ? "edit" : "read-only";
|
|
28764
|
+
const permissionArgs = oneShotPermissionArgs(harness, permission);
|
|
28765
|
+
if (!permissionArgs) {
|
|
28766
|
+
throw new Error(`oneshot_harness_unsupported: ${harness} ${permission === "edit" ? "writer_profile_unaudited" : "permission_profile_unaudited"}`);
|
|
28767
|
+
}
|
|
28588
28768
|
const env = { ...options.env ?? process.env };
|
|
28589
28769
|
let auth;
|
|
28590
28770
|
try {
|
|
@@ -28700,7 +28880,10 @@ Return a final JSON object with an "outcome" field chosen from ${JSON.stringify(
|
|
|
28700
28880
|
const outcome = aborted ? "cancelled" : transportFailed || parsed.isError ? "failed" : determineOutcome(parsed.text, request.allowedOutcomes);
|
|
28701
28881
|
const providerMetadata = {
|
|
28702
28882
|
processStatus: aborted ? "aborted" : transportFailed ? "failed" : "completed",
|
|
28703
|
-
executionEvidenceId: evidence.id
|
|
28883
|
+
executionEvidenceId: evidence.id,
|
|
28884
|
+
permission,
|
|
28885
|
+
permissionProfile: permission === "edit" ? "writer" : "read-only",
|
|
28886
|
+
authored: false
|
|
28704
28887
|
};
|
|
28705
28888
|
if (procResult.code !== null && Number.isFinite(procResult.code)) providerMetadata.processExitCode = procResult.code;
|
|
28706
28889
|
if (procResult.signal) providerMetadata.processSignal = procResult.signal;
|
|
@@ -28903,7 +29086,7 @@ var RuntimeHubClient = class {
|
|
|
28903
29086
|
};
|
|
28904
29087
|
|
|
28905
29088
|
// plugins/kxm/src/hub-binding.ts
|
|
28906
|
-
import { existsSync as existsSync12, mkdirSync as mkdirSync6, readFileSync as readFileSync10, renameSync as renameSync2, rmSync as rmSync2, writeFileSync as
|
|
29089
|
+
import { existsSync as existsSync12, mkdirSync as mkdirSync6, readFileSync as readFileSync10, renameSync as renameSync2, rmSync as rmSync2, writeFileSync as writeFileSync7 } from "node:fs";
|
|
28907
29090
|
import { homedir as homedir2 } from "node:os";
|
|
28908
29091
|
import { dirname as dirname8, isAbsolute as isAbsolute4, join as join16, resolve as resolve7 } from "node:path";
|
|
28909
29092
|
var HUB_BINDING_SCHEMA = "kxm.hub-binding.v1";
|
|
@@ -28975,7 +29158,7 @@ function readHubBinding(env = process.env) {
|
|
|
28975
29158
|
}
|
|
28976
29159
|
|
|
28977
29160
|
// plugins/kxm/src/hub-env.ts
|
|
28978
|
-
import { existsSync as existsSync13, mkdirSync as mkdirSync7, readFileSync as readFileSync11, renameSync as renameSync3, rmSync as rmSync3, writeFileSync as
|
|
29161
|
+
import { existsSync as existsSync13, mkdirSync as mkdirSync7, readFileSync as readFileSync11, renameSync as renameSync3, rmSync as rmSync3, writeFileSync as writeFileSync8 } from "node:fs";
|
|
28979
29162
|
import { homedir as homedir3 } from "node:os";
|
|
28980
29163
|
import { dirname as dirname9, isAbsolute as isAbsolute5, join as join17, resolve as resolve8 } from "node:path";
|
|
28981
29164
|
var HUB_ENV_SCHEMA = "kxm.hub-env.v1";
|
|
@@ -29205,7 +29388,7 @@ function publishKxmSupervisorToken(paths, token) {
|
|
|
29205
29388
|
const file = kxmSupervisorTokenFile(paths);
|
|
29206
29389
|
mkdirSync9(dirname11(file), { recursive: true, mode: 448 });
|
|
29207
29390
|
const temp = `${file}.${process.pid}.tmp`;
|
|
29208
|
-
|
|
29391
|
+
writeFileSync9(temp, `${token}
|
|
29209
29392
|
`, { encoding: "utf8", mode: 384 });
|
|
29210
29393
|
try {
|
|
29211
29394
|
chmodSync2(temp, 384);
|
|
@@ -29250,7 +29433,7 @@ function clearSupervisorError(paths) {
|
|
|
29250
29433
|
function recordSupervisorError(paths, message) {
|
|
29251
29434
|
try {
|
|
29252
29435
|
mkdirSync9(paths.runtimeDir, { recursive: true, mode: 448 });
|
|
29253
|
-
|
|
29436
|
+
writeFileSync9(supervisorErrorFile(paths), `${message}
|
|
29254
29437
|
`, { encoding: "utf8", mode: 384 });
|
|
29255
29438
|
} catch {
|
|
29256
29439
|
}
|