@kontextmind/kxm 0.7.120 → 0.7.121
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude-plugin/marketplace.json +1 -1
- package/.kxm/gates.yaml +24 -0
- package/.kxm/workflows/land.yaml +95 -0
- package/CHANGELOG.md +9 -0
- package/docs/contributing/assignment-runner.md +31 -0
- package/docs/reference/cli-reference.md +37 -0
- package/docs/reference/workflow-catalog.md +7 -0
- package/package.json +1 -1
- package/plugins/kxm/.claude-plugin/plugin.json +1 -1
- package/plugins/kxm/dist/cli.js +147 -99
- 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 +17 -1
- package/plugins/kxm/src/cli/land.ts +48 -0
- package/plugins/kxm/src/cli.ts +15 -0
- package/plugins/kxm/src/mcp-server.ts +1 -1
- package/scripts/pr-land.d.mts +2 -0
- package/scripts/pr-land.mjs +971 -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 join54 = objectValue(step.join);
|
|
18564
|
+
const minimumPassed = join54 && typeof join54.minimumPassed === "number" ? join54.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 join54 = 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: join54
|
|
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 join54 = objectValue2(step.join);
|
|
20945
|
+
if (!join54) return { strategy: "all" };
|
|
20946
|
+
const declared = stringValue2(join54.strategy);
|
|
20947
20947
|
const strategy = declared && JOIN_STRATEGIES.has(declared) ? declared : "all";
|
|
20948
|
-
const minimumPassed = compileOptionalCount(
|
|
20948
|
+
const minimumPassed = compileOptionalCount(join54.minimumPassed, `${stepId}.join.minimumPassed`, stepId, sink);
|
|
20949
20949
|
const compiled = {
|
|
20950
20950
|
strategy,
|
|
20951
20951
|
...minimumPassed !== void 0 ? { minimumPassed } : {},
|
|
20952
|
-
...typeof
|
|
20952
|
+
...typeof join54.cancelRemaining === "boolean" ? { cancelRemaining: join54.cancelRemaining } : {}
|
|
20953
20953
|
};
|
|
20954
20954
|
return compiled;
|
|
20955
20955
|
}
|
|
@@ -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 refuse3 = (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 refuse3("workflow_add_conflict", "--template cannot be combined with --file or --pick");
|
|
34148
34148
|
}
|
|
34149
|
-
if (!workflowId) return
|
|
34149
|
+
if (!workflowId) return refuse3("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 refuse3("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 refuse3("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 refuse3("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 refuse3("workflow_add_failed", err instanceof Error ? err.message : String(err), 1);
|
|
34230
34230
|
}
|
|
34231
34231
|
}
|
|
34232
34232
|
async function cmdWorkflowRemove(runtime, workflowId, options) {
|
|
@@ -37067,11 +37067,51 @@ async function cmdLaneRun(runtime, unit, options) {
|
|
|
37067
37067
|
});
|
|
37068
37068
|
}
|
|
37069
37069
|
|
|
37070
|
+
// plugins/kxm/src/cli/land.ts
|
|
37071
|
+
init_project_config();
|
|
37072
|
+
init_repo_root();
|
|
37073
|
+
init_types();
|
|
37074
|
+
import { spawn as spawn4 } from "node:child_process";
|
|
37075
|
+
import { join as join36 } from "node:path";
|
|
37076
|
+
function childEnv() {
|
|
37077
|
+
const env = {};
|
|
37078
|
+
for (const [name, value] of Object.entries(process.env)) {
|
|
37079
|
+
if (value === void 0) continue;
|
|
37080
|
+
if (name.toUpperCase().startsWith("GIT_")) continue;
|
|
37081
|
+
env[name] = value;
|
|
37082
|
+
}
|
|
37083
|
+
return env;
|
|
37084
|
+
}
|
|
37085
|
+
function refuse2(runtime, error, text) {
|
|
37086
|
+
print(runtime.io, runtime.json, { ok: false, command: "land", error }, text);
|
|
37087
|
+
return 1;
|
|
37088
|
+
}
|
|
37089
|
+
function cmdLand(runtime, options = {}) {
|
|
37090
|
+
const root = discoverKxmProjectRoot(runtime.cwd);
|
|
37091
|
+
if (!root) {
|
|
37092
|
+
return Promise.resolve(refuse2(runtime, "project_required", "land requires a KXM project (run kxm init first)"));
|
|
37093
|
+
}
|
|
37094
|
+
const script = join36(findKxmRepoRoot(import.meta.url), "scripts", "pr-land.mjs");
|
|
37095
|
+
const args = [script];
|
|
37096
|
+
if (options.pr) args.push("--pr", options.pr);
|
|
37097
|
+
if (options.stage) args.push("--stage", options.stage);
|
|
37098
|
+
if (options.bodyFile) args.push("--body-file", options.bodyFile);
|
|
37099
|
+
if (runtime.json) args.push("--json");
|
|
37100
|
+
if (runtime.dryRun) args.push("--dry-run");
|
|
37101
|
+
return new Promise((resolveExit) => {
|
|
37102
|
+
const child = spawn4(process.execPath, args, { cwd: root, env: childEnv(), windowsHide: true });
|
|
37103
|
+
child.stdout.on("data", (chunk) => runtime.io.stdout(chunk.toString("utf8")));
|
|
37104
|
+
child.stderr.on("data", (chunk) => runtime.io.stderr(chunk.toString("utf8")));
|
|
37105
|
+
child.once("error", () => resolveExit(1));
|
|
37106
|
+
child.once("close", (code) => resolveExit(code ?? 1));
|
|
37107
|
+
});
|
|
37108
|
+
}
|
|
37109
|
+
|
|
37070
37110
|
// plugins/kxm/src/cli/hub.ts
|
|
37071
37111
|
init_redact();
|
|
37072
37112
|
import { randomUUID as randomUUID13 } from "node:crypto";
|
|
37073
37113
|
import { existsSync as existsSync35, mkdirSync as mkdirSync28, readFileSync as readFileSync35, readdirSync as readdirSync12, rmSync as rmSync11, writeFileSync as writeFileSync25 } from "node:fs";
|
|
37074
|
-
import { join as
|
|
37114
|
+
import { join as join46, resolve as resolve28 } from "node:path";
|
|
37075
37115
|
init_hub_env();
|
|
37076
37116
|
init_envelope();
|
|
37077
37117
|
|
|
@@ -42769,7 +42809,7 @@ import * as path2 from "node:path";
|
|
|
42769
42809
|
|
|
42770
42810
|
// node_modules/@earendil-works/pi-tui/dist/native-module-path.js
|
|
42771
42811
|
import { createRequire as createRequire2 } from "node:module";
|
|
42772
|
-
import { dirname as dirname19, join as
|
|
42812
|
+
import { dirname as dirname19, join as join37 } from "node:path";
|
|
42773
42813
|
import { fileURLToPath as fileURLToPath2 } from "node:url";
|
|
42774
42814
|
var moduleRequire = createRequire2(import.meta.url);
|
|
42775
42815
|
var TUI_PACKAGE_NAME = "@earendil-works/pi-tui";
|
|
@@ -42778,10 +42818,10 @@ function getNativeModuleCandidates(nativePath, options = {}) {
|
|
|
42778
42818
|
const candidates = [];
|
|
42779
42819
|
try {
|
|
42780
42820
|
const packageEntry = (options.resolvePackage ?? moduleRequire.resolve)(TUI_PACKAGE_NAME);
|
|
42781
|
-
candidates.push(
|
|
42821
|
+
candidates.push(join37(dirname19(packageEntry), "..", nativePath));
|
|
42782
42822
|
} catch {
|
|
42783
42823
|
}
|
|
42784
|
-
candidates.push(
|
|
42824
|
+
candidates.push(join37(moduleDir, "..", nativePath), join37(moduleDir, nativePath), join37(dirname19(options.execPath ?? process.execPath), nativePath));
|
|
42785
42825
|
return Array.from(new Set(candidates));
|
|
42786
42826
|
}
|
|
42787
42827
|
|
|
@@ -45512,7 +45552,7 @@ var MAX_RENDER_WRITE_CHARS = 1024 * 1024;
|
|
|
45512
45552
|
|
|
45513
45553
|
// plugins/kxm/src/tui.ts
|
|
45514
45554
|
import { mkdirSync as mkdirSync25 } from "node:fs";
|
|
45515
|
-
import { join as
|
|
45555
|
+
import { join as join41, resolve as resolve27, dirname as dirname20 } from "node:path";
|
|
45516
45556
|
import { spawnSync as spawnSync7 } from "node:child_process";
|
|
45517
45557
|
|
|
45518
45558
|
// packages/core/tui/src/types/surface.ts
|
|
@@ -45658,7 +45698,7 @@ init_sqlite();
|
|
|
45658
45698
|
init_telemetry();
|
|
45659
45699
|
import { existsSync as existsSync30, readdirSync as readdirSync11, readFileSync as readFileSync30 } from "node:fs";
|
|
45660
45700
|
import { homedir as homedir6 } from "node:os";
|
|
45661
|
-
import { isAbsolute as isAbsolute9, join as
|
|
45701
|
+
import { isAbsolute as isAbsolute9, join as join40, resolve as resolve26 } from "node:path";
|
|
45662
45702
|
var DEFAULT_BUSY_TIMEOUT_MS = 5e3;
|
|
45663
45703
|
var RUNTIME_PROJECT_KEY = /^[A-Za-z0-9_-][A-Za-z0-9._-]*$/;
|
|
45664
45704
|
function processExists2(pid) {
|
|
@@ -45783,16 +45823,16 @@ function readOpenMessageMetadata(database, where = OPEN_MESSAGE_WHERE, params =
|
|
|
45783
45823
|
return messages;
|
|
45784
45824
|
}
|
|
45785
45825
|
function resolveKxmSnapshotPaths(cwd, env = process.env) {
|
|
45786
|
-
const stateDir = env.KXM_STATE_DIR?.trim() ||
|
|
45826
|
+
const stateDir = env.KXM_STATE_DIR?.trim() || join40(cwd, ".kxm", "state");
|
|
45787
45827
|
const configured = env.KXM_DATA_PATH?.trim();
|
|
45788
|
-
const dataPath = configured ? resolve26(cwd, configured) :
|
|
45828
|
+
const dataPath = configured ? resolve26(cwd, configured) : join40(stateDir, "kxm.db");
|
|
45789
45829
|
return { dataPath, stateDir };
|
|
45790
45830
|
}
|
|
45791
45831
|
function resolveKxmStateRoot(stateDir, options) {
|
|
45792
45832
|
if (options?.kxmStateRoot && existsSync30(options.kxmStateRoot)) {
|
|
45793
45833
|
return resolve26(options.kxmStateRoot);
|
|
45794
45834
|
}
|
|
45795
|
-
if (existsSync30(
|
|
45835
|
+
if (existsSync30(join40(stateDir, "runtime", "registry.db")) || existsSync30(join40(stateDir, "runtime", "projects"))) {
|
|
45796
45836
|
return stateDir;
|
|
45797
45837
|
}
|
|
45798
45838
|
const env = options?.env ?? process.env;
|
|
@@ -45803,13 +45843,13 @@ function resolveKxmStateRoot(stateDir, options) {
|
|
|
45803
45843
|
let base;
|
|
45804
45844
|
if (process.platform === "win32") {
|
|
45805
45845
|
const localAppData = env.LOCALAPPDATA?.trim();
|
|
45806
|
-
base = localAppData && isAbsolute9(localAppData) ? localAppData :
|
|
45846
|
+
base = localAppData && isAbsolute9(localAppData) ? localAppData : join40(homedir6(), "AppData", "Local");
|
|
45807
45847
|
base = resolve26(base, "KXM");
|
|
45808
45848
|
} else if (process.platform === "darwin") {
|
|
45809
45849
|
base = resolve26(homedir6(), "Library", "Application Support", "KXM");
|
|
45810
45850
|
} else {
|
|
45811
45851
|
const xdgState = env.XDG_STATE_HOME?.trim();
|
|
45812
|
-
base = xdgState && isAbsolute9(xdgState) ? xdgState :
|
|
45852
|
+
base = xdgState && isAbsolute9(xdgState) ? xdgState : join40(homedir6(), ".local", "state");
|
|
45813
45853
|
base = resolve26(base, "kxm");
|
|
45814
45854
|
}
|
|
45815
45855
|
if (existsSync30(base)) return base;
|
|
@@ -45876,9 +45916,9 @@ function loadLocalMeshSnapshot(dataPath, stateDir, options) {
|
|
|
45876
45916
|
let kxmRunTotal = 0;
|
|
45877
45917
|
const kxmStateRoot = scope && !scope.runtimeProjectId ? void 0 : resolveKxmStateRoot(stateDir, options);
|
|
45878
45918
|
if (kxmStateRoot) {
|
|
45879
|
-
const runtimeDir =
|
|
45880
|
-
const registryDbPath =
|
|
45881
|
-
const projectsDir =
|
|
45919
|
+
const runtimeDir = join40(kxmStateRoot, "runtime");
|
|
45920
|
+
const registryDbPath = join40(runtimeDir, "registry.db");
|
|
45921
|
+
const projectsDir = join40(runtimeDir, "projects");
|
|
45882
45922
|
const projectKeys = /* @__PURE__ */ new Set();
|
|
45883
45923
|
if (existsSync30(registryDbPath)) {
|
|
45884
45924
|
hasKxm = true;
|
|
@@ -45908,7 +45948,7 @@ function loadLocalMeshSnapshot(dataPath, stateDir, options) {
|
|
|
45908
45948
|
}
|
|
45909
45949
|
for (const key of projectKeys) {
|
|
45910
45950
|
if (scope && !RUNTIME_PROJECT_KEY.test(key)) continue;
|
|
45911
|
-
const eventDbPath =
|
|
45951
|
+
const eventDbPath = join40(projectsDir, key, "run-events.db");
|
|
45912
45952
|
if (existsSync30(eventDbPath)) {
|
|
45913
45953
|
hasKxm = true;
|
|
45914
45954
|
try {
|
|
@@ -45930,7 +45970,7 @@ function loadLocalMeshSnapshot(dataPath, stateDir, options) {
|
|
|
45930
45970
|
if (existsSync30(stateDir)) {
|
|
45931
45971
|
for (const file of readdirSync11(stateDir).filter((name) => name.endsWith(".pid"))) {
|
|
45932
45972
|
try {
|
|
45933
|
-
const record = JSON.parse(readFileSync30(
|
|
45973
|
+
const record = JSON.parse(readFileSync30(join40(stateDir, file), "utf8"));
|
|
45934
45974
|
pids.push({
|
|
45935
45975
|
file,
|
|
45936
45976
|
...record.role ? { role: record.role } : {},
|
|
@@ -45969,7 +46009,7 @@ function loadLocalMeshSnapshot(dataPath, stateDir, options) {
|
|
|
45969
46009
|
} else {
|
|
45970
46010
|
source = "legacy";
|
|
45971
46011
|
}
|
|
45972
|
-
const telemetryFile =
|
|
46012
|
+
const telemetryFile = join40(stateDir, "telemetry.jsonl");
|
|
45973
46013
|
const spend = existsSync30(telemetryFile) ? readRoutingRecords(telemetryFile) : [];
|
|
45974
46014
|
return {
|
|
45975
46015
|
source,
|
|
@@ -46104,7 +46144,7 @@ function spawnDegradeWorktree(repoRoot, runId, options) {
|
|
|
46104
46144
|
const cleanRunId = runId.replace(/^run_/, "");
|
|
46105
46145
|
const desc = options?.description ? slugifyBranchPart(options.description, 30) : "degrade";
|
|
46106
46146
|
const branchName = `kxm/run-${cleanRunId}-${desc}`;
|
|
46107
|
-
const relativeWtPath =
|
|
46147
|
+
const relativeWtPath = join41(".kxm", "worktrees", `run-${cleanRunId}-${desc}`);
|
|
46108
46148
|
const absoluteWtPath = resolve27(repoRoot, relativeWtPath);
|
|
46109
46149
|
const jumpCommand = `cd "${absoluteWtPath}"`;
|
|
46110
46150
|
try {
|
|
@@ -46874,7 +46914,7 @@ async function runMeshTui(input) {
|
|
|
46874
46914
|
import { spawnSync as spawnSync8 } from "node:child_process";
|
|
46875
46915
|
import { randomUUID as randomUUID12 } from "node:crypto";
|
|
46876
46916
|
import { existsSync as existsSync31, mkdirSync as mkdirSync26, readFileSync as readFileSync31, renameSync as renameSync8, writeFileSync as writeFileSync23 } from "node:fs";
|
|
46877
|
-
import { join as
|
|
46917
|
+
import { join as join42 } from "node:path";
|
|
46878
46918
|
init_hub_binding();
|
|
46879
46919
|
init_telemetry();
|
|
46880
46920
|
var MAX_SESSION_BRIEF_TASKS = 5;
|
|
@@ -47033,7 +47073,7 @@ function buildSessionBrief(snapshot, current, hub, ship, updateLatest, cost, ses
|
|
|
47033
47073
|
};
|
|
47034
47074
|
}
|
|
47035
47075
|
function readCachedSessionBrief(stateDir) {
|
|
47036
|
-
const file =
|
|
47076
|
+
const file = join42(stateDir, "session-brief.json");
|
|
47037
47077
|
try {
|
|
47038
47078
|
if (!existsSync31(file)) return void 0;
|
|
47039
47079
|
const raw = readFileSync31(file, "utf8");
|
|
@@ -47052,7 +47092,7 @@ function readCachedSessionBrief(stateDir) {
|
|
|
47052
47092
|
function writeCachedSessionBrief(stateDir, brief) {
|
|
47053
47093
|
try {
|
|
47054
47094
|
mkdirSync26(stateDir, { recursive: true, mode: 448 });
|
|
47055
|
-
const file =
|
|
47095
|
+
const file = join42(stateDir, "session-brief.json");
|
|
47056
47096
|
const tmp = `${file}.tmp.${randomUUID12().slice(0, 8)}`;
|
|
47057
47097
|
writeFileSync23(tmp, JSON.stringify(brief, null, 2), { encoding: "utf8", mode: 384 });
|
|
47058
47098
|
renameSync8(tmp, file);
|
|
@@ -47061,7 +47101,7 @@ function writeCachedSessionBrief(stateDir, brief) {
|
|
|
47061
47101
|
}
|
|
47062
47102
|
function estimateSessionCost(stateDir) {
|
|
47063
47103
|
try {
|
|
47064
|
-
const telemetryFile =
|
|
47104
|
+
const telemetryFile = join42(stateDir, "telemetry.jsonl");
|
|
47065
47105
|
if (!existsSync31(telemetryFile)) return void 0;
|
|
47066
47106
|
const records = readRoutingRecords(telemetryFile);
|
|
47067
47107
|
if (records.length === 0) return void 0;
|
|
@@ -47235,10 +47275,10 @@ init_hub_binding();
|
|
|
47235
47275
|
// plugins/kxm/src/kxm-install-kind.ts
|
|
47236
47276
|
init_bindings();
|
|
47237
47277
|
import { existsSync as existsSync32, readFileSync as readFileSync32 } from "node:fs";
|
|
47238
|
-
import { dirname as dirname21, join as
|
|
47278
|
+
import { dirname as dirname21, join as join43 } from "node:path";
|
|
47239
47279
|
function packageIsKxm(root) {
|
|
47240
47280
|
try {
|
|
47241
|
-
const pkg = JSON.parse(readFileSync32(
|
|
47281
|
+
const pkg = JSON.parse(readFileSync32(join43(root, "package.json"), "utf8"));
|
|
47242
47282
|
return pkg.name === "@kontextmind/kxm";
|
|
47243
47283
|
} catch {
|
|
47244
47284
|
return false;
|
|
@@ -47287,12 +47327,12 @@ function report(kind, root) {
|
|
|
47287
47327
|
return { kind, root, instruction: installKindInstruction(kind, root) };
|
|
47288
47328
|
}
|
|
47289
47329
|
function classifyInstallRoot(probe) {
|
|
47290
|
-
const piGitRoot =
|
|
47330
|
+
const piGitRoot = join43(probe.homeDir, ".pi", "agent", "git");
|
|
47291
47331
|
if (isUnder(probe.repoRoot, piGitRoot, probe.platform)) return report("pi-git", probe.repoRoot);
|
|
47292
|
-
const claudeHome = probe.env.CLAUDE_CONFIG_DIR?.trim() ||
|
|
47293
|
-
const pluginsRoot =
|
|
47332
|
+
const claudeHome = probe.env.CLAUDE_CONFIG_DIR?.trim() || join43(probe.homeDir, ".claude");
|
|
47333
|
+
const pluginsRoot = join43(claudeHome, "plugins");
|
|
47294
47334
|
if (isUnder(probe.moduleDir, pluginsRoot, probe.platform)) return report("claude-marketplace", probe.moduleDir);
|
|
47295
|
-
const hasGit = existsSync32(
|
|
47335
|
+
const hasGit = existsSync32(join43(probe.repoRoot, ".git"));
|
|
47296
47336
|
if (hasGit && packageIsKxm(probe.repoRoot)) return report("source", probe.repoRoot);
|
|
47297
47337
|
if (isNpmPackageLayout(probe.repoRoot, probe.platform) && packageIsKxm(probe.repoRoot) && !hasGit) {
|
|
47298
47338
|
return report("npm-package", probe.repoRoot);
|
|
@@ -47317,10 +47357,10 @@ init_bindings();
|
|
|
47317
47357
|
// plugins/kxm/src/kxm-update-config.ts
|
|
47318
47358
|
var import_yaml16 = __toESM(require_dist(), 1);
|
|
47319
47359
|
import { existsSync as existsSync33, readFileSync as readFileSync33 } from "node:fs";
|
|
47320
|
-
import { join as
|
|
47360
|
+
import { join as join44 } from "node:path";
|
|
47321
47361
|
init_bindings();
|
|
47322
47362
|
function loadKxmUpdateConfig(env = process.env) {
|
|
47323
|
-
const path4 =
|
|
47363
|
+
const path4 = join44(kxmUserStateRoot({ env }), "update.yaml");
|
|
47324
47364
|
if (!existsSync33(path4)) return { schema: KXM_UPDATE_SCHEMA, auto: false, source: "github" };
|
|
47325
47365
|
let parsed;
|
|
47326
47366
|
try {
|
|
@@ -47353,7 +47393,7 @@ function loadKxmUpdateConfig(env = process.env) {
|
|
|
47353
47393
|
init_protocol();
|
|
47354
47394
|
init_envelope();
|
|
47355
47395
|
import { existsSync as existsSync34, mkdirSync as mkdirSync27, readFileSync as readFileSync34, writeFileSync as writeFileSync24 } from "node:fs";
|
|
47356
|
-
import { join as
|
|
47396
|
+
import { join as join45 } from "node:path";
|
|
47357
47397
|
var SESSION_SCHEMA = "kxm.session.v1";
|
|
47358
47398
|
var SessionConfigError = class extends Error {
|
|
47359
47399
|
code = "session_config_invalid";
|
|
@@ -47363,12 +47403,12 @@ var SessionConfigError = class extends Error {
|
|
|
47363
47403
|
}
|
|
47364
47404
|
};
|
|
47365
47405
|
function workflowAssetDirs(assetsDir, workflowId) {
|
|
47366
|
-
const root =
|
|
47367
|
-
return [root,
|
|
47406
|
+
const root = join45(assetsDir, "workflows", workflowId);
|
|
47407
|
+
return [root, join45(root, "inputs"), join45(root, "outputs"), join45(root, "generated")];
|
|
47368
47408
|
}
|
|
47369
47409
|
function sessionAssetDirs(assetsDir, sessionId) {
|
|
47370
|
-
const root =
|
|
47371
|
-
return [root,
|
|
47410
|
+
const root = join45(assetsDir, "sessions", sessionId);
|
|
47411
|
+
return [root, join45(root, "inputs"), join45(root, "outputs")];
|
|
47372
47412
|
}
|
|
47373
47413
|
function rosterNames(configDir) {
|
|
47374
47414
|
return [...loadRosterMap(configDir).values()].map((row) => String(row.name));
|
|
@@ -47418,7 +47458,7 @@ function workerFromRosterRow(name, row, project) {
|
|
|
47418
47458
|
function loadRosterMap(configDir) {
|
|
47419
47459
|
const byName = /* @__PURE__ */ new Map();
|
|
47420
47460
|
for (const [file, key] of [["agents.json", "agents"], ["gates.json", "gates"]]) {
|
|
47421
|
-
const path4 =
|
|
47461
|
+
const path4 = join45(configDir, file);
|
|
47422
47462
|
for (const row of loadRoster(path4, key)) {
|
|
47423
47463
|
const name = String(row.name).trim();
|
|
47424
47464
|
const lowered = name.toLowerCase();
|
|
@@ -47460,7 +47500,7 @@ function loadRoster(path4, key) {
|
|
|
47460
47500
|
});
|
|
47461
47501
|
}
|
|
47462
47502
|
function createSession(input) {
|
|
47463
|
-
const assetDir = input.mode === "workflow" && input.workflowId ?
|
|
47503
|
+
const assetDir = input.mode === "workflow" && input.workflowId ? join45("assets", "workflows", input.workflowId) : join45("assets", "sessions", input.id);
|
|
47464
47504
|
return {
|
|
47465
47505
|
schema: SESSION_SCHEMA,
|
|
47466
47506
|
id: input.id,
|
|
@@ -47473,8 +47513,8 @@ function createSession(input) {
|
|
|
47473
47513
|
};
|
|
47474
47514
|
}
|
|
47475
47515
|
function writeSession(assetsDir, session, dryRun = false) {
|
|
47476
|
-
const dir =
|
|
47477
|
-
const path4 =
|
|
47516
|
+
const dir = join45(assetsDir, "sessions", session.id);
|
|
47517
|
+
const path4 = join45(dir, "session.json");
|
|
47478
47518
|
if (!dryRun) {
|
|
47479
47519
|
mkdirSync27(dir, { recursive: true });
|
|
47480
47520
|
writeFileSync24(path4, `${JSON.stringify(session, null, 2)}
|
|
@@ -47530,9 +47570,9 @@ function moduleInstallRoot() {
|
|
|
47530
47570
|
}
|
|
47531
47571
|
}
|
|
47532
47572
|
function warnIgnoredProjectUpdateYaml(runtime) {
|
|
47533
|
-
const projectFile =
|
|
47573
|
+
const projectFile = join46(runtime.dirs.workspace, "update.yaml");
|
|
47534
47574
|
if (!existsSync35(projectFile)) return;
|
|
47535
|
-
const userFile =
|
|
47575
|
+
const userFile = join46(kxmUserStateRoot({ env: runtime.env }), "update.yaml");
|
|
47536
47576
|
runtime.io.stderr(`kxm: ignoring .kxm/update.yaml in ${runtime.dirs.workdir}; update settings are read only from ${userFile}
|
|
47537
47577
|
`);
|
|
47538
47578
|
}
|
|
@@ -47580,7 +47620,7 @@ async function cmdDash(runtime, options = {}) {
|
|
|
47580
47620
|
return 2;
|
|
47581
47621
|
}
|
|
47582
47622
|
const screen = requested;
|
|
47583
|
-
const dataPath = resolve28(runtime.dirs.workdir, runtime.env.KXM_DATA_PATH?.trim() ||
|
|
47623
|
+
const dataPath = resolve28(runtime.dirs.workdir, runtime.env.KXM_DATA_PATH?.trim() || join46(runtime.dirs.state, "kxm.db"));
|
|
47584
47624
|
if (runtime.dryRun) {
|
|
47585
47625
|
print(runtime.io, runtime.json, {
|
|
47586
47626
|
ok: true,
|
|
@@ -47626,7 +47666,7 @@ async function cmdHub(runtime) {
|
|
|
47626
47666
|
config = loadKxmUpdateConfig(runtime.env);
|
|
47627
47667
|
} catch (error) {
|
|
47628
47668
|
if (error instanceof KxmUpdateConfigError) {
|
|
47629
|
-
const yamlPath =
|
|
47669
|
+
const yamlPath = join46(kxmUserStateRoot({ env: runtime.env }), "update.yaml");
|
|
47630
47670
|
runtime.io.stderr(`kxm: ${error.message}; update check skipped; fix or remove ${yamlPath}
|
|
47631
47671
|
`);
|
|
47632
47672
|
} else {
|
|
@@ -47828,7 +47868,7 @@ async function cmdStop(runtime, waitMsFlag) {
|
|
|
47828
47868
|
const orphans = [];
|
|
47829
47869
|
for (const file of pids) {
|
|
47830
47870
|
try {
|
|
47831
|
-
const record = JSON.parse(readFileSync35(
|
|
47871
|
+
const record = JSON.parse(readFileSync35(join46(runtime.dirs.state, file), "utf8"));
|
|
47832
47872
|
const expectedControl = file === "hub.pid" ? "hub.stop" : file.startsWith("worker-") ? `${file.slice(0, -4)}.stop` : void 0;
|
|
47833
47873
|
const expectedRole = file === "hub.pid" ? "hub" : file.startsWith("worker-") ? "worker" : void 0;
|
|
47834
47874
|
if (record.version !== 1 || !Number.isInteger(record.pid) || record.pid <= 0 || !record.startedAt || !expectedControl || record.controlFile !== expectedControl || record.role !== expectedRole) {
|
|
@@ -47848,7 +47888,7 @@ async function cmdStop(runtime, waitMsFlag) {
|
|
|
47848
47888
|
ignored.push(file);
|
|
47849
47889
|
continue;
|
|
47850
47890
|
}
|
|
47851
|
-
writeFileSync25(
|
|
47891
|
+
writeFileSync25(join46(runtime.dirs.state, record.controlFile), `${JSON.stringify({ startedAt: record.startedAt, ...record.generation ? { generation: record.generation } : {}, requestedAt: (/* @__PURE__ */ new Date()).toISOString() })}
|
|
47852
47892
|
`, { encoding: "utf8", mode: 384 });
|
|
47853
47893
|
requested.push(file);
|
|
47854
47894
|
records.set(file, { pid: record.pid, startedAt: record.startedAt, ...record.generation ? { generation: record.generation } : {} });
|
|
@@ -47866,7 +47906,7 @@ async function cmdStop(runtime, waitMsFlag) {
|
|
|
47866
47906
|
while (Date.now() <= deadline && stopped.size < requested.length) {
|
|
47867
47907
|
for (const [file, record] of records) {
|
|
47868
47908
|
try {
|
|
47869
|
-
const current = JSON.parse(readFileSync35(
|
|
47909
|
+
const current = JSON.parse(readFileSync35(join46(runtime.dirs.state, file), "utf8"));
|
|
47870
47910
|
if (current.pid !== record.pid || current.startedAt !== record.startedAt || current.generation !== record.generation || !processExists(record.pid)) stopped.add(file);
|
|
47871
47911
|
} catch {
|
|
47872
47912
|
stopped.add(file);
|
|
@@ -47879,7 +47919,7 @@ async function cmdStop(runtime, waitMsFlag) {
|
|
|
47879
47919
|
for (const file of orphans) {
|
|
47880
47920
|
while (Date.now() <= deadlineOrphans) {
|
|
47881
47921
|
try {
|
|
47882
|
-
const current = JSON.parse(readFileSync35(
|
|
47922
|
+
const current = JSON.parse(readFileSync35(join46(runtime.dirs.state, file), "utf8"));
|
|
47883
47923
|
if (!Number.isInteger(current.serverPid) || !processExists(current.serverPid)) break;
|
|
47884
47924
|
} catch {
|
|
47885
47925
|
break;
|
|
@@ -47887,14 +47927,14 @@ async function cmdStop(runtime, waitMsFlag) {
|
|
|
47887
47927
|
await (runtime.io.sleep ?? ((ms) => new Promise((resolveSleep) => setTimeout(resolveSleep, ms))))(100);
|
|
47888
47928
|
}
|
|
47889
47929
|
try {
|
|
47890
|
-
const current = JSON.parse(readFileSync35(
|
|
47930
|
+
const current = JSON.parse(readFileSync35(join46(runtime.dirs.state, file), "utf8"));
|
|
47891
47931
|
if (Number.isInteger(current.serverPid) && processExists(current.serverPid)) {
|
|
47892
47932
|
try {
|
|
47893
47933
|
process.kill(current.serverPid, "SIGKILL");
|
|
47894
47934
|
} catch {
|
|
47895
47935
|
}
|
|
47896
47936
|
}
|
|
47897
|
-
rmSync11(
|
|
47937
|
+
rmSync11(join46(runtime.dirs.state, file), { force: true });
|
|
47898
47938
|
} catch {
|
|
47899
47939
|
}
|
|
47900
47940
|
stopped.add(file);
|
|
@@ -47909,7 +47949,7 @@ async function cmdSessionStatus(runtime) {
|
|
|
47909
47949
|
const claims = [];
|
|
47910
47950
|
for (const file of names3.filter((name) => name.endsWith(".pid"))) {
|
|
47911
47951
|
try {
|
|
47912
|
-
const record = JSON.parse(readFileSync35(
|
|
47952
|
+
const record = JSON.parse(readFileSync35(join46(stateDir, file), "utf8"));
|
|
47913
47953
|
claims.push({
|
|
47914
47954
|
file,
|
|
47915
47955
|
role: record.role,
|
|
@@ -47924,7 +47964,7 @@ async function cmdSessionStatus(runtime) {
|
|
|
47924
47964
|
const recoveries = [];
|
|
47925
47965
|
for (const file of names3.filter((name) => name.startsWith("worker-recovery-") && name.endsWith(".json"))) {
|
|
47926
47966
|
try {
|
|
47927
|
-
const envelope = JSON.parse(readFileSync35(
|
|
47967
|
+
const envelope = JSON.parse(readFileSync35(join46(stateDir, file), "utf8"));
|
|
47928
47968
|
recoveries.push({
|
|
47929
47969
|
file,
|
|
47930
47970
|
reason: envelope.reason,
|
|
@@ -48039,7 +48079,7 @@ async function cmdSessionBrief(runtime, options = {}) {
|
|
|
48039
48079
|
print(runtime.io, runtime.json, { ok: true, command: "session brief", sessionToken }, sessionToken);
|
|
48040
48080
|
return 0;
|
|
48041
48081
|
}
|
|
48042
|
-
const dataPath = resolve28(runtime.dirs.workdir, runtime.env.KXM_DATA_PATH?.trim() ||
|
|
48082
|
+
const dataPath = resolve28(runtime.dirs.workdir, runtime.env.KXM_DATA_PATH?.trim() || join46(runtime.dirs.state, "kxm.db"));
|
|
48043
48083
|
const env = {
|
|
48044
48084
|
...runtime.env,
|
|
48045
48085
|
KXM_STATE_DIR: runtime.dirs.state,
|
|
@@ -48065,7 +48105,7 @@ async function cmdSessionBrief(runtime, options = {}) {
|
|
|
48065
48105
|
writeCache: !runtime.dryRun
|
|
48066
48106
|
});
|
|
48067
48107
|
if (runtime.dryRun) {
|
|
48068
|
-
if (!readCachedSessionBrief(runtime.dirs.state)) planned.push({ action: "write", target:
|
|
48108
|
+
if (!readCachedSessionBrief(runtime.dirs.state)) planned.push({ action: "write", target: join46(runtime.dirs.state, "session-brief.json") });
|
|
48069
48109
|
print(runtime.io, runtime.json, { ...brief, dryRun: true, planned }, [
|
|
48070
48110
|
options.status ? brief.statusLine : formatSessionBriefText(brief),
|
|
48071
48111
|
...planned.map((change) => `dry run: would ${change.action} ${change.target}`)
|
|
@@ -48151,7 +48191,7 @@ import { spawnSync as spawnSync10 } from "node:child_process";
|
|
|
48151
48191
|
import { createHash as createHash17 } from "node:crypto";
|
|
48152
48192
|
import { existsSync as existsSync42, mkdtempSync as mkdtempSync3, readFileSync as readFileSync40, rmSync as rmSync13 } from "node:fs";
|
|
48153
48193
|
import { tmpdir as tmpdir2 } from "node:os";
|
|
48154
|
-
import { basename as basename11, extname as extname3, join as
|
|
48194
|
+
import { basename as basename11, extname as extname3, join as join52, resolve as resolve33 } from "node:path";
|
|
48155
48195
|
import { createInterface as createInterface3 } from "node:readline";
|
|
48156
48196
|
|
|
48157
48197
|
// plugins/kxm/src/improve.ts
|
|
@@ -48160,7 +48200,7 @@ init_protocol();
|
|
|
48160
48200
|
init_relevance();
|
|
48161
48201
|
import { createHash as createHash16 } from "node:crypto";
|
|
48162
48202
|
import { existsSync as existsSync36, mkdirSync as mkdirSync29, writeFileSync as writeFileSync26 } from "node:fs";
|
|
48163
|
-
import { join as
|
|
48203
|
+
import { join as join47, relative as relative7, resolve as resolve29 } from "node:path";
|
|
48164
48204
|
var CANDIDATE_SCHEMA = "kxm.candidate.v1";
|
|
48165
48205
|
var IMPROVEMENT_REPORT_SCHEMA = "kxm.improvement-report.v2";
|
|
48166
48206
|
function classifyCandidateKind(stepId, agentRole) {
|
|
@@ -48416,7 +48456,7 @@ function groupRoutingRecords(records, options = {}) {
|
|
|
48416
48456
|
}
|
|
48417
48457
|
function buildImprovementReport(records, options = {}) {
|
|
48418
48458
|
const projectRoot = options.projectRoot ? resolve29(options.projectRoot) : process.cwd();
|
|
48419
|
-
const candidatesDir = options.candidatesDir ? resolve29(options.candidatesDir) :
|
|
48459
|
+
const candidatesDir = options.candidatesDir ? resolve29(options.candidatesDir) : join47(projectRoot, ".kxm", "candidates");
|
|
48420
48460
|
const promotionPolicy = options.promotionPolicy ?? "manual_pr";
|
|
48421
48461
|
const groups = groupRoutingRecords(records, options);
|
|
48422
48462
|
const candidates = [];
|
|
@@ -48430,7 +48470,7 @@ function buildImprovementReport(records, options = {}) {
|
|
|
48430
48470
|
group.workflowId
|
|
48431
48471
|
);
|
|
48432
48472
|
const diffFileName = `${group.candidateId}.diff`;
|
|
48433
|
-
const diffFilePath =
|
|
48473
|
+
const diffFilePath = join47(candidatesDir, diffFileName);
|
|
48434
48474
|
const relDiffPath = relative7(projectRoot, diffFilePath).replace(/\\/g, "/");
|
|
48435
48475
|
const candidate = {
|
|
48436
48476
|
schema: CANDIDATE_SCHEMA,
|
|
@@ -48456,7 +48496,7 @@ function buildImprovementReport(records, options = {}) {
|
|
|
48456
48496
|
mkdirSync29(candidatesDir, { recursive: true });
|
|
48457
48497
|
}
|
|
48458
48498
|
writeFileSync26(diffFilePath, diff, "utf8");
|
|
48459
|
-
const jsonFilePath =
|
|
48499
|
+
const jsonFilePath = join47(candidatesDir, `${group.candidateId}.json`);
|
|
48460
48500
|
writeFileSync26(jsonFilePath, JSON.stringify(candidate, null, 2) + "\n", "utf8");
|
|
48461
48501
|
}
|
|
48462
48502
|
candidates.push(candidate);
|
|
@@ -48485,7 +48525,7 @@ function buildImprovementReport(records, options = {}) {
|
|
|
48485
48525
|
}
|
|
48486
48526
|
function writeImprovementReport(improvementsDir, report2, dryRun = false) {
|
|
48487
48527
|
const stamp = report2.createdAt.replace(/[:.]/g, "-");
|
|
48488
|
-
const path4 =
|
|
48528
|
+
const path4 = join47(improvementsDir, `${stamp}.json`);
|
|
48489
48529
|
if (!dryRun) {
|
|
48490
48530
|
mkdirSync29(improvementsDir, { recursive: true });
|
|
48491
48531
|
writeFileSync26(path4, `${JSON.stringify(report2, null, 2)}
|
|
@@ -48714,7 +48754,7 @@ function loadRoutingSources(options) {
|
|
|
48714
48754
|
var import_yaml17 = __toESM(require_dist(), 1);
|
|
48715
48755
|
init_prices();
|
|
48716
48756
|
import { existsSync as existsSync38, readFileSync as readFileSync37 } from "node:fs";
|
|
48717
|
-
import { join as
|
|
48757
|
+
import { join as join48 } from "node:path";
|
|
48718
48758
|
var DEFAULT_MODES_CONFIG = Object.freeze({
|
|
48719
48759
|
schema: "kxm.modes.v1",
|
|
48720
48760
|
majorModes: {
|
|
@@ -48777,7 +48817,7 @@ function loadModesConfig(projectRoot) {
|
|
|
48777
48817
|
if (!projectRoot) {
|
|
48778
48818
|
return DEFAULT_MODES_CONFIG;
|
|
48779
48819
|
}
|
|
48780
|
-
const modesPath =
|
|
48820
|
+
const modesPath = join48(projectRoot, ".kxm", "modes.yaml");
|
|
48781
48821
|
if (!existsSync38(modesPath)) {
|
|
48782
48822
|
return DEFAULT_MODES_CONFIG;
|
|
48783
48823
|
}
|
|
@@ -48868,7 +48908,7 @@ function calculatePromptFootprint(resolved, projectRoot = process.cwd(), catalog
|
|
|
48868
48908
|
estimatedTokens: estimateTokens(baseSystemPromptChars)
|
|
48869
48909
|
});
|
|
48870
48910
|
for (const relPath of resolved.contextFiles) {
|
|
48871
|
-
const fullPath =
|
|
48911
|
+
const fullPath = join48(projectRoot, relPath);
|
|
48872
48912
|
let chars = 0;
|
|
48873
48913
|
if (existsSync38(fullPath)) {
|
|
48874
48914
|
try {
|
|
@@ -49007,7 +49047,7 @@ init_safety_integrity();
|
|
|
49007
49047
|
import { spawnSync as spawnSync9 } from "node:child_process";
|
|
49008
49048
|
import { existsSync as existsSync39, mkdirSync as mkdirSync30, readFileSync as readFileSync38, readdirSync as readdirSync13, rmSync as rmSync12, statSync as statSync5 } from "node:fs";
|
|
49009
49049
|
import { homedir as homedir8 } from "node:os";
|
|
49010
|
-
import { join as
|
|
49050
|
+
import { join as join49, resolve as resolve31 } from "node:path";
|
|
49011
49051
|
var MAX_SSH_OUTPUT_BYTES = 50 * 1024;
|
|
49012
49052
|
var MAX_SSH_OUTPUT_LINES = 2e3;
|
|
49013
49053
|
var DEFAULT_SOCKET_DIR = ".kxm/run/ssh-sockets";
|
|
@@ -49033,7 +49073,7 @@ function truncateSshOutput(raw) {
|
|
|
49033
49073
|
return { text, truncated };
|
|
49034
49074
|
}
|
|
49035
49075
|
function parseSshConfig(configPath) {
|
|
49036
|
-
const targetPath = configPath ??
|
|
49076
|
+
const targetPath = configPath ?? join49(homedir8(), ".ssh", "config");
|
|
49037
49077
|
if (!existsSync39(targetPath)) {
|
|
49038
49078
|
return [];
|
|
49039
49079
|
}
|
|
@@ -49123,7 +49163,7 @@ function ensureSocketDir(socketDir = DEFAULT_SOCKET_DIR) {
|
|
|
49123
49163
|
}
|
|
49124
49164
|
function buildSshArgs(options) {
|
|
49125
49165
|
const socketDir = ensureSocketDir(options.socketDir ?? DEFAULT_SOCKET_DIR);
|
|
49126
|
-
const controlPath =
|
|
49166
|
+
const controlPath = join49(socketDir, "%C");
|
|
49127
49167
|
const persist = options.controlPersist ?? DEFAULT_CONTROL_PERSIST;
|
|
49128
49168
|
const args = [
|
|
49129
49169
|
"-o",
|
|
@@ -49148,7 +49188,7 @@ function buildSshArgs(options) {
|
|
|
49148
49188
|
}
|
|
49149
49189
|
function checkControlSocket(host, socketDir = DEFAULT_SOCKET_DIR, execFn = spawnSync9) {
|
|
49150
49190
|
const resolvedDir = ensureSocketDir(socketDir);
|
|
49151
|
-
const controlPath =
|
|
49191
|
+
const controlPath = join49(resolvedDir, "%C");
|
|
49152
49192
|
try {
|
|
49153
49193
|
const result = execFn("ssh", ["-O", "check", "-o", `ControlPath=${controlPath}`, host], {
|
|
49154
49194
|
encoding: "utf-8"
|
|
@@ -49160,7 +49200,7 @@ function checkControlSocket(host, socketDir = DEFAULT_SOCKET_DIR, execFn = spawn
|
|
|
49160
49200
|
}
|
|
49161
49201
|
function closeControlSocket(host, socketDir = DEFAULT_SOCKET_DIR, execFn = spawnSync9) {
|
|
49162
49202
|
const resolvedDir = ensureSocketDir(socketDir);
|
|
49163
|
-
const controlPath =
|
|
49203
|
+
const controlPath = join49(resolvedDir, "%C");
|
|
49164
49204
|
try {
|
|
49165
49205
|
const result = execFn("ssh", ["-O", "stop", "-o", `ControlPath=${controlPath}`, host], {
|
|
49166
49206
|
encoding: "utf-8"
|
|
@@ -49610,7 +49650,7 @@ complete -c kxm -n "__fish_seen_subcommand_from goal" -a "create list get"
|
|
|
49610
49650
|
// plugins/kxm/src/completion-install.ts
|
|
49611
49651
|
import { existsSync as existsSync40, mkdirSync as mkdirSync31, readFileSync as readFileSync39, writeFileSync as writeFileSync27 } from "node:fs";
|
|
49612
49652
|
import { homedir as homedir9 } from "node:os";
|
|
49613
|
-
import { basename as basename10, delimiter, dirname as dirname24, isAbsolute as isAbsolute10, join as
|
|
49653
|
+
import { basename as basename10, delimiter, dirname as dirname24, isAbsolute as isAbsolute10, join as join50, resolve as resolve32 } from "node:path";
|
|
49614
49654
|
var COMPLETION_MARKER = "# kxm completion";
|
|
49615
49655
|
var PATH_MARKER = "# kxm path";
|
|
49616
49656
|
function detectShell(env = process.env, platform = process.platform) {
|
|
@@ -49632,25 +49672,25 @@ function completionScriptPath(shell, options = {}) {
|
|
|
49632
49672
|
const env = options.env ?? process.env;
|
|
49633
49673
|
const explicit = options.configDir ?? env.KXM_USER_CONFIG_DIR?.trim();
|
|
49634
49674
|
const base = explicit && explicit.length > 0 ? resolve32(explicit) : resolve32(effectiveHome(options), ".config", "kxm");
|
|
49635
|
-
return
|
|
49675
|
+
return join50(base, "completions", `kxm.${shell}`);
|
|
49636
49676
|
}
|
|
49637
49677
|
function bashRcCandidate(options) {
|
|
49638
49678
|
const home = effectiveHome(options);
|
|
49639
|
-
const candidates = [
|
|
49679
|
+
const candidates = [join50(home, ".bashrc"), join50(home, ".bash_profile")];
|
|
49640
49680
|
const existing = candidates.find((candidate) => existsSync40(candidate));
|
|
49641
49681
|
return existing ?? candidates[0];
|
|
49642
49682
|
}
|
|
49643
49683
|
function zshRcCandidate(options) {
|
|
49644
49684
|
const env = options.env ?? process.env;
|
|
49645
49685
|
const home = effectiveHome(options);
|
|
49646
|
-
if (env.ZDOTDIR?.trim()) return
|
|
49647
|
-
return
|
|
49686
|
+
if (env.ZDOTDIR?.trim()) return join50(resolve32(env.ZDOTDIR.trim()), ".zshrc");
|
|
49687
|
+
return join50(home, ".zshrc");
|
|
49648
49688
|
}
|
|
49649
49689
|
function fishCompletionTarget(shell, options) {
|
|
49650
49690
|
const env = options.env ?? process.env;
|
|
49651
49691
|
const home = effectiveHome(options);
|
|
49652
|
-
if (env.XDG_CONFIG_HOME?.trim()) return
|
|
49653
|
-
return
|
|
49692
|
+
if (env.XDG_CONFIG_HOME?.trim()) return join50(resolve32(env.XDG_CONFIG_HOME.trim()), "fish", "completions", "kxm.fish");
|
|
49693
|
+
return join50(home, ".config", "fish", "completions", "kxm.fish");
|
|
49654
49694
|
}
|
|
49655
49695
|
function completionRcTarget(shell, options = {}) {
|
|
49656
49696
|
if (shell === "fish") {
|
|
@@ -49738,7 +49778,7 @@ function kxmBinDir(env = process.env) {
|
|
|
49738
49778
|
const argv1 = env.KXM_ENTRY ?? process.argv[1];
|
|
49739
49779
|
if (argv1 && isAbsolute10(argv1)) {
|
|
49740
49780
|
const dir = dirname24(argv1);
|
|
49741
|
-
if (existsSync40(
|
|
49781
|
+
if (existsSync40(join50(dir, process.platform === "win32" ? "kxm.cmd" : "kxm"))) return dir;
|
|
49742
49782
|
}
|
|
49743
49783
|
const pathEnv = env.PATH ?? "";
|
|
49744
49784
|
for (const part of pathEnv.split(delimiter)) {
|
|
@@ -49778,7 +49818,7 @@ ${line}
|
|
|
49778
49818
|
var import_yaml18 = __toESM(require_dist(), 1);
|
|
49779
49819
|
init_routes();
|
|
49780
49820
|
import { existsSync as existsSync41, mkdirSync as mkdirSync32, writeFileSync as writeFileSync28 } from "node:fs";
|
|
49781
|
-
import { dirname as dirname25, join as
|
|
49821
|
+
import { dirname as dirname25, join as join51 } from "node:path";
|
|
49782
49822
|
var ADMITTED_GUIDE_BINDINGS = Object.freeze({
|
|
49783
49823
|
"anthropic/claude-fable-5.1": { harness: "claude", provider: "anthropic", model: "fable" },
|
|
49784
49824
|
"anthropic/fable": { harness: "claude", provider: "anthropic", model: "fable" },
|
|
@@ -50169,13 +50209,13 @@ function renderGuideSetupFiles(projectRoot, plan) {
|
|
|
50169
50209
|
const stage = roleStages.get(role);
|
|
50170
50210
|
if (!stage) continue;
|
|
50171
50211
|
files.push({
|
|
50172
|
-
path:
|
|
50212
|
+
path: join51(projectRoot, ".kxm", "agents", `${role}.yaml`),
|
|
50173
50213
|
content: (0, import_yaml18.stringify)(agentDocument(role, stage, binding))
|
|
50174
50214
|
});
|
|
50175
50215
|
}
|
|
50176
50216
|
for (const workflow of plan.workflows) {
|
|
50177
50217
|
files.push({
|
|
50178
|
-
path:
|
|
50218
|
+
path: join51(projectRoot, ".kxm", "workflows", `${workflow.slug}.yaml`),
|
|
50179
50219
|
content: (0, import_yaml18.stringify)(workflowDocument(workflow))
|
|
50180
50220
|
});
|
|
50181
50221
|
}
|
|
@@ -50192,7 +50232,7 @@ function mergeGuideRouteAdmission(projectRoot, plan) {
|
|
|
50192
50232
|
}
|
|
50193
50233
|
if (added.length === 0) return added;
|
|
50194
50234
|
policy.updatedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
50195
|
-
const path4 =
|
|
50235
|
+
const path4 = join51(projectRoot, ".kxm", "routes.yaml");
|
|
50196
50236
|
mkdirSync32(dirname25(path4), { recursive: true });
|
|
50197
50237
|
writeFileSync28(path4, (0, import_yaml18.stringify)(policy), "utf8");
|
|
50198
50238
|
return added;
|
|
@@ -50272,7 +50312,7 @@ function applyKxmPackageUpdate(runtime, notice) {
|
|
|
50272
50312
|
detail: `release v${notice.latest} has no sha256 digest for ${name}; refusing to install`
|
|
50273
50313
|
};
|
|
50274
50314
|
}
|
|
50275
|
-
const releaseDir = mkdtempSync3(
|
|
50315
|
+
const releaseDir = mkdtempSync3(join52(tmpdir2(), "kxm-pkg-update-"));
|
|
50276
50316
|
try {
|
|
50277
50317
|
const planned = planKxmPackageUpdate(notice.source, notice.latest, releaseDir, notice.asset);
|
|
50278
50318
|
if (runtime.dryRun) {
|
|
@@ -50659,7 +50699,7 @@ async function cmdImprove(runtime, options = {}) {
|
|
|
50659
50699
|
print(runtime.io, runtime.json, { ok: false, command: "improve", error: "config_invalid", detail: message }, `config_invalid: ${message}`);
|
|
50660
50700
|
return 1;
|
|
50661
50701
|
}
|
|
50662
|
-
const candidatesDir = options.outDir ? resolve33(runtime.cwd, options.outDir) :
|
|
50702
|
+
const candidatesDir = options.outDir ? resolve33(runtime.cwd, options.outDir) : join52(root, ".kxm", "candidates");
|
|
50663
50703
|
const report2 = buildImprovementReport(loaded.records, {
|
|
50664
50704
|
candidatesDir,
|
|
50665
50705
|
projectRoot: root,
|
|
@@ -50668,7 +50708,7 @@ async function cmdImprove(runtime, options = {}) {
|
|
|
50668
50708
|
autoThreshold: config.improvement.autoThreshold,
|
|
50669
50709
|
halfLifeDays: config.improvement.telemetryHalfLifeDays
|
|
50670
50710
|
});
|
|
50671
|
-
const reportDir =
|
|
50711
|
+
const reportDir = join52(runtime.dirs.assets, "improvements");
|
|
50672
50712
|
const reportPath = writeImprovementReport(reportDir, report2, runtime.dryRun);
|
|
50673
50713
|
const text = [
|
|
50674
50714
|
"Sources:",
|
|
@@ -50977,7 +51017,7 @@ async function cmdRoutingReport(runtime, options) {
|
|
|
50977
51017
|
let catalog;
|
|
50978
51018
|
if (includeEquivalentListCost) {
|
|
50979
51019
|
try {
|
|
50980
|
-
const pricesPath = options.prices ? resolve33(runtime.cwd, options.prices) :
|
|
51020
|
+
const pricesPath = options.prices ? resolve33(runtime.cwd, options.prices) : join52(runtime.dirs.workspace, "prices.yaml");
|
|
50981
51021
|
catalog = loadPriceCatalog(pricesPath);
|
|
50982
51022
|
} catch {
|
|
50983
51023
|
}
|
|
@@ -51090,6 +51130,7 @@ var DRY_RUN_COMMANDS = /* @__PURE__ */ new Set([
|
|
|
51090
51130
|
"lane status",
|
|
51091
51131
|
"lane drop",
|
|
51092
51132
|
"lane run",
|
|
51133
|
+
"land",
|
|
51093
51134
|
"plugin install",
|
|
51094
51135
|
"plugin",
|
|
51095
51136
|
"runs status",
|
|
@@ -51391,6 +51432,13 @@ function createProgram(ctx, result) {
|
|
|
51391
51432
|
...options.timeoutMs !== void 0 ? { timeoutMs: options.timeoutMs } : {}
|
|
51392
51433
|
});
|
|
51393
51434
|
});
|
|
51435
|
+
addGlobalOptions(program2.command("land").description("Land the current branch: verify, regenerate docs, push, pull request, rebase, unblock, squash-merge, release, and milestone")).option("--pr <n>", "Existing pull request number").option("--stage <name>", "Run one stage: verify, docs, push, pr, rebase, unblock, merge, release, or milestone").option("--body-file <path>", "Pull request body file used when creating a pull request").action(async function landAction(options) {
|
|
51436
|
+
result.code = await cmdLand(runtimeFrom(ctx, this), {
|
|
51437
|
+
...options.pr !== void 0 ? { pr: options.pr } : {},
|
|
51438
|
+
...options.stage !== void 0 ? { stage: options.stage } : {},
|
|
51439
|
+
...options.bodyFile !== void 0 ? { bodyFile: options.bodyFile } : {}
|
|
51440
|
+
});
|
|
51441
|
+
});
|
|
51394
51442
|
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) {
|
|
51395
51443
|
result.code = await cmdKxmRunCli(runtimeFrom(ctx, this), workflow2, promptParts, options);
|
|
51396
51444
|
}));
|