@kontextmind/kxm 0.7.98 → 0.7.100
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude-plugin/marketplace.json +1 -1
- package/CHANGELOG.md +19 -0
- package/docs/contributing/test-matrix.md +2 -0
- package/docs/guides/peer-messaging.md +2 -2
- package/docs/reference/cli-reference.md +10 -7
- package/docs/reference/config-reference.md +4 -2
- package/docs/reference/http-api.md +1 -0
- package/docs/reference/tools.md +3 -3
- 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 +115 -57
- package/plugins/kxm/dist/client.js +9 -0
- package/plugins/kxm/dist/core.js +4 -1
- package/plugins/kxm/dist/extension.js +13 -1
- package/plugins/kxm/dist/mcp-server.js +14 -2
- package/plugins/kxm/dist/runtime-supervisor.js +19 -4
- package/plugins/kxm/dist/runtime.js +19 -4
- package/plugins/kxm/dist/server.js +12 -1
- package/plugins/kxm/package.json +1 -1
- package/plugins/kxm/skills/kxm-peer/SKILL.md +5 -3
- package/plugins/kxm/src/cli/workflows.ts +34 -9
- package/plugins/kxm/src/cli.ts +3 -1
- package/plugins/kxm/src/client.ts +10 -0
- package/plugins/kxm/src/commands.ts +10 -1
- package/plugins/kxm/src/extension.ts +1 -0
- package/plugins/kxm/src/hub.ts +12 -0
- package/plugins/kxm/src/mcp-server.ts +1 -1
- package/plugins/kxm/src/project-config.ts +45 -3
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 stringify12(x2) {
|
|
168
168
|
return new _Code(safeStringify(x2));
|
|
169
169
|
}
|
|
170
|
-
exports.stringify =
|
|
170
|
+
exports.stringify = stringify12;
|
|
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 stringify12(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 = stringify12;
|
|
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 stringify12 = 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 = stringify12.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 = stringify12.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 stringify12 = 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 = stringify12.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 stringify12 = 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 stringify13 = flow ? stringifyFlowCollection : stringifyBlockCollection;
|
|
9283
|
+
return stringify13(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 = stringify12.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 = stringify12.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 stringify12 = 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 = stringify12.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 = stringify12.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(stringify12.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 stringify12 = (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 = stringify12;
|
|
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 stringify12(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 = stringify12;
|
|
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
|
{
|
|
@@ -22688,10 +22700,13 @@ function readResource(registry, root, file, logicalPath, kind, id, containmentRo
|
|
|
22688
22700
|
parent = dirname4(parent);
|
|
22689
22701
|
}
|
|
22690
22702
|
if (!stat.isFile()) fail2("path", "resource_not_file", label, "configuration resource must be a regular file");
|
|
22691
|
-
|
|
22703
|
+
return { kind, ...id === void 0 ? {} : { id }, file, logicalPath, value: resourceValue(registry, readFileSync5(file), label, kind) };
|
|
22704
|
+
}
|
|
22705
|
+
function resourceValue(registry, input, label, kind) {
|
|
22706
|
+
const value = parseRestrictedYaml2(input, label);
|
|
22692
22707
|
const issues = registry.validate(kind, value, label);
|
|
22693
22708
|
if (issues.length > 0) throw new KxmConfigError(issues);
|
|
22694
|
-
return
|
|
22709
|
+
return value;
|
|
22695
22710
|
}
|
|
22696
22711
|
function readTemplateProvenance(registry, root) {
|
|
22697
22712
|
const file = join6(root, ".kxm", "template-provenance.yaml");
|
|
@@ -22740,7 +22755,7 @@ function readTemplateProvenance(registry, root) {
|
|
|
22740
22755
|
}
|
|
22741
22756
|
return value;
|
|
22742
22757
|
}
|
|
22743
|
-
function listNamedResources(registry, root, directory, logicalDirectory, kind) {
|
|
22758
|
+
function listNamedResources(registry, root, directory, logicalDirectory, kind, replacedId) {
|
|
22744
22759
|
const resources = /* @__PURE__ */ new Map();
|
|
22745
22760
|
if (!existsSync6(directory)) return resources;
|
|
22746
22761
|
const stat = lstatSync(directory);
|
|
@@ -22761,6 +22776,7 @@ function listNamedResources(registry, root, directory, logicalDirectory, kind) {
|
|
|
22761
22776
|
}
|
|
22762
22777
|
const id = basename2(entry.name, ".yaml");
|
|
22763
22778
|
if (kind === "model" && id === "inventory") continue;
|
|
22779
|
+
if (id === replacedId) continue;
|
|
22764
22780
|
if (!resourceIdentifier(id)) {
|
|
22765
22781
|
issues.push(issue2("path", "resource_id_invalid", displayPath(root, join6(directory, entry.name)), `filename-derived identity ${id} is invalid or platform-reserved`));
|
|
22766
22782
|
continue;
|
|
@@ -23365,6 +23381,18 @@ function assertNoRegisteredGates(options) {
|
|
|
23365
23381
|
}
|
|
23366
23382
|
}
|
|
23367
23383
|
function loadKxmProject(projectRoot, options = {}) {
|
|
23384
|
+
return loadProjectBundle(projectRoot, options);
|
|
23385
|
+
}
|
|
23386
|
+
function kxmWorkflowWriteIssues(projectRoot, workflowId, document, options = {}) {
|
|
23387
|
+
try {
|
|
23388
|
+
loadProjectBundle(projectRoot, options, { id: workflowId, document });
|
|
23389
|
+
return [];
|
|
23390
|
+
} catch (error) {
|
|
23391
|
+
if (error instanceof KxmConfigError) return error.issues;
|
|
23392
|
+
throw error;
|
|
23393
|
+
}
|
|
23394
|
+
}
|
|
23395
|
+
function loadProjectBundle(projectRoot, options, workflowCandidate) {
|
|
23368
23396
|
assertNoRegisteredGates(options);
|
|
23369
23397
|
const root = resolve3(projectRoot);
|
|
23370
23398
|
const legacyPresent = legacyConfigFilesAt(root);
|
|
@@ -23398,7 +23426,15 @@ function loadKxmProject(projectRoot, options = {}) {
|
|
|
23398
23426
|
if (earlyIssues.length > 0) throw new KxmConfigError(earlyIssues);
|
|
23399
23427
|
const agents = listNamedResources(registry, root, join6(root, ".kxm", "agents"), ".kxm/agents", "agent");
|
|
23400
23428
|
const models = listNamedResources(registry, root, join6(root, ".kxm", "models"), ".kxm/models", "model");
|
|
23401
|
-
const workflows = listNamedResources(registry, root, join6(root, ".kxm", "workflows"), ".kxm/workflows", "workflow");
|
|
23429
|
+
const workflows = listNamedResources(registry, root, join6(root, ".kxm", "workflows"), ".kxm/workflows", "workflow", workflowCandidate?.id);
|
|
23430
|
+
if (workflowCandidate) {
|
|
23431
|
+
const { id, document } = workflowCandidate;
|
|
23432
|
+
const logicalPath = `.kxm/workflows/${id}.yaml`;
|
|
23433
|
+
if (!resourceIdentifier(id)) fail2("path", "resource_id_invalid", logicalPath, `filename-derived identity ${id} is invalid or platform-reserved`);
|
|
23434
|
+
const collision = [...workflows.keys()].find((candidate) => candidate.toLocaleLowerCase("en-US") === id.toLocaleLowerCase("en-US"));
|
|
23435
|
+
if (collision) fail2("path", "resource_id_collision", logicalPath, `${id} case-folds to existing ${collision}`);
|
|
23436
|
+
workflows.set(id, { kind: "workflow", id, file: join6(root, logicalPath), logicalPath, value: resourceValue(registry, document, logicalPath, "workflow") });
|
|
23437
|
+
}
|
|
23402
23438
|
const gatePath = join6(root, ".kxm", "gates.yaml");
|
|
23403
23439
|
const gateRegistry = existsSync6(gatePath) ? readResource(registry, root, gatePath, ".kxm/gates.yaml", "gate-registry") : void 0;
|
|
23404
23440
|
const environments = [];
|
|
@@ -28907,6 +28943,7 @@ async function cmdRoleResume(runtime, runId, ruling) {
|
|
|
28907
28943
|
}
|
|
28908
28944
|
|
|
28909
28945
|
// plugins/kxm/src/cli/workflows.ts
|
|
28946
|
+
var import_yaml12 = __toESM(require_dist(), 1);
|
|
28910
28947
|
import { randomUUID as randomUUID8 } from "node:crypto";
|
|
28911
28948
|
import { existsSync as existsSync21, readFileSync as readFileSync20 } from "node:fs";
|
|
28912
28949
|
import { join as join22, resolve as resolve17 } from "node:path";
|
|
@@ -29758,12 +29795,12 @@ async function cmdWorkflowDefinitions(runtime, options) {
|
|
|
29758
29795
|
}
|
|
29759
29796
|
async function cmdWorkflowAdd(runtime, workflowId, options) {
|
|
29760
29797
|
const scope = options.scope ?? "local";
|
|
29798
|
+
const refuse = (error, text) => {
|
|
29799
|
+
print(runtime.io, runtime.json, { ok: false, command: "workflow add", error }, `workflow add failed: ${text}`);
|
|
29800
|
+
return 2;
|
|
29801
|
+
};
|
|
29761
29802
|
let content;
|
|
29762
29803
|
if (options.template !== void 0) {
|
|
29763
|
-
const refuse = (error, text) => {
|
|
29764
|
-
print(runtime.io, runtime.json, { ok: false, command: "workflow add", error }, `workflow add failed: ${text}`);
|
|
29765
|
-
return 2;
|
|
29766
|
-
};
|
|
29767
29804
|
if (options.file !== void 0 || options.pick !== void 0) {
|
|
29768
29805
|
return refuse("workflow_add_conflict", "--template cannot be combined with --file or --pick");
|
|
29769
29806
|
}
|
|
@@ -29783,8 +29820,9 @@ async function cmdWorkflowAdd(runtime, workflowId, options) {
|
|
|
29783
29820
|
if (scope === "local") {
|
|
29784
29821
|
const globalDefs = listWorkflowDefinitions({ scope: "global", userConfigDir: runtime.env.KXM_USER_CONFIG_DIR });
|
|
29785
29822
|
for (const gd of globalDefs) {
|
|
29786
|
-
|
|
29787
|
-
|
|
29823
|
+
const definition = parseWorkflowFile(gd.filePath);
|
|
29824
|
+
if (definition && !candidates.some((c) => c.id === gd.id)) {
|
|
29825
|
+
candidates.push({ id: gd.id, description: gd.description, label: "global", payload: definition });
|
|
29788
29826
|
}
|
|
29789
29827
|
}
|
|
29790
29828
|
}
|
|
@@ -29811,9 +29849,29 @@ async function cmdWorkflowAdd(runtime, workflowId, options) {
|
|
|
29811
29849
|
content = scaffoldWorkflowDefinition(options.description || `Workflow ${workflowId}`);
|
|
29812
29850
|
}
|
|
29813
29851
|
try {
|
|
29814
|
-
const
|
|
29852
|
+
const document = typeof content === "string" ? content : (0, import_yaml12.stringify)(content);
|
|
29853
|
+
let repoRoot = runtime.cwd;
|
|
29854
|
+
if (scope === "local") {
|
|
29855
|
+
const projectRoot = discoverKxmProjectRoot(runtime.cwd);
|
|
29856
|
+
if (!projectRoot) {
|
|
29857
|
+
return refuse("project_not_found", "local workflows belong to a KXM project; run kxm init at the repository root, or pass --scope global");
|
|
29858
|
+
}
|
|
29859
|
+
const issues = kxmWorkflowWriteIssues(projectRoot, workflowId, document);
|
|
29860
|
+
if (issues.length > 0) {
|
|
29861
|
+
print(
|
|
29862
|
+
runtime.io,
|
|
29863
|
+
runtime.json,
|
|
29864
|
+
{ ok: false, command: "workflow add", error: "workflow_invalid", issues },
|
|
29865
|
+
`workflow add failed: with this workflow the project would not load, so nothing was written
|
|
29866
|
+
${issues.map((entry) => ` ${entry.file}: ${entry.code}: ${entry.message}`).join("\n")}`
|
|
29867
|
+
);
|
|
29868
|
+
return 2;
|
|
29869
|
+
}
|
|
29870
|
+
repoRoot = projectRoot;
|
|
29871
|
+
}
|
|
29872
|
+
const res = addWorkflowDefinition(workflowId, document, {
|
|
29815
29873
|
scope,
|
|
29816
|
-
repoRoot
|
|
29874
|
+
repoRoot,
|
|
29817
29875
|
userConfigDir: runtime.env.KXM_USER_CONFIG_DIR,
|
|
29818
29876
|
overwrite: options.overwrite,
|
|
29819
29877
|
dryRun: runtime.dryRun
|
|
@@ -30237,7 +30295,7 @@ async function cmdRetrospectiveExport(runtime, runId, options) {
|
|
|
30237
30295
|
}
|
|
30238
30296
|
|
|
30239
30297
|
// plugins/kxm/src/cli/tasks.ts
|
|
30240
|
-
var
|
|
30298
|
+
var import_yaml15 = __toESM(require_dist(), 1);
|
|
30241
30299
|
import { existsSync as existsSync27, readFileSync as readFileSync25, readdirSync as readdirSync10 } from "node:fs";
|
|
30242
30300
|
import { basename as basename7, join as join29, resolve as resolve22 } from "node:path";
|
|
30243
30301
|
|
|
@@ -30348,7 +30406,7 @@ function suggestWorkflowAndRoles(prompt, options = {}) {
|
|
|
30348
30406
|
}
|
|
30349
30407
|
|
|
30350
30408
|
// plugins/kxm/src/task-manager.ts
|
|
30351
|
-
var
|
|
30409
|
+
var import_yaml13 = __toESM(require_dist(), 1);
|
|
30352
30410
|
import { randomUUID as randomUUID9 } from "node:crypto";
|
|
30353
30411
|
import { existsSync as existsSync22, mkdirSync as mkdirSync17, readFileSync as readFileSync21, readdirSync as readdirSync8, writeFileSync as writeFileSync17 } from "node:fs";
|
|
30354
30412
|
import { join as join23, resolve as resolve18 } from "node:path";
|
|
@@ -30382,7 +30440,7 @@ function createGoal(repoRoot, input, options = {}) {
|
|
|
30382
30440
|
};
|
|
30383
30441
|
if (options.dryRun) return record;
|
|
30384
30442
|
mkdirSync17(goalsDirectory(repoRoot), { recursive: true });
|
|
30385
|
-
writeFileSync17(goalFilePath(repoRoot, id), (0,
|
|
30443
|
+
writeFileSync17(goalFilePath(repoRoot, id), (0, import_yaml13.stringify)(record).trim() + "\n", "utf8");
|
|
30386
30444
|
return record;
|
|
30387
30445
|
}
|
|
30388
30446
|
function listGoals(repoRoot) {
|
|
@@ -30394,7 +30452,7 @@ function listGoals(repoRoot) {
|
|
|
30394
30452
|
if (entry.isFile() && (entry.name.endsWith(".yaml") || entry.name.endsWith(".yml"))) {
|
|
30395
30453
|
try {
|
|
30396
30454
|
const text = readFileSync21(join23(dir, entry.name), "utf8");
|
|
30397
|
-
const doc = (0,
|
|
30455
|
+
const doc = (0, import_yaml13.parse)(text);
|
|
30398
30456
|
if (doc && doc.schema === GOAL_SCHEMA) goals.push(doc);
|
|
30399
30457
|
} catch {
|
|
30400
30458
|
}
|
|
@@ -30426,7 +30484,7 @@ function createTask(repoRoot, input, options = {}) {
|
|
|
30426
30484
|
};
|
|
30427
30485
|
if (options.dryRun) return record;
|
|
30428
30486
|
mkdirSync17(tasksDirectory(repoRoot), { recursive: true });
|
|
30429
|
-
writeFileSync17(taskFilePath(repoRoot, id), (0,
|
|
30487
|
+
writeFileSync17(taskFilePath(repoRoot, id), (0, import_yaml13.stringify)(record).trim() + "\n", "utf8");
|
|
30430
30488
|
return record;
|
|
30431
30489
|
}
|
|
30432
30490
|
function listTasks(repoRoot, options = {}) {
|
|
@@ -30438,7 +30496,7 @@ function listTasks(repoRoot, options = {}) {
|
|
|
30438
30496
|
if (entry.isFile() && (entry.name.endsWith(".yaml") || entry.name.endsWith(".yml"))) {
|
|
30439
30497
|
try {
|
|
30440
30498
|
const text = readFileSync21(join23(dir, entry.name), "utf8");
|
|
30441
|
-
const doc = (0,
|
|
30499
|
+
const doc = (0, import_yaml13.parse)(text);
|
|
30442
30500
|
if (doc && doc.schema === TASK_SCHEMA) {
|
|
30443
30501
|
if (options.goalId && doc.goalId !== options.goalId) continue;
|
|
30444
30502
|
if (options.status && doc.status !== options.status) continue;
|
|
@@ -30456,7 +30514,7 @@ function getTask(repoRoot, taskId) {
|
|
|
30456
30514
|
if (!existsSync22(filePath)) return void 0;
|
|
30457
30515
|
try {
|
|
30458
30516
|
const text = readFileSync21(filePath, "utf8");
|
|
30459
|
-
const doc = (0,
|
|
30517
|
+
const doc = (0, import_yaml13.parse)(text);
|
|
30460
30518
|
return doc && doc.schema === TASK_SCHEMA ? doc : void 0;
|
|
30461
30519
|
} catch {
|
|
30462
30520
|
return void 0;
|
|
@@ -30470,7 +30528,7 @@ function updateTaskStatus(repoRoot, taskId, status, options = {}) {
|
|
|
30470
30528
|
task.status = status;
|
|
30471
30529
|
if (options.workflowRunId) task.workflowRunId = options.workflowRunId;
|
|
30472
30530
|
task.updatedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
30473
|
-
if (!options.dryRun) writeFileSync17(taskFilePath(repoRoot, taskId), (0,
|
|
30531
|
+
if (!options.dryRun) writeFileSync17(taskFilePath(repoRoot, taskId), (0, import_yaml13.stringify)(task).trim() + "\n", "utf8");
|
|
30474
30532
|
return task;
|
|
30475
30533
|
}
|
|
30476
30534
|
function syncTaskWithTracker(repoRoot, taskId, options = {}) {
|
|
@@ -30485,7 +30543,7 @@ function syncTaskWithTracker(repoRoot, taskId, options = {}) {
|
|
|
30485
30543
|
task.trackerSync.syncStatus = "synced";
|
|
30486
30544
|
task.trackerSync.lastSyncedAt = now;
|
|
30487
30545
|
task.updatedAt = now;
|
|
30488
|
-
if (!options.dryRun) writeFileSync17(taskFilePath(repoRoot, taskId), (0,
|
|
30546
|
+
if (!options.dryRun) writeFileSync17(taskFilePath(repoRoot, taskId), (0, import_yaml13.stringify)(task).trim() + "\n", "utf8");
|
|
30489
30547
|
return task;
|
|
30490
30548
|
}
|
|
30491
30549
|
|
|
@@ -31257,7 +31315,7 @@ import { join as join28, resolve as resolve21 } from "node:path";
|
|
|
31257
31315
|
import { createInterface as createInterface2 } from "node:readline";
|
|
31258
31316
|
|
|
31259
31317
|
// plugins/kxm/src/model-inventory.ts
|
|
31260
|
-
var
|
|
31318
|
+
var import_yaml14 = __toESM(require_dist(), 1);
|
|
31261
31319
|
import { mkdirSync as mkdirSync18, writeFileSync as writeFileSync18 } from "node:fs";
|
|
31262
31320
|
import { join as join24 } from "node:path";
|
|
31263
31321
|
var OR_URL = "https://openrouter.ai/api/v1/models";
|
|
@@ -31346,7 +31404,7 @@ async function refreshModelInventory(options) {
|
|
|
31346
31404
|
for (const item of nous.data) add(item, "nous", "discount");
|
|
31347
31405
|
const inventory = { schema: "kxm.model-inventory.v1", fetchedAt, currency: "USD", sources, models: [...byId.values()].sort((a, b2) => a.id.localeCompare(b2.id)) };
|
|
31348
31406
|
mkdirSync18(join24(options.outputRoot, ".kxm", "models"), { recursive: true });
|
|
31349
|
-
writeFileSync18(join24(options.outputRoot, ".kxm", "models", "inventory.yaml"), (0,
|
|
31407
|
+
writeFileSync18(join24(options.outputRoot, ".kxm", "models", "inventory.yaml"), (0, import_yaml14.stringify)(inventory), "utf8");
|
|
31350
31408
|
return inventory;
|
|
31351
31409
|
}
|
|
31352
31410
|
|
|
@@ -34527,7 +34585,7 @@ steps:
|
|
|
34527
34585
|
maxTransitions: 2
|
|
34528
34586
|
`;
|
|
34529
34587
|
}
|
|
34530
|
-
const parsedYaml = (0,
|
|
34588
|
+
const parsedYaml = (0, import_yaml15.parse)(yamlContent);
|
|
34531
34589
|
const plan = compileKxmWorkflow({ id: workflowId, value: parsedYaml });
|
|
34532
34590
|
const layout = generateStudioLayout(plan);
|
|
34533
34591
|
print(runtime.io, runtime.json, { ok: true, command: "studio layout", layout }, JSON.stringify(layout, null, 2));
|
|
@@ -34569,7 +34627,7 @@ async function cmdStudioServe(runtime, options) {
|
|
|
34569
34627
|
}
|
|
34570
34628
|
if (targetPath && existsSync27(targetPath)) {
|
|
34571
34629
|
const raw = readFileSync25(targetPath, "utf8");
|
|
34572
|
-
const parsed = (0,
|
|
34630
|
+
const parsed = (0, import_yaml15.parse)(raw);
|
|
34573
34631
|
const wfId = basename7(targetPath).replace(/\.(yaml|yml)$/, "");
|
|
34574
34632
|
return compileKxmWorkflow({ id: wfId, value: parsed });
|
|
34575
34633
|
}
|
|
@@ -45215,7 +45273,7 @@ function resolveInstallKind(probe, npmGlobalRoot) {
|
|
|
45215
45273
|
}
|
|
45216
45274
|
|
|
45217
45275
|
// plugins/kxm/src/kxm-update-config.ts
|
|
45218
|
-
var
|
|
45276
|
+
var import_yaml16 = __toESM(require_dist(), 1);
|
|
45219
45277
|
import { existsSync as existsSync31, readFileSync as readFileSync30 } from "node:fs";
|
|
45220
45278
|
import { join as join39 } from "node:path";
|
|
45221
45279
|
function loadKxmUpdateConfig(env = process.env) {
|
|
@@ -45223,7 +45281,7 @@ function loadKxmUpdateConfig(env = process.env) {
|
|
|
45223
45281
|
if (!existsSync31(path4)) return { schema: KXM_UPDATE_SCHEMA, auto: false, source: "github" };
|
|
45224
45282
|
let parsed;
|
|
45225
45283
|
try {
|
|
45226
|
-
parsed = (0,
|
|
45284
|
+
parsed = (0, import_yaml16.parse)(readFileSync30(path4, "utf8"));
|
|
45227
45285
|
} catch {
|
|
45228
45286
|
throw new KxmUpdateConfigError("update.yaml is not valid YAML");
|
|
45229
45287
|
}
|
|
@@ -46590,7 +46648,7 @@ function loadRoutingSources(options) {
|
|
|
46590
46648
|
}
|
|
46591
46649
|
|
|
46592
46650
|
// plugins/kxm/src/modes.ts
|
|
46593
|
-
var
|
|
46651
|
+
var import_yaml17 = __toESM(require_dist(), 1);
|
|
46594
46652
|
import { existsSync as existsSync36, readFileSync as readFileSync34 } from "node:fs";
|
|
46595
46653
|
import { join as join43 } from "node:path";
|
|
46596
46654
|
var DEFAULT_MODES_CONFIG = Object.freeze({
|
|
@@ -46661,7 +46719,7 @@ function loadModesConfig(projectRoot) {
|
|
|
46661
46719
|
}
|
|
46662
46720
|
try {
|
|
46663
46721
|
const raw = readFileSync34(modesPath, "utf8");
|
|
46664
|
-
const parsed = (0,
|
|
46722
|
+
const parsed = (0, import_yaml17.parse)(raw);
|
|
46665
46723
|
if (parsed && parsed.schema === "kxm.modes.v1" && parsed.majorModes) {
|
|
46666
46724
|
return {
|
|
46667
46725
|
schema: "kxm.modes.v1",
|
|
@@ -47649,7 +47707,7 @@ ${line}
|
|
|
47649
47707
|
}
|
|
47650
47708
|
|
|
47651
47709
|
// plugins/kxm/src/init-guide-setup.ts
|
|
47652
|
-
var
|
|
47710
|
+
var import_yaml18 = __toESM(require_dist(), 1);
|
|
47653
47711
|
import { existsSync as existsSync39, mkdirSync as mkdirSync30, writeFileSync as writeFileSync27 } from "node:fs";
|
|
47654
47712
|
import { dirname as dirname24, join as join46 } from "node:path";
|
|
47655
47713
|
var ADMITTED_GUIDE_BINDINGS = Object.freeze({
|
|
@@ -48045,13 +48103,13 @@ function renderGuideSetupFiles(projectRoot, plan) {
|
|
|
48045
48103
|
if (!stage) continue;
|
|
48046
48104
|
files.push({
|
|
48047
48105
|
path: join46(projectRoot, ".kxm", "agents", `${role}.yaml`),
|
|
48048
|
-
content: (0,
|
|
48106
|
+
content: (0, import_yaml18.stringify)(agentDocument(role, stage, binding))
|
|
48049
48107
|
});
|
|
48050
48108
|
}
|
|
48051
48109
|
for (const workflow of plan.workflows) {
|
|
48052
48110
|
files.push({
|
|
48053
48111
|
path: join46(projectRoot, ".kxm", "workflows", `${workflow.slug}.yaml`),
|
|
48054
|
-
content: (0,
|
|
48112
|
+
content: (0, import_yaml18.stringify)(workflowDocument(workflow))
|
|
48055
48113
|
});
|
|
48056
48114
|
}
|
|
48057
48115
|
return files;
|
|
@@ -48069,7 +48127,7 @@ function mergeGuideRouteAdmission(projectRoot, plan) {
|
|
|
48069
48127
|
policy.updatedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
48070
48128
|
const path4 = join46(projectRoot, ".kxm", "routes.yaml");
|
|
48071
48129
|
mkdirSync30(dirname24(path4), { recursive: true });
|
|
48072
|
-
writeFileSync27(path4, (0,
|
|
48130
|
+
writeFileSync27(path4, (0, import_yaml18.stringify)(policy), "utf8");
|
|
48073
48131
|
return added;
|
|
48074
48132
|
}
|
|
48075
48133
|
function writeGuideSetupFiles(files) {
|
|
@@ -49161,7 +49219,7 @@ async function dispatchAgentCliCommand(runtime, toolName, rawArgs) {
|
|
|
49161
49219
|
let client;
|
|
49162
49220
|
try {
|
|
49163
49221
|
client = await ensureCliClient(runtime);
|
|
49164
|
-
const output = await cmd.execute(client, args);
|
|
49222
|
+
const output = await cmd.execute(client, args, { hubInbox: true });
|
|
49165
49223
|
const payload = output && typeof output === "object" ? output : { result: output };
|
|
49166
49224
|
print(runtime.io, runtime.json, payload, JSON.stringify(output, null, 2));
|
|
49167
49225
|
return 0;
|
|
@@ -262,6 +262,15 @@ var HubClient = class {
|
|
|
262
262
|
}
|
|
263
263
|
}));
|
|
264
264
|
}
|
|
265
|
+
/** This agent's open inbound requests (queued or delivered), oldest first. A read: nothing
|
|
266
|
+
* is acknowledged. */
|
|
267
|
+
async listInbox() {
|
|
268
|
+
if (!this.agent) throw new Error("hub client is not registered");
|
|
269
|
+
const result = await this.request(
|
|
270
|
+
`/v1/agents/${encodeURIComponent(this.agent.id)}/inbox`
|
|
271
|
+
);
|
|
272
|
+
return result.messages;
|
|
273
|
+
}
|
|
265
274
|
async getMessage(messageId) {
|
|
266
275
|
const result = await this.request(`/v1/messages/${encodeURIComponent(messageId)}`);
|
|
267
276
|
return result.message;
|
package/plugins/kxm/dist/core.js
CHANGED
|
@@ -1284,7 +1284,10 @@ var AGENT_COMMANDS = [
|
|
|
1284
1284
|
await reconcileInbox(client, context.inbox, context.notifiedInbox);
|
|
1285
1285
|
return { messages: [...context.inbox.values()] };
|
|
1286
1286
|
}
|
|
1287
|
-
return { messages:
|
|
1287
|
+
if (context?.hubInbox) return { messages: await client.listInbox() };
|
|
1288
|
+
throw new Error(
|
|
1289
|
+
"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"
|
|
1290
|
+
);
|
|
1288
1291
|
}
|
|
1289
1292
|
},
|
|
1290
1293
|
{
|
|
@@ -14842,6 +14842,15 @@ var HubClient = class {
|
|
|
14842
14842
|
}
|
|
14843
14843
|
}));
|
|
14844
14844
|
}
|
|
14845
|
+
/** This agent's open inbound requests (queued or delivered), oldest first. A read: nothing
|
|
14846
|
+
* is acknowledged. */
|
|
14847
|
+
async listInbox() {
|
|
14848
|
+
if (!this.agent) throw new Error("hub client is not registered");
|
|
14849
|
+
const result2 = await this.request(
|
|
14850
|
+
`/v1/agents/${encodeURIComponent(this.agent.id)}/inbox`
|
|
14851
|
+
);
|
|
14852
|
+
return result2.messages;
|
|
14853
|
+
}
|
|
14845
14854
|
async getMessage(messageId) {
|
|
14846
14855
|
const result2 = await this.request(`/v1/messages/${encodeURIComponent(messageId)}`);
|
|
14847
14856
|
return result2.message;
|
|
@@ -15408,7 +15417,10 @@ var AGENT_COMMANDS = [
|
|
|
15408
15417
|
await reconcileInbox(client, context.inbox, context.notifiedInbox);
|
|
15409
15418
|
return { messages: [...context.inbox.values()] };
|
|
15410
15419
|
}
|
|
15411
|
-
return { messages:
|
|
15420
|
+
if (context?.hubInbox) return { messages: await client.listInbox() };
|
|
15421
|
+
throw new Error(
|
|
15422
|
+
"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"
|
|
15423
|
+
);
|
|
15412
15424
|
}
|
|
15413
15425
|
},
|
|
15414
15426
|
{
|
|
@@ -16042,6 +16042,15 @@ var HubClient = class {
|
|
|
16042
16042
|
}
|
|
16043
16043
|
}));
|
|
16044
16044
|
}
|
|
16045
|
+
/** This agent's open inbound requests (queued or delivered), oldest first. A read: nothing
|
|
16046
|
+
* is acknowledged. */
|
|
16047
|
+
async listInbox() {
|
|
16048
|
+
if (!this.agent) throw new Error("hub client is not registered");
|
|
16049
|
+
const result = await this.request(
|
|
16050
|
+
`/v1/agents/${encodeURIComponent(this.agent.id)}/inbox`
|
|
16051
|
+
);
|
|
16052
|
+
return result.messages;
|
|
16053
|
+
}
|
|
16045
16054
|
async getMessage(messageId) {
|
|
16046
16055
|
const result = await this.request(`/v1/messages/${encodeURIComponent(messageId)}`);
|
|
16047
16056
|
return result.message;
|
|
@@ -16700,7 +16709,10 @@ var AGENT_COMMANDS = [
|
|
|
16700
16709
|
await reconcileInbox(client, context.inbox, context.notifiedInbox);
|
|
16701
16710
|
return { messages: [...context.inbox.values()] };
|
|
16702
16711
|
}
|
|
16703
|
-
return { messages:
|
|
16712
|
+
if (context?.hubInbox) return { messages: await client.listInbox() };
|
|
16713
|
+
throw new Error(
|
|
16714
|
+
"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"
|
|
16715
|
+
);
|
|
16704
16716
|
}
|
|
16705
16717
|
},
|
|
16706
16718
|
{
|
|
@@ -17296,7 +17308,7 @@ function sessionTokenFixHint(policy) {
|
|
|
17296
17308
|
}
|
|
17297
17309
|
|
|
17298
17310
|
// plugins/kxm/src/mcp-server.ts
|
|
17299
|
-
var VERSION = "0.7.
|
|
17311
|
+
var VERSION = "0.7.100";
|
|
17300
17312
|
var CONFIGURE_PLUGIN = "/plugin configure kxm@kxm";
|
|
17301
17313
|
var inbox = /* @__PURE__ */ new Map();
|
|
17302
17314
|
var notifiedInbox = /* @__PURE__ */ new Set();
|