@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
package/plugins/kxm/dist/cli.js
CHANGED
|
@@ -164,10 +164,10 @@ var require_code = __commonJS({
|
|
|
164
164
|
function interpolate(x2) {
|
|
165
165
|
return typeof x2 == "number" || typeof x2 == "boolean" || x2 === null ? x2 : safeStringify(Array.isArray(x2) ? x2.join(",") : x2);
|
|
166
166
|
}
|
|
167
|
-
function
|
|
167
|
+
function stringify11(x2) {
|
|
168
168
|
return new _Code(safeStringify(x2));
|
|
169
169
|
}
|
|
170
|
-
exports.stringify =
|
|
170
|
+
exports.stringify = stringify11;
|
|
171
171
|
function safeStringify(x2) {
|
|
172
172
|
return JSON.stringify(x2).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 stringify11(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 = stringify11;
|
|
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 stringify11 = 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 = stringify11.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 = stringify11.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 stringify11 = 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 = stringify11.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 stringify11 = 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 stringify12 = flow ? stringifyFlowCollection : stringifyBlockCollection;
|
|
9283
|
+
return stringify12(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 = stringify11.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 = stringify11.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 stringify11 = 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 = stringify11.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 = stringify11.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(stringify11.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 stringify11 = (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 = stringify11;
|
|
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 stringify11(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 = parse12;
|
|
14723
14723
|
exports.parseAllDocuments = parseAllDocuments;
|
|
14724
14724
|
exports.parseDocument = parseDocument2;
|
|
14725
|
-
exports.stringify =
|
|
14725
|
+
exports.stringify = stringify11;
|
|
14726
14726
|
}
|
|
14727
14727
|
});
|
|
14728
14728
|
|
|
@@ -19626,6 +19626,15 @@ var HubClient = class {
|
|
|
19626
19626
|
}
|
|
19627
19627
|
}));
|
|
19628
19628
|
}
|
|
19629
|
+
/** This agent's open inbound requests (queued or delivered), oldest first. A read: nothing
|
|
19630
|
+
* is acknowledged. */
|
|
19631
|
+
async listInbox() {
|
|
19632
|
+
if (!this.agent) throw new Error("hub client is not registered");
|
|
19633
|
+
const result = await this.request(
|
|
19634
|
+
`/v1/agents/${encodeURIComponent(this.agent.id)}/inbox`
|
|
19635
|
+
);
|
|
19636
|
+
return result.messages;
|
|
19637
|
+
}
|
|
19629
19638
|
async getMessage(messageId) {
|
|
19630
19639
|
const result = await this.request(`/v1/messages/${encodeURIComponent(messageId)}`);
|
|
19631
19640
|
return result.message;
|
|
@@ -20322,7 +20331,10 @@ var AGENT_COMMANDS = [
|
|
|
20322
20331
|
await reconcileInbox(client, context.inbox, context.notifiedInbox);
|
|
20323
20332
|
return { messages: [...context.inbox.values()] };
|
|
20324
20333
|
}
|
|
20325
|
-
return { messages:
|
|
20334
|
+
if (context?.hubInbox) return { messages: await client.listInbox() };
|
|
20335
|
+
throw new Error(
|
|
20336
|
+
"kxm_inbox is not available in this session: it activates each inbound request as a turn, and that turn's final response is the reply"
|
|
20337
|
+
);
|
|
20326
20338
|
}
|
|
20327
20339
|
},
|
|
20328
20340
|
{
|
|
@@ -21219,6 +21231,35 @@ function coreTemplate(projectId, projectName, variant) {
|
|
|
21219
21231
|
}]
|
|
21220
21232
|
]);
|
|
21221
21233
|
if (variant === "v4-registry") {
|
|
21234
|
+
const coordinator = files.get(".kxm/agents/coordinator.yaml");
|
|
21235
|
+
if (coordinator) {
|
|
21236
|
+
files.set(".kxm/agents/coordinator.yaml", {
|
|
21237
|
+
...coordinator,
|
|
21238
|
+
harness: "claude",
|
|
21239
|
+
model: { provider: "anthropic", model: "fable" }
|
|
21240
|
+
});
|
|
21241
|
+
}
|
|
21242
|
+
const implementer = files.get(".kxm/agents/implementer.yaml");
|
|
21243
|
+
if (implementer) {
|
|
21244
|
+
files.set(".kxm/agents/implementer.yaml", {
|
|
21245
|
+
...implementer,
|
|
21246
|
+
harness: "grok",
|
|
21247
|
+
model: { provider: "xai", model: "grok-4.6" }
|
|
21248
|
+
});
|
|
21249
|
+
}
|
|
21250
|
+
const workflow = files.get(".kxm/workflows/default.yaml");
|
|
21251
|
+
if (workflow) {
|
|
21252
|
+
const limits = { ...workflow.limits };
|
|
21253
|
+
delete limits.maxAgentTimeMs;
|
|
21254
|
+
files.set(".kxm/workflows/default.yaml", { ...workflow, limits });
|
|
21255
|
+
}
|
|
21256
|
+
files.set(".kxm/routes.yaml", {
|
|
21257
|
+
schema: "kxm.routes.v2",
|
|
21258
|
+
updatedAt: "2026-09-23T00:00:00.000Z",
|
|
21259
|
+
admitted: ["anthropic/fable", "xai/grok-4.6"],
|
|
21260
|
+
disabled: [],
|
|
21261
|
+
roles: { implementer: ["xai/grok-4.6"] }
|
|
21262
|
+
});
|
|
21222
21263
|
files.set(".kxm/gates.yaml", {
|
|
21223
21264
|
schema: "kxm.gate-registry.v1",
|
|
21224
21265
|
gates: { test: { kind: "command", argv: ["npm", "test"], timeoutMs: 36e5 } }
|
|
@@ -21745,6 +21786,10 @@ var READ_ONLY_ONESHOT_ARGS = Object.freeze({
|
|
|
21745
21786
|
function oneShotReadOnlyArgs(harness) {
|
|
21746
21787
|
return Object.hasOwn(READ_ONLY_ONESHOT_ARGS, harness) ? READ_ONLY_ONESHOT_ARGS[harness] : void 0;
|
|
21747
21788
|
}
|
|
21789
|
+
var WRITER_ONESHOT_ARGS = Object.freeze({
|
|
21790
|
+
pi: Object.freeze(["-a", "--no-extensions", "--no-skills", "--no-prompt-templates", "--no-session"]),
|
|
21791
|
+
grok: Object.freeze(["--always-approve", "--no-subagents", "--disable-web-search"])
|
|
21792
|
+
});
|
|
21748
21793
|
var BUILTIN_HARNESSES = Object.freeze([
|
|
21749
21794
|
{
|
|
21750
21795
|
id: "pi",
|
|
@@ -23591,7 +23636,7 @@ function planKxmInitialization(start = process.cwd(), options = {}) {
|
|
|
23591
23636
|
// plugins/kxm/src/runtime-supervisor.ts
|
|
23592
23637
|
import { spawn as spawn2 } from "node:child_process";
|
|
23593
23638
|
import { createHash as createHash13, createHmac as createHmac2, randomBytes as randomBytes2, timingSafeEqual as timingSafeEqual2 } from "node:crypto";
|
|
23594
|
-
import { chmodSync as chmodSync4, existsSync as existsSync16, lstatSync as lstatSync6, mkdirSync as mkdirSync11, readFileSync as readFileSync14, renameSync as renameSync5, rmSync as rmSync5, writeFileSync as
|
|
23639
|
+
import { chmodSync as chmodSync4, existsSync as existsSync16, lstatSync as lstatSync6, mkdirSync as mkdirSync11, readFileSync as readFileSync14, renameSync as renameSync5, rmSync as rmSync5, writeFileSync as writeFileSync12 } from "node:fs";
|
|
23595
23640
|
import { dirname as dirname11, isAbsolute as isAbsolute6, join as join15 } from "node:path";
|
|
23596
23641
|
|
|
23597
23642
|
// plugins/kxm/src/runtime-store.ts
|
|
@@ -24288,79 +24333,187 @@ var KXM_BACKUP_CEILINGS = {
|
|
|
24288
24333
|
events: 7
|
|
24289
24334
|
};
|
|
24290
24335
|
function kxmBackupCeiling(storeId) {
|
|
24336
|
+
if (storeId === "runtime-registry") return KXM_BACKUP_CEILINGS.registry;
|
|
24291
24337
|
if (storeId.startsWith("events:")) return KXM_BACKUP_CEILINGS.events;
|
|
24292
24338
|
return KXM_BACKUP_CEILINGS[storeId] ?? KXM_BACKUP_CEILINGS["hub-store"];
|
|
24293
24339
|
}
|
|
24294
|
-
function
|
|
24340
|
+
function pushStore(stores, storeId, sourcePath) {
|
|
24341
|
+
if (stores.some((store) => store.storeId === storeId || store.sourcePath === sourcePath)) return;
|
|
24342
|
+
stores.push({ storeId, sourcePath, maxSupportedVersion: kxmBackupCeiling(storeId) });
|
|
24343
|
+
}
|
|
24344
|
+
function discoverUserRuntime(env, stores, files) {
|
|
24345
|
+
let stateRoot;
|
|
24346
|
+
try {
|
|
24347
|
+
stateRoot = kxmUserStateRoot(env ? { env } : {});
|
|
24348
|
+
} catch {
|
|
24349
|
+
return;
|
|
24350
|
+
}
|
|
24351
|
+
const runtimeDir = join8(stateRoot, "runtime");
|
|
24352
|
+
const registryPath = join8(runtimeDir, "registry.db");
|
|
24353
|
+
if (existsSync9(registryPath)) {
|
|
24354
|
+
const storeId = stores.some((store) => store.storeId === "registry") ? "runtime-registry" : "registry";
|
|
24355
|
+
pushStore(stores, storeId, registryPath);
|
|
24356
|
+
}
|
|
24357
|
+
const projectsDir = join8(runtimeDir, "projects");
|
|
24358
|
+
if (!existsSync9(projectsDir)) return;
|
|
24359
|
+
let entries;
|
|
24360
|
+
try {
|
|
24361
|
+
entries = readdirSync2(projectsDir, { withFileTypes: true });
|
|
24362
|
+
} catch {
|
|
24363
|
+
return;
|
|
24364
|
+
}
|
|
24365
|
+
for (const entry of entries) {
|
|
24366
|
+
if (!entry.isDirectory()) continue;
|
|
24367
|
+
const dbPath = join8(projectsDir, entry.name, "run-events.db");
|
|
24368
|
+
if (!existsSync9(dbPath)) continue;
|
|
24369
|
+
const safe = entry.name.replace(/[^a-zA-Z0-9_.-]/g, "_");
|
|
24370
|
+
let storeId = `events:${safe}`;
|
|
24371
|
+
if (stores.some((store) => store.storeId === storeId)) storeId = `events:runtime:${safe}`;
|
|
24372
|
+
pushStore(stores, storeId, dbPath);
|
|
24373
|
+
const sidecar = `${dbPath}.run-prompts.json`;
|
|
24374
|
+
if (existsSync9(sidecar)) {
|
|
24375
|
+
const id = `${storeId}:run-prompts`;
|
|
24376
|
+
if (!files.some((file) => file.id === id || file.sourcePath === sidecar)) {
|
|
24377
|
+
files.push({ id, sourcePath: sidecar });
|
|
24378
|
+
}
|
|
24379
|
+
}
|
|
24380
|
+
}
|
|
24381
|
+
}
|
|
24382
|
+
function discoverBackupSources(projectRoot, options = {}) {
|
|
24295
24383
|
const root = resolve6(projectRoot);
|
|
24296
24384
|
const stores = [];
|
|
24385
|
+
const files = [];
|
|
24297
24386
|
const hubPath = options.hubDataPath ? resolve6(options.hubDataPath) : join8(root, ".kxm", "state", "kxm.db");
|
|
24298
|
-
if (existsSync9(hubPath))
|
|
24299
|
-
stores.push({ storeId: "hub-store", sourcePath: hubPath, maxSupportedVersion: kxmBackupCeiling("hub-store") });
|
|
24300
|
-
}
|
|
24387
|
+
if (existsSync9(hubPath)) pushStore(stores, "hub-store", hubPath);
|
|
24301
24388
|
const registryPath = join8(root, ".kxm", "runtime", "registry.db");
|
|
24302
|
-
if (existsSync9(registryPath))
|
|
24303
|
-
stores.push({ storeId: "registry", sourcePath: registryPath, maxSupportedVersion: kxmBackupCeiling("registry") });
|
|
24304
|
-
}
|
|
24389
|
+
if (existsSync9(registryPath)) pushStore(stores, "registry", registryPath);
|
|
24305
24390
|
const bindingsPath = join8(root, ".kxm", "runtime", "bindings.db");
|
|
24306
|
-
if (existsSync9(bindingsPath))
|
|
24307
|
-
stores.push({ storeId: "binding-store", sourcePath: bindingsPath, maxSupportedVersion: kxmBackupCeiling("binding-store") });
|
|
24308
|
-
}
|
|
24391
|
+
if (existsSync9(bindingsPath)) pushStore(stores, "binding-store", bindingsPath);
|
|
24309
24392
|
const eventsDir = join8(root, ".kxm", "runtime", "events");
|
|
24310
24393
|
if (existsSync9(eventsDir)) {
|
|
24311
24394
|
const entries = readdirSync2(eventsDir, { withFileTypes: true });
|
|
24312
24395
|
for (const entry of entries) {
|
|
24313
24396
|
if (entry.isFile() && entry.name.endsWith(".db")) {
|
|
24314
|
-
const key = entry.name.replace(/\.db$/, "");
|
|
24315
|
-
stores.
|
|
24316
|
-
storeId: `events:${key}`,
|
|
24317
|
-
sourcePath: join8(eventsDir, entry.name),
|
|
24318
|
-
maxSupportedVersion: kxmBackupCeiling(`events:${key}`)
|
|
24319
|
-
});
|
|
24397
|
+
const key = entry.name.replace(/\.db$/, "").replace(/[^a-zA-Z0-9_.-]/g, "_");
|
|
24398
|
+
pushStore(stores, `events:${key}`, join8(eventsDir, entry.name));
|
|
24320
24399
|
}
|
|
24321
24400
|
}
|
|
24322
24401
|
}
|
|
24323
|
-
|
|
24402
|
+
discoverUserRuntime(options.env, stores, files);
|
|
24403
|
+
return { stores, files };
|
|
24404
|
+
}
|
|
24405
|
+
function backupPlainFile(sourcePath, targetPath, id) {
|
|
24406
|
+
const resolvedSource = resolve6(sourcePath);
|
|
24407
|
+
const sourceStat = lstatSync3(resolvedSource, { throwIfNoEntry: false });
|
|
24408
|
+
if (!sourceStat || !sourceStat.isFile() || sourceStat.isSymbolicLink()) {
|
|
24409
|
+
throw databaseError("runtime_path_invalid", resolvedSource, `backup file ${resolvedSource} must be a regular file, not a link or directory`);
|
|
24410
|
+
}
|
|
24411
|
+
checkedParent(targetPath, "backup target");
|
|
24412
|
+
if (existsSync9(targetPath)) unlinkSync2(targetPath);
|
|
24413
|
+
copyFileSync(resolvedSource, targetPath);
|
|
24414
|
+
try {
|
|
24415
|
+
chmodSync3(targetPath, 384);
|
|
24416
|
+
} catch {
|
|
24417
|
+
}
|
|
24418
|
+
return {
|
|
24419
|
+
id,
|
|
24420
|
+
sourcePath: resolvedSource,
|
|
24421
|
+
backupFile: basename3(targetPath),
|
|
24422
|
+
sha256: fileSha256(targetPath),
|
|
24423
|
+
bytes: sourceStat.size
|
|
24424
|
+
};
|
|
24425
|
+
}
|
|
24426
|
+
function backupFilename(sourcePath, id, used) {
|
|
24427
|
+
let filename = basename3(sourcePath);
|
|
24428
|
+
if (used.has(filename)) {
|
|
24429
|
+
filename = `${id.replace(/[^a-zA-Z0-9_.-]/g, "_")}-${filename}`;
|
|
24430
|
+
}
|
|
24431
|
+
used.add(filename);
|
|
24432
|
+
return filename;
|
|
24433
|
+
}
|
|
24434
|
+
function restorePlainFile(backupFilePath, targetPath) {
|
|
24435
|
+
checkedParent(targetPath, "restore target");
|
|
24436
|
+
if (existsSync9(targetPath)) unlinkSync2(targetPath);
|
|
24437
|
+
copyFileSync(backupFilePath, targetPath);
|
|
24438
|
+
try {
|
|
24439
|
+
chmodSync3(targetPath, 384);
|
|
24440
|
+
} catch {
|
|
24441
|
+
}
|
|
24442
|
+
}
|
|
24443
|
+
function backupDiscoverOptions(options) {
|
|
24444
|
+
return {
|
|
24445
|
+
...options.hubDataPath !== void 0 ? { hubDataPath: options.hubDataPath } : {},
|
|
24446
|
+
...options.env !== void 0 ? { env: options.env } : {}
|
|
24447
|
+
};
|
|
24324
24448
|
}
|
|
24325
24449
|
function planBackup(options = {}) {
|
|
24326
24450
|
const projectRoot = options.projectRoot ? resolve6(options.projectRoot) : process.cwd();
|
|
24327
|
-
const
|
|
24328
|
-
|
|
24329
|
-
});
|
|
24330
|
-
if (stores.length === 0) {
|
|
24451
|
+
const discovered = discoverBackupSources(projectRoot, backupDiscoverOptions(options));
|
|
24452
|
+
if (discovered.stores.length === 0) {
|
|
24331
24453
|
throw databaseError("backup_no_stores", projectRoot, "no existing SQLite stores found to backup");
|
|
24332
24454
|
}
|
|
24333
24455
|
const createdAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
24334
24456
|
const timestamp = createdAt.replace(/[:.]/g, "-");
|
|
24335
24457
|
const outDir = options.outDir ? resolve6(options.outDir) : join8(projectRoot, ".kxm", "backups", `backup-${timestamp}`);
|
|
24336
24458
|
const usedFilenames = /* @__PURE__ */ new Set();
|
|
24337
|
-
const
|
|
24338
|
-
|
|
24339
|
-
|
|
24340
|
-
|
|
24341
|
-
|
|
24342
|
-
|
|
24343
|
-
|
|
24344
|
-
|
|
24345
|
-
|
|
24346
|
-
|
|
24459
|
+
const stores = discovered.stores.map((store) => ({
|
|
24460
|
+
storeId: store.storeId,
|
|
24461
|
+
sourcePath: store.sourcePath,
|
|
24462
|
+
backupFile: backupFilename(store.sourcePath, store.storeId, usedFilenames)
|
|
24463
|
+
}));
|
|
24464
|
+
const files = discovered.files.map((file) => ({
|
|
24465
|
+
id: file.id,
|
|
24466
|
+
sourcePath: file.sourcePath,
|
|
24467
|
+
backupFile: backupFilename(file.sourcePath, file.id, usedFilenames)
|
|
24468
|
+
}));
|
|
24469
|
+
return { projectRoot, outDir, createdAt, stores, files };
|
|
24347
24470
|
}
|
|
24348
24471
|
function createBackup(options = {}) {
|
|
24349
|
-
const { projectRoot, outDir, createdAt, stores } = planBackup(options);
|
|
24472
|
+
const { projectRoot, outDir, createdAt, stores, files } = planBackup(options);
|
|
24350
24473
|
const backupId = `bk_${randomBytes(8).toString("hex")}`;
|
|
24351
24474
|
if (!existsSync9(outDir)) {
|
|
24352
24475
|
mkdirSync5(outDir, { recursive: true, mode: 448 });
|
|
24353
24476
|
}
|
|
24354
24477
|
const backedUpStores = [];
|
|
24478
|
+
const backedUpFiles = [];
|
|
24479
|
+
const omitted = [];
|
|
24355
24480
|
for (const store of stores) {
|
|
24356
|
-
|
|
24481
|
+
try {
|
|
24482
|
+
backedUpStores.push(backupDatabaseFile(store.sourcePath, join8(outDir, store.backupFile), store.storeId));
|
|
24483
|
+
} catch {
|
|
24484
|
+
omitted.push(store.storeId);
|
|
24485
|
+
}
|
|
24486
|
+
}
|
|
24487
|
+
for (const file of files) {
|
|
24488
|
+
try {
|
|
24489
|
+
backedUpFiles.push(backupPlainFile(file.sourcePath, join8(outDir, file.backupFile), file.id));
|
|
24490
|
+
} catch {
|
|
24491
|
+
omitted.push(file.id);
|
|
24492
|
+
}
|
|
24493
|
+
}
|
|
24494
|
+
if (backedUpStores.length === 0) {
|
|
24495
|
+
throw databaseError("backup_no_stores", projectRoot, "no SQLite store could be copied");
|
|
24496
|
+
}
|
|
24497
|
+
const again = discoverBackupSources(projectRoot, backupDiscoverOptions(options));
|
|
24498
|
+
for (const store of again.stores) {
|
|
24499
|
+
if (!backedUpStores.some((copied) => copied.storeId === store.storeId) && !omitted.includes(store.storeId)) {
|
|
24500
|
+
omitted.push(store.storeId);
|
|
24501
|
+
}
|
|
24502
|
+
}
|
|
24503
|
+
for (const file of again.files) {
|
|
24504
|
+
if (!backedUpFiles.some((copied) => copied.id === file.id) && !omitted.includes(file.id)) {
|
|
24505
|
+
omitted.push(file.id);
|
|
24506
|
+
}
|
|
24357
24507
|
}
|
|
24358
24508
|
const manifest = {
|
|
24359
24509
|
schema: "kxm.backup-manifest.v1",
|
|
24360
24510
|
backupId,
|
|
24361
24511
|
createdAt,
|
|
24362
24512
|
projectRoot,
|
|
24363
|
-
stores: backedUpStores
|
|
24513
|
+
stores: backedUpStores,
|
|
24514
|
+
...backedUpFiles.length > 0 ? { files: backedUpFiles } : {},
|
|
24515
|
+
complete: omitted.length === 0,
|
|
24516
|
+
...omitted.length > 0 ? { omitted } : {}
|
|
24364
24517
|
};
|
|
24365
24518
|
const manifestJson = JSON.stringify(manifest, null, 2) + "\n";
|
|
24366
24519
|
const manifestSha256 = `sha256:${createHash9("sha256").update(manifestJson, "utf8").digest("hex")}`;
|
|
@@ -24393,6 +24546,9 @@ function planRestore(manifestPathOrDir, options = {}) {
|
|
|
24393
24546
|
if (manifest.schema !== "kxm.backup-manifest.v1" || !Array.isArray(manifest.stores) || manifest.stores.length === 0) {
|
|
24394
24547
|
throw databaseError("restore_manifest_invalid", manifestPath, "manifest is not a valid kxm.backup-manifest.v1 document");
|
|
24395
24548
|
}
|
|
24549
|
+
if (manifest.complete === false) {
|
|
24550
|
+
throw databaseError("restore_incomplete", manifestPath, "backup manifest is incomplete; refusing to restore a partial copy");
|
|
24551
|
+
}
|
|
24396
24552
|
const stores = [];
|
|
24397
24553
|
for (const store of manifest.stores) {
|
|
24398
24554
|
const backupFilePath = join8(manifestDir, store.backupFile);
|
|
@@ -24422,7 +24578,28 @@ function planRestore(manifestPathOrDir, options = {}) {
|
|
|
24422
24578
|
}
|
|
24423
24579
|
stores.push({ storeId: store.storeId, backupFilePath, targetPath, schemaVersion: store.schemaVersion, maxSupportedVersion });
|
|
24424
24580
|
}
|
|
24425
|
-
|
|
24581
|
+
const files = [];
|
|
24582
|
+
for (const file of manifest.files ?? []) {
|
|
24583
|
+
const backupFilePath = join8(manifestDir, file.backupFile);
|
|
24584
|
+
if (!existsSync9(backupFilePath)) {
|
|
24585
|
+
throw databaseError("restore_file_missing", backupFilePath, `backup file ${file.backupFile} missing from ${manifestDir}`);
|
|
24586
|
+
}
|
|
24587
|
+
const actualSha256 = fileSha256(backupFilePath);
|
|
24588
|
+
if (actualSha256 !== file.sha256) {
|
|
24589
|
+
throw databaseError(
|
|
24590
|
+
"restore_manifest_digest_mismatch",
|
|
24591
|
+
backupFilePath,
|
|
24592
|
+
`backup file ${file.backupFile} sha256 ${actualSha256} does not match manifest hash ${file.sha256}`
|
|
24593
|
+
);
|
|
24594
|
+
}
|
|
24595
|
+
let targetPath = file.sourcePath;
|
|
24596
|
+
if (options.projectRoot && manifest.projectRoot && targetPath.startsWith(manifest.projectRoot)) {
|
|
24597
|
+
const rel = targetPath.slice(manifest.projectRoot.length).replace(/^[\\/]+/, "");
|
|
24598
|
+
targetPath = join8(resolve6(options.projectRoot), rel);
|
|
24599
|
+
}
|
|
24600
|
+
files.push({ id: file.id, backupFilePath, targetPath });
|
|
24601
|
+
}
|
|
24602
|
+
return { manifestPath, backupId: manifest.backupId, stores, files };
|
|
24426
24603
|
}
|
|
24427
24604
|
function restoreBackup(manifestPathOrDir, options = {}) {
|
|
24428
24605
|
const plan = planRestore(manifestPathOrDir, options);
|
|
@@ -24433,6 +24610,9 @@ function restoreBackup(manifestPathOrDir, options = {}) {
|
|
|
24433
24610
|
store.schemaVersion,
|
|
24434
24611
|
store.maxSupportedVersion
|
|
24435
24612
|
));
|
|
24613
|
+
for (const file of plan.files) {
|
|
24614
|
+
restorePlainFile(file.backupFilePath, file.targetPath);
|
|
24615
|
+
}
|
|
24436
24616
|
return {
|
|
24437
24617
|
manifestPath: plan.manifestPath,
|
|
24438
24618
|
backupId: plan.backupId,
|
|
@@ -25313,7 +25493,7 @@ var RECORD_LIMIT = 16 * 1024 * 1024;
|
|
|
25313
25493
|
// plugins/kxm/src/prices.ts
|
|
25314
25494
|
var import_yaml3 = __toESM(require_dist(), 1);
|
|
25315
25495
|
import { createHash as createHash11 } from "node:crypto";
|
|
25316
|
-
import { existsSync as existsSync11, readFileSync as readFileSync9, statSync } from "node:fs";
|
|
25496
|
+
import { existsSync as existsSync11, readFileSync as readFileSync9, statSync, writeFileSync as writeFileSync7 } from "node:fs";
|
|
25317
25497
|
import { join as join10 } from "node:path";
|
|
25318
25498
|
|
|
25319
25499
|
// plugins/kxm/src/price-calc.ts
|
|
@@ -25485,13 +25665,38 @@ function loadPriceCatalogForEstimate(options) {
|
|
|
25485
25665
|
}
|
|
25486
25666
|
return { catalog, unavailable: false, stale: false };
|
|
25487
25667
|
}
|
|
25668
|
+
function acknowledgePriceCatalog(projectRoot, now = /* @__PURE__ */ new Date()) {
|
|
25669
|
+
const path4 = join10(projectRoot, ".kxm", "prices.yaml");
|
|
25670
|
+
const loaded = loadPriceCatalog(projectRoot);
|
|
25671
|
+
if (!loaded) throw new Error("price catalog missing");
|
|
25672
|
+
const date = now.toISOString().slice(0, 10);
|
|
25673
|
+
const body = {
|
|
25674
|
+
schema: loaded.schema,
|
|
25675
|
+
date,
|
|
25676
|
+
currency: loaded.currency ?? "USD",
|
|
25677
|
+
models: loaded.models
|
|
25678
|
+
};
|
|
25679
|
+
const stamped = { ...body, sha256: hashPriceCatalog(body) };
|
|
25680
|
+
writeFileSync7(path4, (0, import_yaml3.stringify)({
|
|
25681
|
+
schema: stamped.schema,
|
|
25682
|
+
date: stamped.date,
|
|
25683
|
+
sha256: stamped.sha256,
|
|
25684
|
+
currency: stamped.currency ?? "USD",
|
|
25685
|
+
models: stamped.models
|
|
25686
|
+
}), "utf8");
|
|
25687
|
+
const again = loadPriceCatalog(projectRoot);
|
|
25688
|
+
if (!again || again.date !== date || again.sha256 !== stamped.sha256) {
|
|
25689
|
+
throw new Error("price catalog acknowledge failed verification");
|
|
25690
|
+
}
|
|
25691
|
+
return again;
|
|
25692
|
+
}
|
|
25488
25693
|
|
|
25489
25694
|
// plugins/kxm/src/engine.ts
|
|
25490
25695
|
var import_yaml7 = __toESM(require_dist(), 1);
|
|
25491
25696
|
|
|
25492
25697
|
// plugins/kxm/src/routes.ts
|
|
25493
25698
|
var import_yaml4 = __toESM(require_dist(), 1);
|
|
25494
|
-
import { existsSync as existsSync12, readFileSync as readFileSync10, mkdirSync as mkdirSync7, writeFileSync as
|
|
25699
|
+
import { existsSync as existsSync12, readFileSync as readFileSync10, mkdirSync as mkdirSync7, writeFileSync as writeFileSync8, readdirSync as readdirSync3 } from "node:fs";
|
|
25495
25700
|
import { join as join11 } from "node:path";
|
|
25496
25701
|
var RETIRED_POLICY = ".kxm/producers.yaml";
|
|
25497
25702
|
var empty = () => ({ schema: "kxm.routes.v2", updatedAt: (/* @__PURE__ */ new Date()).toISOString(), admitted: [], disabled: [], roles: {} });
|
|
@@ -25529,11 +25734,11 @@ function setRouteState(root, model, state, role, removeRole2 = false) {
|
|
|
25529
25734
|
roleFile.id ??= role;
|
|
25530
25735
|
roleFile.roster = roster;
|
|
25531
25736
|
mkdirSync7(join11(root, ".kxm", "roles"), { recursive: true });
|
|
25532
|
-
|
|
25737
|
+
writeFileSync8(rolePath, (0, import_yaml4.stringify)(roleFile), "utf8");
|
|
25533
25738
|
}
|
|
25534
25739
|
policy.updatedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
25535
25740
|
mkdirSync7(join11(root, ".kxm"), { recursive: true });
|
|
25536
|
-
|
|
25741
|
+
writeFileSync8(join11(root, ".kxm", "routes.yaml"), (0, import_yaml4.stringify)(policy), "utf8");
|
|
25537
25742
|
return policy;
|
|
25538
25743
|
}
|
|
25539
25744
|
function listRoleBindings(root) {
|
|
@@ -25557,7 +25762,7 @@ function listInventoryModels(root) {
|
|
|
25557
25762
|
// plugins/kxm/src/memory.ts
|
|
25558
25763
|
var import_yaml5 = __toESM(require_dist(), 1);
|
|
25559
25764
|
import { randomUUID as randomUUID5 } from "node:crypto";
|
|
25560
|
-
import { existsSync as existsSync13, mkdirSync as mkdirSync8, readdirSync as readdirSync4, readFileSync as readFileSync11, writeFileSync as
|
|
25765
|
+
import { existsSync as existsSync13, mkdirSync as mkdirSync8, readdirSync as readdirSync4, readFileSync as readFileSync11, writeFileSync as writeFileSync9 } from "node:fs";
|
|
25561
25766
|
import { extname as extname2, join as join12, resolve as resolve8 } from "node:path";
|
|
25562
25767
|
var MEMORY_SCHEMA = "kxm.memory.v1";
|
|
25563
25768
|
var MEMORY_BRIEF_SCHEMA = "kxm.memory-brief.v1";
|
|
@@ -25739,7 +25944,7 @@ function createMemoryNote(repoRoot, summary, options = {}) {
|
|
|
25739
25944
|
const targetPath = join12(candidatesDir, `${id}.md`);
|
|
25740
25945
|
if (options.dryRun) return { record, path: targetPath };
|
|
25741
25946
|
mkdirSync8(candidatesDir, { recursive: true });
|
|
25742
|
-
|
|
25947
|
+
writeFileSync9(targetPath, formatMemoryRecord(record), "utf8");
|
|
25743
25948
|
return { record, path: targetPath };
|
|
25744
25949
|
}
|
|
25745
25950
|
function generateMemoryBrief(repoRoot) {
|
|
@@ -25823,7 +26028,7 @@ function syncHarnessMemory(repoRoot, options = {}) {
|
|
|
25823
26028
|
if (next === original) {
|
|
25824
26029
|
unchanged.push(name);
|
|
25825
26030
|
} else {
|
|
25826
|
-
if (!options.dryRun)
|
|
26031
|
+
if (!options.dryRun) writeFileSync9(join12(root, name), next, "utf8");
|
|
25827
26032
|
updated.push(name);
|
|
25828
26033
|
}
|
|
25829
26034
|
}
|
|
@@ -25833,7 +26038,7 @@ function syncHarnessMemory(repoRoot, options = {}) {
|
|
|
25833
26038
|
// plugins/kxm/src/skills.ts
|
|
25834
26039
|
var import_yaml6 = __toESM(require_dist(), 1);
|
|
25835
26040
|
import { createHash as createHash12 } from "node:crypto";
|
|
25836
|
-
import { existsSync as existsSync14, mkdirSync as mkdirSync9, readdirSync as readdirSync5, readFileSync as readFileSync12, renameSync as renameSync3, rmSync as rmSync3, statSync as statSync2, writeFileSync as
|
|
26041
|
+
import { existsSync as existsSync14, mkdirSync as mkdirSync9, readdirSync as readdirSync5, readFileSync as readFileSync12, renameSync as renameSync3, rmSync as rmSync3, statSync as statSync2, writeFileSync as writeFileSync10 } from "node:fs";
|
|
25837
26042
|
import { dirname as dirname9, join as join13 } from "node:path";
|
|
25838
26043
|
var SKILL_CANDIDATE_SCHEMA = "kxm.skill-candidate.v1";
|
|
25839
26044
|
var SKILL_EVALUATION_SCHEMA = "kxm.skill-evaluation.v1";
|
|
@@ -25937,7 +26142,7 @@ var SkillLifecycle = class {
|
|
|
25937
26142
|
return;
|
|
25938
26143
|
}
|
|
25939
26144
|
mkdirSync9(dirname9(file), { recursive: true });
|
|
25940
|
-
|
|
26145
|
+
writeFileSync10(file, content);
|
|
25941
26146
|
}
|
|
25942
26147
|
dir(state) {
|
|
25943
26148
|
return join13(this.root, state === "candidate" ? "candidates" : `${state}s`.replace("rejecteds", "rejected").replace("promoteds", "promoted"));
|
|
@@ -26574,6 +26779,8 @@ function compareRoutingRecords(records) {
|
|
|
26574
26779
|
const blocked = settled.filter((record) => record.finalOutcome === "blocked").length;
|
|
26575
26780
|
const failed2 = settled.filter((record) => record.finalOutcome === "failed").length;
|
|
26576
26781
|
const reworked = records.filter((record) => record.retries > 0 || record.transitions > 0).length;
|
|
26782
|
+
const missingCostRuns = records.filter((record) => typeof record.costUsd !== "number" || !Number.isFinite(record.costUsd)).length;
|
|
26783
|
+
const summedCost = records.reduce((sum, record) => sum + (typeof record.costUsd === "number" && Number.isFinite(record.costUsd) ? record.costUsd : 0), 0);
|
|
26577
26784
|
return {
|
|
26578
26785
|
behavioralSha256,
|
|
26579
26786
|
runs: records.length,
|
|
@@ -26581,7 +26788,8 @@ function compareRoutingRecords(records) {
|
|
|
26581
26788
|
blocked,
|
|
26582
26789
|
failed: failed2,
|
|
26583
26790
|
reworkRate: records.length === 0 ? 0 : Math.round(reworked / records.length * 100) / 100,
|
|
26584
|
-
totalCostUsd:
|
|
26791
|
+
totalCostUsd: missingCostRuns > 0 ? null : Math.round(summedCost * 1e4) / 1e4,
|
|
26792
|
+
missingCostRuns,
|
|
26585
26793
|
totalTokensIn: records.reduce((sum, record) => sum + (record.tokensIn ?? 0), 0),
|
|
26586
26794
|
totalTokensOut: records.reduce((sum, record) => sum + (record.tokensOut ?? 0), 0),
|
|
26587
26795
|
totalHumanInterventions: records.reduce((sum, record) => sum + record.humanInterventions, 0)
|
|
@@ -26715,7 +26923,7 @@ function generateRoutingReport(records, options = {}) {
|
|
|
26715
26923
|
medianContextTokens = contextVals.length % 2 !== 0 ? contextVals[mid] : Math.round((contextVals[mid - 1] + contextVals[mid]) / 2);
|
|
26716
26924
|
}
|
|
26717
26925
|
const meteredCostUsd = Math.round(meteredCostTotal * 1e4) / 1e4;
|
|
26718
|
-
const costPerAcceptedUsd = acceptedCount > 0 ? meteredCostUsd > 0 || unmeteredAttempts > 0 ? Math.round(meteredCostUsd / acceptedCount * 1e4) / 1e4 :
|
|
26926
|
+
const costPerAcceptedUsd = acceptedCount > 0 ? unknownCostAttempts > 0 ? null : meteredCostUsd > 0 || unmeteredAttempts > 0 ? Math.round(meteredCostUsd / acceptedCount * 1e4) / 1e4 : 0 : null;
|
|
26719
26927
|
const flagged = unknownCostAttempts > 0;
|
|
26720
26928
|
let equivalentListCostUsd = void 0;
|
|
26721
26929
|
if (options.includeEquivalentListCost && options.catalog) {
|
|
@@ -26872,7 +27080,7 @@ var ENGINE_ROUTING_METADATA_KEYS = /* @__PURE__ */ new Set(["workflowId", "askSh
|
|
|
26872
27080
|
var MAX_PRODUCER_ROUTING_METADATA_FIELDS = MAX_PROVIDER_METADATA_FIELDS - ENGINE_ROUTING_METADATA_KEYS.size;
|
|
26873
27081
|
|
|
26874
27082
|
// plugins/kxm/src/hub-binding.ts
|
|
26875
|
-
import { existsSync as existsSync15, mkdirSync as mkdirSync10, readFileSync as readFileSync13, renameSync as renameSync4, rmSync as rmSync4, writeFileSync as
|
|
27083
|
+
import { existsSync as existsSync15, mkdirSync as mkdirSync10, readFileSync as readFileSync13, renameSync as renameSync4, rmSync as rmSync4, writeFileSync as writeFileSync11 } from "node:fs";
|
|
26876
27084
|
import { homedir as homedir4 } from "node:os";
|
|
26877
27085
|
import { dirname as dirname10, isAbsolute as isAbsolute5, join as join14, resolve as resolve10 } from "node:path";
|
|
26878
27086
|
var HUB_BINDING_SCHEMA = "kxm.hub-binding.v1";
|
|
@@ -26964,7 +27172,7 @@ function writeHubBinding(record, env = process.env) {
|
|
|
26964
27172
|
mkdirSync10(dirname10(file), { recursive: true, mode: 448 });
|
|
26965
27173
|
const temporary = join14(dirname10(file), `.hub-binding-${process.pid}.tmp`);
|
|
26966
27174
|
try {
|
|
26967
|
-
|
|
27175
|
+
writeFileSync11(temporary, `${JSON.stringify(record, null, 2)}
|
|
26968
27176
|
`, { encoding: "utf8", mode: 384 });
|
|
26969
27177
|
renameSync4(temporary, file);
|
|
26970
27178
|
} finally {
|
|
@@ -27478,12 +27686,12 @@ import { createInterface } from "node:readline";
|
|
|
27478
27686
|
|
|
27479
27687
|
// plugins/kxm/src/role.ts
|
|
27480
27688
|
var import_yaml9 = __toESM(require_dist(), 1);
|
|
27481
|
-
import { existsSync as existsSync18, mkdirSync as mkdirSync14, readdirSync as readdirSync6, readFileSync as readFileSync17, rmSync as rmSync6, writeFileSync as
|
|
27689
|
+
import { existsSync as existsSync18, mkdirSync as mkdirSync14, readdirSync as readdirSync6, readFileSync as readFileSync17, rmSync as rmSync6, writeFileSync as writeFileSync14 } from "node:fs";
|
|
27482
27690
|
import { join as join19 } from "node:path";
|
|
27483
27691
|
|
|
27484
27692
|
// plugins/kxm/src/config.ts
|
|
27485
27693
|
var import_yaml8 = __toESM(require_dist(), 1);
|
|
27486
|
-
import { existsSync as existsSync17, mkdirSync as mkdirSync13, readFileSync as readFileSync16, writeFileSync as
|
|
27694
|
+
import { existsSync as existsSync17, mkdirSync as mkdirSync13, readFileSync as readFileSync16, writeFileSync as writeFileSync13 } from "node:fs";
|
|
27487
27695
|
import { homedir as homedir5 } from "node:os";
|
|
27488
27696
|
import { dirname as dirname13, join as join18, resolve as resolve12 } from "node:path";
|
|
27489
27697
|
var KXM_CONFIG_SCHEMA = "kxm.config.v1";
|
|
@@ -27663,7 +27871,7 @@ function readConfigFile(targetFile2) {
|
|
|
27663
27871
|
}
|
|
27664
27872
|
function writeConfigFile(targetFile2, value) {
|
|
27665
27873
|
mkdirSync13(dirname13(targetFile2), { recursive: true });
|
|
27666
|
-
|
|
27874
|
+
writeFileSync13(targetFile2, (0, import_yaml8.stringify)(value).trim() + "\n", "utf8");
|
|
27667
27875
|
}
|
|
27668
27876
|
function setKxmConfigValue(repoRoot, keyPath, value, options = {}) {
|
|
27669
27877
|
const targetFile2 = kxmConfigFileForScope(repoRoot, options.scope ?? "project", options.userConfigDir);
|
|
@@ -27896,7 +28104,7 @@ function addRole(role, options = {}) {
|
|
|
27896
28104
|
if (existsSync18(filePath) && !options.overwrite) {
|
|
27897
28105
|
throw new Error(`role_already_exists: role '${role.id}' already exists at ${filePath}`);
|
|
27898
28106
|
}
|
|
27899
|
-
if (!options.dryRun)
|
|
28107
|
+
if (!options.dryRun) writeFileSync14(filePath, (0, import_yaml9.stringify)(role), "utf8");
|
|
27900
28108
|
return { id: role.id, filePath, scope };
|
|
27901
28109
|
}
|
|
27902
28110
|
function removeRole(roleId, options = {}) {
|
|
@@ -27927,7 +28135,7 @@ function modifyRole(roleId, updates, options = {}) {
|
|
|
27927
28135
|
const repoRoot = options.repoRoot ?? process.cwd();
|
|
27928
28136
|
const dir = options.dryRun ? rolesDirectory(scope, repoRoot, options.userConfigDir) : ensureRolesDirectory(scope, repoRoot, options.userConfigDir);
|
|
27929
28137
|
const filePath = join19(dir, `${roleId}.yaml`);
|
|
27930
|
-
if (!options.dryRun)
|
|
28138
|
+
if (!options.dryRun) writeFileSync14(filePath, (0, import_yaml9.stringify)(updated), "utf8");
|
|
27931
28139
|
return { id: roleId, role: updated, filePath, scope };
|
|
27932
28140
|
}
|
|
27933
28141
|
var KXM_ROLE_HOSTS_SCHEMA = "kxm.role-hosts.v1";
|
|
@@ -28070,7 +28278,7 @@ function saveRoleHostsConfig(config, options = {}) {
|
|
|
28070
28278
|
...config.hostProviders && Object.keys(config.hostProviders).length > 0 ? { hostProviders: config.hostProviders } : {}
|
|
28071
28279
|
};
|
|
28072
28280
|
const content = format === "json" ? JSON.stringify(payload, null, 2) + "\n" : (0, import_yaml9.stringify)(payload);
|
|
28073
|
-
|
|
28281
|
+
writeFileSync14(filePath, content, "utf8");
|
|
28074
28282
|
return { filePath, scope };
|
|
28075
28283
|
}
|
|
28076
28284
|
function setRoleSeatHost(seatId, host, options = {}) {
|
|
@@ -28716,7 +28924,7 @@ import { existsSync as existsSync21, readFileSync as readFileSync20 } from "node
|
|
|
28716
28924
|
import { join as join22, resolve as resolve17 } from "node:path";
|
|
28717
28925
|
|
|
28718
28926
|
// plugins/kxm/src/retrospective.ts
|
|
28719
|
-
import { mkdirSync as mkdirSync15, renameSync as renameSync6, writeFileSync as
|
|
28927
|
+
import { mkdirSync as mkdirSync15, renameSync as renameSync6, writeFileSync as writeFileSync15 } from "node:fs";
|
|
28720
28928
|
import { resolve as resolve15 } from "node:path";
|
|
28721
28929
|
var MAX_RETROSPECTIVE_ENTRIES = 500;
|
|
28722
28930
|
var SAFE_RUN_ID = /^run_[A-Za-z0-9_-]{1,120}$/;
|
|
@@ -28943,9 +29151,9 @@ function writeRetrospective(outDir, doc) {
|
|
|
28943
29151
|
if (!jsonPath.startsWith(prefix) || !mdPath.startsWith(prefix)) throw new Error("retrospective path escaped output directory");
|
|
28944
29152
|
const jsonTmp = `${jsonPath}.tmp`;
|
|
28945
29153
|
const mdTmp = `${mdPath}.tmp`;
|
|
28946
|
-
|
|
29154
|
+
writeFileSync15(jsonTmp, `${JSON.stringify(doc, null, 2)}
|
|
28947
29155
|
`, { encoding: "utf8", mode: 384 });
|
|
28948
|
-
|
|
29156
|
+
writeFileSync15(mdTmp, renderRetrospectiveMarkdown(doc), { encoding: "utf8", mode: 384 });
|
|
28949
29157
|
renameSync6(jsonTmp, jsonPath);
|
|
28950
29158
|
renameSync6(mdTmp, mdPath);
|
|
28951
29159
|
return { jsonPath, mdPath };
|
|
@@ -29140,7 +29348,7 @@ async function watchGithubChecks(input) {
|
|
|
29140
29348
|
|
|
29141
29349
|
// plugins/kxm/src/workflow-manager.ts
|
|
29142
29350
|
var import_yaml11 = __toESM(require_dist(), 1);
|
|
29143
|
-
import { existsSync as existsSync20, mkdirSync as mkdirSync16, readdirSync as readdirSync7, readFileSync as readFileSync19, rmSync as rmSync7, writeFileSync as
|
|
29351
|
+
import { existsSync as existsSync20, mkdirSync as mkdirSync16, readdirSync as readdirSync7, readFileSync as readFileSync19, rmSync as rmSync7, writeFileSync as writeFileSync16 } from "node:fs";
|
|
29144
29352
|
import { join as join21 } from "node:path";
|
|
29145
29353
|
var completed = () => ({ target: "$terminal", terminalStatus: "completed" });
|
|
29146
29354
|
var failed = () => ({ target: "$terminal", terminalStatus: "failed" });
|
|
@@ -29399,7 +29607,7 @@ function addWorkflowDefinition(workflowId, content = DEFAULT_WORKFLOW_TEMPLATE,
|
|
|
29399
29607
|
throw new Error(`workflow_already_exists: workflow '${workflowId}' already exists at ${filePath}`);
|
|
29400
29608
|
}
|
|
29401
29609
|
const payload = typeof content === "string" ? content : (0, import_yaml11.stringify)(content);
|
|
29402
|
-
if (!options.dryRun)
|
|
29610
|
+
if (!options.dryRun) writeFileSync16(filePath, payload, "utf8");
|
|
29403
29611
|
return { id: workflowId, filePath, scope };
|
|
29404
29612
|
}
|
|
29405
29613
|
function removeWorkflowDefinition(workflowId, options = {}) {
|
|
@@ -29427,7 +29635,7 @@ function modifyWorkflowDefinition(workflowId, updates, options = {}) {
|
|
|
29427
29635
|
const repoRoot = options.repoRoot ?? process.cwd();
|
|
29428
29636
|
const dir = options.dryRun ? workflowsDirectory(scope, repoRoot, options.userConfigDir) : ensureWorkflowsDirectory(scope, repoRoot, options.userConfigDir);
|
|
29429
29637
|
const filePath = join21(dir, `${workflowId}.yaml`);
|
|
29430
|
-
if (!options.dryRun)
|
|
29638
|
+
if (!options.dryRun) writeFileSync16(filePath, (0, import_yaml11.stringify)(updated), "utf8");
|
|
29431
29639
|
return { id: workflowId, workflow: updated, filePath, scope };
|
|
29432
29640
|
}
|
|
29433
29641
|
|
|
@@ -30154,7 +30362,7 @@ function suggestWorkflowAndRoles(prompt, options = {}) {
|
|
|
30154
30362
|
// plugins/kxm/src/task-manager.ts
|
|
30155
30363
|
var import_yaml12 = __toESM(require_dist(), 1);
|
|
30156
30364
|
import { randomUUID as randomUUID9 } from "node:crypto";
|
|
30157
|
-
import { existsSync as existsSync22, mkdirSync as mkdirSync17, readFileSync as readFileSync21, readdirSync as readdirSync8, writeFileSync as
|
|
30365
|
+
import { existsSync as existsSync22, mkdirSync as mkdirSync17, readFileSync as readFileSync21, readdirSync as readdirSync8, writeFileSync as writeFileSync17 } from "node:fs";
|
|
30158
30366
|
import { join as join23, resolve as resolve18 } from "node:path";
|
|
30159
30367
|
var GOAL_SCHEMA = "kxm.goal.v1";
|
|
30160
30368
|
var TASK_SCHEMA = "kxm.task.v1";
|
|
@@ -30186,7 +30394,7 @@ function createGoal(repoRoot, input, options = {}) {
|
|
|
30186
30394
|
};
|
|
30187
30395
|
if (options.dryRun) return record;
|
|
30188
30396
|
mkdirSync17(goalsDirectory(repoRoot), { recursive: true });
|
|
30189
|
-
|
|
30397
|
+
writeFileSync17(goalFilePath(repoRoot, id), (0, import_yaml12.stringify)(record).trim() + "\n", "utf8");
|
|
30190
30398
|
return record;
|
|
30191
30399
|
}
|
|
30192
30400
|
function listGoals(repoRoot) {
|
|
@@ -30230,7 +30438,7 @@ function createTask(repoRoot, input, options = {}) {
|
|
|
30230
30438
|
};
|
|
30231
30439
|
if (options.dryRun) return record;
|
|
30232
30440
|
mkdirSync17(tasksDirectory(repoRoot), { recursive: true });
|
|
30233
|
-
|
|
30441
|
+
writeFileSync17(taskFilePath(repoRoot, id), (0, import_yaml12.stringify)(record).trim() + "\n", "utf8");
|
|
30234
30442
|
return record;
|
|
30235
30443
|
}
|
|
30236
30444
|
function listTasks(repoRoot, options = {}) {
|
|
@@ -30274,7 +30482,7 @@ function updateTaskStatus(repoRoot, taskId, status, options = {}) {
|
|
|
30274
30482
|
task.status = status;
|
|
30275
30483
|
if (options.workflowRunId) task.workflowRunId = options.workflowRunId;
|
|
30276
30484
|
task.updatedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
30277
|
-
if (!options.dryRun)
|
|
30485
|
+
if (!options.dryRun) writeFileSync17(taskFilePath(repoRoot, taskId), (0, import_yaml12.stringify)(task).trim() + "\n", "utf8");
|
|
30278
30486
|
return task;
|
|
30279
30487
|
}
|
|
30280
30488
|
function syncTaskWithTracker(repoRoot, taskId, options = {}) {
|
|
@@ -30289,7 +30497,7 @@ function syncTaskWithTracker(repoRoot, taskId, options = {}) {
|
|
|
30289
30497
|
task.trackerSync.syncStatus = "synced";
|
|
30290
30498
|
task.trackerSync.lastSyncedAt = now;
|
|
30291
30499
|
task.updatedAt = now;
|
|
30292
|
-
if (!options.dryRun)
|
|
30500
|
+
if (!options.dryRun) writeFileSync17(taskFilePath(repoRoot, taskId), (0, import_yaml12.stringify)(task).trim() + "\n", "utf8");
|
|
30293
30501
|
return task;
|
|
30294
30502
|
}
|
|
30295
30503
|
|
|
@@ -30570,13 +30778,14 @@ function createStudioServer(options = {}) {
|
|
|
30570
30778
|
}
|
|
30571
30779
|
return;
|
|
30572
30780
|
}
|
|
30573
|
-
res.writeHead(
|
|
30781
|
+
res.writeHead(501, { "Content-Type": "application/json" });
|
|
30574
30782
|
res.end(JSON.stringify({
|
|
30575
|
-
ok:
|
|
30783
|
+
ok: false,
|
|
30784
|
+
executed: false,
|
|
30576
30785
|
mutationId,
|
|
30577
30786
|
command,
|
|
30578
|
-
mappedToCli:
|
|
30579
|
-
|
|
30787
|
+
mappedToCli: false,
|
|
30788
|
+
error: "mutation_handler_missing"
|
|
30580
30789
|
}));
|
|
30581
30790
|
return;
|
|
30582
30791
|
}
|
|
@@ -31061,7 +31270,7 @@ import { createInterface as createInterface2 } from "node:readline";
|
|
|
31061
31270
|
|
|
31062
31271
|
// plugins/kxm/src/model-inventory.ts
|
|
31063
31272
|
var import_yaml13 = __toESM(require_dist(), 1);
|
|
31064
|
-
import { mkdirSync as mkdirSync18, writeFileSync as
|
|
31273
|
+
import { mkdirSync as mkdirSync18, writeFileSync as writeFileSync18 } from "node:fs";
|
|
31065
31274
|
import { join as join24 } from "node:path";
|
|
31066
31275
|
var OR_URL = "https://openrouter.ai/api/v1/models";
|
|
31067
31276
|
var NOUS_URL = "https://inference-api.nousresearch.com/v1/models";
|
|
@@ -31149,7 +31358,7 @@ async function refreshModelInventory(options) {
|
|
|
31149
31358
|
for (const item of nous.data) add(item, "nous", "discount");
|
|
31150
31359
|
const inventory = { schema: "kxm.model-inventory.v1", fetchedAt, currency: "USD", sources, models: [...byId.values()].sort((a, b2) => a.id.localeCompare(b2.id)) };
|
|
31151
31360
|
mkdirSync18(join24(options.outputRoot, ".kxm", "models"), { recursive: true });
|
|
31152
|
-
|
|
31361
|
+
writeFileSync18(join24(options.outputRoot, ".kxm", "models", "inventory.yaml"), (0, import_yaml13.stringify)(inventory), "utf8");
|
|
31153
31362
|
return inventory;
|
|
31154
31363
|
}
|
|
31155
31364
|
|
|
@@ -31173,14 +31382,14 @@ import {
|
|
|
31173
31382
|
readdirSync as readdirSync9,
|
|
31174
31383
|
renameSync as renameSync7,
|
|
31175
31384
|
rmSync as rmSync9,
|
|
31176
|
-
writeFileSync as
|
|
31385
|
+
writeFileSync as writeFileSync20
|
|
31177
31386
|
} from "node:fs";
|
|
31178
31387
|
import { dirname as dirname17, isAbsolute as isAbsolute7, join as join26, relative as relative4, resolve as resolve20 } from "node:path";
|
|
31179
31388
|
|
|
31180
31389
|
// plugins/kxm/src/permission.ts
|
|
31181
31390
|
import { spawnSync as spawnSync4 } from "node:child_process";
|
|
31182
31391
|
import { createHash as createHash14 } from "node:crypto";
|
|
31183
|
-
import { existsSync as existsSync23, mkdtempSync, mkdirSync as mkdirSync19, readFileSync as readFileSync22, rmSync as rmSync8, writeFileSync as
|
|
31392
|
+
import { existsSync as existsSync23, mkdtempSync, mkdirSync as mkdirSync19, readFileSync as readFileSync22, rmSync as rmSync8, writeFileSync as writeFileSync19 } from "node:fs";
|
|
31184
31393
|
import { tmpdir } from "node:os";
|
|
31185
31394
|
import { dirname as dirname16, join as join25, resolve as resolve19, sep as sep3 } from "node:path";
|
|
31186
31395
|
var PROSE_FIELDS = {
|
|
@@ -31729,7 +31938,7 @@ function loadKxmProjectAtRevision(root, revision, options = {}) {
|
|
|
31729
31938
|
}
|
|
31730
31939
|
const content = gitBuffer(root, ["cat-file", "blob", `${tree}:${path4}`]);
|
|
31731
31940
|
mkdirSync19(dirname16(absolute), { recursive: true });
|
|
31732
|
-
|
|
31941
|
+
writeFileSync19(absolute, content);
|
|
31733
31942
|
}
|
|
31734
31943
|
initShadowGitRoot(shadowResolved);
|
|
31735
31944
|
const baseProjectFile = join25(shadowResolved, ".kxm", "project.yaml");
|
|
@@ -31831,7 +32040,7 @@ function loadKxmProjectAtRevision(root, revision, options = {}) {
|
|
|
31831
32040
|
}
|
|
31832
32041
|
const content = gitBuffer(memberWorktree, ["cat-file", "blob", `${memberTree}:${path4}`]);
|
|
31833
32042
|
mkdirSync19(dirname16(absolute), { recursive: true });
|
|
31834
|
-
|
|
32043
|
+
writeFileSync19(absolute, content);
|
|
31835
32044
|
}
|
|
31836
32045
|
initShadowGitRoot(memberShadowRoot);
|
|
31837
32046
|
shadowBindings[member.repositoryId] = memberShadowRoot;
|
|
@@ -31945,7 +32154,7 @@ function writeDurableNew(file, bytes, mode) {
|
|
|
31945
32154
|
let descriptor;
|
|
31946
32155
|
try {
|
|
31947
32156
|
descriptor = openSync2(file, "wx", mode);
|
|
31948
|
-
|
|
32157
|
+
writeFileSync20(descriptor, bytes);
|
|
31949
32158
|
fsyncSync2(descriptor);
|
|
31950
32159
|
closeSync2(descriptor);
|
|
31951
32160
|
descriptor = void 0;
|
|
@@ -31962,7 +32171,7 @@ function writeDurable(file, bytes, mode) {
|
|
|
31962
32171
|
let descriptor;
|
|
31963
32172
|
try {
|
|
31964
32173
|
descriptor = openSync2(file, "w", mode);
|
|
31965
|
-
|
|
32174
|
+
writeFileSync20(descriptor, bytes);
|
|
31966
32175
|
fsyncSync2(descriptor);
|
|
31967
32176
|
closeSync2(descriptor);
|
|
31968
32177
|
descriptor = void 0;
|
|
@@ -33386,36 +33595,39 @@ async function cmdBackup(runtime, options) {
|
|
|
33386
33595
|
try {
|
|
33387
33596
|
const backupOptions = {
|
|
33388
33597
|
projectRoot: runtime.cwd,
|
|
33598
|
+
env: runtime.env,
|
|
33389
33599
|
...options.out ? { outDir: resolve21(runtime.cwd, options.out) } : {}
|
|
33390
33600
|
};
|
|
33391
33601
|
if (runtime.dryRun) {
|
|
33392
33602
|
const plan = planBackup(backupOptions);
|
|
33393
33603
|
printPlan(
|
|
33394
33604
|
runtime,
|
|
33395
|
-
{ command: "backup", outDir: plan.outDir, stores: plan.stores },
|
|
33605
|
+
{ command: "backup", outDir: plan.outDir, stores: plan.stores, files: plan.files },
|
|
33396
33606
|
[
|
|
33397
|
-
...plan.stores.map((
|
|
33607
|
+
...[...plan.stores, ...plan.files].map((entry) => ({ action: "write", target: join28(plan.outDir, entry.backupFile) })),
|
|
33398
33608
|
{ action: "write", target: join28(plan.outDir, "manifest.json") }
|
|
33399
33609
|
],
|
|
33400
|
-
`back up ${plan.stores.length} store(s) to ${plan.outDir} (sources are not opened, so their WAL is not checkpointed)`
|
|
33610
|
+
`back up ${plan.stores.length} store(s) and ${plan.files.length} file(s) to ${plan.outDir} (sources are not opened, so their WAL is not checkpointed)`
|
|
33401
33611
|
);
|
|
33402
33612
|
return 0;
|
|
33403
33613
|
}
|
|
33404
33614
|
const { manifest, outDir } = createBackup(backupOptions);
|
|
33615
|
+
const complete = manifest.complete === true;
|
|
33405
33616
|
const payload = {
|
|
33406
|
-
ok:
|
|
33617
|
+
ok: complete,
|
|
33407
33618
|
command: "backup",
|
|
33408
33619
|
backupId: manifest.backupId,
|
|
33409
33620
|
outDir,
|
|
33410
33621
|
manifest
|
|
33411
33622
|
};
|
|
33412
33623
|
const summary = [
|
|
33413
|
-
`Created SQLite backup with ${manifest.stores.length} store(s):`,
|
|
33624
|
+
complete ? `Created SQLite backup with ${manifest.stores.length} store(s):` : `Backup is incomplete (${manifest.omitted?.length ?? 0} omitted); not ok:`,
|
|
33414
33625
|
...manifest.stores.map((s) => ` - ${s.storeId}: ${s.sourcePath} -> ${s.backupFile} (schema v${s.schemaVersion}, ${s.bytes} bytes, sha256 ${s.sha256.slice(0, 12)}...)`),
|
|
33626
|
+
...(manifest.omitted ?? []).map((id) => ` - omitted ${id}`),
|
|
33415
33627
|
`Manifest: ${join28(outDir, "manifest.json")}`
|
|
33416
33628
|
].join("\n");
|
|
33417
33629
|
print(runtime.io, runtime.json, payload, summary);
|
|
33418
|
-
return 0;
|
|
33630
|
+
return complete ? 0 : 1;
|
|
33419
33631
|
} catch (error) {
|
|
33420
33632
|
if (error instanceof KxmConfigError) {
|
|
33421
33633
|
print(runtime.io, runtime.json, { ok: false, command: "backup", error: "backup_failed", issues: error.issues }, `backup failed: ${error.message}`);
|
|
@@ -33435,13 +33647,17 @@ async function cmdRestore(runtime, manifestArg) {
|
|
|
33435
33647
|
command: "restore",
|
|
33436
33648
|
backupId: plan.backupId,
|
|
33437
33649
|
manifestPath: plan.manifestPath,
|
|
33438
|
-
stores: plan.stores.map(({ storeId, targetPath, schemaVersion }) => ({ storeId, targetPath, schemaVersion }))
|
|
33650
|
+
stores: plan.stores.map(({ storeId, targetPath, schemaVersion }) => ({ storeId, targetPath, schemaVersion })),
|
|
33651
|
+
files: plan.files.map(({ id, targetPath }) => ({ id, targetPath }))
|
|
33439
33652
|
},
|
|
33440
|
-
|
|
33441
|
-
|
|
33442
|
-
|
|
33443
|
-
|
|
33444
|
-
|
|
33653
|
+
[
|
|
33654
|
+
...plan.stores.flatMap((store) => [
|
|
33655
|
+
{ action: "write", target: store.targetPath },
|
|
33656
|
+
...[`${store.targetPath}-wal`, `${store.targetPath}-shm`].filter((file) => existsSync26(file)).map((file) => ({ action: "delete", target: file }))
|
|
33657
|
+
]),
|
|
33658
|
+
...plan.files.map((file) => ({ action: "write", target: file.targetPath }))
|
|
33659
|
+
],
|
|
33660
|
+
`restore ${plan.stores.length} store(s) and ${plan.files.length} file(s) from ${plan.manifestPath}; digests verified against the manifest`
|
|
33445
33661
|
);
|
|
33446
33662
|
return 0;
|
|
33447
33663
|
}
|
|
@@ -34418,14 +34634,14 @@ import { readFileSync as readFileSync26 } from "node:fs";
|
|
|
34418
34634
|
import { join as join31, relative as relative5, resolve as resolve23 } from "node:path";
|
|
34419
34635
|
|
|
34420
34636
|
// plugins/kxm/src/wiki.ts
|
|
34421
|
-
import { mkdirSync as mkdirSync22, writeFileSync as
|
|
34637
|
+
import { mkdirSync as mkdirSync22, writeFileSync as writeFileSync21 } from "node:fs";
|
|
34422
34638
|
import { join as join30 } from "node:path";
|
|
34423
34639
|
function writeCompiledWiki(root, wiki) {
|
|
34424
34640
|
const written = [];
|
|
34425
34641
|
for (const [relativePath, content] of [...wiki.pages].sort(([left], [right]) => left.localeCompare(right))) {
|
|
34426
34642
|
const absolute = join30(root, relativePath);
|
|
34427
34643
|
mkdirSync22(absolute.slice(0, absolute.lastIndexOf("/")), { recursive: true });
|
|
34428
|
-
|
|
34644
|
+
writeFileSync21(absolute, content);
|
|
34429
34645
|
written.push(relativePath);
|
|
34430
34646
|
}
|
|
34431
34647
|
return written;
|
|
@@ -34817,7 +35033,7 @@ ${lines.join("\n")}`
|
|
|
34817
35033
|
|
|
34818
35034
|
// plugins/kxm/src/cli/hub.ts
|
|
34819
35035
|
import { randomUUID as randomUUID14 } from "node:crypto";
|
|
34820
|
-
import { existsSync as existsSync33, mkdirSync as mkdirSync26, readFileSync as readFileSync32, readdirSync as readdirSync12, rmSync as rmSync11, writeFileSync as
|
|
35036
|
+
import { existsSync as existsSync33, mkdirSync as mkdirSync26, readFileSync as readFileSync32, readdirSync as readdirSync12, rmSync as rmSync11, writeFileSync as writeFileSync24 } from "node:fs";
|
|
34821
35037
|
import { join as join41, resolve as resolve26 } from "node:path";
|
|
34822
35038
|
|
|
34823
35039
|
// node_modules/marked/lib/marked.esm.js
|
|
@@ -44578,7 +44794,7 @@ async function runMeshTui(input) {
|
|
|
44578
44794
|
// plugins/kxm/src/session-work.ts
|
|
44579
44795
|
import { spawnSync as spawnSync6 } from "node:child_process";
|
|
44580
44796
|
import { randomUUID as randomUUID13 } from "node:crypto";
|
|
44581
|
-
import { existsSync as existsSync29, mkdirSync as mkdirSync24, readFileSync as readFileSync28, renameSync as renameSync8, writeFileSync as
|
|
44797
|
+
import { existsSync as existsSync29, mkdirSync as mkdirSync24, readFileSync as readFileSync28, renameSync as renameSync8, writeFileSync as writeFileSync22 } from "node:fs";
|
|
44582
44798
|
import { join as join37 } from "node:path";
|
|
44583
44799
|
var MAX_SESSION_BRIEF_TASKS = 5;
|
|
44584
44800
|
var MAX_SESSION_BRIEF_PLANS = 5;
|
|
@@ -44757,7 +44973,7 @@ function writeCachedSessionBrief(stateDir, brief) {
|
|
|
44757
44973
|
mkdirSync24(stateDir, { recursive: true, mode: 448 });
|
|
44758
44974
|
const file = join37(stateDir, "session-brief.json");
|
|
44759
44975
|
const tmp = `${file}.tmp.${randomUUID13().slice(0, 8)}`;
|
|
44760
|
-
|
|
44976
|
+
writeFileSync22(tmp, JSON.stringify(brief, null, 2), { encoding: "utf8", mode: 384 });
|
|
44761
44977
|
renameSync8(tmp, file);
|
|
44762
44978
|
} catch {
|
|
44763
44979
|
}
|
|
@@ -45045,7 +45261,7 @@ function loadKxmUpdateConfig(env = process.env) {
|
|
|
45045
45261
|
}
|
|
45046
45262
|
|
|
45047
45263
|
// plugins/kxm/src/session.ts
|
|
45048
|
-
import { existsSync as existsSync32, mkdirSync as mkdirSync25, readFileSync as readFileSync31, writeFileSync as
|
|
45264
|
+
import { existsSync as existsSync32, mkdirSync as mkdirSync25, readFileSync as readFileSync31, writeFileSync as writeFileSync23 } from "node:fs";
|
|
45049
45265
|
import { join as join40 } from "node:path";
|
|
45050
45266
|
var SESSION_SCHEMA = "kxm.session.v1";
|
|
45051
45267
|
var SessionConfigError = class extends Error {
|
|
@@ -45170,7 +45386,7 @@ function writeSession(assetsDir, session, dryRun = false) {
|
|
|
45170
45386
|
const path4 = join40(dir, "session.json");
|
|
45171
45387
|
if (!dryRun) {
|
|
45172
45388
|
mkdirSync25(dir, { recursive: true });
|
|
45173
|
-
|
|
45389
|
+
writeFileSync23(path4, `${JSON.stringify(session, null, 2)}
|
|
45174
45390
|
`, { encoding: "utf8" });
|
|
45175
45391
|
}
|
|
45176
45392
|
return path4;
|
|
@@ -45539,7 +45755,7 @@ async function cmdStop(runtime, waitMsFlag) {
|
|
|
45539
45755
|
ignored.push(file);
|
|
45540
45756
|
continue;
|
|
45541
45757
|
}
|
|
45542
|
-
|
|
45758
|
+
writeFileSync24(join41(runtime.dirs.state, record.controlFile), `${JSON.stringify({ startedAt: record.startedAt, ...record.generation ? { generation: record.generation } : {}, requestedAt: (/* @__PURE__ */ new Date()).toISOString() })}
|
|
45543
45759
|
`, { encoding: "utf8", mode: 384 });
|
|
45544
45760
|
requested.push(file);
|
|
45545
45761
|
records.set(file, { pid: record.pid, startedAt: record.startedAt, ...record.generation ? { generation: record.generation } : {} });
|
|
@@ -45839,7 +46055,7 @@ import { createInterface as createInterface3 } from "node:readline";
|
|
|
45839
46055
|
|
|
45840
46056
|
// plugins/kxm/src/improve.ts
|
|
45841
46057
|
import { createHash as createHash15 } from "node:crypto";
|
|
45842
|
-
import { existsSync as existsSync34, mkdirSync as mkdirSync27, writeFileSync as
|
|
46058
|
+
import { existsSync as existsSync34, mkdirSync as mkdirSync27, writeFileSync as writeFileSync25 } from "node:fs";
|
|
45843
46059
|
import { join as join42, relative as relative6, resolve as resolve27 } from "node:path";
|
|
45844
46060
|
var CANDIDATE_SCHEMA = "kxm.candidate.v1";
|
|
45845
46061
|
var IMPROVEMENT_REPORT_SCHEMA = "kxm.improvement-report.v2";
|
|
@@ -46135,9 +46351,9 @@ function buildImprovementReport(records, options = {}) {
|
|
|
46135
46351
|
if (!existsSync34(candidatesDir)) {
|
|
46136
46352
|
mkdirSync27(candidatesDir, { recursive: true });
|
|
46137
46353
|
}
|
|
46138
|
-
|
|
46354
|
+
writeFileSync25(diffFilePath, diff, "utf8");
|
|
46139
46355
|
const jsonFilePath = join42(candidatesDir, `${group.candidateId}.json`);
|
|
46140
|
-
|
|
46356
|
+
writeFileSync25(jsonFilePath, JSON.stringify(candidate, null, 2) + "\n", "utf8");
|
|
46141
46357
|
}
|
|
46142
46358
|
candidates.push(candidate);
|
|
46143
46359
|
}
|
|
@@ -46168,7 +46384,7 @@ function writeImprovementReport(improvementsDir, report2, dryRun = false) {
|
|
|
46168
46384
|
const path4 = join42(improvementsDir, `${stamp}.json`);
|
|
46169
46385
|
if (!dryRun) {
|
|
46170
46386
|
mkdirSync27(improvementsDir, { recursive: true });
|
|
46171
|
-
|
|
46387
|
+
writeFileSync25(path4, `${JSON.stringify(report2, null, 2)}
|
|
46172
46388
|
`, { encoding: "utf8" });
|
|
46173
46389
|
}
|
|
46174
46390
|
return path4;
|
|
@@ -47278,7 +47494,7 @@ complete -c kxm -n "__fish_seen_subcommand_from goal" -a "create list get"
|
|
|
47278
47494
|
}
|
|
47279
47495
|
|
|
47280
47496
|
// plugins/kxm/src/completion-install.ts
|
|
47281
|
-
import { existsSync as existsSync38, mkdirSync as mkdirSync29, readFileSync as readFileSync36, writeFileSync as
|
|
47497
|
+
import { existsSync as existsSync38, mkdirSync as mkdirSync29, readFileSync as readFileSync36, writeFileSync as writeFileSync26 } from "node:fs";
|
|
47282
47498
|
import { homedir as homedir9 } from "node:os";
|
|
47283
47499
|
import { basename as basename9, delimiter, dirname as dirname23, isAbsolute as isAbsolute9, join as join45, resolve as resolve30 } from "node:path";
|
|
47284
47500
|
var COMPLETION_MARKER = "# kxm completion";
|
|
@@ -47362,7 +47578,7 @@ function installShellCompletion(shellInput, options = {}) {
|
|
|
47362
47578
|
alreadyInstalled = fishInstalled;
|
|
47363
47579
|
if (!options.dryRun && (!fishInstalled || options.overwrite)) {
|
|
47364
47580
|
mkdirSync29(resolve30(fishTarget, ".."), { recursive: true });
|
|
47365
|
-
|
|
47581
|
+
writeFileSync26(fishTarget, script, { encoding: "utf8" });
|
|
47366
47582
|
}
|
|
47367
47583
|
return {
|
|
47368
47584
|
ok: true,
|
|
@@ -47381,7 +47597,7 @@ function installShellCompletion(shellInput, options = {}) {
|
|
|
47381
47597
|
if (!options.dryRun) {
|
|
47382
47598
|
if (!existingScriptMatches || options.overwrite) {
|
|
47383
47599
|
mkdirSync29(resolve30(scriptPath, ".."), { recursive: true });
|
|
47384
|
-
|
|
47600
|
+
writeFileSync26(scriptPath, script, { encoding: "utf8" });
|
|
47385
47601
|
}
|
|
47386
47602
|
if (rcFile && !alreadyInstalled) {
|
|
47387
47603
|
const line = sourceLine(shell, scriptPath);
|
|
@@ -47391,7 +47607,7 @@ ${marker}
|
|
|
47391
47607
|
${line}
|
|
47392
47608
|
`;
|
|
47393
47609
|
mkdirSync29(resolve30(rcFile, ".."), { recursive: true });
|
|
47394
|
-
|
|
47610
|
+
writeFileSync26(rcFile, (existsSync38(rcFile) ? readFileSync36(rcFile, "utf8") : "") + stanza, { encoding: "utf8" });
|
|
47395
47611
|
rcModified = true;
|
|
47396
47612
|
}
|
|
47397
47613
|
}
|
|
@@ -47436,7 +47652,7 @@ function installPathEntry(shellInput, options = {}) {
|
|
|
47436
47652
|
const alreadyInstalled = rcContent.includes(binDir) || (options.env?.PATH ?? process.env.PATH ?? "").split(delimiter).includes(binDir);
|
|
47437
47653
|
if (!options.dryRun && rcFile && !alreadyInstalled) {
|
|
47438
47654
|
mkdirSync29(dirname23(rcFile), { recursive: true });
|
|
47439
|
-
|
|
47655
|
+
writeFileSync26(rcFile, rcContent + `
|
|
47440
47656
|
${PATH_MARKER}
|
|
47441
47657
|
${line}
|
|
47442
47658
|
`, { encoding: "utf8" });
|
|
@@ -47446,17 +47662,17 @@ ${line}
|
|
|
47446
47662
|
|
|
47447
47663
|
// plugins/kxm/src/init-guide-setup.ts
|
|
47448
47664
|
var import_yaml17 = __toESM(require_dist(), 1);
|
|
47449
|
-
import { existsSync as existsSync39, mkdirSync as mkdirSync30, writeFileSync as
|
|
47665
|
+
import { existsSync as existsSync39, mkdirSync as mkdirSync30, writeFileSync as writeFileSync27 } from "node:fs";
|
|
47450
47666
|
import { dirname as dirname24, join as join46 } from "node:path";
|
|
47451
|
-
var
|
|
47452
|
-
anthropic: "claude",
|
|
47453
|
-
|
|
47454
|
-
"
|
|
47455
|
-
xai: "grok",
|
|
47456
|
-
|
|
47457
|
-
|
|
47458
|
-
|
|
47459
|
-
|
|
47667
|
+
var ADMITTED_GUIDE_BINDINGS = Object.freeze({
|
|
47668
|
+
"anthropic/claude-fable-5.1": { harness: "claude", provider: "anthropic", model: "fable" },
|
|
47669
|
+
"anthropic/fable": { harness: "claude", provider: "anthropic", model: "fable" },
|
|
47670
|
+
"openai/gpt-5.6-sol": { harness: "codex", provider: "openai", model: "gpt-5.6-sol" },
|
|
47671
|
+
"x-ai/grok-4.6": { harness: "grok", provider: "xai", model: "grok-4.6" },
|
|
47672
|
+
"xai/grok-4.6": { harness: "grok", provider: "xai", model: "grok-4.6" },
|
|
47673
|
+
"google/gemini-3.8-flash": { harness: "pi", provider: "antigravity", model: "gemini-3.8-flash-high" },
|
|
47674
|
+
"google/gemini-3.8-flash-high": { harness: "pi", provider: "antigravity", model: "gemini-3.8-flash-high" },
|
|
47675
|
+
"qwen/qwen3-coder-plus": { harness: "pi", provider: "openrouter", model: "qwen/qwen3-coder-plus" }
|
|
47460
47676
|
});
|
|
47461
47677
|
var GUIDE_WORKFLOWS = [
|
|
47462
47678
|
{
|
|
@@ -47754,16 +47970,9 @@ function authenticatedHarnesses(inventory) {
|
|
|
47754
47970
|
}
|
|
47755
47971
|
function resolveCandidate(candidates, eligible) {
|
|
47756
47972
|
for (const candidate of candidates) {
|
|
47757
|
-
const
|
|
47758
|
-
if (
|
|
47759
|
-
|
|
47760
|
-
return { harness: nativeHarness, provider: NATIVE_HARNESS_PROVIDERS[nativeHarness], model: candidate.model };
|
|
47761
|
-
}
|
|
47762
|
-
continue;
|
|
47763
|
-
}
|
|
47764
|
-
if (eligible.has("pi")) {
|
|
47765
|
-
return { harness: "pi", provider: "openrouter", model: `${candidate.vendor}/${candidate.model}` };
|
|
47766
|
-
}
|
|
47973
|
+
const mapped = ADMITTED_GUIDE_BINDINGS[`${candidate.vendor}/${candidate.model}`];
|
|
47974
|
+
if (!mapped || !eligible.has(mapped.harness)) continue;
|
|
47975
|
+
return mapped;
|
|
47767
47976
|
}
|
|
47768
47977
|
return void 0;
|
|
47769
47978
|
}
|
|
@@ -47784,7 +47993,7 @@ function planGuideSetup(options) {
|
|
|
47784
47993
|
workflow: workflow.slug,
|
|
47785
47994
|
stage: stage.slug,
|
|
47786
47995
|
role: stage.role,
|
|
47787
|
-
reason: "no guide candidate has an authenticated harness (see `kxm harness list`)"
|
|
47996
|
+
reason: "no admitted guide candidate has an authenticated harness (see `kxm harness list`)"
|
|
47788
47997
|
});
|
|
47789
47998
|
covered = false;
|
|
47790
47999
|
continue;
|
|
@@ -47821,6 +48030,7 @@ function workflowDocument(workflow) {
|
|
|
47821
48030
|
id: stage.slug,
|
|
47822
48031
|
kind: "agent",
|
|
47823
48032
|
agent: stage.role,
|
|
48033
|
+
repositories: { control: isWriterRole(stage.role) ? "write" : "read" },
|
|
47824
48034
|
maxAttempts: 2,
|
|
47825
48035
|
on: {
|
|
47826
48036
|
passed: last ? { target: "$terminal", terminalStatus: "completed" } : workflow.stages[index + 1].slug,
|
|
@@ -47858,6 +48068,22 @@ function renderGuideSetupFiles(projectRoot, plan) {
|
|
|
47858
48068
|
}
|
|
47859
48069
|
return files;
|
|
47860
48070
|
}
|
|
48071
|
+
function mergeGuideRouteAdmission(projectRoot, plan) {
|
|
48072
|
+
const policy = loadRoutePolicy(projectRoot);
|
|
48073
|
+
const added = [];
|
|
48074
|
+
for (const binding of plan.agents.values()) {
|
|
48075
|
+
const selector = `${binding.provider}/${binding.model}`;
|
|
48076
|
+
if (policy.disabled.includes(selector) || policy.admitted.includes(selector)) continue;
|
|
48077
|
+
policy.admitted.push(selector);
|
|
48078
|
+
added.push(selector);
|
|
48079
|
+
}
|
|
48080
|
+
if (added.length === 0) return added;
|
|
48081
|
+
policy.updatedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
48082
|
+
const path4 = join46(projectRoot, ".kxm", "routes.yaml");
|
|
48083
|
+
mkdirSync30(dirname24(path4), { recursive: true });
|
|
48084
|
+
writeFileSync27(path4, (0, import_yaml17.stringify)(policy), "utf8");
|
|
48085
|
+
return added;
|
|
48086
|
+
}
|
|
47861
48087
|
function writeGuideSetupFiles(files) {
|
|
47862
48088
|
const written = [];
|
|
47863
48089
|
const existed = [];
|
|
@@ -47867,7 +48093,7 @@ function writeGuideSetupFiles(files) {
|
|
|
47867
48093
|
continue;
|
|
47868
48094
|
}
|
|
47869
48095
|
mkdirSync30(dirname24(file.path), { recursive: true });
|
|
47870
|
-
|
|
48096
|
+
writeFileSync27(file.path, file.content, "utf8");
|
|
47871
48097
|
written.push(file.path);
|
|
47872
48098
|
}
|
|
47873
48099
|
return { written, existed };
|
|
@@ -48571,9 +48797,12 @@ Set up workflow-guide agents and workflows for authenticated harnesses (${harnes
|
|
|
48571
48797
|
const plan = planGuideSetup({ inventory, selected });
|
|
48572
48798
|
const files = renderGuideSetupFiles(runtime.cwd, plan);
|
|
48573
48799
|
const report2 = writeGuideSetupFiles(files);
|
|
48800
|
+
const admitted = mergeGuideRouteAdmission(runtime.cwd, plan);
|
|
48574
48801
|
for (const file of report2.written) runtime.io.stdout(`wrote ${file}
|
|
48575
48802
|
`);
|
|
48576
48803
|
for (const file of report2.existed) runtime.io.stdout(`kept existing ${file} (not overwritten)
|
|
48804
|
+
`);
|
|
48805
|
+
for (const selector of admitted) runtime.io.stdout(`admitted route ${selector}
|
|
48577
48806
|
`);
|
|
48578
48807
|
for (const skip of plan.skipped) {
|
|
48579
48808
|
runtime.io.stdout(`skipped ${skip.workflow}/${skip.role}: ${skip.reason}
|
|
@@ -48583,6 +48812,23 @@ Set up workflow-guide agents and workflows for authenticated harnesses (${harnes
|
|
|
48583
48812
|
runtime.io.stdout("inspect with `kxm workflow definitions`; guide candidates are dated research \u2014 verify before dispatch\n");
|
|
48584
48813
|
}
|
|
48585
48814
|
}
|
|
48815
|
+
async function cmdPricesAcknowledge(runtime) {
|
|
48816
|
+
try {
|
|
48817
|
+
const catalog = acknowledgePriceCatalog(runtime.cwd);
|
|
48818
|
+
print(runtime.io, runtime.json, {
|
|
48819
|
+
ok: true,
|
|
48820
|
+
command: "prices acknowledge",
|
|
48821
|
+
date: catalog.date,
|
|
48822
|
+
sha256: catalog.sha256,
|
|
48823
|
+
note: "stamped the existing list as today's estimate; vendor rates were not fetched"
|
|
48824
|
+
}, `price catalog stamped ${catalog.date} (list estimate only; vendor rates were not fetched)`);
|
|
48825
|
+
return 0;
|
|
48826
|
+
} catch (error) {
|
|
48827
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
48828
|
+
print(runtime.io, runtime.json, { ok: false, command: "prices acknowledge", error: "prices_acknowledge_failed", message }, `prices acknowledge failed: ${message}`);
|
|
48829
|
+
return 1;
|
|
48830
|
+
}
|
|
48831
|
+
}
|
|
48586
48832
|
async function cmdRoutingReport(runtime, options) {
|
|
48587
48833
|
let file;
|
|
48588
48834
|
let records;
|
|
@@ -48927,7 +49173,7 @@ async function dispatchAgentCliCommand(runtime, toolName, rawArgs) {
|
|
|
48927
49173
|
let client;
|
|
48928
49174
|
try {
|
|
48929
49175
|
client = await ensureCliClient(runtime);
|
|
48930
|
-
const output = await cmd.execute(client, args);
|
|
49176
|
+
const output = await cmd.execute(client, args, { hubInbox: true });
|
|
48931
49177
|
const payload = output && typeof output === "object" ? output : { result: output };
|
|
48932
49178
|
print(runtime.io, runtime.json, payload, JSON.stringify(output, null, 2));
|
|
48933
49179
|
return 0;
|
|
@@ -48979,7 +49225,7 @@ function createProgram(ctx, result) {
|
|
|
48979
49225
|
maybeOfferGuideSetup
|
|
48980
49226
|
});
|
|
48981
49227
|
});
|
|
48982
|
-
addGlobalOptions(program2.command("backup").description("Create a verified SQLite backup of the project hub store
|
|
49228
|
+
addGlobalOptions(program2.command("backup").description("Create a verified SQLite backup of the project hub store and the Runtime stores under the user state root, with a hashed manifest")).option("--out <dir>", "Directory to write backup and manifest").action(async function backupAction(options) {
|
|
48983
49229
|
result.code = await cmdBackup(runtimeFrom(ctx, this), options);
|
|
48984
49230
|
});
|
|
48985
49231
|
addGlobalOptions(program2.command("restore <manifest>").description("Restore SQLite stores from a verified backup manifest")).action(async function restoreAction(manifest) {
|
|
@@ -48993,7 +49239,7 @@ function createProgram(ctx, result) {
|
|
|
48993
49239
|
addGlobalOptions(runCmd.command("status").description("Show the projected status of a run, including durable drive receipt state (open / receipt verified / unsettled / orphaned)")).argument("<runId>", "Run id").action(async function runStatusAction(runId) {
|
|
48994
49240
|
result.code = await cmdKxmRunStatus(runtimeFrom(ctx, this), runId);
|
|
48995
49241
|
});
|
|
48996
|
-
addGlobalOptions(runCmd.command("drive").description("Drive a run with live harness calls, or with the model-free simulation when --simulated is passed")).argument("<runId>", "Run id").option("--simulated", "Use the model-free simulation producer").option("--wait", "Wait until a drive receipt is recorded; exits 0 only for a VERIFIED COMPLETED settlement").option("--timeout-ms <n>", "Wait timeout in milliseconds (default 60000, max 600000)").action(async function runDriveAction(runId, options) {
|
|
49242
|
+
addGlobalOptions(runCmd.command("drive").description("Drive a run with live harness calls, or with the model-free simulation when --simulated is passed")).argument("<runId>", "Run id").option("--simulated", "Use the model-free simulation producer instead of a live model").option("--wait", "Wait until a drive receipt is recorded; exits 0 only for a VERIFIED COMPLETED settlement").option("--timeout-ms <n>", "Wait timeout in milliseconds (default 60000, max 600000)").action(async function runDriveAction(runId, options) {
|
|
48997
49243
|
result.code = await cmdKxmRunDrive(runtimeFrom(ctx, this), runId, options.simulated === true, {
|
|
48998
49244
|
wait: options.wait === true,
|
|
48999
49245
|
...options.timeoutMs !== void 0 ? { timeoutMs: options.timeoutMs } : {}
|
|
@@ -49013,6 +49259,11 @@ function createProgram(ctx, result) {
|
|
|
49013
49259
|
addGlobalOptions(tenantCmd.command("status").description("Read hub metadata and authoritative Runtime run state as one labeled view")).action(async function tenantStatusAction() {
|
|
49014
49260
|
result.code = await cmdTenantStatus(runtimeFrom(ctx, this));
|
|
49015
49261
|
});
|
|
49262
|
+
const pricesCmd = addGlobalOptions(program2.command("prices").description("Stamp the local list-price catalog. Estimates stay unknown until today's stamp"));
|
|
49263
|
+
pricesCmd.helpCommand("help", "Show prices help");
|
|
49264
|
+
addGlobalOptions(pricesCmd.command("acknowledge").description("Stamp the existing .kxm/prices.yaml list as today's estimate without fetching vendor rates")).action(async function pricesAcknowledgeAction() {
|
|
49265
|
+
result.code = await cmdPricesAcknowledge(runtimeFrom(ctx, this));
|
|
49266
|
+
});
|
|
49016
49267
|
const modelsCmd = addGlobalOptions(program2.command("models").description("Manage model catalogs, roles, and route state"));
|
|
49017
49268
|
modelsCmd.action(async function modelsScreenAction() {
|
|
49018
49269
|
result.code = await cmdModelsScreen(runtimeFrom(ctx, this));
|
|
@@ -49223,7 +49474,7 @@ function createProgram(ctx, result) {
|
|
|
49223
49474
|
addGlobalOptions(github.command("watch").description("Poll required checks and post the signed signal")).option("--run-id <id>", "Workflow run ID").option("--stage-id <id>", "Waiting stage ID").option("--signal-key <key>", "Wait signal key").option("--repo <owner/name>", "GitHub repository").option("--pr <number>", "Pull request number").option("--required <names>", "Comma-separated required check names").option("--timeout-ms <ms>", "Watch timeout").option("--interval-ms <ms>", "Poll interval").option("--delivery-id <id>", "Stable callback delivery ID").action(async function watchAction(options) {
|
|
49224
49475
|
result.code = await cmdGithubWatch(runtimeFrom(ctx, this), options);
|
|
49225
49476
|
});
|
|
49226
|
-
const improve = addGlobalOptions(program2.command("improve").description("Propose coded-repeat candidates from this project's Runtime routing records and telemetry"));
|
|
49477
|
+
const improve = addGlobalOptions(program2.command("improve").description("Propose coded-repeat candidates from this project's Runtime routing records and telemetry. Proposals are not applied to the next run"));
|
|
49227
49478
|
improve.helpCommand("help", "Show improve help");
|
|
49228
49479
|
addGlobalOptions(improve.command("report", { isDefault: true }).description("Generate improvement report and candidates from routing records")).option("--file <path>", "Read only this routing-record JSONL instead of the project's Runtime store and telemetry").option("--out-dir <path>", "Directory for candidates (default .kxm/candidates)").action(async function improveReportAction(options) {
|
|
49229
49480
|
result.code = await cmdImprove(runtimeFrom(ctx, this), options);
|