@kontextmind/kxm 0.7.122 → 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 +11 -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/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 +56 -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 +241 -160
- package/plugins/kxm/dist/mcp-server.js +1 -1
- package/plugins/kxm/package.json +1 -1
- package/plugins/kxm/skills/kxm/SKILL.md +1 -2
- package/plugins/kxm/skills/kxm-runs/SKILL.md +7 -0
- package/plugins/kxm/src/cli/docs.ts +78 -0
- package/plugins/kxm/src/cli.ts +14 -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
|
}
|
|
@@ -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));
|
|
@@ -37111,8 +37182,8 @@ function cmdLand(runtime, options = {}) {
|
|
|
37111
37182
|
init_project_config();
|
|
37112
37183
|
init_types();
|
|
37113
37184
|
import { spawnSync as spawnSync7 } from "node:child_process";
|
|
37114
|
-
import { existsSync as
|
|
37115
|
-
import { join as
|
|
37185
|
+
import { existsSync as existsSync31 } from "node:fs";
|
|
37186
|
+
import { join as join38 } from "node:path";
|
|
37116
37187
|
var kxmAssignCliSeams = {};
|
|
37117
37188
|
var RUNNER_REL = "scripts/assignment-run.mjs";
|
|
37118
37189
|
function refuse3(runtime, command, error, text) {
|
|
@@ -37184,7 +37255,7 @@ async function cmdAssign(runtime, subcommand, args) {
|
|
|
37184
37255
|
const command = `assign ${subcommand}`;
|
|
37185
37256
|
const root = discoverKxmProjectRoot(runtime.cwd);
|
|
37186
37257
|
if (!root) return refuse3(runtime, command, "project_required", `${command} requires a KXM project (run kxm init first)`);
|
|
37187
|
-
if (!
|
|
37258
|
+
if (!existsSync31(join38(root, "scripts", "assignment-run.mjs"))) {
|
|
37188
37259
|
return refuse3(runtime, command, "assign_runner_missing", `${command} requires scripts/assignment-run.mjs in the project root`);
|
|
37189
37260
|
}
|
|
37190
37261
|
const argv = ["node", RUNNER_REL, ...runnerArgv(subcommand, args)];
|
|
@@ -37195,7 +37266,7 @@ async function cmdAssign(runtime, subcommand, args) {
|
|
|
37195
37266
|
`);
|
|
37196
37267
|
return 0;
|
|
37197
37268
|
}
|
|
37198
|
-
const
|
|
37269
|
+
const spawn6 = kxmAssignCliSeams.spawn ?? ((commandName, commandArgs, options) => {
|
|
37199
37270
|
const result2 = spawnSync7(commandName, commandArgs, {
|
|
37200
37271
|
cwd: options.cwd,
|
|
37201
37272
|
stdio: options.stdio,
|
|
@@ -37204,7 +37275,7 @@ async function cmdAssign(runtime, subcommand, args) {
|
|
|
37204
37275
|
});
|
|
37205
37276
|
return { status: result2.status, ...result2.error ? { error: result2.error } : {} };
|
|
37206
37277
|
});
|
|
37207
|
-
const result =
|
|
37278
|
+
const result = spawn6("node", argv.slice(1), { cwd: root, stdio: "inherit", env: runtime.env });
|
|
37208
37279
|
if (result.status === null) {
|
|
37209
37280
|
const detail = result.error?.message ?? "the assignment runner could not be started";
|
|
37210
37281
|
return refuse3(runtime, command, "assign_spawn_failed", detail);
|
|
@@ -37215,8 +37286,8 @@ async function cmdAssign(runtime, subcommand, args) {
|
|
|
37215
37286
|
// plugins/kxm/src/cli/hub.ts
|
|
37216
37287
|
init_redact();
|
|
37217
37288
|
import { randomUUID as randomUUID13 } from "node:crypto";
|
|
37218
|
-
import { existsSync as
|
|
37219
|
-
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";
|
|
37220
37291
|
init_hub_env();
|
|
37221
37292
|
init_envelope();
|
|
37222
37293
|
|
|
@@ -42914,7 +42985,7 @@ import * as path2 from "node:path";
|
|
|
42914
42985
|
|
|
42915
42986
|
// node_modules/@earendil-works/pi-tui/dist/native-module-path.js
|
|
42916
42987
|
import { createRequire as createRequire2 } from "node:module";
|
|
42917
|
-
import { dirname as dirname19, join as
|
|
42988
|
+
import { dirname as dirname19, join as join39 } from "node:path";
|
|
42918
42989
|
import { fileURLToPath as fileURLToPath2 } from "node:url";
|
|
42919
42990
|
var moduleRequire = createRequire2(import.meta.url);
|
|
42920
42991
|
var TUI_PACKAGE_NAME = "@earendil-works/pi-tui";
|
|
@@ -42923,10 +42994,10 @@ function getNativeModuleCandidates(nativePath, options = {}) {
|
|
|
42923
42994
|
const candidates = [];
|
|
42924
42995
|
try {
|
|
42925
42996
|
const packageEntry = (options.resolvePackage ?? moduleRequire.resolve)(TUI_PACKAGE_NAME);
|
|
42926
|
-
candidates.push(
|
|
42997
|
+
candidates.push(join39(dirname19(packageEntry), "..", nativePath));
|
|
42927
42998
|
} catch {
|
|
42928
42999
|
}
|
|
42929
|
-
candidates.push(
|
|
43000
|
+
candidates.push(join39(moduleDir, "..", nativePath), join39(moduleDir, nativePath), join39(dirname19(options.execPath ?? process.execPath), nativePath));
|
|
42930
43001
|
return Array.from(new Set(candidates));
|
|
42931
43002
|
}
|
|
42932
43003
|
|
|
@@ -45657,7 +45728,7 @@ var MAX_RENDER_WRITE_CHARS = 1024 * 1024;
|
|
|
45657
45728
|
|
|
45658
45729
|
// plugins/kxm/src/tui.ts
|
|
45659
45730
|
import { mkdirSync as mkdirSync25 } from "node:fs";
|
|
45660
|
-
import { join as
|
|
45731
|
+
import { join as join43, resolve as resolve27, dirname as dirname20 } from "node:path";
|
|
45661
45732
|
import { spawnSync as spawnSync8 } from "node:child_process";
|
|
45662
45733
|
|
|
45663
45734
|
// packages/core/tui/src/types/surface.ts
|
|
@@ -45801,9 +45872,9 @@ var SHARED_EFFECT_KINDS = Object.freeze([
|
|
|
45801
45872
|
// plugins/kxm/src/local-snapshot.ts
|
|
45802
45873
|
init_sqlite();
|
|
45803
45874
|
init_telemetry();
|
|
45804
|
-
import { existsSync as
|
|
45875
|
+
import { existsSync as existsSync32, readdirSync as readdirSync11, readFileSync as readFileSync30 } from "node:fs";
|
|
45805
45876
|
import { homedir as homedir6 } from "node:os";
|
|
45806
|
-
import { isAbsolute as isAbsolute9, join as
|
|
45877
|
+
import { isAbsolute as isAbsolute9, join as join42, resolve as resolve26 } from "node:path";
|
|
45807
45878
|
var DEFAULT_BUSY_TIMEOUT_MS = 5e3;
|
|
45808
45879
|
var RUNTIME_PROJECT_KEY = /^[A-Za-z0-9_-][A-Za-z0-9._-]*$/;
|
|
45809
45880
|
function processExists2(pid) {
|
|
@@ -45928,36 +45999,36 @@ function readOpenMessageMetadata(database, where = OPEN_MESSAGE_WHERE, params =
|
|
|
45928
45999
|
return messages;
|
|
45929
46000
|
}
|
|
45930
46001
|
function resolveKxmSnapshotPaths(cwd, env = process.env) {
|
|
45931
|
-
const stateDir = env.KXM_STATE_DIR?.trim() ||
|
|
46002
|
+
const stateDir = env.KXM_STATE_DIR?.trim() || join42(cwd, ".kxm", "state");
|
|
45932
46003
|
const configured = env.KXM_DATA_PATH?.trim();
|
|
45933
|
-
const dataPath = configured ? resolve26(cwd, configured) :
|
|
46004
|
+
const dataPath = configured ? resolve26(cwd, configured) : join42(stateDir, "kxm.db");
|
|
45934
46005
|
return { dataPath, stateDir };
|
|
45935
46006
|
}
|
|
45936
46007
|
function resolveKxmStateRoot(stateDir, options) {
|
|
45937
|
-
if (options?.kxmStateRoot &&
|
|
46008
|
+
if (options?.kxmStateRoot && existsSync32(options.kxmStateRoot)) {
|
|
45938
46009
|
return resolve26(options.kxmStateRoot);
|
|
45939
46010
|
}
|
|
45940
|
-
if (
|
|
46011
|
+
if (existsSync32(join42(stateDir, "runtime", "registry.db")) || existsSync32(join42(stateDir, "runtime", "projects"))) {
|
|
45941
46012
|
return stateDir;
|
|
45942
46013
|
}
|
|
45943
46014
|
const env = options?.env ?? process.env;
|
|
45944
46015
|
const explicit = env.KXM_STATE_HOME?.trim() || env.KXM_USER_STATE_DIR?.trim() || env.KXM_STATE_ROOT?.trim();
|
|
45945
|
-
if (explicit && isAbsolute9(explicit) &&
|
|
46016
|
+
if (explicit && isAbsolute9(explicit) && existsSync32(resolve26(explicit))) {
|
|
45946
46017
|
return resolve26(explicit);
|
|
45947
46018
|
}
|
|
45948
46019
|
let base;
|
|
45949
46020
|
if (process.platform === "win32") {
|
|
45950
46021
|
const localAppData = env.LOCALAPPDATA?.trim();
|
|
45951
|
-
base = localAppData && isAbsolute9(localAppData) ? localAppData :
|
|
46022
|
+
base = localAppData && isAbsolute9(localAppData) ? localAppData : join42(homedir6(), "AppData", "Local");
|
|
45952
46023
|
base = resolve26(base, "KXM");
|
|
45953
46024
|
} else if (process.platform === "darwin") {
|
|
45954
46025
|
base = resolve26(homedir6(), "Library", "Application Support", "KXM");
|
|
45955
46026
|
} else {
|
|
45956
46027
|
const xdgState = env.XDG_STATE_HOME?.trim();
|
|
45957
|
-
base = xdgState && isAbsolute9(xdgState) ? xdgState :
|
|
46028
|
+
base = xdgState && isAbsolute9(xdgState) ? xdgState : join42(homedir6(), ".local", "state");
|
|
45958
46029
|
base = resolve26(base, "kxm");
|
|
45959
46030
|
}
|
|
45960
|
-
if (
|
|
46031
|
+
if (existsSync32(base)) return base;
|
|
45961
46032
|
return void 0;
|
|
45962
46033
|
}
|
|
45963
46034
|
function readRuntimeRuns(eventDb, projectId) {
|
|
@@ -45990,7 +46061,7 @@ function loadLocalMeshSnapshot(dataPath, stateDir, options) {
|
|
|
45990
46061
|
let legacyRuns = [];
|
|
45991
46062
|
let legacyRunTotal = 0;
|
|
45992
46063
|
let plans = [];
|
|
45993
|
-
if (
|
|
46064
|
+
if (existsSync32(dataPath)) {
|
|
45994
46065
|
hasLegacy = true;
|
|
45995
46066
|
const database = openReadOnlyDatabase(dataPath);
|
|
45996
46067
|
try {
|
|
@@ -46021,11 +46092,11 @@ function loadLocalMeshSnapshot(dataPath, stateDir, options) {
|
|
|
46021
46092
|
let kxmRunTotal = 0;
|
|
46022
46093
|
const kxmStateRoot = scope && !scope.runtimeProjectId ? void 0 : resolveKxmStateRoot(stateDir, options);
|
|
46023
46094
|
if (kxmStateRoot) {
|
|
46024
|
-
const runtimeDir =
|
|
46025
|
-
const registryDbPath =
|
|
46026
|
-
const projectsDir =
|
|
46095
|
+
const runtimeDir = join42(kxmStateRoot, "runtime");
|
|
46096
|
+
const registryDbPath = join42(runtimeDir, "registry.db");
|
|
46097
|
+
const projectsDir = join42(runtimeDir, "projects");
|
|
46027
46098
|
const projectKeys = /* @__PURE__ */ new Set();
|
|
46028
|
-
if (
|
|
46099
|
+
if (existsSync32(registryDbPath)) {
|
|
46029
46100
|
hasKxm = true;
|
|
46030
46101
|
try {
|
|
46031
46102
|
const regDb = openReadOnlyDatabase(registryDbPath);
|
|
@@ -46041,7 +46112,7 @@ function loadLocalMeshSnapshot(dataPath, stateDir, options) {
|
|
|
46041
46112
|
} catch {
|
|
46042
46113
|
}
|
|
46043
46114
|
}
|
|
46044
|
-
if (!scope &&
|
|
46115
|
+
if (!scope && existsSync32(projectsDir)) {
|
|
46045
46116
|
try {
|
|
46046
46117
|
for (const entry of readdirSync11(projectsDir, { withFileTypes: true })) {
|
|
46047
46118
|
if (entry.isDirectory()) {
|
|
@@ -46053,8 +46124,8 @@ function loadLocalMeshSnapshot(dataPath, stateDir, options) {
|
|
|
46053
46124
|
}
|
|
46054
46125
|
for (const key of projectKeys) {
|
|
46055
46126
|
if (scope && !RUNTIME_PROJECT_KEY.test(key)) continue;
|
|
46056
|
-
const eventDbPath =
|
|
46057
|
-
if (
|
|
46127
|
+
const eventDbPath = join42(projectsDir, key, "run-events.db");
|
|
46128
|
+
if (existsSync32(eventDbPath)) {
|
|
46058
46129
|
hasKxm = true;
|
|
46059
46130
|
try {
|
|
46060
46131
|
const eventDb = openReadOnlyDatabase(eventDbPath);
|
|
@@ -46072,10 +46143,10 @@ function loadLocalMeshSnapshot(dataPath, stateDir, options) {
|
|
|
46072
46143
|
}
|
|
46073
46144
|
}
|
|
46074
46145
|
const pids = [];
|
|
46075
|
-
if (
|
|
46146
|
+
if (existsSync32(stateDir)) {
|
|
46076
46147
|
for (const file of readdirSync11(stateDir).filter((name) => name.endsWith(".pid"))) {
|
|
46077
46148
|
try {
|
|
46078
|
-
const record = JSON.parse(readFileSync30(
|
|
46149
|
+
const record = JSON.parse(readFileSync30(join42(stateDir, file), "utf8"));
|
|
46079
46150
|
pids.push({
|
|
46080
46151
|
file,
|
|
46081
46152
|
...record.role ? { role: record.role } : {},
|
|
@@ -46114,8 +46185,8 @@ function loadLocalMeshSnapshot(dataPath, stateDir, options) {
|
|
|
46114
46185
|
} else {
|
|
46115
46186
|
source = "legacy";
|
|
46116
46187
|
}
|
|
46117
|
-
const telemetryFile =
|
|
46118
|
-
const spend =
|
|
46188
|
+
const telemetryFile = join42(stateDir, "telemetry.jsonl");
|
|
46189
|
+
const spend = existsSync32(telemetryFile) ? readRoutingRecords(telemetryFile) : [];
|
|
46119
46190
|
return {
|
|
46120
46191
|
source,
|
|
46121
46192
|
agents: agents.sort((a, b2) => Number(b2.online) - Number(a.online) || a.name.localeCompare(b2.name)),
|
|
@@ -46249,7 +46320,7 @@ function spawnDegradeWorktree(repoRoot, runId, options) {
|
|
|
46249
46320
|
const cleanRunId = runId.replace(/^run_/, "");
|
|
46250
46321
|
const desc = options?.description ? slugifyBranchPart(options.description, 30) : "degrade";
|
|
46251
46322
|
const branchName = `kxm/run-${cleanRunId}-${desc}`;
|
|
46252
|
-
const relativeWtPath =
|
|
46323
|
+
const relativeWtPath = join43(".kxm", "worktrees", `run-${cleanRunId}-${desc}`);
|
|
46253
46324
|
const absoluteWtPath = resolve27(repoRoot, relativeWtPath);
|
|
46254
46325
|
const jumpCommand = `cd "${absoluteWtPath}"`;
|
|
46255
46326
|
try {
|
|
@@ -47018,8 +47089,8 @@ async function runMeshTui(input) {
|
|
|
47018
47089
|
// plugins/kxm/src/session-work.ts
|
|
47019
47090
|
import { spawnSync as spawnSync9 } from "node:child_process";
|
|
47020
47091
|
import { randomUUID as randomUUID12 } from "node:crypto";
|
|
47021
|
-
import { existsSync as
|
|
47022
|
-
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";
|
|
47023
47094
|
init_hub_binding();
|
|
47024
47095
|
init_telemetry();
|
|
47025
47096
|
var MAX_SESSION_BRIEF_TASKS = 5;
|
|
@@ -47178,9 +47249,9 @@ function buildSessionBrief(snapshot, current, hub, ship, updateLatest, cost, ses
|
|
|
47178
47249
|
};
|
|
47179
47250
|
}
|
|
47180
47251
|
function readCachedSessionBrief(stateDir) {
|
|
47181
|
-
const file =
|
|
47252
|
+
const file = join44(stateDir, "session-brief.json");
|
|
47182
47253
|
try {
|
|
47183
|
-
if (!
|
|
47254
|
+
if (!existsSync33(file)) return void 0;
|
|
47184
47255
|
const raw = readFileSync31(file, "utf8");
|
|
47185
47256
|
const parsed = JSON.parse(raw);
|
|
47186
47257
|
if (parsed && parsed.schema === "kxm.session-brief.v1" && typeof parsed.generatedAt === "string") {
|
|
@@ -47197,7 +47268,7 @@ function readCachedSessionBrief(stateDir) {
|
|
|
47197
47268
|
function writeCachedSessionBrief(stateDir, brief) {
|
|
47198
47269
|
try {
|
|
47199
47270
|
mkdirSync26(stateDir, { recursive: true, mode: 448 });
|
|
47200
|
-
const file =
|
|
47271
|
+
const file = join44(stateDir, "session-brief.json");
|
|
47201
47272
|
const tmp = `${file}.tmp.${randomUUID12().slice(0, 8)}`;
|
|
47202
47273
|
writeFileSync23(tmp, JSON.stringify(brief, null, 2), { encoding: "utf8", mode: 384 });
|
|
47203
47274
|
renameSync8(tmp, file);
|
|
@@ -47206,8 +47277,8 @@ function writeCachedSessionBrief(stateDir, brief) {
|
|
|
47206
47277
|
}
|
|
47207
47278
|
function estimateSessionCost(stateDir) {
|
|
47208
47279
|
try {
|
|
47209
|
-
const telemetryFile =
|
|
47210
|
-
if (!
|
|
47280
|
+
const telemetryFile = join44(stateDir, "telemetry.jsonl");
|
|
47281
|
+
if (!existsSync33(telemetryFile)) return void 0;
|
|
47211
47282
|
const records = readRoutingRecords(telemetryFile);
|
|
47212
47283
|
if (records.length === 0) return void 0;
|
|
47213
47284
|
let totalCost = 0;
|
|
@@ -47379,11 +47450,11 @@ init_hub_binding();
|
|
|
47379
47450
|
|
|
47380
47451
|
// plugins/kxm/src/kxm-install-kind.ts
|
|
47381
47452
|
init_bindings();
|
|
47382
|
-
import { existsSync as
|
|
47383
|
-
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";
|
|
47384
47455
|
function packageIsKxm(root) {
|
|
47385
47456
|
try {
|
|
47386
|
-
const pkg = JSON.parse(readFileSync32(
|
|
47457
|
+
const pkg = JSON.parse(readFileSync32(join45(root, "package.json"), "utf8"));
|
|
47387
47458
|
return pkg.name === "@kontextmind/kxm";
|
|
47388
47459
|
} catch {
|
|
47389
47460
|
return false;
|
|
@@ -47432,12 +47503,12 @@ function report(kind, root) {
|
|
|
47432
47503
|
return { kind, root, instruction: installKindInstruction(kind, root) };
|
|
47433
47504
|
}
|
|
47434
47505
|
function classifyInstallRoot(probe) {
|
|
47435
|
-
const piGitRoot =
|
|
47506
|
+
const piGitRoot = join45(probe.homeDir, ".pi", "agent", "git");
|
|
47436
47507
|
if (isUnder(probe.repoRoot, piGitRoot, probe.platform)) return report("pi-git", probe.repoRoot);
|
|
47437
|
-
const claudeHome = probe.env.CLAUDE_CONFIG_DIR?.trim() ||
|
|
47438
|
-
const pluginsRoot =
|
|
47508
|
+
const claudeHome = probe.env.CLAUDE_CONFIG_DIR?.trim() || join45(probe.homeDir, ".claude");
|
|
47509
|
+
const pluginsRoot = join45(claudeHome, "plugins");
|
|
47439
47510
|
if (isUnder(probe.moduleDir, pluginsRoot, probe.platform)) return report("claude-marketplace", probe.moduleDir);
|
|
47440
|
-
const hasGit =
|
|
47511
|
+
const hasGit = existsSync34(join45(probe.repoRoot, ".git"));
|
|
47441
47512
|
if (hasGit && packageIsKxm(probe.repoRoot)) return report("source", probe.repoRoot);
|
|
47442
47513
|
if (isNpmPackageLayout(probe.repoRoot, probe.platform) && packageIsKxm(probe.repoRoot) && !hasGit) {
|
|
47443
47514
|
return report("npm-package", probe.repoRoot);
|
|
@@ -47461,12 +47532,12 @@ init_bindings();
|
|
|
47461
47532
|
|
|
47462
47533
|
// plugins/kxm/src/kxm-update-config.ts
|
|
47463
47534
|
var import_yaml16 = __toESM(require_dist(), 1);
|
|
47464
|
-
import { existsSync as
|
|
47465
|
-
import { join as
|
|
47535
|
+
import { existsSync as existsSync35, readFileSync as readFileSync33 } from "node:fs";
|
|
47536
|
+
import { join as join46 } from "node:path";
|
|
47466
47537
|
init_bindings();
|
|
47467
47538
|
function loadKxmUpdateConfig(env = process.env) {
|
|
47468
|
-
const path4 =
|
|
47469
|
-
if (!
|
|
47539
|
+
const path4 = join46(kxmUserStateRoot({ env }), "update.yaml");
|
|
47540
|
+
if (!existsSync35(path4)) return { schema: KXM_UPDATE_SCHEMA, auto: false, source: "github" };
|
|
47470
47541
|
let parsed;
|
|
47471
47542
|
try {
|
|
47472
47543
|
parsed = (0, import_yaml16.parse)(readFileSync33(path4, "utf8"));
|
|
@@ -47497,8 +47568,8 @@ function loadKxmUpdateConfig(env = process.env) {
|
|
|
47497
47568
|
// plugins/kxm/src/session.ts
|
|
47498
47569
|
init_protocol();
|
|
47499
47570
|
init_envelope();
|
|
47500
|
-
import { existsSync as
|
|
47501
|
-
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";
|
|
47502
47573
|
var SESSION_SCHEMA = "kxm.session.v1";
|
|
47503
47574
|
var SessionConfigError = class extends Error {
|
|
47504
47575
|
code = "session_config_invalid";
|
|
@@ -47508,12 +47579,12 @@ var SessionConfigError = class extends Error {
|
|
|
47508
47579
|
}
|
|
47509
47580
|
};
|
|
47510
47581
|
function workflowAssetDirs(assetsDir, workflowId) {
|
|
47511
|
-
const root =
|
|
47512
|
-
return [root,
|
|
47582
|
+
const root = join47(assetsDir, "workflows", workflowId);
|
|
47583
|
+
return [root, join47(root, "inputs"), join47(root, "outputs"), join47(root, "generated")];
|
|
47513
47584
|
}
|
|
47514
47585
|
function sessionAssetDirs(assetsDir, sessionId) {
|
|
47515
|
-
const root =
|
|
47516
|
-
return [root,
|
|
47586
|
+
const root = join47(assetsDir, "sessions", sessionId);
|
|
47587
|
+
return [root, join47(root, "inputs"), join47(root, "outputs")];
|
|
47517
47588
|
}
|
|
47518
47589
|
function rosterNames(configDir) {
|
|
47519
47590
|
return [...loadRosterMap(configDir).values()].map((row) => String(row.name));
|
|
@@ -47563,7 +47634,7 @@ function workerFromRosterRow(name, row, project) {
|
|
|
47563
47634
|
function loadRosterMap(configDir) {
|
|
47564
47635
|
const byName = /* @__PURE__ */ new Map();
|
|
47565
47636
|
for (const [file, key] of [["agents.json", "agents"], ["gates.json", "gates"]]) {
|
|
47566
|
-
const path4 =
|
|
47637
|
+
const path4 = join47(configDir, file);
|
|
47567
47638
|
for (const row of loadRoster(path4, key)) {
|
|
47568
47639
|
const name = String(row.name).trim();
|
|
47569
47640
|
const lowered = name.toLowerCase();
|
|
@@ -47577,7 +47648,7 @@ function loadRosterMap(configDir) {
|
|
|
47577
47648
|
return byName;
|
|
47578
47649
|
}
|
|
47579
47650
|
function loadRoster(path4, key) {
|
|
47580
|
-
if (!
|
|
47651
|
+
if (!existsSync36(path4)) return [];
|
|
47581
47652
|
let parsed;
|
|
47582
47653
|
try {
|
|
47583
47654
|
parsed = JSON.parse(readFileSync34(path4, "utf8"));
|
|
@@ -47605,7 +47676,7 @@ function loadRoster(path4, key) {
|
|
|
47605
47676
|
});
|
|
47606
47677
|
}
|
|
47607
47678
|
function createSession(input) {
|
|
47608
|
-
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);
|
|
47609
47680
|
return {
|
|
47610
47681
|
schema: SESSION_SCHEMA,
|
|
47611
47682
|
id: input.id,
|
|
@@ -47618,8 +47689,8 @@ function createSession(input) {
|
|
|
47618
47689
|
};
|
|
47619
47690
|
}
|
|
47620
47691
|
function writeSession(assetsDir, session, dryRun = false) {
|
|
47621
|
-
const dir =
|
|
47622
|
-
const path4 =
|
|
47692
|
+
const dir = join47(assetsDir, "sessions", session.id);
|
|
47693
|
+
const path4 = join47(dir, "session.json");
|
|
47623
47694
|
if (!dryRun) {
|
|
47624
47695
|
mkdirSync27(dir, { recursive: true });
|
|
47625
47696
|
writeFileSync24(path4, `${JSON.stringify(session, null, 2)}
|
|
@@ -47675,9 +47746,9 @@ function moduleInstallRoot() {
|
|
|
47675
47746
|
}
|
|
47676
47747
|
}
|
|
47677
47748
|
function warnIgnoredProjectUpdateYaml(runtime) {
|
|
47678
|
-
const projectFile =
|
|
47679
|
-
if (!
|
|
47680
|
-
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");
|
|
47681
47752
|
runtime.io.stderr(`kxm: ignoring .kxm/update.yaml in ${runtime.dirs.workdir}; update settings are read only from ${userFile}
|
|
47682
47753
|
`);
|
|
47683
47754
|
}
|
|
@@ -47725,7 +47796,7 @@ async function cmdDash(runtime, options = {}) {
|
|
|
47725
47796
|
return 2;
|
|
47726
47797
|
}
|
|
47727
47798
|
const screen = requested;
|
|
47728
|
-
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"));
|
|
47729
47800
|
if (runtime.dryRun) {
|
|
47730
47801
|
print(runtime.io, runtime.json, {
|
|
47731
47802
|
ok: true,
|
|
@@ -47771,7 +47842,7 @@ async function cmdHub(runtime) {
|
|
|
47771
47842
|
config = loadKxmUpdateConfig(runtime.env);
|
|
47772
47843
|
} catch (error) {
|
|
47773
47844
|
if (error instanceof KxmUpdateConfigError) {
|
|
47774
|
-
const yamlPath =
|
|
47845
|
+
const yamlPath = join48(kxmUserStateRoot({ env: runtime.env }), "update.yaml");
|
|
47775
47846
|
runtime.io.stderr(`kxm: ${error.message}; update check skipped; fix or remove ${yamlPath}
|
|
47776
47847
|
`);
|
|
47777
47848
|
} else {
|
|
@@ -47958,7 +48029,7 @@ async function cmdWorker(runtime, options) {
|
|
|
47958
48029
|
return await (runtime.io.spawnWorker ?? ((launchEnv) => spawnScript("kxm-worker.mjs", launchEnv)))(extraEnv);
|
|
47959
48030
|
}
|
|
47960
48031
|
async function cmdStop(runtime, waitMsFlag) {
|
|
47961
|
-
const pids =
|
|
48032
|
+
const pids = existsSync37(runtime.dirs.state) ? readdirSync12(runtime.dirs.state).filter((name) => name.endsWith(".pid")) : [];
|
|
47962
48033
|
if (runtime.dryRun) {
|
|
47963
48034
|
print(runtime.io, runtime.json, { ok: true, command: "stop", dryRun: true, pidFiles: pids }, "would signal pid files");
|
|
47964
48035
|
return 0;
|
|
@@ -47973,7 +48044,7 @@ async function cmdStop(runtime, waitMsFlag) {
|
|
|
47973
48044
|
const orphans = [];
|
|
47974
48045
|
for (const file of pids) {
|
|
47975
48046
|
try {
|
|
47976
|
-
const record = JSON.parse(readFileSync35(
|
|
48047
|
+
const record = JSON.parse(readFileSync35(join48(runtime.dirs.state, file), "utf8"));
|
|
47977
48048
|
const expectedControl = file === "hub.pid" ? "hub.stop" : file.startsWith("worker-") ? `${file.slice(0, -4)}.stop` : void 0;
|
|
47978
48049
|
const expectedRole = file === "hub.pid" ? "hub" : file.startsWith("worker-") ? "worker" : void 0;
|
|
47979
48050
|
if (record.version !== 1 || !Number.isInteger(record.pid) || record.pid <= 0 || !record.startedAt || !expectedControl || record.controlFile !== expectedControl || record.role !== expectedRole) {
|
|
@@ -47993,7 +48064,7 @@ async function cmdStop(runtime, waitMsFlag) {
|
|
|
47993
48064
|
ignored.push(file);
|
|
47994
48065
|
continue;
|
|
47995
48066
|
}
|
|
47996
|
-
writeFileSync25(
|
|
48067
|
+
writeFileSync25(join48(runtime.dirs.state, record.controlFile), `${JSON.stringify({ startedAt: record.startedAt, ...record.generation ? { generation: record.generation } : {}, requestedAt: (/* @__PURE__ */ new Date()).toISOString() })}
|
|
47997
48068
|
`, { encoding: "utf8", mode: 384 });
|
|
47998
48069
|
requested.push(file);
|
|
47999
48070
|
records.set(file, { pid: record.pid, startedAt: record.startedAt, ...record.generation ? { generation: record.generation } : {} });
|
|
@@ -48011,7 +48082,7 @@ async function cmdStop(runtime, waitMsFlag) {
|
|
|
48011
48082
|
while (Date.now() <= deadline && stopped.size < requested.length) {
|
|
48012
48083
|
for (const [file, record] of records) {
|
|
48013
48084
|
try {
|
|
48014
|
-
const current = JSON.parse(readFileSync35(
|
|
48085
|
+
const current = JSON.parse(readFileSync35(join48(runtime.dirs.state, file), "utf8"));
|
|
48015
48086
|
if (current.pid !== record.pid || current.startedAt !== record.startedAt || current.generation !== record.generation || !processExists(record.pid)) stopped.add(file);
|
|
48016
48087
|
} catch {
|
|
48017
48088
|
stopped.add(file);
|
|
@@ -48024,7 +48095,7 @@ async function cmdStop(runtime, waitMsFlag) {
|
|
|
48024
48095
|
for (const file of orphans) {
|
|
48025
48096
|
while (Date.now() <= deadlineOrphans) {
|
|
48026
48097
|
try {
|
|
48027
|
-
const current = JSON.parse(readFileSync35(
|
|
48098
|
+
const current = JSON.parse(readFileSync35(join48(runtime.dirs.state, file), "utf8"));
|
|
48028
48099
|
if (!Number.isInteger(current.serverPid) || !processExists(current.serverPid)) break;
|
|
48029
48100
|
} catch {
|
|
48030
48101
|
break;
|
|
@@ -48032,14 +48103,14 @@ async function cmdStop(runtime, waitMsFlag) {
|
|
|
48032
48103
|
await (runtime.io.sleep ?? ((ms) => new Promise((resolveSleep) => setTimeout(resolveSleep, ms))))(100);
|
|
48033
48104
|
}
|
|
48034
48105
|
try {
|
|
48035
|
-
const current = JSON.parse(readFileSync35(
|
|
48106
|
+
const current = JSON.parse(readFileSync35(join48(runtime.dirs.state, file), "utf8"));
|
|
48036
48107
|
if (Number.isInteger(current.serverPid) && processExists(current.serverPid)) {
|
|
48037
48108
|
try {
|
|
48038
48109
|
process.kill(current.serverPid, "SIGKILL");
|
|
48039
48110
|
} catch {
|
|
48040
48111
|
}
|
|
48041
48112
|
}
|
|
48042
|
-
rmSync11(
|
|
48113
|
+
rmSync11(join48(runtime.dirs.state, file), { force: true });
|
|
48043
48114
|
} catch {
|
|
48044
48115
|
}
|
|
48045
48116
|
stopped.add(file);
|
|
@@ -48050,11 +48121,11 @@ async function cmdStop(runtime, waitMsFlag) {
|
|
|
48050
48121
|
}
|
|
48051
48122
|
async function cmdSessionStatus(runtime) {
|
|
48052
48123
|
const stateDir = runtime.dirs.state;
|
|
48053
|
-
const names3 =
|
|
48124
|
+
const names3 = existsSync37(stateDir) ? readdirSync12(stateDir) : [];
|
|
48054
48125
|
const claims = [];
|
|
48055
48126
|
for (const file of names3.filter((name) => name.endsWith(".pid"))) {
|
|
48056
48127
|
try {
|
|
48057
|
-
const record = JSON.parse(readFileSync35(
|
|
48128
|
+
const record = JSON.parse(readFileSync35(join48(stateDir, file), "utf8"));
|
|
48058
48129
|
claims.push({
|
|
48059
48130
|
file,
|
|
48060
48131
|
role: record.role,
|
|
@@ -48069,7 +48140,7 @@ async function cmdSessionStatus(runtime) {
|
|
|
48069
48140
|
const recoveries = [];
|
|
48070
48141
|
for (const file of names3.filter((name) => name.startsWith("worker-recovery-") && name.endsWith(".json"))) {
|
|
48071
48142
|
try {
|
|
48072
|
-
const envelope = JSON.parse(readFileSync35(
|
|
48143
|
+
const envelope = JSON.parse(readFileSync35(join48(stateDir, file), "utf8"));
|
|
48073
48144
|
recoveries.push({
|
|
48074
48145
|
file,
|
|
48075
48146
|
reason: envelope.reason,
|
|
@@ -48095,7 +48166,7 @@ async function cmdSessionStatus(runtime) {
|
|
|
48095
48166
|
async function cmdAuthToken(runtime, options = {}) {
|
|
48096
48167
|
const tokenFile = sessionTokenPath(runtime.env.KXM_USER_CONFIG_DIR);
|
|
48097
48168
|
if (options.clear && runtime.dryRun) {
|
|
48098
|
-
const present =
|
|
48169
|
+
const present = existsSync37(tokenFile);
|
|
48099
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");
|
|
48100
48171
|
return 0;
|
|
48101
48172
|
}
|
|
@@ -48184,7 +48255,7 @@ async function cmdSessionBrief(runtime, options = {}) {
|
|
|
48184
48255
|
print(runtime.io, runtime.json, { ok: true, command: "session brief", sessionToken }, sessionToken);
|
|
48185
48256
|
return 0;
|
|
48186
48257
|
}
|
|
48187
|
-
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"));
|
|
48188
48259
|
const env = {
|
|
48189
48260
|
...runtime.env,
|
|
48190
48261
|
KXM_STATE_DIR: runtime.dirs.state,
|
|
@@ -48210,7 +48281,7 @@ async function cmdSessionBrief(runtime, options = {}) {
|
|
|
48210
48281
|
writeCache: !runtime.dryRun
|
|
48211
48282
|
});
|
|
48212
48283
|
if (runtime.dryRun) {
|
|
48213
|
-
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") });
|
|
48214
48285
|
print(runtime.io, runtime.json, { ...brief, dryRun: true, planned }, [
|
|
48215
48286
|
options.status ? brief.statusLine : formatSessionBriefText(brief),
|
|
48216
48287
|
...planned.map((change) => `dry run: would ${change.action} ${change.target}`)
|
|
@@ -48294,9 +48365,9 @@ init_routing();
|
|
|
48294
48365
|
init_prices();
|
|
48295
48366
|
import { spawnSync as spawnSync11 } from "node:child_process";
|
|
48296
48367
|
import { createHash as createHash17 } from "node:crypto";
|
|
48297
|
-
import { existsSync as
|
|
48368
|
+
import { existsSync as existsSync44, mkdtempSync as mkdtempSync3, readFileSync as readFileSync40, rmSync as rmSync13 } from "node:fs";
|
|
48298
48369
|
import { tmpdir as tmpdir2 } from "node:os";
|
|
48299
|
-
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";
|
|
48300
48371
|
import { createInterface as createInterface3 } from "node:readline";
|
|
48301
48372
|
|
|
48302
48373
|
// plugins/kxm/src/improve.ts
|
|
@@ -48304,8 +48375,8 @@ init_routing();
|
|
|
48304
48375
|
init_protocol();
|
|
48305
48376
|
init_relevance();
|
|
48306
48377
|
import { createHash as createHash16 } from "node:crypto";
|
|
48307
|
-
import { existsSync as
|
|
48308
|
-
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";
|
|
48309
48380
|
var CANDIDATE_SCHEMA = "kxm.candidate.v1";
|
|
48310
48381
|
var IMPROVEMENT_REPORT_SCHEMA = "kxm.improvement-report.v2";
|
|
48311
48382
|
function classifyCandidateKind(stepId, agentRole) {
|
|
@@ -48561,7 +48632,7 @@ function groupRoutingRecords(records, options = {}) {
|
|
|
48561
48632
|
}
|
|
48562
48633
|
function buildImprovementReport(records, options = {}) {
|
|
48563
48634
|
const projectRoot = options.projectRoot ? resolve29(options.projectRoot) : process.cwd();
|
|
48564
|
-
const candidatesDir = options.candidatesDir ? resolve29(options.candidatesDir) :
|
|
48635
|
+
const candidatesDir = options.candidatesDir ? resolve29(options.candidatesDir) : join49(projectRoot, ".kxm", "candidates");
|
|
48565
48636
|
const promotionPolicy = options.promotionPolicy ?? "manual_pr";
|
|
48566
48637
|
const groups = groupRoutingRecords(records, options);
|
|
48567
48638
|
const candidates = [];
|
|
@@ -48575,7 +48646,7 @@ function buildImprovementReport(records, options = {}) {
|
|
|
48575
48646
|
group.workflowId
|
|
48576
48647
|
);
|
|
48577
48648
|
const diffFileName = `${group.candidateId}.diff`;
|
|
48578
|
-
const diffFilePath =
|
|
48649
|
+
const diffFilePath = join49(candidatesDir, diffFileName);
|
|
48579
48650
|
const relDiffPath = relative7(projectRoot, diffFilePath).replace(/\\/g, "/");
|
|
48580
48651
|
const candidate = {
|
|
48581
48652
|
schema: CANDIDATE_SCHEMA,
|
|
@@ -48597,11 +48668,11 @@ function buildImprovementReport(records, options = {}) {
|
|
|
48597
48668
|
createdAt: nowIso()
|
|
48598
48669
|
};
|
|
48599
48670
|
if (!options.dryRun) {
|
|
48600
|
-
if (!
|
|
48671
|
+
if (!existsSync38(candidatesDir)) {
|
|
48601
48672
|
mkdirSync29(candidatesDir, { recursive: true });
|
|
48602
48673
|
}
|
|
48603
48674
|
writeFileSync26(diffFilePath, diff, "utf8");
|
|
48604
|
-
const jsonFilePath =
|
|
48675
|
+
const jsonFilePath = join49(candidatesDir, `${group.candidateId}.json`);
|
|
48605
48676
|
writeFileSync26(jsonFilePath, JSON.stringify(candidate, null, 2) + "\n", "utf8");
|
|
48606
48677
|
}
|
|
48607
48678
|
candidates.push(candidate);
|
|
@@ -48630,7 +48701,7 @@ function buildImprovementReport(records, options = {}) {
|
|
|
48630
48701
|
}
|
|
48631
48702
|
function writeImprovementReport(improvementsDir, report2, dryRun = false) {
|
|
48632
48703
|
const stamp = report2.createdAt.replace(/[:.]/g, "-");
|
|
48633
|
-
const path4 =
|
|
48704
|
+
const path4 = join49(improvementsDir, `${stamp}.json`);
|
|
48634
48705
|
if (!dryRun) {
|
|
48635
48706
|
mkdirSync29(improvementsDir, { recursive: true });
|
|
48636
48707
|
writeFileSync26(path4, `${JSON.stringify(report2, null, 2)}
|
|
@@ -48714,7 +48785,7 @@ init_project_config();
|
|
|
48714
48785
|
init_runtime_store();
|
|
48715
48786
|
init_routing();
|
|
48716
48787
|
init_telemetry();
|
|
48717
|
-
import { existsSync as
|
|
48788
|
+
import { existsSync as existsSync39 } from "node:fs";
|
|
48718
48789
|
import { resolve as resolve30 } from "node:path";
|
|
48719
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";
|
|
48720
48791
|
var SIMULATED_HARNESS = "driver-simulated";
|
|
@@ -48737,7 +48808,7 @@ function readEngineRoutingRecords(path4) {
|
|
|
48737
48808
|
undecided: 0,
|
|
48738
48809
|
duplicatesDropped: 0
|
|
48739
48810
|
};
|
|
48740
|
-
if (!
|
|
48811
|
+
if (!existsSync39(path4)) return { records: [], source };
|
|
48741
48812
|
source.exists = true;
|
|
48742
48813
|
let rows;
|
|
48743
48814
|
let database;
|
|
@@ -48813,7 +48884,7 @@ function readEngineRoutingRecords(path4) {
|
|
|
48813
48884
|
};
|
|
48814
48885
|
}
|
|
48815
48886
|
function readJsonlSource(kind, path4) {
|
|
48816
|
-
const exists =
|
|
48887
|
+
const exists = existsSync39(path4);
|
|
48817
48888
|
const records = exists ? readRoutingRecords(path4).map((entry) => entry.routing) : [];
|
|
48818
48889
|
return { records, source: { kind, path: path4, exists, records: records.length, duplicatesDropped: 0 } };
|
|
48819
48890
|
}
|
|
@@ -48858,8 +48929,8 @@ function loadRoutingSources(options) {
|
|
|
48858
48929
|
// plugins/kxm/src/modes.ts
|
|
48859
48930
|
var import_yaml17 = __toESM(require_dist(), 1);
|
|
48860
48931
|
init_prices();
|
|
48861
|
-
import { existsSync as
|
|
48862
|
-
import { join as
|
|
48932
|
+
import { existsSync as existsSync40, readFileSync as readFileSync37 } from "node:fs";
|
|
48933
|
+
import { join as join50 } from "node:path";
|
|
48863
48934
|
var DEFAULT_MODES_CONFIG = Object.freeze({
|
|
48864
48935
|
schema: "kxm.modes.v1",
|
|
48865
48936
|
majorModes: {
|
|
@@ -48922,8 +48993,8 @@ function loadModesConfig(projectRoot) {
|
|
|
48922
48993
|
if (!projectRoot) {
|
|
48923
48994
|
return DEFAULT_MODES_CONFIG;
|
|
48924
48995
|
}
|
|
48925
|
-
const modesPath =
|
|
48926
|
-
if (!
|
|
48996
|
+
const modesPath = join50(projectRoot, ".kxm", "modes.yaml");
|
|
48997
|
+
if (!existsSync40(modesPath)) {
|
|
48927
48998
|
return DEFAULT_MODES_CONFIG;
|
|
48928
48999
|
}
|
|
48929
49000
|
try {
|
|
@@ -49013,9 +49084,9 @@ function calculatePromptFootprint(resolved, projectRoot = process.cwd(), catalog
|
|
|
49013
49084
|
estimatedTokens: estimateTokens(baseSystemPromptChars)
|
|
49014
49085
|
});
|
|
49015
49086
|
for (const relPath of resolved.contextFiles) {
|
|
49016
|
-
const fullPath =
|
|
49087
|
+
const fullPath = join50(projectRoot, relPath);
|
|
49017
49088
|
let chars = 0;
|
|
49018
|
-
if (
|
|
49089
|
+
if (existsSync40(fullPath)) {
|
|
49019
49090
|
try {
|
|
49020
49091
|
chars = readFileSync37(fullPath, "utf8").length;
|
|
49021
49092
|
} catch {
|
|
@@ -49150,9 +49221,9 @@ ${divider}
|
|
|
49150
49221
|
// plugins/kxm/src/ssh-remote.ts
|
|
49151
49222
|
init_safety_integrity();
|
|
49152
49223
|
import { spawnSync as spawnSync10 } from "node:child_process";
|
|
49153
|
-
import { existsSync as
|
|
49224
|
+
import { existsSync as existsSync41, mkdirSync as mkdirSync30, readFileSync as readFileSync38, readdirSync as readdirSync13, rmSync as rmSync12, statSync as statSync5 } from "node:fs";
|
|
49154
49225
|
import { homedir as homedir8 } from "node:os";
|
|
49155
|
-
import { join as
|
|
49226
|
+
import { join as join51, resolve as resolve31 } from "node:path";
|
|
49156
49227
|
var MAX_SSH_OUTPUT_BYTES = 50 * 1024;
|
|
49157
49228
|
var MAX_SSH_OUTPUT_LINES = 2e3;
|
|
49158
49229
|
var DEFAULT_SOCKET_DIR = ".kxm/run/ssh-sockets";
|
|
@@ -49178,8 +49249,8 @@ function truncateSshOutput(raw) {
|
|
|
49178
49249
|
return { text, truncated };
|
|
49179
49250
|
}
|
|
49180
49251
|
function parseSshConfig(configPath) {
|
|
49181
|
-
const targetPath = configPath ??
|
|
49182
|
-
if (!
|
|
49252
|
+
const targetPath = configPath ?? join51(homedir8(), ".ssh", "config");
|
|
49253
|
+
if (!existsSync41(targetPath)) {
|
|
49183
49254
|
return [];
|
|
49184
49255
|
}
|
|
49185
49256
|
try {
|
|
@@ -49261,14 +49332,14 @@ function resolveSshHostG(host, execFn = spawnSync10) {
|
|
|
49261
49332
|
}
|
|
49262
49333
|
function ensureSocketDir(socketDir = DEFAULT_SOCKET_DIR) {
|
|
49263
49334
|
const resolved = resolve31(socketDir);
|
|
49264
|
-
if (!
|
|
49335
|
+
if (!existsSync41(resolved)) {
|
|
49265
49336
|
mkdirSync30(resolved, { recursive: true, mode: 448 });
|
|
49266
49337
|
}
|
|
49267
49338
|
return resolved;
|
|
49268
49339
|
}
|
|
49269
49340
|
function buildSshArgs(options) {
|
|
49270
49341
|
const socketDir = ensureSocketDir(options.socketDir ?? DEFAULT_SOCKET_DIR);
|
|
49271
|
-
const controlPath =
|
|
49342
|
+
const controlPath = join51(socketDir, "%C");
|
|
49272
49343
|
const persist = options.controlPersist ?? DEFAULT_CONTROL_PERSIST;
|
|
49273
49344
|
const args = [
|
|
49274
49345
|
"-o",
|
|
@@ -49293,7 +49364,7 @@ function buildSshArgs(options) {
|
|
|
49293
49364
|
}
|
|
49294
49365
|
function checkControlSocket(host, socketDir = DEFAULT_SOCKET_DIR, execFn = spawnSync10) {
|
|
49295
49366
|
const resolvedDir = ensureSocketDir(socketDir);
|
|
49296
|
-
const controlPath =
|
|
49367
|
+
const controlPath = join51(resolvedDir, "%C");
|
|
49297
49368
|
try {
|
|
49298
49369
|
const result = execFn("ssh", ["-O", "check", "-o", `ControlPath=${controlPath}`, host], {
|
|
49299
49370
|
encoding: "utf-8"
|
|
@@ -49305,7 +49376,7 @@ function checkControlSocket(host, socketDir = DEFAULT_SOCKET_DIR, execFn = spawn
|
|
|
49305
49376
|
}
|
|
49306
49377
|
function closeControlSocket(host, socketDir = DEFAULT_SOCKET_DIR, execFn = spawnSync10) {
|
|
49307
49378
|
const resolvedDir = ensureSocketDir(socketDir);
|
|
49308
|
-
const controlPath =
|
|
49379
|
+
const controlPath = join51(resolvedDir, "%C");
|
|
49309
49380
|
try {
|
|
49310
49381
|
const result = execFn("ssh", ["-O", "stop", "-o", `ControlPath=${controlPath}`, host], {
|
|
49311
49382
|
encoding: "utf-8"
|
|
@@ -49753,9 +49824,9 @@ complete -c kxm -n "__fish_seen_subcommand_from goal" -a "create list get"
|
|
|
49753
49824
|
}
|
|
49754
49825
|
|
|
49755
49826
|
// plugins/kxm/src/completion-install.ts
|
|
49756
|
-
import { existsSync as
|
|
49827
|
+
import { existsSync as existsSync42, mkdirSync as mkdirSync31, readFileSync as readFileSync39, writeFileSync as writeFileSync27 } from "node:fs";
|
|
49757
49828
|
import { homedir as homedir9 } from "node:os";
|
|
49758
|
-
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";
|
|
49759
49830
|
var COMPLETION_MARKER = "# kxm completion";
|
|
49760
49831
|
var PATH_MARKER = "# kxm path";
|
|
49761
49832
|
function detectShell(env = process.env, platform = process.platform) {
|
|
@@ -49777,25 +49848,25 @@ function completionScriptPath(shell, options = {}) {
|
|
|
49777
49848
|
const env = options.env ?? process.env;
|
|
49778
49849
|
const explicit = options.configDir ?? env.KXM_USER_CONFIG_DIR?.trim();
|
|
49779
49850
|
const base = explicit && explicit.length > 0 ? resolve32(explicit) : resolve32(effectiveHome(options), ".config", "kxm");
|
|
49780
|
-
return
|
|
49851
|
+
return join52(base, "completions", `kxm.${shell}`);
|
|
49781
49852
|
}
|
|
49782
49853
|
function bashRcCandidate(options) {
|
|
49783
49854
|
const home = effectiveHome(options);
|
|
49784
|
-
const candidates = [
|
|
49785
|
-
const existing = candidates.find((candidate) =>
|
|
49855
|
+
const candidates = [join52(home, ".bashrc"), join52(home, ".bash_profile")];
|
|
49856
|
+
const existing = candidates.find((candidate) => existsSync42(candidate));
|
|
49786
49857
|
return existing ?? candidates[0];
|
|
49787
49858
|
}
|
|
49788
49859
|
function zshRcCandidate(options) {
|
|
49789
49860
|
const env = options.env ?? process.env;
|
|
49790
49861
|
const home = effectiveHome(options);
|
|
49791
|
-
if (env.ZDOTDIR?.trim()) return
|
|
49792
|
-
return
|
|
49862
|
+
if (env.ZDOTDIR?.trim()) return join52(resolve32(env.ZDOTDIR.trim()), ".zshrc");
|
|
49863
|
+
return join52(home, ".zshrc");
|
|
49793
49864
|
}
|
|
49794
49865
|
function fishCompletionTarget(shell, options) {
|
|
49795
49866
|
const env = options.env ?? process.env;
|
|
49796
49867
|
const home = effectiveHome(options);
|
|
49797
|
-
if (env.XDG_CONFIG_HOME?.trim()) return
|
|
49798
|
-
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");
|
|
49799
49870
|
}
|
|
49800
49871
|
function completionRcTarget(shell, options = {}) {
|
|
49801
49872
|
if (shell === "fish") {
|
|
@@ -49827,13 +49898,13 @@ function installShellCompletion(shellInput, options = {}) {
|
|
|
49827
49898
|
const scriptPath = completionScriptPath(shell, options);
|
|
49828
49899
|
const { rcFile } = completionRcTarget(shell, options);
|
|
49829
49900
|
const script = generateShellCompletion(shell);
|
|
49830
|
-
const existingScript =
|
|
49901
|
+
const existingScript = existsSync42(scriptPath);
|
|
49831
49902
|
const existingScriptMatches = existingScript && readFileSync39(scriptPath, "utf8") === script;
|
|
49832
49903
|
let rcModified = false;
|
|
49833
49904
|
let alreadyInstalled = false;
|
|
49834
49905
|
if (shell === "fish") {
|
|
49835
49906
|
const fishTarget = fishCompletionTarget(shell, options);
|
|
49836
|
-
const fishInstalled =
|
|
49907
|
+
const fishInstalled = existsSync42(fishTarget) && readFileSync39(fishTarget, "utf8") === script;
|
|
49837
49908
|
alreadyInstalled = fishInstalled;
|
|
49838
49909
|
if (!options.dryRun && (!fishInstalled || options.overwrite)) {
|
|
49839
49910
|
mkdirSync31(resolve32(fishTarget, ".."), { recursive: true });
|
|
@@ -49850,7 +49921,7 @@ function installShellCompletion(shellInput, options = {}) {
|
|
|
49850
49921
|
}
|
|
49851
49922
|
if (rcFile) {
|
|
49852
49923
|
const line = sourceLine(shell, scriptPath);
|
|
49853
|
-
const rcContent =
|
|
49924
|
+
const rcContent = existsSync42(rcFile) ? readFileSync39(rcFile, "utf8") : "";
|
|
49854
49925
|
alreadyInstalled = rcContent.includes(line) || rcContent.includes(`${COMPLETION_MARKER}`);
|
|
49855
49926
|
}
|
|
49856
49927
|
if (!options.dryRun) {
|
|
@@ -49866,7 +49937,7 @@ ${marker}
|
|
|
49866
49937
|
${line}
|
|
49867
49938
|
`;
|
|
49868
49939
|
mkdirSync31(resolve32(rcFile, ".."), { recursive: true });
|
|
49869
|
-
writeFileSync27(rcFile, (
|
|
49940
|
+
writeFileSync27(rcFile, (existsSync42(rcFile) ? readFileSync39(rcFile, "utf8") : "") + stanza, { encoding: "utf8" });
|
|
49870
49941
|
rcModified = true;
|
|
49871
49942
|
}
|
|
49872
49943
|
}
|
|
@@ -49883,13 +49954,13 @@ function kxmBinDir(env = process.env) {
|
|
|
49883
49954
|
const argv1 = env.KXM_ENTRY ?? process.argv[1];
|
|
49884
49955
|
if (argv1 && isAbsolute10(argv1)) {
|
|
49885
49956
|
const dir = dirname24(argv1);
|
|
49886
|
-
if (
|
|
49957
|
+
if (existsSync42(join52(dir, process.platform === "win32" ? "kxm.cmd" : "kxm"))) return dir;
|
|
49887
49958
|
}
|
|
49888
49959
|
const pathEnv = env.PATH ?? "";
|
|
49889
49960
|
for (const part of pathEnv.split(delimiter)) {
|
|
49890
49961
|
if (!part) continue;
|
|
49891
49962
|
const candidate = resolve32(part, process.platform === "win32" ? "kxm.cmd" : "kxm");
|
|
49892
|
-
if (
|
|
49963
|
+
if (existsSync42(candidate)) return resolve32(part);
|
|
49893
49964
|
}
|
|
49894
49965
|
return void 0;
|
|
49895
49966
|
}
|
|
@@ -49907,7 +49978,7 @@ function installPathEntry(shellInput, options = {}) {
|
|
|
49907
49978
|
}
|
|
49908
49979
|
const { rcFile } = completionRcTarget(shell, options);
|
|
49909
49980
|
const line = pathLine(binDir);
|
|
49910
|
-
const rcContent =
|
|
49981
|
+
const rcContent = existsSync42(rcFile ?? "") ? readFileSync39(rcFile, "utf8") : "";
|
|
49911
49982
|
const alreadyInstalled = rcContent.includes(binDir) || (options.env?.PATH ?? process.env.PATH ?? "").split(delimiter).includes(binDir);
|
|
49912
49983
|
if (!options.dryRun && rcFile && !alreadyInstalled) {
|
|
49913
49984
|
mkdirSync31(dirname24(rcFile), { recursive: true });
|
|
@@ -49922,8 +49993,8 @@ ${line}
|
|
|
49922
49993
|
// plugins/kxm/src/init-guide-setup.ts
|
|
49923
49994
|
var import_yaml18 = __toESM(require_dist(), 1);
|
|
49924
49995
|
init_routes();
|
|
49925
|
-
import { existsSync as
|
|
49926
|
-
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";
|
|
49927
49998
|
var ADMITTED_GUIDE_BINDINGS = Object.freeze({
|
|
49928
49999
|
"anthropic/claude-fable-5.1": { harness: "claude", provider: "anthropic", model: "fable" },
|
|
49929
50000
|
"anthropic/fable": { harness: "claude", provider: "anthropic", model: "fable" },
|
|
@@ -50314,13 +50385,13 @@ function renderGuideSetupFiles(projectRoot, plan) {
|
|
|
50314
50385
|
const stage = roleStages.get(role);
|
|
50315
50386
|
if (!stage) continue;
|
|
50316
50387
|
files.push({
|
|
50317
|
-
path:
|
|
50388
|
+
path: join53(projectRoot, ".kxm", "agents", `${role}.yaml`),
|
|
50318
50389
|
content: (0, import_yaml18.stringify)(agentDocument(role, stage, binding))
|
|
50319
50390
|
});
|
|
50320
50391
|
}
|
|
50321
50392
|
for (const workflow of plan.workflows) {
|
|
50322
50393
|
files.push({
|
|
50323
|
-
path:
|
|
50394
|
+
path: join53(projectRoot, ".kxm", "workflows", `${workflow.slug}.yaml`),
|
|
50324
50395
|
content: (0, import_yaml18.stringify)(workflowDocument(workflow))
|
|
50325
50396
|
});
|
|
50326
50397
|
}
|
|
@@ -50337,7 +50408,7 @@ function mergeGuideRouteAdmission(projectRoot, plan) {
|
|
|
50337
50408
|
}
|
|
50338
50409
|
if (added.length === 0) return added;
|
|
50339
50410
|
policy.updatedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
50340
|
-
const path4 =
|
|
50411
|
+
const path4 = join53(projectRoot, ".kxm", "routes.yaml");
|
|
50341
50412
|
mkdirSync32(dirname25(path4), { recursive: true });
|
|
50342
50413
|
writeFileSync28(path4, (0, import_yaml18.stringify)(policy), "utf8");
|
|
50343
50414
|
return added;
|
|
@@ -50346,7 +50417,7 @@ function writeGuideSetupFiles(files) {
|
|
|
50346
50417
|
const written = [];
|
|
50347
50418
|
const existed = [];
|
|
50348
50419
|
for (const file of files) {
|
|
50349
|
-
if (
|
|
50420
|
+
if (existsSync43(file.path)) {
|
|
50350
50421
|
existed.push(file.path);
|
|
50351
50422
|
continue;
|
|
50352
50423
|
}
|
|
@@ -50417,7 +50488,7 @@ function applyKxmPackageUpdate(runtime, notice) {
|
|
|
50417
50488
|
detail: `release v${notice.latest} has no sha256 digest for ${name}; refusing to install`
|
|
50418
50489
|
};
|
|
50419
50490
|
}
|
|
50420
|
-
const releaseDir = mkdtempSync3(
|
|
50491
|
+
const releaseDir = mkdtempSync3(join54(tmpdir2(), "kxm-pkg-update-"));
|
|
50421
50492
|
try {
|
|
50422
50493
|
const planned = planKxmPackageUpdate(notice.source, notice.latest, releaseDir, notice.asset);
|
|
50423
50494
|
if (runtime.dryRun) {
|
|
@@ -50426,7 +50497,7 @@ function applyKxmPackageUpdate(runtime, notice) {
|
|
|
50426
50497
|
for (const step of planned) {
|
|
50427
50498
|
if (step.kind === "verify") {
|
|
50428
50499
|
if (!verifyReleaseAssetDigest(step.path, step.sha256)) {
|
|
50429
|
-
const actual =
|
|
50500
|
+
const actual = existsSync44(step.path) ? createHash17("sha256").update(readFileSync40(step.path)).digest("hex") : "missing";
|
|
50430
50501
|
return {
|
|
50431
50502
|
ok: false,
|
|
50432
50503
|
error: "release_digest_mismatch",
|
|
@@ -50704,7 +50775,7 @@ async function cmdValidate(runtime, fileFlag) {
|
|
|
50704
50775
|
}
|
|
50705
50776
|
const selectedFile = explicitFile || configuredFile;
|
|
50706
50777
|
const file = selectedFile ? resolve33(runtime.cwd, selectedFile) : void 0;
|
|
50707
|
-
if (file && !
|
|
50778
|
+
if (file && !existsSync44(file)) {
|
|
50708
50779
|
printWorker(runtime, worker, { ok: false, command: "validate", error: "file_not_found", file }, `workflow file not found: ${file}`);
|
|
50709
50780
|
return 1;
|
|
50710
50781
|
}
|
|
@@ -50804,7 +50875,7 @@ async function cmdImprove(runtime, options = {}) {
|
|
|
50804
50875
|
print(runtime.io, runtime.json, { ok: false, command: "improve", error: "config_invalid", detail: message }, `config_invalid: ${message}`);
|
|
50805
50876
|
return 1;
|
|
50806
50877
|
}
|
|
50807
|
-
const candidatesDir = options.outDir ? resolve33(runtime.cwd, options.outDir) :
|
|
50878
|
+
const candidatesDir = options.outDir ? resolve33(runtime.cwd, options.outDir) : join54(root, ".kxm", "candidates");
|
|
50808
50879
|
const report2 = buildImprovementReport(loaded.records, {
|
|
50809
50880
|
candidatesDir,
|
|
50810
50881
|
projectRoot: root,
|
|
@@ -50813,7 +50884,7 @@ async function cmdImprove(runtime, options = {}) {
|
|
|
50813
50884
|
autoThreshold: config.improvement.autoThreshold,
|
|
50814
50885
|
halfLifeDays: config.improvement.telemetryHalfLifeDays
|
|
50815
50886
|
});
|
|
50816
|
-
const reportDir =
|
|
50887
|
+
const reportDir = join54(runtime.dirs.assets, "improvements");
|
|
50817
50888
|
const reportPath = writeImprovementReport(reportDir, report2, runtime.dryRun);
|
|
50818
50889
|
const text = [
|
|
50819
50890
|
"Sources:",
|
|
@@ -50957,7 +51028,7 @@ async function maybeOfferCompletionInstall(runtime) {
|
|
|
50957
51028
|
if (!pathNeeded) {
|
|
50958
51029
|
const scriptPath = completionScriptPath(shell, { env: runtime.env, configDir: runtime.env.KXM_USER_CONFIG_DIR });
|
|
50959
51030
|
const { rcFile } = completionRcTarget(shell, { env: runtime.env });
|
|
50960
|
-
if (rcFile &&
|
|
51031
|
+
if (rcFile && existsSync44(rcFile)) {
|
|
50961
51032
|
try {
|
|
50962
51033
|
if (readFileSync40(rcFile, "utf8").includes(scriptPath)) return;
|
|
50963
51034
|
} catch {
|
|
@@ -51122,7 +51193,7 @@ async function cmdRoutingReport(runtime, options) {
|
|
|
51122
51193
|
let catalog;
|
|
51123
51194
|
if (includeEquivalentListCost) {
|
|
51124
51195
|
try {
|
|
51125
|
-
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");
|
|
51126
51197
|
catalog = loadPriceCatalog(pricesPath);
|
|
51127
51198
|
} catch {
|
|
51128
51199
|
}
|
|
@@ -51343,7 +51414,9 @@ var DRY_RUN_COMMANDS = /* @__PURE__ */ new Set([
|
|
|
51343
51414
|
"task run",
|
|
51344
51415
|
"task sync",
|
|
51345
51416
|
"studio layout",
|
|
51346
|
-
"studio serve"
|
|
51417
|
+
"studio serve",
|
|
51418
|
+
"docs build",
|
|
51419
|
+
"docs serve"
|
|
51347
51420
|
]);
|
|
51348
51421
|
var DryRunRefused = class extends Error {
|
|
51349
51422
|
code;
|
|
@@ -51623,6 +51696,14 @@ function createProgram(ctx, result) {
|
|
|
51623
51696
|
addGlobalOptions(runCmd.command("list").description("List recent runs for the current project")).action(async function runListAction() {
|
|
51624
51697
|
result.code = await cmdKxmRunList(runtimeFrom(ctx, this));
|
|
51625
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
|
+
});
|
|
51626
51707
|
const tenantCmd = addGlobalOptions(program2.command("tenant").description("Composed tenant reads for machine clients (portal)"));
|
|
51627
51708
|
tenantCmd.helpCommand("help", "Show tenant help");
|
|
51628
51709
|
addGlobalOptions(tenantCmd.command("status").description("Read hub metadata and authoritative Runtime run state as one labeled view")).action(async function tenantStatusAction() {
|