@kontextmind/kxm 0.7.121 → 0.7.123
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 +18 -0
- package/docs/architecture/access-schema.yaml +60 -0
- package/docs/architecture/access.md +33 -0
- package/docs/architecture/agent-path.md +36 -0
- package/docs/architecture/authentication.md +29 -0
- package/docs/architecture/hosted-direction.md +59 -0
- package/docs/architecture/index.md +19 -0
- package/docs/architecture/inventory.md +38 -0
- package/docs/architecture/platform.md +48 -0
- package/docs/assets/logo.png +0 -0
- package/docs/contributing/assignment-runner.md +25 -22
- package/docs/guides/agent-skills.md +1 -1
- package/docs/index.md +56 -0
- package/docs/javascripts/mermaid-init.js +83 -0
- package/docs/javascripts/mermaid.min.js +4376 -0
- package/docs/reference/cli-reference.md +148 -3
- package/docs/robots.txt +44 -0
- package/docs/stylesheets/extra.css +100 -0
- package/package.json +1 -1
- package/plugins/kxm/.claude-plugin/plugin.json +1 -1
- package/plugins/kxm/dist/cli.js +418 -184
- package/plugins/kxm/dist/mcp-server.js +1 -1
- package/plugins/kxm/package.json +1 -1
- package/plugins/kxm/skills/kxm/SKILL.md +1 -1
- package/plugins/kxm/skills/kxm-runs/SKILL.md +16 -1
- package/plugins/kxm/src/cli/assign.ts +144 -0
- package/plugins/kxm/src/cli/docs.ts +78 -0
- package/plugins/kxm/src/cli.ts +85 -0
- package/plugins/kxm/src/mcp-server.ts +1 -1
- package/schemas/roadmap-state.schema.json +147 -0
package/plugins/kxm/dist/cli.js
CHANGED
|
@@ -18560,8 +18560,8 @@ function validateWorkflow(workflow, agents, models, repositories, gates, issues)
|
|
|
18560
18560
|
const writable = Object.values(objectValue(step.repositories) ?? {}).filter((access) => access === "write").length;
|
|
18561
18561
|
if (maxWriteRepositories > writable) issues.push(issue2("semantic", "write_repository_bound_invalid", file, `${stepId} maxWriteRepositories exceeds writable repository scope`));
|
|
18562
18562
|
}
|
|
18563
|
-
const
|
|
18564
|
-
const minimumPassed =
|
|
18563
|
+
const join56 = objectValue(step.join);
|
|
18564
|
+
const minimumPassed = join56 && typeof join56.minimumPassed === "number" ? join56.minimumPassed : void 0;
|
|
18565
18565
|
if (minimumPassed !== void 0 && minimumPassed > maximum) issues.push(issue2("semantic", "join_impossible", file, `${stepId} minimumPassed exceeds assignment maximum`));
|
|
18566
18566
|
const distinctBy = names(assignment?.distinctBy);
|
|
18567
18567
|
if (distinctBy.length > 0) {
|
|
@@ -20863,7 +20863,7 @@ function compileStep(step, index, stepIndex, requirePlanHash, sink) {
|
|
|
20863
20863
|
const maxAttempts = compileCountField(step.maxAttempts, 1, `${id}.maxAttempts`, id, sink);
|
|
20864
20864
|
const timeoutMs = compileOptionalDuration(step.timeoutMs, `${id}.timeoutMs`, id, sink);
|
|
20865
20865
|
const assignments = compileAssignments(step, id, agent, sink);
|
|
20866
|
-
const
|
|
20866
|
+
const join56 = compileJoin(step, id, sink);
|
|
20867
20867
|
const requiredEvidence = compileEvidence(step, id, sink);
|
|
20868
20868
|
const transitions = compileTransitions(step, id, index, stepIndex, sink);
|
|
20869
20869
|
const outcomes = Object.keys(transitions).sort(compareCodeUnits4);
|
|
@@ -20891,7 +20891,7 @@ function compileStep(step, index, stepIndex, requirePlanHash, sink) {
|
|
|
20891
20891
|
transitions: orderedTransitions,
|
|
20892
20892
|
requiresPlanHash: requirePlanHash.includes(id),
|
|
20893
20893
|
assignments,
|
|
20894
|
-
join:
|
|
20894
|
+
join: join56
|
|
20895
20895
|
};
|
|
20896
20896
|
if (kind === "agent" || kind === "moa") {
|
|
20897
20897
|
if (!agent) return void 0;
|
|
@@ -20941,15 +20941,15 @@ function compileAssignments(step, stepId, primaryAgentId, sink) {
|
|
|
20941
20941
|
};
|
|
20942
20942
|
}
|
|
20943
20943
|
function compileJoin(step, stepId, sink) {
|
|
20944
|
-
const
|
|
20945
|
-
if (!
|
|
20946
|
-
const declared = stringValue2(
|
|
20944
|
+
const join56 = objectValue2(step.join);
|
|
20945
|
+
if (!join56) return { strategy: "all" };
|
|
20946
|
+
const declared = stringValue2(join56.strategy);
|
|
20947
20947
|
const strategy = declared && JOIN_STRATEGIES.has(declared) ? declared : "all";
|
|
20948
|
-
const minimumPassed = compileOptionalCount(
|
|
20948
|
+
const minimumPassed = compileOptionalCount(join56.minimumPassed, `${stepId}.join.minimumPassed`, stepId, sink);
|
|
20949
20949
|
const compiled = {
|
|
20950
20950
|
strategy,
|
|
20951
20951
|
...minimumPassed !== void 0 ? { minimumPassed } : {},
|
|
20952
|
-
...typeof
|
|
20952
|
+
...typeof join56.cancelRemaining === "boolean" ? { cancelRemaining: join56.cancelRemaining } : {}
|
|
20953
20953
|
};
|
|
20954
20954
|
return compiled;
|
|
20955
20955
|
}
|
|
@@ -30324,10 +30324,10 @@ Expecting one of '${allowedValues.join("', '")}'`);
|
|
|
30324
30324
|
* @param {string} flag
|
|
30325
30325
|
* @private
|
|
30326
30326
|
*/
|
|
30327
|
-
unknownOption(
|
|
30327
|
+
unknownOption(flag2) {
|
|
30328
30328
|
if (this._allowUnknownOption) return;
|
|
30329
30329
|
let suggestion = "";
|
|
30330
|
-
if (
|
|
30330
|
+
if (flag2.startsWith("--") && this._showSuggestionAfterError) {
|
|
30331
30331
|
let candidateFlags = [];
|
|
30332
30332
|
let command = this;
|
|
30333
30333
|
do {
|
|
@@ -30335,9 +30335,9 @@ Expecting one of '${allowedValues.join("', '")}'`);
|
|
|
30335
30335
|
candidateFlags = candidateFlags.concat(moreFlags);
|
|
30336
30336
|
command = command.parent;
|
|
30337
30337
|
} while (command && !command._enablePositionalOptions);
|
|
30338
|
-
suggestion = suggestSimilar(
|
|
30338
|
+
suggestion = suggestSimilar(flag2, candidateFlags);
|
|
30339
30339
|
}
|
|
30340
|
-
const message = `error: unknown option '${
|
|
30340
|
+
const message = `error: unknown option '${flag2}'${suggestion}`;
|
|
30341
30341
|
this.error(message, { code: "commander.unknownOption" });
|
|
30342
30342
|
}
|
|
30343
30343
|
/**
|
|
@@ -34136,7 +34136,7 @@ async function cmdWorkflowDefinitions(runtime, options) {
|
|
|
34136
34136
|
}
|
|
34137
34137
|
async function cmdWorkflowAdd(runtime, workflowId, options) {
|
|
34138
34138
|
const scope = options.scope ?? "local";
|
|
34139
|
-
const
|
|
34139
|
+
const refuse4 = (error, message, code = 2) => {
|
|
34140
34140
|
print(runtime.io, runtime.json, { ok: false, command: "workflow add", error, message }, `workflow add failed: ${message}`);
|
|
34141
34141
|
return code;
|
|
34142
34142
|
};
|
|
@@ -34144,12 +34144,12 @@ async function cmdWorkflowAdd(runtime, workflowId, options) {
|
|
|
34144
34144
|
let content;
|
|
34145
34145
|
if (options.template !== void 0) {
|
|
34146
34146
|
if (options.file !== void 0 || options.pick !== void 0) {
|
|
34147
|
-
return
|
|
34147
|
+
return refuse4("workflow_add_conflict", "--template cannot be combined with --file or --pick");
|
|
34148
34148
|
}
|
|
34149
|
-
if (!workflowId) return
|
|
34149
|
+
if (!workflowId) return refuse4("workflow_id_required", "usage: kxm workflow add <workflowId> --template <name>");
|
|
34150
34150
|
const template = Object.hasOwn(WORKFLOW_TEMPLATES, options.template) ? WORKFLOW_TEMPLATES[options.template] : void 0;
|
|
34151
34151
|
if (!template) {
|
|
34152
|
-
return
|
|
34152
|
+
return refuse4("workflow_template_unknown", `unknown template ${options.template}; choose ${Object.keys(WORKFLOW_TEMPLATES).join(", ")}`);
|
|
34153
34153
|
}
|
|
34154
34154
|
content = { ...template, ...options.description !== void 0 ? { description: options.description } : {} };
|
|
34155
34155
|
} else if (!workflowId || options.pick) {
|
|
@@ -34169,7 +34169,7 @@ async function cmdWorkflowAdd(runtime, workflowId, options) {
|
|
|
34169
34169
|
}
|
|
34170
34170
|
const picked = await resolvePickItem(runtime.io, `Select a workflow template to add (${scope})`, candidates, options.pick, runtime.env);
|
|
34171
34171
|
if (!picked) {
|
|
34172
|
-
return
|
|
34172
|
+
return refuse4("workflow_id_required", "provide a workflowId or select an available workflow with --pick <id>", 1);
|
|
34173
34173
|
}
|
|
34174
34174
|
workflowId ??= picked.id;
|
|
34175
34175
|
if (options.file === void 0) {
|
|
@@ -34191,7 +34191,7 @@ async function cmdWorkflowAdd(runtime, workflowId, options) {
|
|
|
34191
34191
|
if (scope === "local") {
|
|
34192
34192
|
const projectRoot = discoverKxmProjectRoot(runtime.cwd);
|
|
34193
34193
|
if (!projectRoot) {
|
|
34194
|
-
return
|
|
34194
|
+
return refuse4("project_not_found", "local workflows belong to a KXM project; run kxm init at the repository root, or pass --scope global");
|
|
34195
34195
|
}
|
|
34196
34196
|
const issues = kxmWorkflowWriteIssues(projectRoot, workflowId, document);
|
|
34197
34197
|
if (issues.length > 0) {
|
|
@@ -34226,7 +34226,7 @@ ${issues.map((entry) => ` ${entry.file}: ${entry.code}: ${entry.message}`).join
|
|
|
34226
34226
|
);
|
|
34227
34227
|
return 0;
|
|
34228
34228
|
} catch (err) {
|
|
34229
|
-
return
|
|
34229
|
+
return refuse4("workflow_add_failed", err instanceof Error ? err.message : String(err), 1);
|
|
34230
34230
|
}
|
|
34231
34231
|
}
|
|
34232
34232
|
async function cmdWorkflowRemove(runtime, workflowId, options) {
|
|
@@ -36612,19 +36612,90 @@ async function cmdPluginInstall(runtime, options) {
|
|
|
36612
36612
|
return ok ? 0 : 1;
|
|
36613
36613
|
}
|
|
36614
36614
|
|
|
36615
|
+
// plugins/kxm/src/cli/docs.ts
|
|
36616
|
+
init_project_config();
|
|
36617
|
+
init_types();
|
|
36618
|
+
import { spawn as spawn4 } from "node:child_process";
|
|
36619
|
+
import { existsSync as existsSync29 } from "node:fs";
|
|
36620
|
+
import { join as join35 } from "node:path";
|
|
36621
|
+
var GENERATOR = "plans/kxm-roadmap/update-dashboard.mjs";
|
|
36622
|
+
var SERVER = "ops/docs-site/serve.py";
|
|
36623
|
+
function requireProject(runtime, command) {
|
|
36624
|
+
const root = discoverKxmProjectRoot(runtime.cwd);
|
|
36625
|
+
if (!root) {
|
|
36626
|
+
print(
|
|
36627
|
+
runtime.io,
|
|
36628
|
+
runtime.json,
|
|
36629
|
+
{ ok: false, command, error: "project_required" },
|
|
36630
|
+
`kxm ${command} requires a KXM project (run kxm init first)`
|
|
36631
|
+
);
|
|
36632
|
+
return 1;
|
|
36633
|
+
}
|
|
36634
|
+
return root;
|
|
36635
|
+
}
|
|
36636
|
+
function requireFile(runtime, command, root, relative8, error) {
|
|
36637
|
+
const file = join35(root, relative8);
|
|
36638
|
+
if (existsSync29(file)) return file;
|
|
36639
|
+
print(
|
|
36640
|
+
runtime.io,
|
|
36641
|
+
runtime.json,
|
|
36642
|
+
{ ok: false, command, error, path: relative8 },
|
|
36643
|
+
`kxm ${command} requires ${relative8}`
|
|
36644
|
+
);
|
|
36645
|
+
return 1;
|
|
36646
|
+
}
|
|
36647
|
+
function printCommand(runtime, command, line) {
|
|
36648
|
+
print(
|
|
36649
|
+
runtime.io,
|
|
36650
|
+
runtime.json,
|
|
36651
|
+
{ ok: true, command, dryRun: true, detail: line },
|
|
36652
|
+
line
|
|
36653
|
+
);
|
|
36654
|
+
return 0;
|
|
36655
|
+
}
|
|
36656
|
+
function runInherited(command, args, cwd) {
|
|
36657
|
+
return new Promise((resolveExit) => {
|
|
36658
|
+
const child = spawn4(command, [...args], { cwd, stdio: "inherit" });
|
|
36659
|
+
child.once("error", () => resolveExit(1));
|
|
36660
|
+
child.once("exit", (code) => resolveExit(code ?? 1));
|
|
36661
|
+
});
|
|
36662
|
+
}
|
|
36663
|
+
async function cmdDocsBuild(runtime) {
|
|
36664
|
+
const command = "docs build";
|
|
36665
|
+
const root = requireProject(runtime, command);
|
|
36666
|
+
if (typeof root === "number") return root;
|
|
36667
|
+
const file = requireFile(runtime, command, root, GENERATOR, "docs_generator_missing");
|
|
36668
|
+
if (typeof file === "number") return file;
|
|
36669
|
+
const line = `node ${GENERATOR}`;
|
|
36670
|
+
if (runtime.dryRun) return printCommand(runtime, command, line);
|
|
36671
|
+
return runInherited(process.execPath, [file], root);
|
|
36672
|
+
}
|
|
36673
|
+
async function cmdDocsServe(runtime, options = {}) {
|
|
36674
|
+
const command = "docs serve";
|
|
36675
|
+
const root = requireProject(runtime, command);
|
|
36676
|
+
if (typeof root === "number") return root;
|
|
36677
|
+
const file = requireFile(runtime, command, root, SERVER, "docs_server_missing");
|
|
36678
|
+
if (typeof file === "number") return file;
|
|
36679
|
+
const args = [file];
|
|
36680
|
+
if (options.port !== void 0 && options.port !== "") args.push("--port", options.port);
|
|
36681
|
+
const line = ["python3", SERVER, ...args.slice(1)].join(" ");
|
|
36682
|
+
if (runtime.dryRun) return printCommand(runtime, command, line);
|
|
36683
|
+
return runInherited("python3", args, root);
|
|
36684
|
+
}
|
|
36685
|
+
|
|
36615
36686
|
// plugins/kxm/src/cli/lanes.ts
|
|
36616
36687
|
init_project_config();
|
|
36617
36688
|
init_runtime_supervisor();
|
|
36618
36689
|
init_types();
|
|
36619
36690
|
import { spawnSync as spawnSync6 } from "node:child_process";
|
|
36620
|
-
import { chmodSync as chmodSync6, existsSync as
|
|
36621
|
-
import { basename as basename8, dirname as dirname18, join as
|
|
36691
|
+
import { chmodSync as chmodSync6, existsSync as existsSync30, mkdirSync as mkdirSync24, readFileSync as readFileSync29, writeFileSync as writeFileSync22 } from "node:fs";
|
|
36692
|
+
import { basename as basename8, dirname as dirname18, join as join36, resolve as resolve25 } from "node:path";
|
|
36622
36693
|
var LANE_SCHEMA = "kxm.lanes.v1";
|
|
36623
36694
|
var SHA_RE = /^[a-f0-9]{40,64}$/;
|
|
36624
36695
|
var TIMESTAMP_RE = /^[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}(?:\.[0-9]{1,9})?Z$/;
|
|
36625
36696
|
var SETTLED_RUN = /* @__PURE__ */ new Set(["completed", "failed", "cancelled"]);
|
|
36626
36697
|
function lanesFile(runtime) {
|
|
36627
|
-
return
|
|
36698
|
+
return join36(runtime.dirs.state, "lanes.json");
|
|
36628
36699
|
}
|
|
36629
36700
|
function gitEnv() {
|
|
36630
36701
|
return Object.fromEntries(Object.entries(process.env).filter(([name]) => !name.toUpperCase().startsWith("GIT_")));
|
|
@@ -36672,7 +36743,7 @@ function isLaneFile(value) {
|
|
|
36672
36743
|
}
|
|
36673
36744
|
function loadLanes(runtime, command) {
|
|
36674
36745
|
const file = lanesFile(runtime);
|
|
36675
|
-
if (!
|
|
36746
|
+
if (!existsSync30(file)) return { schema: LANE_SCHEMA, lanes: {} };
|
|
36676
36747
|
try {
|
|
36677
36748
|
const parsed = JSON.parse(readFileSync29(file, "utf8"));
|
|
36678
36749
|
if (!isLaneFile(parsed)) return refuse(runtime, command, "lanes_unreadable", `lane record ${file} is malformed`);
|
|
@@ -36731,7 +36802,7 @@ function withLaneCwd(runtime, unit, command = "lane") {
|
|
|
36731
36802
|
const loaded = loadLanes(runtime, command);
|
|
36732
36803
|
if (typeof loaded === "number") return loaded;
|
|
36733
36804
|
const lane = loaded.lanes[unit];
|
|
36734
|
-
if (!lane || !
|
|
36805
|
+
if (!lane || !existsSync30(lane.path)) {
|
|
36735
36806
|
return refuse(runtime, command, "lane_missing", `lane ${unit} is not recorded or its worktree is absent`, { unit });
|
|
36736
36807
|
}
|
|
36737
36808
|
return {
|
|
@@ -36802,7 +36873,7 @@ function aheadBehind(path4, baseSha) {
|
|
|
36802
36873
|
return { behind: Number(match[1]), ahead: Number(match[2]) };
|
|
36803
36874
|
}
|
|
36804
36875
|
function laneView(unit, record) {
|
|
36805
|
-
const exists =
|
|
36876
|
+
const exists = existsSync30(record.path);
|
|
36806
36877
|
const counts = exists ? aheadBehind(record.path, record.baseSha) : { ahead: null, behind: null };
|
|
36807
36878
|
return {
|
|
36808
36879
|
unit,
|
|
@@ -36893,7 +36964,7 @@ async function cmdLaneCreate(runtime, unit, options = {}) {
|
|
|
36893
36964
|
const loaded = loadLanes(runtime, command);
|
|
36894
36965
|
if (typeof loaded === "number") return loaded;
|
|
36895
36966
|
const path4 = laneWorktreePath(root, unit);
|
|
36896
|
-
if (loaded.lanes[unit] ||
|
|
36967
|
+
if (loaded.lanes[unit] || existsSync30(path4) || branchExists(root, unit)) {
|
|
36897
36968
|
return refuse(runtime, command, "lane_exists", `lane ${unit} already exists`, { unit });
|
|
36898
36969
|
}
|
|
36899
36970
|
const baseSha = resolveBase(root, base);
|
|
@@ -36918,7 +36989,7 @@ async function cmdLaneCreate(runtime, unit, options = {}) {
|
|
|
36918
36989
|
return refuse(runtime, command, "lane_git_failed", `git worktree add failed: ${added.stderr.trim().slice(0, 300)}`, { unit });
|
|
36919
36990
|
}
|
|
36920
36991
|
const recordedPath = discoverKxmProjectRoot(path4) ?? path4;
|
|
36921
|
-
if (!
|
|
36992
|
+
if (!existsSync30(join36(recordedPath, ".kxm", "project.yaml"))) {
|
|
36922
36993
|
git2(root, ["worktree", "remove", "--force", path4]);
|
|
36923
36994
|
return refuse(runtime, command, "lane_not_project", `lane ${recordedPath} has no .kxm/project.yaml; the worktree was removed`, { unit, path: recordedPath });
|
|
36924
36995
|
}
|
|
@@ -36982,7 +37053,7 @@ async function cmdLaneDrop(runtime, unit, options = {}) {
|
|
|
36982
37053
|
if (!record) return refuse(runtime, command, "lane_missing", `lane ${unit} is not recorded`, { unit });
|
|
36983
37054
|
const force = options.force === true;
|
|
36984
37055
|
if (!force) {
|
|
36985
|
-
if (
|
|
37056
|
+
if (existsSync30(record.path)) {
|
|
36986
37057
|
const dirty = porcelainCount(record.path);
|
|
36987
37058
|
if (dirty === null) {
|
|
36988
37059
|
return refuse(runtime, command, "lane_git_failed", `lane ${unit} worktree status could not be read`, { unit });
|
|
@@ -37001,7 +37072,7 @@ async function cmdLaneDrop(runtime, unit, options = {}) {
|
|
|
37001
37072
|
], `drop lane ${unit}; branch ${record.branch} is not deleted`);
|
|
37002
37073
|
return 0;
|
|
37003
37074
|
}
|
|
37004
|
-
if (
|
|
37075
|
+
if (existsSync30(record.path)) {
|
|
37005
37076
|
const removed = git2(root, ["worktree", "remove", ...force ? ["--force"] : [], record.path]);
|
|
37006
37077
|
if (removed.status !== 0) {
|
|
37007
37078
|
return refuse(runtime, command, "lane_git_failed", `git worktree remove failed: ${removed.stderr.trim().slice(0, 300)}`, { unit });
|
|
@@ -37071,8 +37142,8 @@ async function cmdLaneRun(runtime, unit, options) {
|
|
|
37071
37142
|
init_project_config();
|
|
37072
37143
|
init_repo_root();
|
|
37073
37144
|
init_types();
|
|
37074
|
-
import { spawn as
|
|
37075
|
-
import { join as
|
|
37145
|
+
import { spawn as spawn5 } from "node:child_process";
|
|
37146
|
+
import { join as join37 } from "node:path";
|
|
37076
37147
|
function childEnv() {
|
|
37077
37148
|
const env = {};
|
|
37078
37149
|
for (const [name, value] of Object.entries(process.env)) {
|
|
@@ -37091,7 +37162,7 @@ function cmdLand(runtime, options = {}) {
|
|
|
37091
37162
|
if (!root) {
|
|
37092
37163
|
return Promise.resolve(refuse2(runtime, "project_required", "land requires a KXM project (run kxm init first)"));
|
|
37093
37164
|
}
|
|
37094
|
-
const script =
|
|
37165
|
+
const script = join37(findKxmRepoRoot(import.meta.url), "scripts", "pr-land.mjs");
|
|
37095
37166
|
const args = [script];
|
|
37096
37167
|
if (options.pr) args.push("--pr", options.pr);
|
|
37097
37168
|
if (options.stage) args.push("--stage", options.stage);
|
|
@@ -37099,7 +37170,7 @@ function cmdLand(runtime, options = {}) {
|
|
|
37099
37170
|
if (runtime.json) args.push("--json");
|
|
37100
37171
|
if (runtime.dryRun) args.push("--dry-run");
|
|
37101
37172
|
return new Promise((resolveExit) => {
|
|
37102
|
-
const child =
|
|
37173
|
+
const child = spawn5(process.execPath, args, { cwd: root, env: childEnv(), windowsHide: true });
|
|
37103
37174
|
child.stdout.on("data", (chunk) => runtime.io.stdout(chunk.toString("utf8")));
|
|
37104
37175
|
child.stderr.on("data", (chunk) => runtime.io.stderr(chunk.toString("utf8")));
|
|
37105
37176
|
child.once("error", () => resolveExit(1));
|
|
@@ -37107,11 +37178,116 @@ function cmdLand(runtime, options = {}) {
|
|
|
37107
37178
|
});
|
|
37108
37179
|
}
|
|
37109
37180
|
|
|
37181
|
+
// plugins/kxm/src/cli/assign.ts
|
|
37182
|
+
init_project_config();
|
|
37183
|
+
init_types();
|
|
37184
|
+
import { spawnSync as spawnSync7 } from "node:child_process";
|
|
37185
|
+
import { existsSync as existsSync31 } from "node:fs";
|
|
37186
|
+
import { join as join38 } from "node:path";
|
|
37187
|
+
var kxmAssignCliSeams = {};
|
|
37188
|
+
var RUNNER_REL = "scripts/assignment-run.mjs";
|
|
37189
|
+
function refuse3(runtime, command, error, text) {
|
|
37190
|
+
print(runtime.io, runtime.json, { ok: false, command, error }, text);
|
|
37191
|
+
return 1;
|
|
37192
|
+
}
|
|
37193
|
+
function flag(value) {
|
|
37194
|
+
if (value === void 0) throw new Error("assign invocation missing a parsed flag");
|
|
37195
|
+
return value;
|
|
37196
|
+
}
|
|
37197
|
+
function runnerArgv(subcommand, args) {
|
|
37198
|
+
switch (subcommand) {
|
|
37199
|
+
case "run":
|
|
37200
|
+
return ["run", "--manifest", flag(args.manifest)];
|
|
37201
|
+
case "witness":
|
|
37202
|
+
return ["witness", "--record-dir", flag(args.recordDir)];
|
|
37203
|
+
case "plan-current":
|
|
37204
|
+
return [
|
|
37205
|
+
"plan-current",
|
|
37206
|
+
"--task-dir",
|
|
37207
|
+
flag(args.taskDir),
|
|
37208
|
+
"--plan",
|
|
37209
|
+
flag(args.plan),
|
|
37210
|
+
"--sha256",
|
|
37211
|
+
flag(args.sha256),
|
|
37212
|
+
"--base-commit",
|
|
37213
|
+
flag(args.baseCommit),
|
|
37214
|
+
"--expected-generation",
|
|
37215
|
+
flag(args.expectedGeneration)
|
|
37216
|
+
];
|
|
37217
|
+
case "attribute":
|
|
37218
|
+
return [
|
|
37219
|
+
"attribute",
|
|
37220
|
+
"--task-dir",
|
|
37221
|
+
flag(args.taskDir),
|
|
37222
|
+
"--record-dir",
|
|
37223
|
+
flag(args.recordDir),
|
|
37224
|
+
"--class",
|
|
37225
|
+
flag(args.classification),
|
|
37226
|
+
"--explanation-file",
|
|
37227
|
+
flag(args.explanationFile)
|
|
37228
|
+
];
|
|
37229
|
+
case "observe-cost":
|
|
37230
|
+
return ["observe-cost", "--task-dir", flag(args.taskDir), "--input", flag(args.input)];
|
|
37231
|
+
case "accept": {
|
|
37232
|
+
const argv = [
|
|
37233
|
+
"accept",
|
|
37234
|
+
"--task-dir",
|
|
37235
|
+
flag(args.taskDir),
|
|
37236
|
+
"--commit",
|
|
37237
|
+
flag(args.commit),
|
|
37238
|
+
"--record-dir",
|
|
37239
|
+
flag(args.recordDir)
|
|
37240
|
+
];
|
|
37241
|
+
for (const critic of args.critics ?? []) argv.push("--critic", critic);
|
|
37242
|
+
if (args.observedPr !== void 0) argv.push("--observed-pr", args.observedPr);
|
|
37243
|
+
if (args.observedCi !== void 0) argv.push("--observed-ci", args.observedCi);
|
|
37244
|
+
return argv;
|
|
37245
|
+
}
|
|
37246
|
+
case "change-report":
|
|
37247
|
+
return ["change-report", "--task-dir", flag(args.taskDir)];
|
|
37248
|
+
default: {
|
|
37249
|
+
const unreachable = subcommand;
|
|
37250
|
+
throw new Error(`unknown assign verb ${String(unreachable)}`);
|
|
37251
|
+
}
|
|
37252
|
+
}
|
|
37253
|
+
}
|
|
37254
|
+
async function cmdAssign(runtime, subcommand, args) {
|
|
37255
|
+
const command = `assign ${subcommand}`;
|
|
37256
|
+
const root = discoverKxmProjectRoot(runtime.cwd);
|
|
37257
|
+
if (!root) return refuse3(runtime, command, "project_required", `${command} requires a KXM project (run kxm init first)`);
|
|
37258
|
+
if (!existsSync31(join38(root, "scripts", "assignment-run.mjs"))) {
|
|
37259
|
+
return refuse3(runtime, command, "assign_runner_missing", `${command} requires scripts/assignment-run.mjs in the project root`);
|
|
37260
|
+
}
|
|
37261
|
+
const argv = ["node", RUNNER_REL, ...runnerArgv(subcommand, args)];
|
|
37262
|
+
if (runtime.dryRun) {
|
|
37263
|
+
const payload = { schema: CLI_RESULT_SCHEMA, ok: true, command, dryRun: true, argv };
|
|
37264
|
+
runtime.io.stdout(runtime.json ? `${JSON.stringify(payload)}
|
|
37265
|
+
` : `${argv.join(" ")}
|
|
37266
|
+
`);
|
|
37267
|
+
return 0;
|
|
37268
|
+
}
|
|
37269
|
+
const spawn6 = kxmAssignCliSeams.spawn ?? ((commandName, commandArgs, options) => {
|
|
37270
|
+
const result2 = spawnSync7(commandName, commandArgs, {
|
|
37271
|
+
cwd: options.cwd,
|
|
37272
|
+
stdio: options.stdio,
|
|
37273
|
+
env: options.env,
|
|
37274
|
+
windowsHide: true
|
|
37275
|
+
});
|
|
37276
|
+
return { status: result2.status, ...result2.error ? { error: result2.error } : {} };
|
|
37277
|
+
});
|
|
37278
|
+
const result = spawn6("node", argv.slice(1), { cwd: root, stdio: "inherit", env: runtime.env });
|
|
37279
|
+
if (result.status === null) {
|
|
37280
|
+
const detail = result.error?.message ?? "the assignment runner could not be started";
|
|
37281
|
+
return refuse3(runtime, command, "assign_spawn_failed", detail);
|
|
37282
|
+
}
|
|
37283
|
+
return result.status;
|
|
37284
|
+
}
|
|
37285
|
+
|
|
37110
37286
|
// plugins/kxm/src/cli/hub.ts
|
|
37111
37287
|
init_redact();
|
|
37112
37288
|
import { randomUUID as randomUUID13 } from "node:crypto";
|
|
37113
|
-
import { existsSync as
|
|
37114
|
-
import { join as
|
|
37289
|
+
import { existsSync as existsSync37, mkdirSync as mkdirSync28, readFileSync as readFileSync35, readdirSync as readdirSync12, rmSync as rmSync11, writeFileSync as writeFileSync25 } from "node:fs";
|
|
37290
|
+
import { join as join48, resolve as resolve28 } from "node:path";
|
|
37115
37291
|
init_hub_env();
|
|
37116
37292
|
init_envelope();
|
|
37117
37293
|
|
|
@@ -42809,7 +42985,7 @@ import * as path2 from "node:path";
|
|
|
42809
42985
|
|
|
42810
42986
|
// node_modules/@earendil-works/pi-tui/dist/native-module-path.js
|
|
42811
42987
|
import { createRequire as createRequire2 } from "node:module";
|
|
42812
|
-
import { dirname as dirname19, join as
|
|
42988
|
+
import { dirname as dirname19, join as join39 } from "node:path";
|
|
42813
42989
|
import { fileURLToPath as fileURLToPath2 } from "node:url";
|
|
42814
42990
|
var moduleRequire = createRequire2(import.meta.url);
|
|
42815
42991
|
var TUI_PACKAGE_NAME = "@earendil-works/pi-tui";
|
|
@@ -42818,10 +42994,10 @@ function getNativeModuleCandidates(nativePath, options = {}) {
|
|
|
42818
42994
|
const candidates = [];
|
|
42819
42995
|
try {
|
|
42820
42996
|
const packageEntry = (options.resolvePackage ?? moduleRequire.resolve)(TUI_PACKAGE_NAME);
|
|
42821
|
-
candidates.push(
|
|
42997
|
+
candidates.push(join39(dirname19(packageEntry), "..", nativePath));
|
|
42822
42998
|
} catch {
|
|
42823
42999
|
}
|
|
42824
|
-
candidates.push(
|
|
43000
|
+
candidates.push(join39(moduleDir, "..", nativePath), join39(moduleDir, nativePath), join39(dirname19(options.execPath ?? process.execPath), nativePath));
|
|
42825
43001
|
return Array.from(new Set(candidates));
|
|
42826
43002
|
}
|
|
42827
43003
|
|
|
@@ -45552,8 +45728,8 @@ var MAX_RENDER_WRITE_CHARS = 1024 * 1024;
|
|
|
45552
45728
|
|
|
45553
45729
|
// plugins/kxm/src/tui.ts
|
|
45554
45730
|
import { mkdirSync as mkdirSync25 } from "node:fs";
|
|
45555
|
-
import { join as
|
|
45556
|
-
import { spawnSync as
|
|
45731
|
+
import { join as join43, resolve as resolve27, dirname as dirname20 } from "node:path";
|
|
45732
|
+
import { spawnSync as spawnSync8 } from "node:child_process";
|
|
45557
45733
|
|
|
45558
45734
|
// packages/core/tui/src/types/surface.ts
|
|
45559
45735
|
var KXM_TUI_LIMITS = Object.freeze({
|
|
@@ -45696,9 +45872,9 @@ var SHARED_EFFECT_KINDS = Object.freeze([
|
|
|
45696
45872
|
// plugins/kxm/src/local-snapshot.ts
|
|
45697
45873
|
init_sqlite();
|
|
45698
45874
|
init_telemetry();
|
|
45699
|
-
import { existsSync as
|
|
45875
|
+
import { existsSync as existsSync32, readdirSync as readdirSync11, readFileSync as readFileSync30 } from "node:fs";
|
|
45700
45876
|
import { homedir as homedir6 } from "node:os";
|
|
45701
|
-
import { isAbsolute as isAbsolute9, join as
|
|
45877
|
+
import { isAbsolute as isAbsolute9, join as join42, resolve as resolve26 } from "node:path";
|
|
45702
45878
|
var DEFAULT_BUSY_TIMEOUT_MS = 5e3;
|
|
45703
45879
|
var RUNTIME_PROJECT_KEY = /^[A-Za-z0-9_-][A-Za-z0-9._-]*$/;
|
|
45704
45880
|
function processExists2(pid) {
|
|
@@ -45823,36 +45999,36 @@ function readOpenMessageMetadata(database, where = OPEN_MESSAGE_WHERE, params =
|
|
|
45823
45999
|
return messages;
|
|
45824
46000
|
}
|
|
45825
46001
|
function resolveKxmSnapshotPaths(cwd, env = process.env) {
|
|
45826
|
-
const stateDir = env.KXM_STATE_DIR?.trim() ||
|
|
46002
|
+
const stateDir = env.KXM_STATE_DIR?.trim() || join42(cwd, ".kxm", "state");
|
|
45827
46003
|
const configured = env.KXM_DATA_PATH?.trim();
|
|
45828
|
-
const dataPath = configured ? resolve26(cwd, configured) :
|
|
46004
|
+
const dataPath = configured ? resolve26(cwd, configured) : join42(stateDir, "kxm.db");
|
|
45829
46005
|
return { dataPath, stateDir };
|
|
45830
46006
|
}
|
|
45831
46007
|
function resolveKxmStateRoot(stateDir, options) {
|
|
45832
|
-
if (options?.kxmStateRoot &&
|
|
46008
|
+
if (options?.kxmStateRoot && existsSync32(options.kxmStateRoot)) {
|
|
45833
46009
|
return resolve26(options.kxmStateRoot);
|
|
45834
46010
|
}
|
|
45835
|
-
if (
|
|
46011
|
+
if (existsSync32(join42(stateDir, "runtime", "registry.db")) || existsSync32(join42(stateDir, "runtime", "projects"))) {
|
|
45836
46012
|
return stateDir;
|
|
45837
46013
|
}
|
|
45838
46014
|
const env = options?.env ?? process.env;
|
|
45839
46015
|
const explicit = env.KXM_STATE_HOME?.trim() || env.KXM_USER_STATE_DIR?.trim() || env.KXM_STATE_ROOT?.trim();
|
|
45840
|
-
if (explicit && isAbsolute9(explicit) &&
|
|
46016
|
+
if (explicit && isAbsolute9(explicit) && existsSync32(resolve26(explicit))) {
|
|
45841
46017
|
return resolve26(explicit);
|
|
45842
46018
|
}
|
|
45843
46019
|
let base;
|
|
45844
46020
|
if (process.platform === "win32") {
|
|
45845
46021
|
const localAppData = env.LOCALAPPDATA?.trim();
|
|
45846
|
-
base = localAppData && isAbsolute9(localAppData) ? localAppData :
|
|
46022
|
+
base = localAppData && isAbsolute9(localAppData) ? localAppData : join42(homedir6(), "AppData", "Local");
|
|
45847
46023
|
base = resolve26(base, "KXM");
|
|
45848
46024
|
} else if (process.platform === "darwin") {
|
|
45849
46025
|
base = resolve26(homedir6(), "Library", "Application Support", "KXM");
|
|
45850
46026
|
} else {
|
|
45851
46027
|
const xdgState = env.XDG_STATE_HOME?.trim();
|
|
45852
|
-
base = xdgState && isAbsolute9(xdgState) ? xdgState :
|
|
46028
|
+
base = xdgState && isAbsolute9(xdgState) ? xdgState : join42(homedir6(), ".local", "state");
|
|
45853
46029
|
base = resolve26(base, "kxm");
|
|
45854
46030
|
}
|
|
45855
|
-
if (
|
|
46031
|
+
if (existsSync32(base)) return base;
|
|
45856
46032
|
return void 0;
|
|
45857
46033
|
}
|
|
45858
46034
|
function readRuntimeRuns(eventDb, projectId) {
|
|
@@ -45885,7 +46061,7 @@ function loadLocalMeshSnapshot(dataPath, stateDir, options) {
|
|
|
45885
46061
|
let legacyRuns = [];
|
|
45886
46062
|
let legacyRunTotal = 0;
|
|
45887
46063
|
let plans = [];
|
|
45888
|
-
if (
|
|
46064
|
+
if (existsSync32(dataPath)) {
|
|
45889
46065
|
hasLegacy = true;
|
|
45890
46066
|
const database = openReadOnlyDatabase(dataPath);
|
|
45891
46067
|
try {
|
|
@@ -45916,11 +46092,11 @@ function loadLocalMeshSnapshot(dataPath, stateDir, options) {
|
|
|
45916
46092
|
let kxmRunTotal = 0;
|
|
45917
46093
|
const kxmStateRoot = scope && !scope.runtimeProjectId ? void 0 : resolveKxmStateRoot(stateDir, options);
|
|
45918
46094
|
if (kxmStateRoot) {
|
|
45919
|
-
const runtimeDir =
|
|
45920
|
-
const registryDbPath =
|
|
45921
|
-
const projectsDir =
|
|
46095
|
+
const runtimeDir = join42(kxmStateRoot, "runtime");
|
|
46096
|
+
const registryDbPath = join42(runtimeDir, "registry.db");
|
|
46097
|
+
const projectsDir = join42(runtimeDir, "projects");
|
|
45922
46098
|
const projectKeys = /* @__PURE__ */ new Set();
|
|
45923
|
-
if (
|
|
46099
|
+
if (existsSync32(registryDbPath)) {
|
|
45924
46100
|
hasKxm = true;
|
|
45925
46101
|
try {
|
|
45926
46102
|
const regDb = openReadOnlyDatabase(registryDbPath);
|
|
@@ -45936,7 +46112,7 @@ function loadLocalMeshSnapshot(dataPath, stateDir, options) {
|
|
|
45936
46112
|
} catch {
|
|
45937
46113
|
}
|
|
45938
46114
|
}
|
|
45939
|
-
if (!scope &&
|
|
46115
|
+
if (!scope && existsSync32(projectsDir)) {
|
|
45940
46116
|
try {
|
|
45941
46117
|
for (const entry of readdirSync11(projectsDir, { withFileTypes: true })) {
|
|
45942
46118
|
if (entry.isDirectory()) {
|
|
@@ -45948,8 +46124,8 @@ function loadLocalMeshSnapshot(dataPath, stateDir, options) {
|
|
|
45948
46124
|
}
|
|
45949
46125
|
for (const key of projectKeys) {
|
|
45950
46126
|
if (scope && !RUNTIME_PROJECT_KEY.test(key)) continue;
|
|
45951
|
-
const eventDbPath =
|
|
45952
|
-
if (
|
|
46127
|
+
const eventDbPath = join42(projectsDir, key, "run-events.db");
|
|
46128
|
+
if (existsSync32(eventDbPath)) {
|
|
45953
46129
|
hasKxm = true;
|
|
45954
46130
|
try {
|
|
45955
46131
|
const eventDb = openReadOnlyDatabase(eventDbPath);
|
|
@@ -45967,10 +46143,10 @@ function loadLocalMeshSnapshot(dataPath, stateDir, options) {
|
|
|
45967
46143
|
}
|
|
45968
46144
|
}
|
|
45969
46145
|
const pids = [];
|
|
45970
|
-
if (
|
|
46146
|
+
if (existsSync32(stateDir)) {
|
|
45971
46147
|
for (const file of readdirSync11(stateDir).filter((name) => name.endsWith(".pid"))) {
|
|
45972
46148
|
try {
|
|
45973
|
-
const record = JSON.parse(readFileSync30(
|
|
46149
|
+
const record = JSON.parse(readFileSync30(join42(stateDir, file), "utf8"));
|
|
45974
46150
|
pids.push({
|
|
45975
46151
|
file,
|
|
45976
46152
|
...record.role ? { role: record.role } : {},
|
|
@@ -46009,8 +46185,8 @@ function loadLocalMeshSnapshot(dataPath, stateDir, options) {
|
|
|
46009
46185
|
} else {
|
|
46010
46186
|
source = "legacy";
|
|
46011
46187
|
}
|
|
46012
|
-
const telemetryFile =
|
|
46013
|
-
const spend =
|
|
46188
|
+
const telemetryFile = join42(stateDir, "telemetry.jsonl");
|
|
46189
|
+
const spend = existsSync32(telemetryFile) ? readRoutingRecords(telemetryFile) : [];
|
|
46014
46190
|
return {
|
|
46015
46191
|
source,
|
|
46016
46192
|
agents: agents.sort((a, b2) => Number(b2.online) - Number(a.online) || a.name.localeCompare(b2.name)),
|
|
@@ -46110,16 +46286,16 @@ function applyMeshTuiKey(view, key, itemCount = 0) {
|
|
|
46110
46286
|
function copyToClipboard(text) {
|
|
46111
46287
|
try {
|
|
46112
46288
|
if (process.platform === "darwin") {
|
|
46113
|
-
const proc =
|
|
46289
|
+
const proc = spawnSync8("pbcopy", { input: text, encoding: "utf8", windowsHide: true });
|
|
46114
46290
|
return proc.status === 0;
|
|
46115
46291
|
}
|
|
46116
46292
|
if (process.platform === "win32") {
|
|
46117
|
-
const proc =
|
|
46293
|
+
const proc = spawnSync8("clip", { input: text, encoding: "utf8", windowsHide: true });
|
|
46118
46294
|
return proc.status === 0;
|
|
46119
46295
|
}
|
|
46120
|
-
const wl =
|
|
46296
|
+
const wl = spawnSync8("wl-copy", [text], { encoding: "utf8", windowsHide: true });
|
|
46121
46297
|
if (wl.status === 0) return true;
|
|
46122
|
-
const xclip =
|
|
46298
|
+
const xclip = spawnSync8("xclip", ["-selection", "clipboard"], { input: text, encoding: "utf8", windowsHide: true });
|
|
46123
46299
|
return xclip.status === 0;
|
|
46124
46300
|
} catch {
|
|
46125
46301
|
return false;
|
|
@@ -46127,7 +46303,7 @@ function copyToClipboard(text) {
|
|
|
46127
46303
|
}
|
|
46128
46304
|
function spawnDegradeWorktree(repoRoot, runId, options) {
|
|
46129
46305
|
const runner = options?.execFn ?? ((cmd, args) => {
|
|
46130
|
-
const res =
|
|
46306
|
+
const res = spawnSync8(cmd, args, {
|
|
46131
46307
|
cwd: repoRoot,
|
|
46132
46308
|
encoding: "utf8",
|
|
46133
46309
|
windowsHide: true,
|
|
@@ -46144,7 +46320,7 @@ function spawnDegradeWorktree(repoRoot, runId, options) {
|
|
|
46144
46320
|
const cleanRunId = runId.replace(/^run_/, "");
|
|
46145
46321
|
const desc = options?.description ? slugifyBranchPart(options.description, 30) : "degrade";
|
|
46146
46322
|
const branchName = `kxm/run-${cleanRunId}-${desc}`;
|
|
46147
|
-
const relativeWtPath =
|
|
46323
|
+
const relativeWtPath = join43(".kxm", "worktrees", `run-${cleanRunId}-${desc}`);
|
|
46148
46324
|
const absoluteWtPath = resolve27(repoRoot, relativeWtPath);
|
|
46149
46325
|
const jumpCommand = `cd "${absoluteWtPath}"`;
|
|
46150
46326
|
try {
|
|
@@ -46911,10 +47087,10 @@ async function runMeshTui(input) {
|
|
|
46911
47087
|
}
|
|
46912
47088
|
|
|
46913
47089
|
// plugins/kxm/src/session-work.ts
|
|
46914
|
-
import { spawnSync as
|
|
47090
|
+
import { spawnSync as spawnSync9 } from "node:child_process";
|
|
46915
47091
|
import { randomUUID as randomUUID12 } from "node:crypto";
|
|
46916
|
-
import { existsSync as
|
|
46917
|
-
import { join as
|
|
47092
|
+
import { existsSync as existsSync33, mkdirSync as mkdirSync26, readFileSync as readFileSync31, renameSync as renameSync8, writeFileSync as writeFileSync23 } from "node:fs";
|
|
47093
|
+
import { join as join44 } from "node:path";
|
|
46918
47094
|
init_hub_binding();
|
|
46919
47095
|
init_telemetry();
|
|
46920
47096
|
var MAX_SESSION_BRIEF_TASKS = 5;
|
|
@@ -46972,10 +47148,10 @@ function formatShipLine(ship) {
|
|
|
46972
47148
|
}
|
|
46973
47149
|
function readGitShip(cwd) {
|
|
46974
47150
|
try {
|
|
46975
|
-
const dirty =
|
|
47151
|
+
const dirty = spawnSync9("git", ["-C", cwd, "status", "--porcelain"], { encoding: "utf8", windowsHide: true });
|
|
46976
47152
|
if (dirty.status !== 0) return void 0;
|
|
46977
47153
|
const isDirty = dirty.stdout.trim().length > 0;
|
|
46978
|
-
const upstream =
|
|
47154
|
+
const upstream = spawnSync9("git", ["-C", cwd, "rev-list", "--count", "@{u}..HEAD"], { encoding: "utf8", windowsHide: true });
|
|
46979
47155
|
if (upstream.status === 0) {
|
|
46980
47156
|
return {
|
|
46981
47157
|
dirty: isDirty,
|
|
@@ -46983,9 +47159,9 @@ function readGitShip(cwd) {
|
|
|
46983
47159
|
};
|
|
46984
47160
|
}
|
|
46985
47161
|
for (const baseRef of ["origin/HEAD", "main", "origin/main", "master", "origin/master"]) {
|
|
46986
|
-
const mb =
|
|
47162
|
+
const mb = spawnSync9("git", ["-C", cwd, "merge-base", baseRef, "HEAD"], { encoding: "utf8", windowsHide: true });
|
|
46987
47163
|
if (mb.status === 0 && mb.stdout.trim()) {
|
|
46988
|
-
const count =
|
|
47164
|
+
const count = spawnSync9("git", ["-C", cwd, "rev-list", "--count", `${mb.stdout.trim()}..HEAD`], { encoding: "utf8", windowsHide: true });
|
|
46989
47165
|
if (count.status === 0) {
|
|
46990
47166
|
return {
|
|
46991
47167
|
dirty: isDirty,
|
|
@@ -47073,9 +47249,9 @@ function buildSessionBrief(snapshot, current, hub, ship, updateLatest, cost, ses
|
|
|
47073
47249
|
};
|
|
47074
47250
|
}
|
|
47075
47251
|
function readCachedSessionBrief(stateDir) {
|
|
47076
|
-
const file =
|
|
47252
|
+
const file = join44(stateDir, "session-brief.json");
|
|
47077
47253
|
try {
|
|
47078
|
-
if (!
|
|
47254
|
+
if (!existsSync33(file)) return void 0;
|
|
47079
47255
|
const raw = readFileSync31(file, "utf8");
|
|
47080
47256
|
const parsed = JSON.parse(raw);
|
|
47081
47257
|
if (parsed && parsed.schema === "kxm.session-brief.v1" && typeof parsed.generatedAt === "string") {
|
|
@@ -47092,7 +47268,7 @@ function readCachedSessionBrief(stateDir) {
|
|
|
47092
47268
|
function writeCachedSessionBrief(stateDir, brief) {
|
|
47093
47269
|
try {
|
|
47094
47270
|
mkdirSync26(stateDir, { recursive: true, mode: 448 });
|
|
47095
|
-
const file =
|
|
47271
|
+
const file = join44(stateDir, "session-brief.json");
|
|
47096
47272
|
const tmp = `${file}.tmp.${randomUUID12().slice(0, 8)}`;
|
|
47097
47273
|
writeFileSync23(tmp, JSON.stringify(brief, null, 2), { encoding: "utf8", mode: 384 });
|
|
47098
47274
|
renameSync8(tmp, file);
|
|
@@ -47101,8 +47277,8 @@ function writeCachedSessionBrief(stateDir, brief) {
|
|
|
47101
47277
|
}
|
|
47102
47278
|
function estimateSessionCost(stateDir) {
|
|
47103
47279
|
try {
|
|
47104
|
-
const telemetryFile =
|
|
47105
|
-
if (!
|
|
47280
|
+
const telemetryFile = join44(stateDir, "telemetry.jsonl");
|
|
47281
|
+
if (!existsSync33(telemetryFile)) return void 0;
|
|
47106
47282
|
const records = readRoutingRecords(telemetryFile);
|
|
47107
47283
|
if (records.length === 0) return void 0;
|
|
47108
47284
|
let totalCost = 0;
|
|
@@ -47274,11 +47450,11 @@ init_hub_binding();
|
|
|
47274
47450
|
|
|
47275
47451
|
// plugins/kxm/src/kxm-install-kind.ts
|
|
47276
47452
|
init_bindings();
|
|
47277
|
-
import { existsSync as
|
|
47278
|
-
import { dirname as dirname21, join as
|
|
47453
|
+
import { existsSync as existsSync34, readFileSync as readFileSync32 } from "node:fs";
|
|
47454
|
+
import { dirname as dirname21, join as join45 } from "node:path";
|
|
47279
47455
|
function packageIsKxm(root) {
|
|
47280
47456
|
try {
|
|
47281
|
-
const pkg = JSON.parse(readFileSync32(
|
|
47457
|
+
const pkg = JSON.parse(readFileSync32(join45(root, "package.json"), "utf8"));
|
|
47282
47458
|
return pkg.name === "@kontextmind/kxm";
|
|
47283
47459
|
} catch {
|
|
47284
47460
|
return false;
|
|
@@ -47327,12 +47503,12 @@ function report(kind, root) {
|
|
|
47327
47503
|
return { kind, root, instruction: installKindInstruction(kind, root) };
|
|
47328
47504
|
}
|
|
47329
47505
|
function classifyInstallRoot(probe) {
|
|
47330
|
-
const piGitRoot =
|
|
47506
|
+
const piGitRoot = join45(probe.homeDir, ".pi", "agent", "git");
|
|
47331
47507
|
if (isUnder(probe.repoRoot, piGitRoot, probe.platform)) return report("pi-git", probe.repoRoot);
|
|
47332
|
-
const claudeHome = probe.env.CLAUDE_CONFIG_DIR?.trim() ||
|
|
47333
|
-
const pluginsRoot =
|
|
47508
|
+
const claudeHome = probe.env.CLAUDE_CONFIG_DIR?.trim() || join45(probe.homeDir, ".claude");
|
|
47509
|
+
const pluginsRoot = join45(claudeHome, "plugins");
|
|
47334
47510
|
if (isUnder(probe.moduleDir, pluginsRoot, probe.platform)) return report("claude-marketplace", probe.moduleDir);
|
|
47335
|
-
const hasGit =
|
|
47511
|
+
const hasGit = existsSync34(join45(probe.repoRoot, ".git"));
|
|
47336
47512
|
if (hasGit && packageIsKxm(probe.repoRoot)) return report("source", probe.repoRoot);
|
|
47337
47513
|
if (isNpmPackageLayout(probe.repoRoot, probe.platform) && packageIsKxm(probe.repoRoot) && !hasGit) {
|
|
47338
47514
|
return report("npm-package", probe.repoRoot);
|
|
@@ -47356,12 +47532,12 @@ init_bindings();
|
|
|
47356
47532
|
|
|
47357
47533
|
// plugins/kxm/src/kxm-update-config.ts
|
|
47358
47534
|
var import_yaml16 = __toESM(require_dist(), 1);
|
|
47359
|
-
import { existsSync as
|
|
47360
|
-
import { join as
|
|
47535
|
+
import { existsSync as existsSync35, readFileSync as readFileSync33 } from "node:fs";
|
|
47536
|
+
import { join as join46 } from "node:path";
|
|
47361
47537
|
init_bindings();
|
|
47362
47538
|
function loadKxmUpdateConfig(env = process.env) {
|
|
47363
|
-
const path4 =
|
|
47364
|
-
if (!
|
|
47539
|
+
const path4 = join46(kxmUserStateRoot({ env }), "update.yaml");
|
|
47540
|
+
if (!existsSync35(path4)) return { schema: KXM_UPDATE_SCHEMA, auto: false, source: "github" };
|
|
47365
47541
|
let parsed;
|
|
47366
47542
|
try {
|
|
47367
47543
|
parsed = (0, import_yaml16.parse)(readFileSync33(path4, "utf8"));
|
|
@@ -47392,8 +47568,8 @@ function loadKxmUpdateConfig(env = process.env) {
|
|
|
47392
47568
|
// plugins/kxm/src/session.ts
|
|
47393
47569
|
init_protocol();
|
|
47394
47570
|
init_envelope();
|
|
47395
|
-
import { existsSync as
|
|
47396
|
-
import { join as
|
|
47571
|
+
import { existsSync as existsSync36, mkdirSync as mkdirSync27, readFileSync as readFileSync34, writeFileSync as writeFileSync24 } from "node:fs";
|
|
47572
|
+
import { join as join47 } from "node:path";
|
|
47397
47573
|
var SESSION_SCHEMA = "kxm.session.v1";
|
|
47398
47574
|
var SessionConfigError = class extends Error {
|
|
47399
47575
|
code = "session_config_invalid";
|
|
@@ -47403,12 +47579,12 @@ var SessionConfigError = class extends Error {
|
|
|
47403
47579
|
}
|
|
47404
47580
|
};
|
|
47405
47581
|
function workflowAssetDirs(assetsDir, workflowId) {
|
|
47406
|
-
const root =
|
|
47407
|
-
return [root,
|
|
47582
|
+
const root = join47(assetsDir, "workflows", workflowId);
|
|
47583
|
+
return [root, join47(root, "inputs"), join47(root, "outputs"), join47(root, "generated")];
|
|
47408
47584
|
}
|
|
47409
47585
|
function sessionAssetDirs(assetsDir, sessionId) {
|
|
47410
|
-
const root =
|
|
47411
|
-
return [root,
|
|
47586
|
+
const root = join47(assetsDir, "sessions", sessionId);
|
|
47587
|
+
return [root, join47(root, "inputs"), join47(root, "outputs")];
|
|
47412
47588
|
}
|
|
47413
47589
|
function rosterNames(configDir) {
|
|
47414
47590
|
return [...loadRosterMap(configDir).values()].map((row) => String(row.name));
|
|
@@ -47458,7 +47634,7 @@ function workerFromRosterRow(name, row, project) {
|
|
|
47458
47634
|
function loadRosterMap(configDir) {
|
|
47459
47635
|
const byName = /* @__PURE__ */ new Map();
|
|
47460
47636
|
for (const [file, key] of [["agents.json", "agents"], ["gates.json", "gates"]]) {
|
|
47461
|
-
const path4 =
|
|
47637
|
+
const path4 = join47(configDir, file);
|
|
47462
47638
|
for (const row of loadRoster(path4, key)) {
|
|
47463
47639
|
const name = String(row.name).trim();
|
|
47464
47640
|
const lowered = name.toLowerCase();
|
|
@@ -47472,7 +47648,7 @@ function loadRosterMap(configDir) {
|
|
|
47472
47648
|
return byName;
|
|
47473
47649
|
}
|
|
47474
47650
|
function loadRoster(path4, key) {
|
|
47475
|
-
if (!
|
|
47651
|
+
if (!existsSync36(path4)) return [];
|
|
47476
47652
|
let parsed;
|
|
47477
47653
|
try {
|
|
47478
47654
|
parsed = JSON.parse(readFileSync34(path4, "utf8"));
|
|
@@ -47500,7 +47676,7 @@ function loadRoster(path4, key) {
|
|
|
47500
47676
|
});
|
|
47501
47677
|
}
|
|
47502
47678
|
function createSession(input) {
|
|
47503
|
-
const assetDir = input.mode === "workflow" && input.workflowId ?
|
|
47679
|
+
const assetDir = input.mode === "workflow" && input.workflowId ? join47("assets", "workflows", input.workflowId) : join47("assets", "sessions", input.id);
|
|
47504
47680
|
return {
|
|
47505
47681
|
schema: SESSION_SCHEMA,
|
|
47506
47682
|
id: input.id,
|
|
@@ -47513,8 +47689,8 @@ function createSession(input) {
|
|
|
47513
47689
|
};
|
|
47514
47690
|
}
|
|
47515
47691
|
function writeSession(assetsDir, session, dryRun = false) {
|
|
47516
|
-
const dir =
|
|
47517
|
-
const path4 =
|
|
47692
|
+
const dir = join47(assetsDir, "sessions", session.id);
|
|
47693
|
+
const path4 = join47(dir, "session.json");
|
|
47518
47694
|
if (!dryRun) {
|
|
47519
47695
|
mkdirSync27(dir, { recursive: true });
|
|
47520
47696
|
writeFileSync24(path4, `${JSON.stringify(session, null, 2)}
|
|
@@ -47570,9 +47746,9 @@ function moduleInstallRoot() {
|
|
|
47570
47746
|
}
|
|
47571
47747
|
}
|
|
47572
47748
|
function warnIgnoredProjectUpdateYaml(runtime) {
|
|
47573
|
-
const projectFile =
|
|
47574
|
-
if (!
|
|
47575
|
-
const userFile =
|
|
47749
|
+
const projectFile = join48(runtime.dirs.workspace, "update.yaml");
|
|
47750
|
+
if (!existsSync37(projectFile)) return;
|
|
47751
|
+
const userFile = join48(kxmUserStateRoot({ env: runtime.env }), "update.yaml");
|
|
47576
47752
|
runtime.io.stderr(`kxm: ignoring .kxm/update.yaml in ${runtime.dirs.workdir}; update settings are read only from ${userFile}
|
|
47577
47753
|
`);
|
|
47578
47754
|
}
|
|
@@ -47620,7 +47796,7 @@ async function cmdDash(runtime, options = {}) {
|
|
|
47620
47796
|
return 2;
|
|
47621
47797
|
}
|
|
47622
47798
|
const screen = requested;
|
|
47623
|
-
const dataPath = resolve28(runtime.dirs.workdir, runtime.env.KXM_DATA_PATH?.trim() ||
|
|
47799
|
+
const dataPath = resolve28(runtime.dirs.workdir, runtime.env.KXM_DATA_PATH?.trim() || join48(runtime.dirs.state, "kxm.db"));
|
|
47624
47800
|
if (runtime.dryRun) {
|
|
47625
47801
|
print(runtime.io, runtime.json, {
|
|
47626
47802
|
ok: true,
|
|
@@ -47666,7 +47842,7 @@ async function cmdHub(runtime) {
|
|
|
47666
47842
|
config = loadKxmUpdateConfig(runtime.env);
|
|
47667
47843
|
} catch (error) {
|
|
47668
47844
|
if (error instanceof KxmUpdateConfigError) {
|
|
47669
|
-
const yamlPath =
|
|
47845
|
+
const yamlPath = join48(kxmUserStateRoot({ env: runtime.env }), "update.yaml");
|
|
47670
47846
|
runtime.io.stderr(`kxm: ${error.message}; update check skipped; fix or remove ${yamlPath}
|
|
47671
47847
|
`);
|
|
47672
47848
|
} else {
|
|
@@ -47853,7 +48029,7 @@ async function cmdWorker(runtime, options) {
|
|
|
47853
48029
|
return await (runtime.io.spawnWorker ?? ((launchEnv) => spawnScript("kxm-worker.mjs", launchEnv)))(extraEnv);
|
|
47854
48030
|
}
|
|
47855
48031
|
async function cmdStop(runtime, waitMsFlag) {
|
|
47856
|
-
const pids =
|
|
48032
|
+
const pids = existsSync37(runtime.dirs.state) ? readdirSync12(runtime.dirs.state).filter((name) => name.endsWith(".pid")) : [];
|
|
47857
48033
|
if (runtime.dryRun) {
|
|
47858
48034
|
print(runtime.io, runtime.json, { ok: true, command: "stop", dryRun: true, pidFiles: pids }, "would signal pid files");
|
|
47859
48035
|
return 0;
|
|
@@ -47868,7 +48044,7 @@ async function cmdStop(runtime, waitMsFlag) {
|
|
|
47868
48044
|
const orphans = [];
|
|
47869
48045
|
for (const file of pids) {
|
|
47870
48046
|
try {
|
|
47871
|
-
const record = JSON.parse(readFileSync35(
|
|
48047
|
+
const record = JSON.parse(readFileSync35(join48(runtime.dirs.state, file), "utf8"));
|
|
47872
48048
|
const expectedControl = file === "hub.pid" ? "hub.stop" : file.startsWith("worker-") ? `${file.slice(0, -4)}.stop` : void 0;
|
|
47873
48049
|
const expectedRole = file === "hub.pid" ? "hub" : file.startsWith("worker-") ? "worker" : void 0;
|
|
47874
48050
|
if (record.version !== 1 || !Number.isInteger(record.pid) || record.pid <= 0 || !record.startedAt || !expectedControl || record.controlFile !== expectedControl || record.role !== expectedRole) {
|
|
@@ -47888,7 +48064,7 @@ async function cmdStop(runtime, waitMsFlag) {
|
|
|
47888
48064
|
ignored.push(file);
|
|
47889
48065
|
continue;
|
|
47890
48066
|
}
|
|
47891
|
-
writeFileSync25(
|
|
48067
|
+
writeFileSync25(join48(runtime.dirs.state, record.controlFile), `${JSON.stringify({ startedAt: record.startedAt, ...record.generation ? { generation: record.generation } : {}, requestedAt: (/* @__PURE__ */ new Date()).toISOString() })}
|
|
47892
48068
|
`, { encoding: "utf8", mode: 384 });
|
|
47893
48069
|
requested.push(file);
|
|
47894
48070
|
records.set(file, { pid: record.pid, startedAt: record.startedAt, ...record.generation ? { generation: record.generation } : {} });
|
|
@@ -47906,7 +48082,7 @@ async function cmdStop(runtime, waitMsFlag) {
|
|
|
47906
48082
|
while (Date.now() <= deadline && stopped.size < requested.length) {
|
|
47907
48083
|
for (const [file, record] of records) {
|
|
47908
48084
|
try {
|
|
47909
|
-
const current = JSON.parse(readFileSync35(
|
|
48085
|
+
const current = JSON.parse(readFileSync35(join48(runtime.dirs.state, file), "utf8"));
|
|
47910
48086
|
if (current.pid !== record.pid || current.startedAt !== record.startedAt || current.generation !== record.generation || !processExists(record.pid)) stopped.add(file);
|
|
47911
48087
|
} catch {
|
|
47912
48088
|
stopped.add(file);
|
|
@@ -47919,7 +48095,7 @@ async function cmdStop(runtime, waitMsFlag) {
|
|
|
47919
48095
|
for (const file of orphans) {
|
|
47920
48096
|
while (Date.now() <= deadlineOrphans) {
|
|
47921
48097
|
try {
|
|
47922
|
-
const current = JSON.parse(readFileSync35(
|
|
48098
|
+
const current = JSON.parse(readFileSync35(join48(runtime.dirs.state, file), "utf8"));
|
|
47923
48099
|
if (!Number.isInteger(current.serverPid) || !processExists(current.serverPid)) break;
|
|
47924
48100
|
} catch {
|
|
47925
48101
|
break;
|
|
@@ -47927,14 +48103,14 @@ async function cmdStop(runtime, waitMsFlag) {
|
|
|
47927
48103
|
await (runtime.io.sleep ?? ((ms) => new Promise((resolveSleep) => setTimeout(resolveSleep, ms))))(100);
|
|
47928
48104
|
}
|
|
47929
48105
|
try {
|
|
47930
|
-
const current = JSON.parse(readFileSync35(
|
|
48106
|
+
const current = JSON.parse(readFileSync35(join48(runtime.dirs.state, file), "utf8"));
|
|
47931
48107
|
if (Number.isInteger(current.serverPid) && processExists(current.serverPid)) {
|
|
47932
48108
|
try {
|
|
47933
48109
|
process.kill(current.serverPid, "SIGKILL");
|
|
47934
48110
|
} catch {
|
|
47935
48111
|
}
|
|
47936
48112
|
}
|
|
47937
|
-
rmSync11(
|
|
48113
|
+
rmSync11(join48(runtime.dirs.state, file), { force: true });
|
|
47938
48114
|
} catch {
|
|
47939
48115
|
}
|
|
47940
48116
|
stopped.add(file);
|
|
@@ -47945,11 +48121,11 @@ async function cmdStop(runtime, waitMsFlag) {
|
|
|
47945
48121
|
}
|
|
47946
48122
|
async function cmdSessionStatus(runtime) {
|
|
47947
48123
|
const stateDir = runtime.dirs.state;
|
|
47948
|
-
const names3 =
|
|
48124
|
+
const names3 = existsSync37(stateDir) ? readdirSync12(stateDir) : [];
|
|
47949
48125
|
const claims = [];
|
|
47950
48126
|
for (const file of names3.filter((name) => name.endsWith(".pid"))) {
|
|
47951
48127
|
try {
|
|
47952
|
-
const record = JSON.parse(readFileSync35(
|
|
48128
|
+
const record = JSON.parse(readFileSync35(join48(stateDir, file), "utf8"));
|
|
47953
48129
|
claims.push({
|
|
47954
48130
|
file,
|
|
47955
48131
|
role: record.role,
|
|
@@ -47964,7 +48140,7 @@ async function cmdSessionStatus(runtime) {
|
|
|
47964
48140
|
const recoveries = [];
|
|
47965
48141
|
for (const file of names3.filter((name) => name.startsWith("worker-recovery-") && name.endsWith(".json"))) {
|
|
47966
48142
|
try {
|
|
47967
|
-
const envelope = JSON.parse(readFileSync35(
|
|
48143
|
+
const envelope = JSON.parse(readFileSync35(join48(stateDir, file), "utf8"));
|
|
47968
48144
|
recoveries.push({
|
|
47969
48145
|
file,
|
|
47970
48146
|
reason: envelope.reason,
|
|
@@ -47990,7 +48166,7 @@ async function cmdSessionStatus(runtime) {
|
|
|
47990
48166
|
async function cmdAuthToken(runtime, options = {}) {
|
|
47991
48167
|
const tokenFile = sessionTokenPath(runtime.env.KXM_USER_CONFIG_DIR);
|
|
47992
48168
|
if (options.clear && runtime.dryRun) {
|
|
47993
|
-
const present =
|
|
48169
|
+
const present = existsSync37(tokenFile);
|
|
47994
48170
|
printPlan(runtime, { command: "auth token", cleared: present }, present ? [{ action: "delete", target: tokenFile }] : [], present ? "clear the session token from disk" : "no session token file to clear");
|
|
47995
48171
|
return 0;
|
|
47996
48172
|
}
|
|
@@ -48079,7 +48255,7 @@ async function cmdSessionBrief(runtime, options = {}) {
|
|
|
48079
48255
|
print(runtime.io, runtime.json, { ok: true, command: "session brief", sessionToken }, sessionToken);
|
|
48080
48256
|
return 0;
|
|
48081
48257
|
}
|
|
48082
|
-
const dataPath = resolve28(runtime.dirs.workdir, runtime.env.KXM_DATA_PATH?.trim() ||
|
|
48258
|
+
const dataPath = resolve28(runtime.dirs.workdir, runtime.env.KXM_DATA_PATH?.trim() || join48(runtime.dirs.state, "kxm.db"));
|
|
48083
48259
|
const env = {
|
|
48084
48260
|
...runtime.env,
|
|
48085
48261
|
KXM_STATE_DIR: runtime.dirs.state,
|
|
@@ -48105,7 +48281,7 @@ async function cmdSessionBrief(runtime, options = {}) {
|
|
|
48105
48281
|
writeCache: !runtime.dryRun
|
|
48106
48282
|
});
|
|
48107
48283
|
if (runtime.dryRun) {
|
|
48108
|
-
if (!readCachedSessionBrief(runtime.dirs.state)) planned.push({ action: "write", target:
|
|
48284
|
+
if (!readCachedSessionBrief(runtime.dirs.state)) planned.push({ action: "write", target: join48(runtime.dirs.state, "session-brief.json") });
|
|
48109
48285
|
print(runtime.io, runtime.json, { ...brief, dryRun: true, planned }, [
|
|
48110
48286
|
options.status ? brief.statusLine : formatSessionBriefText(brief),
|
|
48111
48287
|
...planned.map((change) => `dry run: would ${change.action} ${change.target}`)
|
|
@@ -48187,11 +48363,11 @@ init_redact();
|
|
|
48187
48363
|
init_telemetry();
|
|
48188
48364
|
init_routing();
|
|
48189
48365
|
init_prices();
|
|
48190
|
-
import { spawnSync as
|
|
48366
|
+
import { spawnSync as spawnSync11 } from "node:child_process";
|
|
48191
48367
|
import { createHash as createHash17 } from "node:crypto";
|
|
48192
|
-
import { existsSync as
|
|
48368
|
+
import { existsSync as existsSync44, mkdtempSync as mkdtempSync3, readFileSync as readFileSync40, rmSync as rmSync13 } from "node:fs";
|
|
48193
48369
|
import { tmpdir as tmpdir2 } from "node:os";
|
|
48194
|
-
import { basename as basename11, extname as extname3, join as
|
|
48370
|
+
import { basename as basename11, extname as extname3, join as join54, resolve as resolve33 } from "node:path";
|
|
48195
48371
|
import { createInterface as createInterface3 } from "node:readline";
|
|
48196
48372
|
|
|
48197
48373
|
// plugins/kxm/src/improve.ts
|
|
@@ -48199,8 +48375,8 @@ init_routing();
|
|
|
48199
48375
|
init_protocol();
|
|
48200
48376
|
init_relevance();
|
|
48201
48377
|
import { createHash as createHash16 } from "node:crypto";
|
|
48202
|
-
import { existsSync as
|
|
48203
|
-
import { join as
|
|
48378
|
+
import { existsSync as existsSync38, mkdirSync as mkdirSync29, writeFileSync as writeFileSync26 } from "node:fs";
|
|
48379
|
+
import { join as join49, relative as relative7, resolve as resolve29 } from "node:path";
|
|
48204
48380
|
var CANDIDATE_SCHEMA = "kxm.candidate.v1";
|
|
48205
48381
|
var IMPROVEMENT_REPORT_SCHEMA = "kxm.improvement-report.v2";
|
|
48206
48382
|
function classifyCandidateKind(stepId, agentRole) {
|
|
@@ -48456,7 +48632,7 @@ function groupRoutingRecords(records, options = {}) {
|
|
|
48456
48632
|
}
|
|
48457
48633
|
function buildImprovementReport(records, options = {}) {
|
|
48458
48634
|
const projectRoot = options.projectRoot ? resolve29(options.projectRoot) : process.cwd();
|
|
48459
|
-
const candidatesDir = options.candidatesDir ? resolve29(options.candidatesDir) :
|
|
48635
|
+
const candidatesDir = options.candidatesDir ? resolve29(options.candidatesDir) : join49(projectRoot, ".kxm", "candidates");
|
|
48460
48636
|
const promotionPolicy = options.promotionPolicy ?? "manual_pr";
|
|
48461
48637
|
const groups = groupRoutingRecords(records, options);
|
|
48462
48638
|
const candidates = [];
|
|
@@ -48470,7 +48646,7 @@ function buildImprovementReport(records, options = {}) {
|
|
|
48470
48646
|
group.workflowId
|
|
48471
48647
|
);
|
|
48472
48648
|
const diffFileName = `${group.candidateId}.diff`;
|
|
48473
|
-
const diffFilePath =
|
|
48649
|
+
const diffFilePath = join49(candidatesDir, diffFileName);
|
|
48474
48650
|
const relDiffPath = relative7(projectRoot, diffFilePath).replace(/\\/g, "/");
|
|
48475
48651
|
const candidate = {
|
|
48476
48652
|
schema: CANDIDATE_SCHEMA,
|
|
@@ -48492,11 +48668,11 @@ function buildImprovementReport(records, options = {}) {
|
|
|
48492
48668
|
createdAt: nowIso()
|
|
48493
48669
|
};
|
|
48494
48670
|
if (!options.dryRun) {
|
|
48495
|
-
if (!
|
|
48671
|
+
if (!existsSync38(candidatesDir)) {
|
|
48496
48672
|
mkdirSync29(candidatesDir, { recursive: true });
|
|
48497
48673
|
}
|
|
48498
48674
|
writeFileSync26(diffFilePath, diff, "utf8");
|
|
48499
|
-
const jsonFilePath =
|
|
48675
|
+
const jsonFilePath = join49(candidatesDir, `${group.candidateId}.json`);
|
|
48500
48676
|
writeFileSync26(jsonFilePath, JSON.stringify(candidate, null, 2) + "\n", "utf8");
|
|
48501
48677
|
}
|
|
48502
48678
|
candidates.push(candidate);
|
|
@@ -48525,7 +48701,7 @@ function buildImprovementReport(records, options = {}) {
|
|
|
48525
48701
|
}
|
|
48526
48702
|
function writeImprovementReport(improvementsDir, report2, dryRun = false) {
|
|
48527
48703
|
const stamp = report2.createdAt.replace(/[:.]/g, "-");
|
|
48528
|
-
const path4 =
|
|
48704
|
+
const path4 = join49(improvementsDir, `${stamp}.json`);
|
|
48529
48705
|
if (!dryRun) {
|
|
48530
48706
|
mkdirSync29(improvementsDir, { recursive: true });
|
|
48531
48707
|
writeFileSync26(path4, `${JSON.stringify(report2, null, 2)}
|
|
@@ -48609,7 +48785,7 @@ init_project_config();
|
|
|
48609
48785
|
init_runtime_store();
|
|
48610
48786
|
init_routing();
|
|
48611
48787
|
init_telemetry();
|
|
48612
|
-
import { existsSync as
|
|
48788
|
+
import { existsSync as existsSync39 } from "node:fs";
|
|
48613
48789
|
import { resolve as resolve30 } from "node:path";
|
|
48614
48790
|
var ENGINE_EVENTS_SQL = "SELECT run_id, sequence, event_type, payload FROM events WHERE event_type IN ('routing.attempt.recorded','step.entered','run.status_changed') ORDER BY run_id, sequence";
|
|
48615
48791
|
var SIMULATED_HARNESS = "driver-simulated";
|
|
@@ -48632,7 +48808,7 @@ function readEngineRoutingRecords(path4) {
|
|
|
48632
48808
|
undecided: 0,
|
|
48633
48809
|
duplicatesDropped: 0
|
|
48634
48810
|
};
|
|
48635
|
-
if (!
|
|
48811
|
+
if (!existsSync39(path4)) return { records: [], source };
|
|
48636
48812
|
source.exists = true;
|
|
48637
48813
|
let rows;
|
|
48638
48814
|
let database;
|
|
@@ -48708,7 +48884,7 @@ function readEngineRoutingRecords(path4) {
|
|
|
48708
48884
|
};
|
|
48709
48885
|
}
|
|
48710
48886
|
function readJsonlSource(kind, path4) {
|
|
48711
|
-
const exists =
|
|
48887
|
+
const exists = existsSync39(path4);
|
|
48712
48888
|
const records = exists ? readRoutingRecords(path4).map((entry) => entry.routing) : [];
|
|
48713
48889
|
return { records, source: { kind, path: path4, exists, records: records.length, duplicatesDropped: 0 } };
|
|
48714
48890
|
}
|
|
@@ -48753,8 +48929,8 @@ function loadRoutingSources(options) {
|
|
|
48753
48929
|
// plugins/kxm/src/modes.ts
|
|
48754
48930
|
var import_yaml17 = __toESM(require_dist(), 1);
|
|
48755
48931
|
init_prices();
|
|
48756
|
-
import { existsSync as
|
|
48757
|
-
import { join as
|
|
48932
|
+
import { existsSync as existsSync40, readFileSync as readFileSync37 } from "node:fs";
|
|
48933
|
+
import { join as join50 } from "node:path";
|
|
48758
48934
|
var DEFAULT_MODES_CONFIG = Object.freeze({
|
|
48759
48935
|
schema: "kxm.modes.v1",
|
|
48760
48936
|
majorModes: {
|
|
@@ -48817,8 +48993,8 @@ function loadModesConfig(projectRoot) {
|
|
|
48817
48993
|
if (!projectRoot) {
|
|
48818
48994
|
return DEFAULT_MODES_CONFIG;
|
|
48819
48995
|
}
|
|
48820
|
-
const modesPath =
|
|
48821
|
-
if (!
|
|
48996
|
+
const modesPath = join50(projectRoot, ".kxm", "modes.yaml");
|
|
48997
|
+
if (!existsSync40(modesPath)) {
|
|
48822
48998
|
return DEFAULT_MODES_CONFIG;
|
|
48823
48999
|
}
|
|
48824
49000
|
try {
|
|
@@ -48908,9 +49084,9 @@ function calculatePromptFootprint(resolved, projectRoot = process.cwd(), catalog
|
|
|
48908
49084
|
estimatedTokens: estimateTokens(baseSystemPromptChars)
|
|
48909
49085
|
});
|
|
48910
49086
|
for (const relPath of resolved.contextFiles) {
|
|
48911
|
-
const fullPath =
|
|
49087
|
+
const fullPath = join50(projectRoot, relPath);
|
|
48912
49088
|
let chars = 0;
|
|
48913
|
-
if (
|
|
49089
|
+
if (existsSync40(fullPath)) {
|
|
48914
49090
|
try {
|
|
48915
49091
|
chars = readFileSync37(fullPath, "utf8").length;
|
|
48916
49092
|
} catch {
|
|
@@ -49044,10 +49220,10 @@ ${divider}
|
|
|
49044
49220
|
|
|
49045
49221
|
// plugins/kxm/src/ssh-remote.ts
|
|
49046
49222
|
init_safety_integrity();
|
|
49047
|
-
import { spawnSync as
|
|
49048
|
-
import { existsSync as
|
|
49223
|
+
import { spawnSync as spawnSync10 } from "node:child_process";
|
|
49224
|
+
import { existsSync as existsSync41, mkdirSync as mkdirSync30, readFileSync as readFileSync38, readdirSync as readdirSync13, rmSync as rmSync12, statSync as statSync5 } from "node:fs";
|
|
49049
49225
|
import { homedir as homedir8 } from "node:os";
|
|
49050
|
-
import { join as
|
|
49226
|
+
import { join as join51, resolve as resolve31 } from "node:path";
|
|
49051
49227
|
var MAX_SSH_OUTPUT_BYTES = 50 * 1024;
|
|
49052
49228
|
var MAX_SSH_OUTPUT_LINES = 2e3;
|
|
49053
49229
|
var DEFAULT_SOCKET_DIR = ".kxm/run/ssh-sockets";
|
|
@@ -49073,8 +49249,8 @@ function truncateSshOutput(raw) {
|
|
|
49073
49249
|
return { text, truncated };
|
|
49074
49250
|
}
|
|
49075
49251
|
function parseSshConfig(configPath) {
|
|
49076
|
-
const targetPath = configPath ??
|
|
49077
|
-
if (!
|
|
49252
|
+
const targetPath = configPath ?? join51(homedir8(), ".ssh", "config");
|
|
49253
|
+
if (!existsSync41(targetPath)) {
|
|
49078
49254
|
return [];
|
|
49079
49255
|
}
|
|
49080
49256
|
try {
|
|
@@ -49120,7 +49296,7 @@ function parseSshConfig(configPath) {
|
|
|
49120
49296
|
return [];
|
|
49121
49297
|
}
|
|
49122
49298
|
}
|
|
49123
|
-
function resolveSshHostG(host, execFn =
|
|
49299
|
+
function resolveSshHostG(host, execFn = spawnSync10) {
|
|
49124
49300
|
try {
|
|
49125
49301
|
const result = execFn("ssh", ["-G", host], { encoding: "utf-8" });
|
|
49126
49302
|
if (result.status !== 0 || !result.stdout) {
|
|
@@ -49156,14 +49332,14 @@ function resolveSshHostG(host, execFn = spawnSync9) {
|
|
|
49156
49332
|
}
|
|
49157
49333
|
function ensureSocketDir(socketDir = DEFAULT_SOCKET_DIR) {
|
|
49158
49334
|
const resolved = resolve31(socketDir);
|
|
49159
|
-
if (!
|
|
49335
|
+
if (!existsSync41(resolved)) {
|
|
49160
49336
|
mkdirSync30(resolved, { recursive: true, mode: 448 });
|
|
49161
49337
|
}
|
|
49162
49338
|
return resolved;
|
|
49163
49339
|
}
|
|
49164
49340
|
function buildSshArgs(options) {
|
|
49165
49341
|
const socketDir = ensureSocketDir(options.socketDir ?? DEFAULT_SOCKET_DIR);
|
|
49166
|
-
const controlPath =
|
|
49342
|
+
const controlPath = join51(socketDir, "%C");
|
|
49167
49343
|
const persist = options.controlPersist ?? DEFAULT_CONTROL_PERSIST;
|
|
49168
49344
|
const args = [
|
|
49169
49345
|
"-o",
|
|
@@ -49186,9 +49362,9 @@ function buildSshArgs(options) {
|
|
|
49186
49362
|
args.push(options.host);
|
|
49187
49363
|
return args;
|
|
49188
49364
|
}
|
|
49189
|
-
function checkControlSocket(host, socketDir = DEFAULT_SOCKET_DIR, execFn =
|
|
49365
|
+
function checkControlSocket(host, socketDir = DEFAULT_SOCKET_DIR, execFn = spawnSync10) {
|
|
49190
49366
|
const resolvedDir = ensureSocketDir(socketDir);
|
|
49191
|
-
const controlPath =
|
|
49367
|
+
const controlPath = join51(resolvedDir, "%C");
|
|
49192
49368
|
try {
|
|
49193
49369
|
const result = execFn("ssh", ["-O", "check", "-o", `ControlPath=${controlPath}`, host], {
|
|
49194
49370
|
encoding: "utf-8"
|
|
@@ -49198,9 +49374,9 @@ function checkControlSocket(host, socketDir = DEFAULT_SOCKET_DIR, execFn = spawn
|
|
|
49198
49374
|
return false;
|
|
49199
49375
|
}
|
|
49200
49376
|
}
|
|
49201
|
-
function closeControlSocket(host, socketDir = DEFAULT_SOCKET_DIR, execFn =
|
|
49377
|
+
function closeControlSocket(host, socketDir = DEFAULT_SOCKET_DIR, execFn = spawnSync10) {
|
|
49202
49378
|
const resolvedDir = ensureSocketDir(socketDir);
|
|
49203
|
-
const controlPath =
|
|
49379
|
+
const controlPath = join51(resolvedDir, "%C");
|
|
49204
49380
|
try {
|
|
49205
49381
|
const result = execFn("ssh", ["-O", "stop", "-o", `ControlPath=${controlPath}`, host], {
|
|
49206
49382
|
encoding: "utf-8"
|
|
@@ -49212,7 +49388,7 @@ function closeControlSocket(host, socketDir = DEFAULT_SOCKET_DIR, execFn = spawn
|
|
|
49212
49388
|
}
|
|
49213
49389
|
function executeSshRun(params) {
|
|
49214
49390
|
const startTime = Date.now();
|
|
49215
|
-
const execSyncFn = params.execFn ??
|
|
49391
|
+
const execSyncFn = params.execFn ?? spawnSync10;
|
|
49216
49392
|
if (params.action === "info") {
|
|
49217
49393
|
if (params.host) {
|
|
49218
49394
|
const hostInfo = resolveSshHostG(params.host, execSyncFn);
|
|
@@ -49648,9 +49824,9 @@ complete -c kxm -n "__fish_seen_subcommand_from goal" -a "create list get"
|
|
|
49648
49824
|
}
|
|
49649
49825
|
|
|
49650
49826
|
// plugins/kxm/src/completion-install.ts
|
|
49651
|
-
import { existsSync as
|
|
49827
|
+
import { existsSync as existsSync42, mkdirSync as mkdirSync31, readFileSync as readFileSync39, writeFileSync as writeFileSync27 } from "node:fs";
|
|
49652
49828
|
import { homedir as homedir9 } from "node:os";
|
|
49653
|
-
import { basename as basename10, delimiter, dirname as dirname24, isAbsolute as isAbsolute10, join as
|
|
49829
|
+
import { basename as basename10, delimiter, dirname as dirname24, isAbsolute as isAbsolute10, join as join52, resolve as resolve32 } from "node:path";
|
|
49654
49830
|
var COMPLETION_MARKER = "# kxm completion";
|
|
49655
49831
|
var PATH_MARKER = "# kxm path";
|
|
49656
49832
|
function detectShell(env = process.env, platform = process.platform) {
|
|
@@ -49672,25 +49848,25 @@ function completionScriptPath(shell, options = {}) {
|
|
|
49672
49848
|
const env = options.env ?? process.env;
|
|
49673
49849
|
const explicit = options.configDir ?? env.KXM_USER_CONFIG_DIR?.trim();
|
|
49674
49850
|
const base = explicit && explicit.length > 0 ? resolve32(explicit) : resolve32(effectiveHome(options), ".config", "kxm");
|
|
49675
|
-
return
|
|
49851
|
+
return join52(base, "completions", `kxm.${shell}`);
|
|
49676
49852
|
}
|
|
49677
49853
|
function bashRcCandidate(options) {
|
|
49678
49854
|
const home = effectiveHome(options);
|
|
49679
|
-
const candidates = [
|
|
49680
|
-
const existing = candidates.find((candidate) =>
|
|
49855
|
+
const candidates = [join52(home, ".bashrc"), join52(home, ".bash_profile")];
|
|
49856
|
+
const existing = candidates.find((candidate) => existsSync42(candidate));
|
|
49681
49857
|
return existing ?? candidates[0];
|
|
49682
49858
|
}
|
|
49683
49859
|
function zshRcCandidate(options) {
|
|
49684
49860
|
const env = options.env ?? process.env;
|
|
49685
49861
|
const home = effectiveHome(options);
|
|
49686
|
-
if (env.ZDOTDIR?.trim()) return
|
|
49687
|
-
return
|
|
49862
|
+
if (env.ZDOTDIR?.trim()) return join52(resolve32(env.ZDOTDIR.trim()), ".zshrc");
|
|
49863
|
+
return join52(home, ".zshrc");
|
|
49688
49864
|
}
|
|
49689
49865
|
function fishCompletionTarget(shell, options) {
|
|
49690
49866
|
const env = options.env ?? process.env;
|
|
49691
49867
|
const home = effectiveHome(options);
|
|
49692
|
-
if (env.XDG_CONFIG_HOME?.trim()) return
|
|
49693
|
-
return
|
|
49868
|
+
if (env.XDG_CONFIG_HOME?.trim()) return join52(resolve32(env.XDG_CONFIG_HOME.trim()), "fish", "completions", "kxm.fish");
|
|
49869
|
+
return join52(home, ".config", "fish", "completions", "kxm.fish");
|
|
49694
49870
|
}
|
|
49695
49871
|
function completionRcTarget(shell, options = {}) {
|
|
49696
49872
|
if (shell === "fish") {
|
|
@@ -49722,13 +49898,13 @@ function installShellCompletion(shellInput, options = {}) {
|
|
|
49722
49898
|
const scriptPath = completionScriptPath(shell, options);
|
|
49723
49899
|
const { rcFile } = completionRcTarget(shell, options);
|
|
49724
49900
|
const script = generateShellCompletion(shell);
|
|
49725
|
-
const existingScript =
|
|
49901
|
+
const existingScript = existsSync42(scriptPath);
|
|
49726
49902
|
const existingScriptMatches = existingScript && readFileSync39(scriptPath, "utf8") === script;
|
|
49727
49903
|
let rcModified = false;
|
|
49728
49904
|
let alreadyInstalled = false;
|
|
49729
49905
|
if (shell === "fish") {
|
|
49730
49906
|
const fishTarget = fishCompletionTarget(shell, options);
|
|
49731
|
-
const fishInstalled =
|
|
49907
|
+
const fishInstalled = existsSync42(fishTarget) && readFileSync39(fishTarget, "utf8") === script;
|
|
49732
49908
|
alreadyInstalled = fishInstalled;
|
|
49733
49909
|
if (!options.dryRun && (!fishInstalled || options.overwrite)) {
|
|
49734
49910
|
mkdirSync31(resolve32(fishTarget, ".."), { recursive: true });
|
|
@@ -49745,7 +49921,7 @@ function installShellCompletion(shellInput, options = {}) {
|
|
|
49745
49921
|
}
|
|
49746
49922
|
if (rcFile) {
|
|
49747
49923
|
const line = sourceLine(shell, scriptPath);
|
|
49748
|
-
const rcContent =
|
|
49924
|
+
const rcContent = existsSync42(rcFile) ? readFileSync39(rcFile, "utf8") : "";
|
|
49749
49925
|
alreadyInstalled = rcContent.includes(line) || rcContent.includes(`${COMPLETION_MARKER}`);
|
|
49750
49926
|
}
|
|
49751
49927
|
if (!options.dryRun) {
|
|
@@ -49761,7 +49937,7 @@ ${marker}
|
|
|
49761
49937
|
${line}
|
|
49762
49938
|
`;
|
|
49763
49939
|
mkdirSync31(resolve32(rcFile, ".."), { recursive: true });
|
|
49764
|
-
writeFileSync27(rcFile, (
|
|
49940
|
+
writeFileSync27(rcFile, (existsSync42(rcFile) ? readFileSync39(rcFile, "utf8") : "") + stanza, { encoding: "utf8" });
|
|
49765
49941
|
rcModified = true;
|
|
49766
49942
|
}
|
|
49767
49943
|
}
|
|
@@ -49778,13 +49954,13 @@ function kxmBinDir(env = process.env) {
|
|
|
49778
49954
|
const argv1 = env.KXM_ENTRY ?? process.argv[1];
|
|
49779
49955
|
if (argv1 && isAbsolute10(argv1)) {
|
|
49780
49956
|
const dir = dirname24(argv1);
|
|
49781
|
-
if (
|
|
49957
|
+
if (existsSync42(join52(dir, process.platform === "win32" ? "kxm.cmd" : "kxm"))) return dir;
|
|
49782
49958
|
}
|
|
49783
49959
|
const pathEnv = env.PATH ?? "";
|
|
49784
49960
|
for (const part of pathEnv.split(delimiter)) {
|
|
49785
49961
|
if (!part) continue;
|
|
49786
49962
|
const candidate = resolve32(part, process.platform === "win32" ? "kxm.cmd" : "kxm");
|
|
49787
|
-
if (
|
|
49963
|
+
if (existsSync42(candidate)) return resolve32(part);
|
|
49788
49964
|
}
|
|
49789
49965
|
return void 0;
|
|
49790
49966
|
}
|
|
@@ -49802,7 +49978,7 @@ function installPathEntry(shellInput, options = {}) {
|
|
|
49802
49978
|
}
|
|
49803
49979
|
const { rcFile } = completionRcTarget(shell, options);
|
|
49804
49980
|
const line = pathLine(binDir);
|
|
49805
|
-
const rcContent =
|
|
49981
|
+
const rcContent = existsSync42(rcFile ?? "") ? readFileSync39(rcFile, "utf8") : "";
|
|
49806
49982
|
const alreadyInstalled = rcContent.includes(binDir) || (options.env?.PATH ?? process.env.PATH ?? "").split(delimiter).includes(binDir);
|
|
49807
49983
|
if (!options.dryRun && rcFile && !alreadyInstalled) {
|
|
49808
49984
|
mkdirSync31(dirname24(rcFile), { recursive: true });
|
|
@@ -49817,8 +49993,8 @@ ${line}
|
|
|
49817
49993
|
// plugins/kxm/src/init-guide-setup.ts
|
|
49818
49994
|
var import_yaml18 = __toESM(require_dist(), 1);
|
|
49819
49995
|
init_routes();
|
|
49820
|
-
import { existsSync as
|
|
49821
|
-
import { dirname as dirname25, join as
|
|
49996
|
+
import { existsSync as existsSync43, mkdirSync as mkdirSync32, writeFileSync as writeFileSync28 } from "node:fs";
|
|
49997
|
+
import { dirname as dirname25, join as join53 } from "node:path";
|
|
49822
49998
|
var ADMITTED_GUIDE_BINDINGS = Object.freeze({
|
|
49823
49999
|
"anthropic/claude-fable-5.1": { harness: "claude", provider: "anthropic", model: "fable" },
|
|
49824
50000
|
"anthropic/fable": { harness: "claude", provider: "anthropic", model: "fable" },
|
|
@@ -50209,13 +50385,13 @@ function renderGuideSetupFiles(projectRoot, plan) {
|
|
|
50209
50385
|
const stage = roleStages.get(role);
|
|
50210
50386
|
if (!stage) continue;
|
|
50211
50387
|
files.push({
|
|
50212
|
-
path:
|
|
50388
|
+
path: join53(projectRoot, ".kxm", "agents", `${role}.yaml`),
|
|
50213
50389
|
content: (0, import_yaml18.stringify)(agentDocument(role, stage, binding))
|
|
50214
50390
|
});
|
|
50215
50391
|
}
|
|
50216
50392
|
for (const workflow of plan.workflows) {
|
|
50217
50393
|
files.push({
|
|
50218
|
-
path:
|
|
50394
|
+
path: join53(projectRoot, ".kxm", "workflows", `${workflow.slug}.yaml`),
|
|
50219
50395
|
content: (0, import_yaml18.stringify)(workflowDocument(workflow))
|
|
50220
50396
|
});
|
|
50221
50397
|
}
|
|
@@ -50232,7 +50408,7 @@ function mergeGuideRouteAdmission(projectRoot, plan) {
|
|
|
50232
50408
|
}
|
|
50233
50409
|
if (added.length === 0) return added;
|
|
50234
50410
|
policy.updatedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
50235
|
-
const path4 =
|
|
50411
|
+
const path4 = join53(projectRoot, ".kxm", "routes.yaml");
|
|
50236
50412
|
mkdirSync32(dirname25(path4), { recursive: true });
|
|
50237
50413
|
writeFileSync28(path4, (0, import_yaml18.stringify)(policy), "utf8");
|
|
50238
50414
|
return added;
|
|
@@ -50241,7 +50417,7 @@ function writeGuideSetupFiles(files) {
|
|
|
50241
50417
|
const written = [];
|
|
50242
50418
|
const existed = [];
|
|
50243
50419
|
for (const file of files) {
|
|
50244
|
-
if (
|
|
50420
|
+
if (existsSync43(file.path)) {
|
|
50245
50421
|
existed.push(file.path);
|
|
50246
50422
|
continue;
|
|
50247
50423
|
}
|
|
@@ -50274,7 +50450,7 @@ init_types();
|
|
|
50274
50450
|
init_repo_root();
|
|
50275
50451
|
function cliSpawn(runtime, command, args, extra) {
|
|
50276
50452
|
if (runtime.io.spawnSync) return runtime.io.spawnSync(command, args);
|
|
50277
|
-
const result =
|
|
50453
|
+
const result = spawnSync11(command, [...args], {
|
|
50278
50454
|
encoding: "utf8",
|
|
50279
50455
|
windowsHide: true,
|
|
50280
50456
|
shell: process.platform === "win32",
|
|
@@ -50312,7 +50488,7 @@ function applyKxmPackageUpdate(runtime, notice) {
|
|
|
50312
50488
|
detail: `release v${notice.latest} has no sha256 digest for ${name}; refusing to install`
|
|
50313
50489
|
};
|
|
50314
50490
|
}
|
|
50315
|
-
const releaseDir = mkdtempSync3(
|
|
50491
|
+
const releaseDir = mkdtempSync3(join54(tmpdir2(), "kxm-pkg-update-"));
|
|
50316
50492
|
try {
|
|
50317
50493
|
const planned = planKxmPackageUpdate(notice.source, notice.latest, releaseDir, notice.asset);
|
|
50318
50494
|
if (runtime.dryRun) {
|
|
@@ -50321,7 +50497,7 @@ function applyKxmPackageUpdate(runtime, notice) {
|
|
|
50321
50497
|
for (const step of planned) {
|
|
50322
50498
|
if (step.kind === "verify") {
|
|
50323
50499
|
if (!verifyReleaseAssetDigest(step.path, step.sha256)) {
|
|
50324
|
-
const actual =
|
|
50500
|
+
const actual = existsSync44(step.path) ? createHash17("sha256").update(readFileSync40(step.path)).digest("hex") : "missing";
|
|
50325
50501
|
return {
|
|
50326
50502
|
ok: false,
|
|
50327
50503
|
error: "release_digest_mismatch",
|
|
@@ -50599,7 +50775,7 @@ async function cmdValidate(runtime, fileFlag) {
|
|
|
50599
50775
|
}
|
|
50600
50776
|
const selectedFile = explicitFile || configuredFile;
|
|
50601
50777
|
const file = selectedFile ? resolve33(runtime.cwd, selectedFile) : void 0;
|
|
50602
|
-
if (file && !
|
|
50778
|
+
if (file && !existsSync44(file)) {
|
|
50603
50779
|
printWorker(runtime, worker, { ok: false, command: "validate", error: "file_not_found", file }, `workflow file not found: ${file}`);
|
|
50604
50780
|
return 1;
|
|
50605
50781
|
}
|
|
@@ -50699,7 +50875,7 @@ async function cmdImprove(runtime, options = {}) {
|
|
|
50699
50875
|
print(runtime.io, runtime.json, { ok: false, command: "improve", error: "config_invalid", detail: message }, `config_invalid: ${message}`);
|
|
50700
50876
|
return 1;
|
|
50701
50877
|
}
|
|
50702
|
-
const candidatesDir = options.outDir ? resolve33(runtime.cwd, options.outDir) :
|
|
50878
|
+
const candidatesDir = options.outDir ? resolve33(runtime.cwd, options.outDir) : join54(root, ".kxm", "candidates");
|
|
50703
50879
|
const report2 = buildImprovementReport(loaded.records, {
|
|
50704
50880
|
candidatesDir,
|
|
50705
50881
|
projectRoot: root,
|
|
@@ -50708,7 +50884,7 @@ async function cmdImprove(runtime, options = {}) {
|
|
|
50708
50884
|
autoThreshold: config.improvement.autoThreshold,
|
|
50709
50885
|
halfLifeDays: config.improvement.telemetryHalfLifeDays
|
|
50710
50886
|
});
|
|
50711
|
-
const reportDir =
|
|
50887
|
+
const reportDir = join54(runtime.dirs.assets, "improvements");
|
|
50712
50888
|
const reportPath = writeImprovementReport(reportDir, report2, runtime.dryRun);
|
|
50713
50889
|
const text = [
|
|
50714
50890
|
"Sources:",
|
|
@@ -50852,7 +51028,7 @@ async function maybeOfferCompletionInstall(runtime) {
|
|
|
50852
51028
|
if (!pathNeeded) {
|
|
50853
51029
|
const scriptPath = completionScriptPath(shell, { env: runtime.env, configDir: runtime.env.KXM_USER_CONFIG_DIR });
|
|
50854
51030
|
const { rcFile } = completionRcTarget(shell, { env: runtime.env });
|
|
50855
|
-
if (rcFile &&
|
|
51031
|
+
if (rcFile && existsSync44(rcFile)) {
|
|
50856
51032
|
try {
|
|
50857
51033
|
if (readFileSync40(rcFile, "utf8").includes(scriptPath)) return;
|
|
50858
51034
|
} catch {
|
|
@@ -51017,7 +51193,7 @@ async function cmdRoutingReport(runtime, options) {
|
|
|
51017
51193
|
let catalog;
|
|
51018
51194
|
if (includeEquivalentListCost) {
|
|
51019
51195
|
try {
|
|
51020
|
-
const pricesPath = options.prices ? resolve33(runtime.cwd, options.prices) :
|
|
51196
|
+
const pricesPath = options.prices ? resolve33(runtime.cwd, options.prices) : join54(runtime.dirs.workspace, "prices.yaml");
|
|
51021
51197
|
catalog = loadPriceCatalog(pricesPath);
|
|
51022
51198
|
} catch {
|
|
51023
51199
|
}
|
|
@@ -51131,6 +51307,13 @@ var DRY_RUN_COMMANDS = /* @__PURE__ */ new Set([
|
|
|
51131
51307
|
"lane drop",
|
|
51132
51308
|
"lane run",
|
|
51133
51309
|
"land",
|
|
51310
|
+
"assign run",
|
|
51311
|
+
"assign witness",
|
|
51312
|
+
"assign plan-current",
|
|
51313
|
+
"assign attribute",
|
|
51314
|
+
"assign observe-cost",
|
|
51315
|
+
"assign accept",
|
|
51316
|
+
"assign change-report",
|
|
51134
51317
|
"plugin install",
|
|
51135
51318
|
"plugin",
|
|
51136
51319
|
"runs status",
|
|
@@ -51231,7 +51414,9 @@ var DRY_RUN_COMMANDS = /* @__PURE__ */ new Set([
|
|
|
51231
51414
|
"task run",
|
|
51232
51415
|
"task sync",
|
|
51233
51416
|
"studio layout",
|
|
51234
|
-
"studio serve"
|
|
51417
|
+
"studio serve",
|
|
51418
|
+
"docs build",
|
|
51419
|
+
"docs serve"
|
|
51235
51420
|
]);
|
|
51236
51421
|
var DryRunRefused = class extends Error {
|
|
51237
51422
|
code;
|
|
@@ -51439,6 +51624,47 @@ function createProgram(ctx, result) {
|
|
|
51439
51624
|
...options.bodyFile !== void 0 ? { bodyFile: options.bodyFile } : {}
|
|
51440
51625
|
});
|
|
51441
51626
|
});
|
|
51627
|
+
const assignCmd = addGlobalOptions(program2.command("assign").description("Run this repository's developer assignment runner"));
|
|
51628
|
+
assignCmd.helpCommand("help", "Show assign help");
|
|
51629
|
+
addGlobalOptions(assignCmd.command("run").description("Dispatch a bound assignment manifest")).requiredOption("--manifest <path>", "Absolute path to the assignment manifest").action(async function assignRunAction(options) {
|
|
51630
|
+
result.code = await cmdAssign(runtimeFrom(ctx, this), "run", { manifest: options.manifest });
|
|
51631
|
+
});
|
|
51632
|
+
addGlobalOptions(assignCmd.command("witness").description("Run the fixed verification witness for an existing assignment")).requiredOption("--record-dir <path>", "Absolute path to the assignment record directory").action(async function assignWitnessAction(options) {
|
|
51633
|
+
result.code = await cmdAssign(runtimeFrom(ctx, this), "witness", { recordDir: options.recordDir });
|
|
51634
|
+
});
|
|
51635
|
+
addGlobalOptions(assignCmd.command("plan-current").description("Stamp or advance the current-plan pointer")).requiredOption("--task-dir <path>", "Absolute path to the task directory").requiredOption("--plan <path>", "Absolute path to the plan file").requiredOption("--sha256 <hex>", "SHA-256 of the plan file").requiredOption("--base-commit <sha>", "Base commit the pointer records").requiredOption("--expected-generation <n>", "Generation the pointer must currently have").action(async function assignPlanCurrentAction(options) {
|
|
51636
|
+
result.code = await cmdAssign(runtimeFrom(ctx, this), "plan-current", {
|
|
51637
|
+
taskDir: options.taskDir,
|
|
51638
|
+
plan: options.plan,
|
|
51639
|
+
sha256: options.sha256,
|
|
51640
|
+
baseCommit: options.baseCommit,
|
|
51641
|
+
expectedGeneration: options.expectedGeneration
|
|
51642
|
+
});
|
|
51643
|
+
});
|
|
51644
|
+
addGlobalOptions(assignCmd.command("attribute").description("Attach a private attribution note")).requiredOption("--task-dir <path>", "Absolute path to the task directory").requiredOption("--record-dir <path>", "Absolute path to the assignment record directory").requiredOption("--class <class>", "orchestration, model, environment, or unclassified").requiredOption("--explanation-file <path>", "Absolute path to the note file").action(async function assignAttributeAction(options) {
|
|
51645
|
+
result.code = await cmdAssign(runtimeFrom(ctx, this), "attribute", {
|
|
51646
|
+
taskDir: options.taskDir,
|
|
51647
|
+
recordDir: options.recordDir,
|
|
51648
|
+
classification: options.class,
|
|
51649
|
+
explanationFile: options.explanationFile
|
|
51650
|
+
});
|
|
51651
|
+
});
|
|
51652
|
+
addGlobalOptions(assignCmd.command("observe-cost").description("Import one historical cost observation as cost-only")).requiredOption("--task-dir <path>", "Absolute path to the task directory").requiredOption("--input <path>", "Absolute path to the observation file").action(async function assignObserveCostAction(options) {
|
|
51653
|
+
result.code = await cmdAssign(runtimeFrom(ctx, this), "observe-cost", { taskDir: options.taskDir, input: options.input });
|
|
51654
|
+
});
|
|
51655
|
+
addGlobalOptions(assignCmd.command("accept").description("Bind an exact witnessed commit and two critic PASS records")).requiredOption("--task-dir <path>", "Absolute path to the task directory").requiredOption("--commit <sha>", "Commit to accept").requiredOption("--record-dir <path>", "Absolute path to the writer record directory").requiredOption("--critic <path>", "Absolute path to a critic record directory; pass twice", (value, previous) => previous.concat(value), []).option("--observed-pr <id>", "Observed pull request id").option("--observed-ci <id>", "Observed CI run id").action(async function assignAcceptAction(options) {
|
|
51656
|
+
result.code = await cmdAssign(runtimeFrom(ctx, this), "accept", {
|
|
51657
|
+
taskDir: options.taskDir,
|
|
51658
|
+
commit: options.commit,
|
|
51659
|
+
recordDir: options.recordDir,
|
|
51660
|
+
critics: options.critic,
|
|
51661
|
+
...options.observedPr !== void 0 ? { observedPr: options.observedPr } : {},
|
|
51662
|
+
...options.observedCi !== void 0 ? { observedCi: options.observedCi } : {}
|
|
51663
|
+
});
|
|
51664
|
+
});
|
|
51665
|
+
addGlobalOptions(assignCmd.command("change-report").description("Report attempts, rework, costs, and retained verification history")).requiredOption("--task-dir <path>", "Absolute path to the task directory").action(async function assignChangeReportAction(options) {
|
|
51666
|
+
result.code = await cmdAssign(runtimeFrom(ctx, this), "change-report", { taskDir: options.taskDir });
|
|
51667
|
+
});
|
|
51442
51668
|
addGlobalOptions(program2.command("run").description("Create a KXM run without executing steps; follow its prerequisites, then kxm runs drive <runId> --wait").argument("[workflow]", "Workflow id to run").argument("[prompt...]", "Run prompt (events keep its hash; the full text is kept in a local 0600 sidecar file)").option("--brief <file>", "Read the run prompt from a file instead of the positional prompt").option("--lane <unit>", "Discover the project from this lane's worktree").action(async function runAction(workflow2, promptParts, options) {
|
|
51443
51669
|
result.code = await cmdKxmRunCli(runtimeFrom(ctx, this), workflow2, promptParts, options);
|
|
51444
51670
|
}));
|
|
@@ -51470,6 +51696,14 @@ function createProgram(ctx, result) {
|
|
|
51470
51696
|
addGlobalOptions(runCmd.command("list").description("List recent runs for the current project")).action(async function runListAction() {
|
|
51471
51697
|
result.code = await cmdKxmRunList(runtimeFrom(ctx, this));
|
|
51472
51698
|
});
|
|
51699
|
+
const docsCmd = addGlobalOptions(program2.command("docs").description("Build and serve the tailnet docs site"));
|
|
51700
|
+
docsCmd.helpCommand("help", "Show docs help");
|
|
51701
|
+
addGlobalOptions(docsCmd.command("build").description("Regenerate the docs site from the roadmap state")).action(async function docsBuildAction() {
|
|
51702
|
+
result.code = await cmdDocsBuild(runtimeFrom(ctx, this));
|
|
51703
|
+
});
|
|
51704
|
+
addGlobalOptions(docsCmd.command("serve").description("Serve the built docs site on this machine's tailnet address")).option("--port <port>", "Port passed through to the docs server").action(async function docsServeAction(options) {
|
|
51705
|
+
result.code = await cmdDocsServe(runtimeFrom(ctx, this), options);
|
|
51706
|
+
});
|
|
51473
51707
|
const tenantCmd = addGlobalOptions(program2.command("tenant").description("Composed tenant reads for machine clients (portal)"));
|
|
51474
51708
|
tenantCmd.helpCommand("help", "Show tenant help");
|
|
51475
51709
|
addGlobalOptions(tenantCmd.command("status").description("Read hub metadata and authoritative Runtime run state as one labeled view")).action(async function tenantStatusAction() {
|