@kontextmind/kxm 0.7.122 → 0.7.124

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.
Files changed (48) hide show
  1. package/.claude-plugin/marketplace.json +1 -1
  2. package/.kxm/workflows/implement-only.yaml +20 -0
  3. package/.kxm/workflows/review-arch-only.yaml +20 -0
  4. package/.kxm/workflows/review-cli-only.yaml +20 -0
  5. package/CHANGELOG.md +31 -3
  6. package/docs/architecture/access-schema.yaml +60 -0
  7. package/docs/architecture/access.md +33 -0
  8. package/docs/architecture/agent-path.md +36 -0
  9. package/docs/architecture/authentication.md +29 -0
  10. package/docs/architecture/hosted-direction.md +59 -0
  11. package/docs/architecture/index.md +19 -0
  12. package/docs/architecture/inventory.md +38 -0
  13. package/docs/architecture/platform.md +48 -0
  14. package/docs/assets/logo.png +0 -0
  15. package/docs/contributing/assignment-runner.md +15 -4
  16. package/docs/index.md +56 -0
  17. package/docs/javascripts/mermaid-init.js +83 -0
  18. package/docs/javascripts/mermaid.min.js +4376 -0
  19. package/docs/reference/cli-reference.md +57 -4
  20. package/docs/reference/config-reference.md +2 -1
  21. package/docs/reference/workflow-catalog.md +10 -0
  22. package/docs/reference/workflow-definitions.md +1 -1
  23. package/docs/robots.txt +44 -0
  24. package/docs/stylesheets/extra.css +100 -0
  25. package/package.json +1 -1
  26. package/plugins/kxm/.claude-plugin/plugin.json +1 -1
  27. package/plugins/kxm/dist/cli.js +265 -165
  28. package/plugins/kxm/dist/mcp-server.js +1 -1
  29. package/plugins/kxm/dist/runtime-supervisor.js +209 -72
  30. package/plugins/kxm/dist/runtime.js +233 -94
  31. package/plugins/kxm/package.json +1 -1
  32. package/plugins/kxm/skills/kxm/SKILL.md +1 -2
  33. package/plugins/kxm/skills/kxm-runs/SKILL.md +7 -0
  34. package/plugins/kxm/src/cli/docs.ts +78 -0
  35. package/plugins/kxm/src/cli/project.ts +14 -2
  36. package/plugins/kxm/src/cli.ts +14 -0
  37. package/plugins/kxm/src/engine-fold.ts +15 -7
  38. package/plugins/kxm/src/engine-plan.ts +10 -1
  39. package/plugins/kxm/src/engine.ts +105 -2
  40. package/plugins/kxm/src/mcp-server.ts +1 -1
  41. package/plugins/kxm/src/oneshot-evidence.ts +44 -0
  42. package/plugins/kxm/src/oneshot-producer.ts +5 -5
  43. package/plugins/kxm/src/runtime-service.ts +10 -0
  44. package/plugins/kxm/src/runtime-store.ts +1 -0
  45. package/plugins/kxm/src/runtime-supervisor.ts +2 -0
  46. package/schemas/drive-receipt.schema.json +1 -0
  47. package/schemas/project.schema.json +2 -1
  48. package/schemas/roadmap-state.schema.json +147 -0
@@ -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 join55 = objectValue(step.join);
18564
- const minimumPassed = join55 && typeof join55.minimumPassed === "number" ? join55.minimumPassed : void 0;
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 join55 = compileJoin(step, id, sink);
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: join55
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 join55 = objectValue2(step.join);
20945
- if (!join55) return { strategy: "all" };
20946
- const declared = stringValue2(join55.strategy);
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(join55.minimumPassed, `${stepId}.join.minimumPassed`, stepId, sink);
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 join55.cancelRemaining === "boolean" ? { cancelRemaining: join55.cancelRemaining } : {}
20952
+ ...typeof join56.cancelRemaining === "boolean" ? { cancelRemaining: join56.cancelRemaining } : {}
20953
20953
  };
20954
20954
  return compiled;
20955
20955
  }
@@ -21375,13 +21375,16 @@ function objectValue3(value) {
21375
21375
  function kxmProjectAdmissionLimits(bundle) {
21376
21376
  const limits = objectValue3(bundle.project.value.limits);
21377
21377
  const maxConcurrentRuns = typeof limits?.maxConcurrentRuns === "number" && Number.isInteger(limits.maxConcurrentRuns) && limits.maxConcurrentRuns >= 1 ? limits.maxConcurrentRuns : 1;
21378
+ const declared = limits?.agentStepTimeoutMs;
21379
+ const agentStepTimeoutMs = typeof declared === "number" && Number.isInteger(declared) && declared >= KXM_MIN_AGENT_STEP_TIMEOUT_MS ? declared : KXM_DEFAULT_AGENT_STEP_TIMEOUT_MS;
21378
21380
  return {
21379
21381
  maxConcurrentRuns,
21380
21382
  ...typeof limits?.maxRunDurationMs === "number" ? { maxRunDurationMs: limits.maxRunDurationMs } : {},
21381
- ...typeof limits?.maxAgentTimeMs === "number" ? { maxAgentTimeMs: limits.maxAgentTimeMs } : {}
21383
+ ...typeof limits?.maxAgentTimeMs === "number" ? { maxAgentTimeMs: limits.maxAgentTimeMs } : {},
21384
+ agentStepTimeoutMs
21382
21385
  };
21383
21386
  }
21384
- var RUNTIME_EPOCH_NS;
21387
+ var KXM_DEFAULT_AGENT_STEP_TIMEOUT_MS, KXM_MIN_AGENT_STEP_TIMEOUT_MS, RUNTIME_EPOCH_NS;
21385
21388
  var init_runtime_service = __esm({
21386
21389
  "plugins/kxm/src/runtime-service.ts"() {
21387
21390
  "use strict";
@@ -21391,6 +21394,8 @@ var init_runtime_service = __esm({
21391
21394
  init_engine_plan();
21392
21395
  init_runtime_owner();
21393
21396
  init_runtime_store();
21397
+ KXM_DEFAULT_AGENT_STEP_TIMEOUT_MS = 36e5;
21398
+ KXM_MIN_AGENT_STEP_TIMEOUT_MS = 6e4;
21394
21399
  RUNTIME_EPOCH_NS = process.hrtime.bigint();
21395
21400
  }
21396
21401
  });
@@ -21400,6 +21405,7 @@ var TEXT_LIMIT, ARGV_LIMIT, RECORD_LIMIT;
21400
21405
  var init_oneshot_evidence = __esm({
21401
21406
  "plugins/kxm/src/oneshot-evidence.ts"() {
21402
21407
  "use strict";
21408
+ init_bindings();
21403
21409
  TEXT_LIMIT = 4 * 1024 * 1024;
21404
21410
  ARGV_LIMIT = 64 * 1024;
21405
21411
  RECORD_LIMIT = 16 * 1024 * 1024;
@@ -23195,6 +23201,15 @@ function resolveProducerRoute(projectRoot, step, agentId) {
23195
23201
  const model = selector.slice(slash + 1);
23196
23202
  return { provider, model, selector };
23197
23203
  }
23204
+ function unsupportedAgentStepTimeout(step, limitMs) {
23205
+ if (step.kind !== "agent" && step.kind !== "moa") return void 0;
23206
+ if (step.timeoutMs === void 0 || step.timeoutMs <= limitMs) return void 0;
23207
+ return {
23208
+ reason: "step_unsupported",
23209
+ field: "timeoutMs",
23210
+ detail: "step timeoutMs is wider than project limits.agentStepTimeoutMs"
23211
+ };
23212
+ }
23198
23213
  function kxmLiveRunPrerequisites(bundle, workflowId, projectRoot) {
23199
23214
  const workflow = bundle.workflows.get(workflowId);
23200
23215
  if (!workflow) throw runtimeError("run_workflow_unknown", workflowId, `workflow ${workflowId} does not exist in this project`);
@@ -23213,7 +23228,8 @@ function kxmLiveRunPrerequisites(bundle, workflowId, projectRoot) {
23213
23228
  for (const transition2 of Object.values(step.transitions)) {
23214
23229
  if (transition2.to === "step") pending.push(transition2.target);
23215
23230
  }
23216
- const unsupported = step.kind === "gate" ? unsupportedGateStep(plan, step, envelope, { projectRoot }) ?? starterGatePrerequisite(step, envelope.gates, projectRoot) : unsupportedStep(plan, step, "oneshot");
23231
+ const limitMs = envelope.projectLimits.agentStepTimeoutMs ?? KXM_DEFAULT_AGENT_STEP_TIMEOUT_MS;
23232
+ const unsupported = step.kind === "gate" ? unsupportedGateStep(plan, step, envelope, { projectRoot }) ?? starterGatePrerequisite(step, envelope.gates, projectRoot) : unsupportedAgentStepTimeout(step, limitMs) ?? unsupportedStep(plan, step, "oneshot");
23217
23233
  if (unsupported) {
23218
23234
  prerequisites.push({ ...unsupported, stepId });
23219
23235
  continue;
@@ -23533,6 +23549,7 @@ var init_engine = __esm({
23533
23549
  init_context_packet();
23534
23550
  init_engine_compile();
23535
23551
  init_harness();
23552
+ init_oneshot_evidence();
23536
23553
  init_engine_fold();
23537
23554
  init_engine_plan();
23538
23555
  init_dispatch_context();
@@ -23556,7 +23573,6 @@ var init_oneshot_producer = __esm({
23556
23573
  "plugins/kxm/src/oneshot-producer.ts"() {
23557
23574
  "use strict";
23558
23575
  init_oneshot_evidence();
23559
- init_bindings();
23560
23576
  init_oneshot_process();
23561
23577
  init_oneshot_process();
23562
23578
  init_harness();
@@ -26990,7 +27006,10 @@ function formatDriveStatusLine(runStatus, drive) {
26990
27006
  }
26991
27007
  function formatRunStatusLine(run, drive) {
26992
27008
  const reason = typeof drive?.receipt?.settlement?.reason === "string" ? drive.receipt.settlement.reason : "";
26993
- const statusLabel = run.status === "cancelled" ? formatCancelledStatus(reason) : run.status;
27009
+ const handoff = drive?.receipt?.settlement?.handoff;
27010
+ const attemptId = typeof handoff?.attemptId === "string" ? handoff.attemptId : "";
27011
+ const handoffReason = typeof handoff?.reason === "string" ? handoff.reason : "";
27012
+ const statusLabel = run.status === "cancelled" ? formatCancelledStatus(reason) : run.status === "cancelling" && attemptId.length > 0 && handoffReason.length > 0 ? `cancelling (attempt ${attemptId}, ${handoffReason})` : run.status;
26994
27013
  return `run ${run.runId}: ${statusLabel} (workflow ${run.workflowId}, updated ${run.updatedAt})`;
26995
27014
  }
26996
27015
  async function cmdKxmRunStatus(runtime, runId) {
@@ -36612,19 +36631,90 @@ async function cmdPluginInstall(runtime, options) {
36612
36631
  return ok ? 0 : 1;
36613
36632
  }
36614
36633
 
36634
+ // plugins/kxm/src/cli/docs.ts
36635
+ init_project_config();
36636
+ init_types();
36637
+ import { spawn as spawn4 } from "node:child_process";
36638
+ import { existsSync as existsSync29 } from "node:fs";
36639
+ import { join as join35 } from "node:path";
36640
+ var GENERATOR = "plans/kxm-roadmap/update-dashboard.mjs";
36641
+ var SERVER = "ops/docs-site/serve.py";
36642
+ function requireProject(runtime, command) {
36643
+ const root = discoverKxmProjectRoot(runtime.cwd);
36644
+ if (!root) {
36645
+ print(
36646
+ runtime.io,
36647
+ runtime.json,
36648
+ { ok: false, command, error: "project_required" },
36649
+ `kxm ${command} requires a KXM project (run kxm init first)`
36650
+ );
36651
+ return 1;
36652
+ }
36653
+ return root;
36654
+ }
36655
+ function requireFile(runtime, command, root, relative8, error) {
36656
+ const file = join35(root, relative8);
36657
+ if (existsSync29(file)) return file;
36658
+ print(
36659
+ runtime.io,
36660
+ runtime.json,
36661
+ { ok: false, command, error, path: relative8 },
36662
+ `kxm ${command} requires ${relative8}`
36663
+ );
36664
+ return 1;
36665
+ }
36666
+ function printCommand(runtime, command, line) {
36667
+ print(
36668
+ runtime.io,
36669
+ runtime.json,
36670
+ { ok: true, command, dryRun: true, detail: line },
36671
+ line
36672
+ );
36673
+ return 0;
36674
+ }
36675
+ function runInherited(command, args, cwd) {
36676
+ return new Promise((resolveExit) => {
36677
+ const child = spawn4(command, [...args], { cwd, stdio: "inherit" });
36678
+ child.once("error", () => resolveExit(1));
36679
+ child.once("exit", (code) => resolveExit(code ?? 1));
36680
+ });
36681
+ }
36682
+ async function cmdDocsBuild(runtime) {
36683
+ const command = "docs build";
36684
+ const root = requireProject(runtime, command);
36685
+ if (typeof root === "number") return root;
36686
+ const file = requireFile(runtime, command, root, GENERATOR, "docs_generator_missing");
36687
+ if (typeof file === "number") return file;
36688
+ const line = `node ${GENERATOR}`;
36689
+ if (runtime.dryRun) return printCommand(runtime, command, line);
36690
+ return runInherited(process.execPath, [file], root);
36691
+ }
36692
+ async function cmdDocsServe(runtime, options = {}) {
36693
+ const command = "docs serve";
36694
+ const root = requireProject(runtime, command);
36695
+ if (typeof root === "number") return root;
36696
+ const file = requireFile(runtime, command, root, SERVER, "docs_server_missing");
36697
+ if (typeof file === "number") return file;
36698
+ const args = [file];
36699
+ if (options.port !== void 0 && options.port !== "") args.push("--port", options.port);
36700
+ const line = ["python3", SERVER, ...args.slice(1)].join(" ");
36701
+ if (runtime.dryRun) return printCommand(runtime, command, line);
36702
+ return runInherited("python3", args, root);
36703
+ }
36704
+
36615
36705
  // plugins/kxm/src/cli/lanes.ts
36616
36706
  init_project_config();
36617
36707
  init_runtime_supervisor();
36618
36708
  init_types();
36619
36709
  import { spawnSync as spawnSync6 } from "node:child_process";
36620
- import { chmodSync as chmodSync6, existsSync as existsSync29, mkdirSync as mkdirSync24, readFileSync as readFileSync29, writeFileSync as writeFileSync22 } from "node:fs";
36621
- import { basename as basename8, dirname as dirname18, join as join35, resolve as resolve25 } from "node:path";
36710
+ import { chmodSync as chmodSync6, existsSync as existsSync30, mkdirSync as mkdirSync24, readFileSync as readFileSync29, writeFileSync as writeFileSync22 } from "node:fs";
36711
+ import { basename as basename8, dirname as dirname18, join as join36, resolve as resolve25 } from "node:path";
36622
36712
  var LANE_SCHEMA = "kxm.lanes.v1";
36623
36713
  var SHA_RE = /^[a-f0-9]{40,64}$/;
36624
36714
  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
36715
  var SETTLED_RUN = /* @__PURE__ */ new Set(["completed", "failed", "cancelled"]);
36626
36716
  function lanesFile(runtime) {
36627
- return join35(runtime.dirs.state, "lanes.json");
36717
+ return join36(runtime.dirs.state, "lanes.json");
36628
36718
  }
36629
36719
  function gitEnv() {
36630
36720
  return Object.fromEntries(Object.entries(process.env).filter(([name]) => !name.toUpperCase().startsWith("GIT_")));
@@ -36672,7 +36762,7 @@ function isLaneFile(value) {
36672
36762
  }
36673
36763
  function loadLanes(runtime, command) {
36674
36764
  const file = lanesFile(runtime);
36675
- if (!existsSync29(file)) return { schema: LANE_SCHEMA, lanes: {} };
36765
+ if (!existsSync30(file)) return { schema: LANE_SCHEMA, lanes: {} };
36676
36766
  try {
36677
36767
  const parsed = JSON.parse(readFileSync29(file, "utf8"));
36678
36768
  if (!isLaneFile(parsed)) return refuse(runtime, command, "lanes_unreadable", `lane record ${file} is malformed`);
@@ -36731,7 +36821,7 @@ function withLaneCwd(runtime, unit, command = "lane") {
36731
36821
  const loaded = loadLanes(runtime, command);
36732
36822
  if (typeof loaded === "number") return loaded;
36733
36823
  const lane = loaded.lanes[unit];
36734
- if (!lane || !existsSync29(lane.path)) {
36824
+ if (!lane || !existsSync30(lane.path)) {
36735
36825
  return refuse(runtime, command, "lane_missing", `lane ${unit} is not recorded or its worktree is absent`, { unit });
36736
36826
  }
36737
36827
  return {
@@ -36802,7 +36892,7 @@ function aheadBehind(path4, baseSha) {
36802
36892
  return { behind: Number(match[1]), ahead: Number(match[2]) };
36803
36893
  }
36804
36894
  function laneView(unit, record) {
36805
- const exists = existsSync29(record.path);
36895
+ const exists = existsSync30(record.path);
36806
36896
  const counts = exists ? aheadBehind(record.path, record.baseSha) : { ahead: null, behind: null };
36807
36897
  return {
36808
36898
  unit,
@@ -36893,7 +36983,7 @@ async function cmdLaneCreate(runtime, unit, options = {}) {
36893
36983
  const loaded = loadLanes(runtime, command);
36894
36984
  if (typeof loaded === "number") return loaded;
36895
36985
  const path4 = laneWorktreePath(root, unit);
36896
- if (loaded.lanes[unit] || existsSync29(path4) || branchExists(root, unit)) {
36986
+ if (loaded.lanes[unit] || existsSync30(path4) || branchExists(root, unit)) {
36897
36987
  return refuse(runtime, command, "lane_exists", `lane ${unit} already exists`, { unit });
36898
36988
  }
36899
36989
  const baseSha = resolveBase(root, base);
@@ -36918,7 +37008,7 @@ async function cmdLaneCreate(runtime, unit, options = {}) {
36918
37008
  return refuse(runtime, command, "lane_git_failed", `git worktree add failed: ${added.stderr.trim().slice(0, 300)}`, { unit });
36919
37009
  }
36920
37010
  const recordedPath = discoverKxmProjectRoot(path4) ?? path4;
36921
- if (!existsSync29(join35(recordedPath, ".kxm", "project.yaml"))) {
37011
+ if (!existsSync30(join36(recordedPath, ".kxm", "project.yaml"))) {
36922
37012
  git2(root, ["worktree", "remove", "--force", path4]);
36923
37013
  return refuse(runtime, command, "lane_not_project", `lane ${recordedPath} has no .kxm/project.yaml; the worktree was removed`, { unit, path: recordedPath });
36924
37014
  }
@@ -36982,7 +37072,7 @@ async function cmdLaneDrop(runtime, unit, options = {}) {
36982
37072
  if (!record) return refuse(runtime, command, "lane_missing", `lane ${unit} is not recorded`, { unit });
36983
37073
  const force = options.force === true;
36984
37074
  if (!force) {
36985
- if (existsSync29(record.path)) {
37075
+ if (existsSync30(record.path)) {
36986
37076
  const dirty = porcelainCount(record.path);
36987
37077
  if (dirty === null) {
36988
37078
  return refuse(runtime, command, "lane_git_failed", `lane ${unit} worktree status could not be read`, { unit });
@@ -37001,7 +37091,7 @@ async function cmdLaneDrop(runtime, unit, options = {}) {
37001
37091
  ], `drop lane ${unit}; branch ${record.branch} is not deleted`);
37002
37092
  return 0;
37003
37093
  }
37004
- if (existsSync29(record.path)) {
37094
+ if (existsSync30(record.path)) {
37005
37095
  const removed = git2(root, ["worktree", "remove", ...force ? ["--force"] : [], record.path]);
37006
37096
  if (removed.status !== 0) {
37007
37097
  return refuse(runtime, command, "lane_git_failed", `git worktree remove failed: ${removed.stderr.trim().slice(0, 300)}`, { unit });
@@ -37071,8 +37161,8 @@ async function cmdLaneRun(runtime, unit, options) {
37071
37161
  init_project_config();
37072
37162
  init_repo_root();
37073
37163
  init_types();
37074
- import { spawn as spawn4 } from "node:child_process";
37075
- import { join as join36 } from "node:path";
37164
+ import { spawn as spawn5 } from "node:child_process";
37165
+ import { join as join37 } from "node:path";
37076
37166
  function childEnv() {
37077
37167
  const env = {};
37078
37168
  for (const [name, value] of Object.entries(process.env)) {
@@ -37091,7 +37181,7 @@ function cmdLand(runtime, options = {}) {
37091
37181
  if (!root) {
37092
37182
  return Promise.resolve(refuse2(runtime, "project_required", "land requires a KXM project (run kxm init first)"));
37093
37183
  }
37094
- const script = join36(findKxmRepoRoot(import.meta.url), "scripts", "pr-land.mjs");
37184
+ const script = join37(findKxmRepoRoot(import.meta.url), "scripts", "pr-land.mjs");
37095
37185
  const args = [script];
37096
37186
  if (options.pr) args.push("--pr", options.pr);
37097
37187
  if (options.stage) args.push("--stage", options.stage);
@@ -37099,7 +37189,7 @@ function cmdLand(runtime, options = {}) {
37099
37189
  if (runtime.json) args.push("--json");
37100
37190
  if (runtime.dryRun) args.push("--dry-run");
37101
37191
  return new Promise((resolveExit) => {
37102
- const child = spawn4(process.execPath, args, { cwd: root, env: childEnv(), windowsHide: true });
37192
+ const child = spawn5(process.execPath, args, { cwd: root, env: childEnv(), windowsHide: true });
37103
37193
  child.stdout.on("data", (chunk) => runtime.io.stdout(chunk.toString("utf8")));
37104
37194
  child.stderr.on("data", (chunk) => runtime.io.stderr(chunk.toString("utf8")));
37105
37195
  child.once("error", () => resolveExit(1));
@@ -37111,8 +37201,8 @@ function cmdLand(runtime, options = {}) {
37111
37201
  init_project_config();
37112
37202
  init_types();
37113
37203
  import { spawnSync as spawnSync7 } from "node:child_process";
37114
- import { existsSync as existsSync30 } from "node:fs";
37115
- import { join as join37 } from "node:path";
37204
+ import { existsSync as existsSync31 } from "node:fs";
37205
+ import { join as join38 } from "node:path";
37116
37206
  var kxmAssignCliSeams = {};
37117
37207
  var RUNNER_REL = "scripts/assignment-run.mjs";
37118
37208
  function refuse3(runtime, command, error, text) {
@@ -37184,7 +37274,7 @@ async function cmdAssign(runtime, subcommand, args) {
37184
37274
  const command = `assign ${subcommand}`;
37185
37275
  const root = discoverKxmProjectRoot(runtime.cwd);
37186
37276
  if (!root) return refuse3(runtime, command, "project_required", `${command} requires a KXM project (run kxm init first)`);
37187
- if (!existsSync30(join37(root, "scripts", "assignment-run.mjs"))) {
37277
+ if (!existsSync31(join38(root, "scripts", "assignment-run.mjs"))) {
37188
37278
  return refuse3(runtime, command, "assign_runner_missing", `${command} requires scripts/assignment-run.mjs in the project root`);
37189
37279
  }
37190
37280
  const argv = ["node", RUNNER_REL, ...runnerArgv(subcommand, args)];
@@ -37195,7 +37285,7 @@ async function cmdAssign(runtime, subcommand, args) {
37195
37285
  `);
37196
37286
  return 0;
37197
37287
  }
37198
- const spawn5 = kxmAssignCliSeams.spawn ?? ((commandName, commandArgs, options) => {
37288
+ const spawn6 = kxmAssignCliSeams.spawn ?? ((commandName, commandArgs, options) => {
37199
37289
  const result2 = spawnSync7(commandName, commandArgs, {
37200
37290
  cwd: options.cwd,
37201
37291
  stdio: options.stdio,
@@ -37204,7 +37294,7 @@ async function cmdAssign(runtime, subcommand, args) {
37204
37294
  });
37205
37295
  return { status: result2.status, ...result2.error ? { error: result2.error } : {} };
37206
37296
  });
37207
- const result = spawn5("node", argv.slice(1), { cwd: root, stdio: "inherit", env: runtime.env });
37297
+ const result = spawn6("node", argv.slice(1), { cwd: root, stdio: "inherit", env: runtime.env });
37208
37298
  if (result.status === null) {
37209
37299
  const detail = result.error?.message ?? "the assignment runner could not be started";
37210
37300
  return refuse3(runtime, command, "assign_spawn_failed", detail);
@@ -37215,8 +37305,8 @@ async function cmdAssign(runtime, subcommand, args) {
37215
37305
  // plugins/kxm/src/cli/hub.ts
37216
37306
  init_redact();
37217
37307
  import { randomUUID as randomUUID13 } from "node:crypto";
37218
- import { existsSync as existsSync36, mkdirSync as mkdirSync28, readFileSync as readFileSync35, readdirSync as readdirSync12, rmSync as rmSync11, writeFileSync as writeFileSync25 } from "node:fs";
37219
- import { join as join47, resolve as resolve28 } from "node:path";
37308
+ import { existsSync as existsSync37, mkdirSync as mkdirSync28, readFileSync as readFileSync35, readdirSync as readdirSync12, rmSync as rmSync11, writeFileSync as writeFileSync25 } from "node:fs";
37309
+ import { join as join48, resolve as resolve28 } from "node:path";
37220
37310
  init_hub_env();
37221
37311
  init_envelope();
37222
37312
 
@@ -42914,7 +43004,7 @@ import * as path2 from "node:path";
42914
43004
 
42915
43005
  // node_modules/@earendil-works/pi-tui/dist/native-module-path.js
42916
43006
  import { createRequire as createRequire2 } from "node:module";
42917
- import { dirname as dirname19, join as join38 } from "node:path";
43007
+ import { dirname as dirname19, join as join39 } from "node:path";
42918
43008
  import { fileURLToPath as fileURLToPath2 } from "node:url";
42919
43009
  var moduleRequire = createRequire2(import.meta.url);
42920
43010
  var TUI_PACKAGE_NAME = "@earendil-works/pi-tui";
@@ -42923,10 +43013,10 @@ function getNativeModuleCandidates(nativePath, options = {}) {
42923
43013
  const candidates = [];
42924
43014
  try {
42925
43015
  const packageEntry = (options.resolvePackage ?? moduleRequire.resolve)(TUI_PACKAGE_NAME);
42926
- candidates.push(join38(dirname19(packageEntry), "..", nativePath));
43016
+ candidates.push(join39(dirname19(packageEntry), "..", nativePath));
42927
43017
  } catch {
42928
43018
  }
42929
- candidates.push(join38(moduleDir, "..", nativePath), join38(moduleDir, nativePath), join38(dirname19(options.execPath ?? process.execPath), nativePath));
43019
+ candidates.push(join39(moduleDir, "..", nativePath), join39(moduleDir, nativePath), join39(dirname19(options.execPath ?? process.execPath), nativePath));
42930
43020
  return Array.from(new Set(candidates));
42931
43021
  }
42932
43022
 
@@ -45657,7 +45747,7 @@ var MAX_RENDER_WRITE_CHARS = 1024 * 1024;
45657
45747
 
45658
45748
  // plugins/kxm/src/tui.ts
45659
45749
  import { mkdirSync as mkdirSync25 } from "node:fs";
45660
- import { join as join42, resolve as resolve27, dirname as dirname20 } from "node:path";
45750
+ import { join as join43, resolve as resolve27, dirname as dirname20 } from "node:path";
45661
45751
  import { spawnSync as spawnSync8 } from "node:child_process";
45662
45752
 
45663
45753
  // packages/core/tui/src/types/surface.ts
@@ -45801,9 +45891,9 @@ var SHARED_EFFECT_KINDS = Object.freeze([
45801
45891
  // plugins/kxm/src/local-snapshot.ts
45802
45892
  init_sqlite();
45803
45893
  init_telemetry();
45804
- import { existsSync as existsSync31, readdirSync as readdirSync11, readFileSync as readFileSync30 } from "node:fs";
45894
+ import { existsSync as existsSync32, readdirSync as readdirSync11, readFileSync as readFileSync30 } from "node:fs";
45805
45895
  import { homedir as homedir6 } from "node:os";
45806
- import { isAbsolute as isAbsolute9, join as join41, resolve as resolve26 } from "node:path";
45896
+ import { isAbsolute as isAbsolute9, join as join42, resolve as resolve26 } from "node:path";
45807
45897
  var DEFAULT_BUSY_TIMEOUT_MS = 5e3;
45808
45898
  var RUNTIME_PROJECT_KEY = /^[A-Za-z0-9_-][A-Za-z0-9._-]*$/;
45809
45899
  function processExists2(pid) {
@@ -45928,36 +46018,36 @@ function readOpenMessageMetadata(database, where = OPEN_MESSAGE_WHERE, params =
45928
46018
  return messages;
45929
46019
  }
45930
46020
  function resolveKxmSnapshotPaths(cwd, env = process.env) {
45931
- const stateDir = env.KXM_STATE_DIR?.trim() || join41(cwd, ".kxm", "state");
46021
+ const stateDir = env.KXM_STATE_DIR?.trim() || join42(cwd, ".kxm", "state");
45932
46022
  const configured = env.KXM_DATA_PATH?.trim();
45933
- const dataPath = configured ? resolve26(cwd, configured) : join41(stateDir, "kxm.db");
46023
+ const dataPath = configured ? resolve26(cwd, configured) : join42(stateDir, "kxm.db");
45934
46024
  return { dataPath, stateDir };
45935
46025
  }
45936
46026
  function resolveKxmStateRoot(stateDir, options) {
45937
- if (options?.kxmStateRoot && existsSync31(options.kxmStateRoot)) {
46027
+ if (options?.kxmStateRoot && existsSync32(options.kxmStateRoot)) {
45938
46028
  return resolve26(options.kxmStateRoot);
45939
46029
  }
45940
- if (existsSync31(join41(stateDir, "runtime", "registry.db")) || existsSync31(join41(stateDir, "runtime", "projects"))) {
46030
+ if (existsSync32(join42(stateDir, "runtime", "registry.db")) || existsSync32(join42(stateDir, "runtime", "projects"))) {
45941
46031
  return stateDir;
45942
46032
  }
45943
46033
  const env = options?.env ?? process.env;
45944
46034
  const explicit = env.KXM_STATE_HOME?.trim() || env.KXM_USER_STATE_DIR?.trim() || env.KXM_STATE_ROOT?.trim();
45945
- if (explicit && isAbsolute9(explicit) && existsSync31(resolve26(explicit))) {
46035
+ if (explicit && isAbsolute9(explicit) && existsSync32(resolve26(explicit))) {
45946
46036
  return resolve26(explicit);
45947
46037
  }
45948
46038
  let base;
45949
46039
  if (process.platform === "win32") {
45950
46040
  const localAppData = env.LOCALAPPDATA?.trim();
45951
- base = localAppData && isAbsolute9(localAppData) ? localAppData : join41(homedir6(), "AppData", "Local");
46041
+ base = localAppData && isAbsolute9(localAppData) ? localAppData : join42(homedir6(), "AppData", "Local");
45952
46042
  base = resolve26(base, "KXM");
45953
46043
  } else if (process.platform === "darwin") {
45954
46044
  base = resolve26(homedir6(), "Library", "Application Support", "KXM");
45955
46045
  } else {
45956
46046
  const xdgState = env.XDG_STATE_HOME?.trim();
45957
- base = xdgState && isAbsolute9(xdgState) ? xdgState : join41(homedir6(), ".local", "state");
46047
+ base = xdgState && isAbsolute9(xdgState) ? xdgState : join42(homedir6(), ".local", "state");
45958
46048
  base = resolve26(base, "kxm");
45959
46049
  }
45960
- if (existsSync31(base)) return base;
46050
+ if (existsSync32(base)) return base;
45961
46051
  return void 0;
45962
46052
  }
45963
46053
  function readRuntimeRuns(eventDb, projectId) {
@@ -45990,7 +46080,7 @@ function loadLocalMeshSnapshot(dataPath, stateDir, options) {
45990
46080
  let legacyRuns = [];
45991
46081
  let legacyRunTotal = 0;
45992
46082
  let plans = [];
45993
- if (existsSync31(dataPath)) {
46083
+ if (existsSync32(dataPath)) {
45994
46084
  hasLegacy = true;
45995
46085
  const database = openReadOnlyDatabase(dataPath);
45996
46086
  try {
@@ -46021,11 +46111,11 @@ function loadLocalMeshSnapshot(dataPath, stateDir, options) {
46021
46111
  let kxmRunTotal = 0;
46022
46112
  const kxmStateRoot = scope && !scope.runtimeProjectId ? void 0 : resolveKxmStateRoot(stateDir, options);
46023
46113
  if (kxmStateRoot) {
46024
- const runtimeDir = join41(kxmStateRoot, "runtime");
46025
- const registryDbPath = join41(runtimeDir, "registry.db");
46026
- const projectsDir = join41(runtimeDir, "projects");
46114
+ const runtimeDir = join42(kxmStateRoot, "runtime");
46115
+ const registryDbPath = join42(runtimeDir, "registry.db");
46116
+ const projectsDir = join42(runtimeDir, "projects");
46027
46117
  const projectKeys = /* @__PURE__ */ new Set();
46028
- if (existsSync31(registryDbPath)) {
46118
+ if (existsSync32(registryDbPath)) {
46029
46119
  hasKxm = true;
46030
46120
  try {
46031
46121
  const regDb = openReadOnlyDatabase(registryDbPath);
@@ -46041,7 +46131,7 @@ function loadLocalMeshSnapshot(dataPath, stateDir, options) {
46041
46131
  } catch {
46042
46132
  }
46043
46133
  }
46044
- if (!scope && existsSync31(projectsDir)) {
46134
+ if (!scope && existsSync32(projectsDir)) {
46045
46135
  try {
46046
46136
  for (const entry of readdirSync11(projectsDir, { withFileTypes: true })) {
46047
46137
  if (entry.isDirectory()) {
@@ -46053,8 +46143,8 @@ function loadLocalMeshSnapshot(dataPath, stateDir, options) {
46053
46143
  }
46054
46144
  for (const key of projectKeys) {
46055
46145
  if (scope && !RUNTIME_PROJECT_KEY.test(key)) continue;
46056
- const eventDbPath = join41(projectsDir, key, "run-events.db");
46057
- if (existsSync31(eventDbPath)) {
46146
+ const eventDbPath = join42(projectsDir, key, "run-events.db");
46147
+ if (existsSync32(eventDbPath)) {
46058
46148
  hasKxm = true;
46059
46149
  try {
46060
46150
  const eventDb = openReadOnlyDatabase(eventDbPath);
@@ -46072,10 +46162,10 @@ function loadLocalMeshSnapshot(dataPath, stateDir, options) {
46072
46162
  }
46073
46163
  }
46074
46164
  const pids = [];
46075
- if (existsSync31(stateDir)) {
46165
+ if (existsSync32(stateDir)) {
46076
46166
  for (const file of readdirSync11(stateDir).filter((name) => name.endsWith(".pid"))) {
46077
46167
  try {
46078
- const record = JSON.parse(readFileSync30(join41(stateDir, file), "utf8"));
46168
+ const record = JSON.parse(readFileSync30(join42(stateDir, file), "utf8"));
46079
46169
  pids.push({
46080
46170
  file,
46081
46171
  ...record.role ? { role: record.role } : {},
@@ -46114,8 +46204,8 @@ function loadLocalMeshSnapshot(dataPath, stateDir, options) {
46114
46204
  } else {
46115
46205
  source = "legacy";
46116
46206
  }
46117
- const telemetryFile = join41(stateDir, "telemetry.jsonl");
46118
- const spend = existsSync31(telemetryFile) ? readRoutingRecords(telemetryFile) : [];
46207
+ const telemetryFile = join42(stateDir, "telemetry.jsonl");
46208
+ const spend = existsSync32(telemetryFile) ? readRoutingRecords(telemetryFile) : [];
46119
46209
  return {
46120
46210
  source,
46121
46211
  agents: agents.sort((a, b2) => Number(b2.online) - Number(a.online) || a.name.localeCompare(b2.name)),
@@ -46249,7 +46339,7 @@ function spawnDegradeWorktree(repoRoot, runId, options) {
46249
46339
  const cleanRunId = runId.replace(/^run_/, "");
46250
46340
  const desc = options?.description ? slugifyBranchPart(options.description, 30) : "degrade";
46251
46341
  const branchName = `kxm/run-${cleanRunId}-${desc}`;
46252
- const relativeWtPath = join42(".kxm", "worktrees", `run-${cleanRunId}-${desc}`);
46342
+ const relativeWtPath = join43(".kxm", "worktrees", `run-${cleanRunId}-${desc}`);
46253
46343
  const absoluteWtPath = resolve27(repoRoot, relativeWtPath);
46254
46344
  const jumpCommand = `cd "${absoluteWtPath}"`;
46255
46345
  try {
@@ -47018,8 +47108,8 @@ async function runMeshTui(input) {
47018
47108
  // plugins/kxm/src/session-work.ts
47019
47109
  import { spawnSync as spawnSync9 } from "node:child_process";
47020
47110
  import { randomUUID as randomUUID12 } from "node:crypto";
47021
- import { existsSync as existsSync32, mkdirSync as mkdirSync26, readFileSync as readFileSync31, renameSync as renameSync8, writeFileSync as writeFileSync23 } from "node:fs";
47022
- import { join as join43 } from "node:path";
47111
+ import { existsSync as existsSync33, mkdirSync as mkdirSync26, readFileSync as readFileSync31, renameSync as renameSync8, writeFileSync as writeFileSync23 } from "node:fs";
47112
+ import { join as join44 } from "node:path";
47023
47113
  init_hub_binding();
47024
47114
  init_telemetry();
47025
47115
  var MAX_SESSION_BRIEF_TASKS = 5;
@@ -47178,9 +47268,9 @@ function buildSessionBrief(snapshot, current, hub, ship, updateLatest, cost, ses
47178
47268
  };
47179
47269
  }
47180
47270
  function readCachedSessionBrief(stateDir) {
47181
- const file = join43(stateDir, "session-brief.json");
47271
+ const file = join44(stateDir, "session-brief.json");
47182
47272
  try {
47183
- if (!existsSync32(file)) return void 0;
47273
+ if (!existsSync33(file)) return void 0;
47184
47274
  const raw = readFileSync31(file, "utf8");
47185
47275
  const parsed = JSON.parse(raw);
47186
47276
  if (parsed && parsed.schema === "kxm.session-brief.v1" && typeof parsed.generatedAt === "string") {
@@ -47197,7 +47287,7 @@ function readCachedSessionBrief(stateDir) {
47197
47287
  function writeCachedSessionBrief(stateDir, brief) {
47198
47288
  try {
47199
47289
  mkdirSync26(stateDir, { recursive: true, mode: 448 });
47200
- const file = join43(stateDir, "session-brief.json");
47290
+ const file = join44(stateDir, "session-brief.json");
47201
47291
  const tmp = `${file}.tmp.${randomUUID12().slice(0, 8)}`;
47202
47292
  writeFileSync23(tmp, JSON.stringify(brief, null, 2), { encoding: "utf8", mode: 384 });
47203
47293
  renameSync8(tmp, file);
@@ -47206,8 +47296,8 @@ function writeCachedSessionBrief(stateDir, brief) {
47206
47296
  }
47207
47297
  function estimateSessionCost(stateDir) {
47208
47298
  try {
47209
- const telemetryFile = join43(stateDir, "telemetry.jsonl");
47210
- if (!existsSync32(telemetryFile)) return void 0;
47299
+ const telemetryFile = join44(stateDir, "telemetry.jsonl");
47300
+ if (!existsSync33(telemetryFile)) return void 0;
47211
47301
  const records = readRoutingRecords(telemetryFile);
47212
47302
  if (records.length === 0) return void 0;
47213
47303
  let totalCost = 0;
@@ -47379,11 +47469,11 @@ init_hub_binding();
47379
47469
 
47380
47470
  // plugins/kxm/src/kxm-install-kind.ts
47381
47471
  init_bindings();
47382
- import { existsSync as existsSync33, readFileSync as readFileSync32 } from "node:fs";
47383
- import { dirname as dirname21, join as join44 } from "node:path";
47472
+ import { existsSync as existsSync34, readFileSync as readFileSync32 } from "node:fs";
47473
+ import { dirname as dirname21, join as join45 } from "node:path";
47384
47474
  function packageIsKxm(root) {
47385
47475
  try {
47386
- const pkg = JSON.parse(readFileSync32(join44(root, "package.json"), "utf8"));
47476
+ const pkg = JSON.parse(readFileSync32(join45(root, "package.json"), "utf8"));
47387
47477
  return pkg.name === "@kontextmind/kxm";
47388
47478
  } catch {
47389
47479
  return false;
@@ -47432,12 +47522,12 @@ function report(kind, root) {
47432
47522
  return { kind, root, instruction: installKindInstruction(kind, root) };
47433
47523
  }
47434
47524
  function classifyInstallRoot(probe) {
47435
- const piGitRoot = join44(probe.homeDir, ".pi", "agent", "git");
47525
+ const piGitRoot = join45(probe.homeDir, ".pi", "agent", "git");
47436
47526
  if (isUnder(probe.repoRoot, piGitRoot, probe.platform)) return report("pi-git", probe.repoRoot);
47437
- const claudeHome = probe.env.CLAUDE_CONFIG_DIR?.trim() || join44(probe.homeDir, ".claude");
47438
- const pluginsRoot = join44(claudeHome, "plugins");
47527
+ const claudeHome = probe.env.CLAUDE_CONFIG_DIR?.trim() || join45(probe.homeDir, ".claude");
47528
+ const pluginsRoot = join45(claudeHome, "plugins");
47439
47529
  if (isUnder(probe.moduleDir, pluginsRoot, probe.platform)) return report("claude-marketplace", probe.moduleDir);
47440
- const hasGit = existsSync33(join44(probe.repoRoot, ".git"));
47530
+ const hasGit = existsSync34(join45(probe.repoRoot, ".git"));
47441
47531
  if (hasGit && packageIsKxm(probe.repoRoot)) return report("source", probe.repoRoot);
47442
47532
  if (isNpmPackageLayout(probe.repoRoot, probe.platform) && packageIsKxm(probe.repoRoot) && !hasGit) {
47443
47533
  return report("npm-package", probe.repoRoot);
@@ -47461,12 +47551,12 @@ init_bindings();
47461
47551
 
47462
47552
  // plugins/kxm/src/kxm-update-config.ts
47463
47553
  var import_yaml16 = __toESM(require_dist(), 1);
47464
- import { existsSync as existsSync34, readFileSync as readFileSync33 } from "node:fs";
47465
- import { join as join45 } from "node:path";
47554
+ import { existsSync as existsSync35, readFileSync as readFileSync33 } from "node:fs";
47555
+ import { join as join46 } from "node:path";
47466
47556
  init_bindings();
47467
47557
  function loadKxmUpdateConfig(env = process.env) {
47468
- const path4 = join45(kxmUserStateRoot({ env }), "update.yaml");
47469
- if (!existsSync34(path4)) return { schema: KXM_UPDATE_SCHEMA, auto: false, source: "github" };
47558
+ const path4 = join46(kxmUserStateRoot({ env }), "update.yaml");
47559
+ if (!existsSync35(path4)) return { schema: KXM_UPDATE_SCHEMA, auto: false, source: "github" };
47470
47560
  let parsed;
47471
47561
  try {
47472
47562
  parsed = (0, import_yaml16.parse)(readFileSync33(path4, "utf8"));
@@ -47497,8 +47587,8 @@ function loadKxmUpdateConfig(env = process.env) {
47497
47587
  // plugins/kxm/src/session.ts
47498
47588
  init_protocol();
47499
47589
  init_envelope();
47500
- import { existsSync as existsSync35, mkdirSync as mkdirSync27, readFileSync as readFileSync34, writeFileSync as writeFileSync24 } from "node:fs";
47501
- import { join as join46 } from "node:path";
47590
+ import { existsSync as existsSync36, mkdirSync as mkdirSync27, readFileSync as readFileSync34, writeFileSync as writeFileSync24 } from "node:fs";
47591
+ import { join as join47 } from "node:path";
47502
47592
  var SESSION_SCHEMA = "kxm.session.v1";
47503
47593
  var SessionConfigError = class extends Error {
47504
47594
  code = "session_config_invalid";
@@ -47508,12 +47598,12 @@ var SessionConfigError = class extends Error {
47508
47598
  }
47509
47599
  };
47510
47600
  function workflowAssetDirs(assetsDir, workflowId) {
47511
- const root = join46(assetsDir, "workflows", workflowId);
47512
- return [root, join46(root, "inputs"), join46(root, "outputs"), join46(root, "generated")];
47601
+ const root = join47(assetsDir, "workflows", workflowId);
47602
+ return [root, join47(root, "inputs"), join47(root, "outputs"), join47(root, "generated")];
47513
47603
  }
47514
47604
  function sessionAssetDirs(assetsDir, sessionId) {
47515
- const root = join46(assetsDir, "sessions", sessionId);
47516
- return [root, join46(root, "inputs"), join46(root, "outputs")];
47605
+ const root = join47(assetsDir, "sessions", sessionId);
47606
+ return [root, join47(root, "inputs"), join47(root, "outputs")];
47517
47607
  }
47518
47608
  function rosterNames(configDir) {
47519
47609
  return [...loadRosterMap(configDir).values()].map((row) => String(row.name));
@@ -47563,7 +47653,7 @@ function workerFromRosterRow(name, row, project) {
47563
47653
  function loadRosterMap(configDir) {
47564
47654
  const byName = /* @__PURE__ */ new Map();
47565
47655
  for (const [file, key] of [["agents.json", "agents"], ["gates.json", "gates"]]) {
47566
- const path4 = join46(configDir, file);
47656
+ const path4 = join47(configDir, file);
47567
47657
  for (const row of loadRoster(path4, key)) {
47568
47658
  const name = String(row.name).trim();
47569
47659
  const lowered = name.toLowerCase();
@@ -47577,7 +47667,7 @@ function loadRosterMap(configDir) {
47577
47667
  return byName;
47578
47668
  }
47579
47669
  function loadRoster(path4, key) {
47580
- if (!existsSync35(path4)) return [];
47670
+ if (!existsSync36(path4)) return [];
47581
47671
  let parsed;
47582
47672
  try {
47583
47673
  parsed = JSON.parse(readFileSync34(path4, "utf8"));
@@ -47605,7 +47695,7 @@ function loadRoster(path4, key) {
47605
47695
  });
47606
47696
  }
47607
47697
  function createSession(input) {
47608
- const assetDir = input.mode === "workflow" && input.workflowId ? join46("assets", "workflows", input.workflowId) : join46("assets", "sessions", input.id);
47698
+ const assetDir = input.mode === "workflow" && input.workflowId ? join47("assets", "workflows", input.workflowId) : join47("assets", "sessions", input.id);
47609
47699
  return {
47610
47700
  schema: SESSION_SCHEMA,
47611
47701
  id: input.id,
@@ -47618,8 +47708,8 @@ function createSession(input) {
47618
47708
  };
47619
47709
  }
47620
47710
  function writeSession(assetsDir, session, dryRun = false) {
47621
- const dir = join46(assetsDir, "sessions", session.id);
47622
- const path4 = join46(dir, "session.json");
47711
+ const dir = join47(assetsDir, "sessions", session.id);
47712
+ const path4 = join47(dir, "session.json");
47623
47713
  if (!dryRun) {
47624
47714
  mkdirSync27(dir, { recursive: true });
47625
47715
  writeFileSync24(path4, `${JSON.stringify(session, null, 2)}
@@ -47675,9 +47765,9 @@ function moduleInstallRoot() {
47675
47765
  }
47676
47766
  }
47677
47767
  function warnIgnoredProjectUpdateYaml(runtime) {
47678
- const projectFile = join47(runtime.dirs.workspace, "update.yaml");
47679
- if (!existsSync36(projectFile)) return;
47680
- const userFile = join47(kxmUserStateRoot({ env: runtime.env }), "update.yaml");
47768
+ const projectFile = join48(runtime.dirs.workspace, "update.yaml");
47769
+ if (!existsSync37(projectFile)) return;
47770
+ const userFile = join48(kxmUserStateRoot({ env: runtime.env }), "update.yaml");
47681
47771
  runtime.io.stderr(`kxm: ignoring .kxm/update.yaml in ${runtime.dirs.workdir}; update settings are read only from ${userFile}
47682
47772
  `);
47683
47773
  }
@@ -47725,7 +47815,7 @@ async function cmdDash(runtime, options = {}) {
47725
47815
  return 2;
47726
47816
  }
47727
47817
  const screen = requested;
47728
- const dataPath = resolve28(runtime.dirs.workdir, runtime.env.KXM_DATA_PATH?.trim() || join47(runtime.dirs.state, "kxm.db"));
47818
+ const dataPath = resolve28(runtime.dirs.workdir, runtime.env.KXM_DATA_PATH?.trim() || join48(runtime.dirs.state, "kxm.db"));
47729
47819
  if (runtime.dryRun) {
47730
47820
  print(runtime.io, runtime.json, {
47731
47821
  ok: true,
@@ -47771,7 +47861,7 @@ async function cmdHub(runtime) {
47771
47861
  config = loadKxmUpdateConfig(runtime.env);
47772
47862
  } catch (error) {
47773
47863
  if (error instanceof KxmUpdateConfigError) {
47774
- const yamlPath = join47(kxmUserStateRoot({ env: runtime.env }), "update.yaml");
47864
+ const yamlPath = join48(kxmUserStateRoot({ env: runtime.env }), "update.yaml");
47775
47865
  runtime.io.stderr(`kxm: ${error.message}; update check skipped; fix or remove ${yamlPath}
47776
47866
  `);
47777
47867
  } else {
@@ -47958,7 +48048,7 @@ async function cmdWorker(runtime, options) {
47958
48048
  return await (runtime.io.spawnWorker ?? ((launchEnv) => spawnScript("kxm-worker.mjs", launchEnv)))(extraEnv);
47959
48049
  }
47960
48050
  async function cmdStop(runtime, waitMsFlag) {
47961
- const pids = existsSync36(runtime.dirs.state) ? readdirSync12(runtime.dirs.state).filter((name) => name.endsWith(".pid")) : [];
48051
+ const pids = existsSync37(runtime.dirs.state) ? readdirSync12(runtime.dirs.state).filter((name) => name.endsWith(".pid")) : [];
47962
48052
  if (runtime.dryRun) {
47963
48053
  print(runtime.io, runtime.json, { ok: true, command: "stop", dryRun: true, pidFiles: pids }, "would signal pid files");
47964
48054
  return 0;
@@ -47973,7 +48063,7 @@ async function cmdStop(runtime, waitMsFlag) {
47973
48063
  const orphans = [];
47974
48064
  for (const file of pids) {
47975
48065
  try {
47976
- const record = JSON.parse(readFileSync35(join47(runtime.dirs.state, file), "utf8"));
48066
+ const record = JSON.parse(readFileSync35(join48(runtime.dirs.state, file), "utf8"));
47977
48067
  const expectedControl = file === "hub.pid" ? "hub.stop" : file.startsWith("worker-") ? `${file.slice(0, -4)}.stop` : void 0;
47978
48068
  const expectedRole = file === "hub.pid" ? "hub" : file.startsWith("worker-") ? "worker" : void 0;
47979
48069
  if (record.version !== 1 || !Number.isInteger(record.pid) || record.pid <= 0 || !record.startedAt || !expectedControl || record.controlFile !== expectedControl || record.role !== expectedRole) {
@@ -47993,7 +48083,7 @@ async function cmdStop(runtime, waitMsFlag) {
47993
48083
  ignored.push(file);
47994
48084
  continue;
47995
48085
  }
47996
- writeFileSync25(join47(runtime.dirs.state, record.controlFile), `${JSON.stringify({ startedAt: record.startedAt, ...record.generation ? { generation: record.generation } : {}, requestedAt: (/* @__PURE__ */ new Date()).toISOString() })}
48086
+ writeFileSync25(join48(runtime.dirs.state, record.controlFile), `${JSON.stringify({ startedAt: record.startedAt, ...record.generation ? { generation: record.generation } : {}, requestedAt: (/* @__PURE__ */ new Date()).toISOString() })}
47997
48087
  `, { encoding: "utf8", mode: 384 });
47998
48088
  requested.push(file);
47999
48089
  records.set(file, { pid: record.pid, startedAt: record.startedAt, ...record.generation ? { generation: record.generation } : {} });
@@ -48011,7 +48101,7 @@ async function cmdStop(runtime, waitMsFlag) {
48011
48101
  while (Date.now() <= deadline && stopped.size < requested.length) {
48012
48102
  for (const [file, record] of records) {
48013
48103
  try {
48014
- const current = JSON.parse(readFileSync35(join47(runtime.dirs.state, file), "utf8"));
48104
+ const current = JSON.parse(readFileSync35(join48(runtime.dirs.state, file), "utf8"));
48015
48105
  if (current.pid !== record.pid || current.startedAt !== record.startedAt || current.generation !== record.generation || !processExists(record.pid)) stopped.add(file);
48016
48106
  } catch {
48017
48107
  stopped.add(file);
@@ -48024,7 +48114,7 @@ async function cmdStop(runtime, waitMsFlag) {
48024
48114
  for (const file of orphans) {
48025
48115
  while (Date.now() <= deadlineOrphans) {
48026
48116
  try {
48027
- const current = JSON.parse(readFileSync35(join47(runtime.dirs.state, file), "utf8"));
48117
+ const current = JSON.parse(readFileSync35(join48(runtime.dirs.state, file), "utf8"));
48028
48118
  if (!Number.isInteger(current.serverPid) || !processExists(current.serverPid)) break;
48029
48119
  } catch {
48030
48120
  break;
@@ -48032,14 +48122,14 @@ async function cmdStop(runtime, waitMsFlag) {
48032
48122
  await (runtime.io.sleep ?? ((ms) => new Promise((resolveSleep) => setTimeout(resolveSleep, ms))))(100);
48033
48123
  }
48034
48124
  try {
48035
- const current = JSON.parse(readFileSync35(join47(runtime.dirs.state, file), "utf8"));
48125
+ const current = JSON.parse(readFileSync35(join48(runtime.dirs.state, file), "utf8"));
48036
48126
  if (Number.isInteger(current.serverPid) && processExists(current.serverPid)) {
48037
48127
  try {
48038
48128
  process.kill(current.serverPid, "SIGKILL");
48039
48129
  } catch {
48040
48130
  }
48041
48131
  }
48042
- rmSync11(join47(runtime.dirs.state, file), { force: true });
48132
+ rmSync11(join48(runtime.dirs.state, file), { force: true });
48043
48133
  } catch {
48044
48134
  }
48045
48135
  stopped.add(file);
@@ -48050,11 +48140,11 @@ async function cmdStop(runtime, waitMsFlag) {
48050
48140
  }
48051
48141
  async function cmdSessionStatus(runtime) {
48052
48142
  const stateDir = runtime.dirs.state;
48053
- const names3 = existsSync36(stateDir) ? readdirSync12(stateDir) : [];
48143
+ const names3 = existsSync37(stateDir) ? readdirSync12(stateDir) : [];
48054
48144
  const claims = [];
48055
48145
  for (const file of names3.filter((name) => name.endsWith(".pid"))) {
48056
48146
  try {
48057
- const record = JSON.parse(readFileSync35(join47(stateDir, file), "utf8"));
48147
+ const record = JSON.parse(readFileSync35(join48(stateDir, file), "utf8"));
48058
48148
  claims.push({
48059
48149
  file,
48060
48150
  role: record.role,
@@ -48069,7 +48159,7 @@ async function cmdSessionStatus(runtime) {
48069
48159
  const recoveries = [];
48070
48160
  for (const file of names3.filter((name) => name.startsWith("worker-recovery-") && name.endsWith(".json"))) {
48071
48161
  try {
48072
- const envelope = JSON.parse(readFileSync35(join47(stateDir, file), "utf8"));
48162
+ const envelope = JSON.parse(readFileSync35(join48(stateDir, file), "utf8"));
48073
48163
  recoveries.push({
48074
48164
  file,
48075
48165
  reason: envelope.reason,
@@ -48095,7 +48185,7 @@ async function cmdSessionStatus(runtime) {
48095
48185
  async function cmdAuthToken(runtime, options = {}) {
48096
48186
  const tokenFile = sessionTokenPath(runtime.env.KXM_USER_CONFIG_DIR);
48097
48187
  if (options.clear && runtime.dryRun) {
48098
- const present = existsSync36(tokenFile);
48188
+ const present = existsSync37(tokenFile);
48099
48189
  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
48190
  return 0;
48101
48191
  }
@@ -48184,7 +48274,7 @@ async function cmdSessionBrief(runtime, options = {}) {
48184
48274
  print(runtime.io, runtime.json, { ok: true, command: "session brief", sessionToken }, sessionToken);
48185
48275
  return 0;
48186
48276
  }
48187
- const dataPath = resolve28(runtime.dirs.workdir, runtime.env.KXM_DATA_PATH?.trim() || join47(runtime.dirs.state, "kxm.db"));
48277
+ const dataPath = resolve28(runtime.dirs.workdir, runtime.env.KXM_DATA_PATH?.trim() || join48(runtime.dirs.state, "kxm.db"));
48188
48278
  const env = {
48189
48279
  ...runtime.env,
48190
48280
  KXM_STATE_DIR: runtime.dirs.state,
@@ -48210,7 +48300,7 @@ async function cmdSessionBrief(runtime, options = {}) {
48210
48300
  writeCache: !runtime.dryRun
48211
48301
  });
48212
48302
  if (runtime.dryRun) {
48213
- if (!readCachedSessionBrief(runtime.dirs.state)) planned.push({ action: "write", target: join47(runtime.dirs.state, "session-brief.json") });
48303
+ if (!readCachedSessionBrief(runtime.dirs.state)) planned.push({ action: "write", target: join48(runtime.dirs.state, "session-brief.json") });
48214
48304
  print(runtime.io, runtime.json, { ...brief, dryRun: true, planned }, [
48215
48305
  options.status ? brief.statusLine : formatSessionBriefText(brief),
48216
48306
  ...planned.map((change) => `dry run: would ${change.action} ${change.target}`)
@@ -48294,9 +48384,9 @@ init_routing();
48294
48384
  init_prices();
48295
48385
  import { spawnSync as spawnSync11 } from "node:child_process";
48296
48386
  import { createHash as createHash17 } from "node:crypto";
48297
- import { existsSync as existsSync43, mkdtempSync as mkdtempSync3, readFileSync as readFileSync40, rmSync as rmSync13 } from "node:fs";
48387
+ import { existsSync as existsSync44, mkdtempSync as mkdtempSync3, readFileSync as readFileSync40, rmSync as rmSync13 } from "node:fs";
48298
48388
  import { tmpdir as tmpdir2 } from "node:os";
48299
- import { basename as basename11, extname as extname3, join as join53, resolve as resolve33 } from "node:path";
48389
+ import { basename as basename11, extname as extname3, join as join54, resolve as resolve33 } from "node:path";
48300
48390
  import { createInterface as createInterface3 } from "node:readline";
48301
48391
 
48302
48392
  // plugins/kxm/src/improve.ts
@@ -48304,8 +48394,8 @@ init_routing();
48304
48394
  init_protocol();
48305
48395
  init_relevance();
48306
48396
  import { createHash as createHash16 } from "node:crypto";
48307
- import { existsSync as existsSync37, mkdirSync as mkdirSync29, writeFileSync as writeFileSync26 } from "node:fs";
48308
- import { join as join48, relative as relative7, resolve as resolve29 } from "node:path";
48397
+ import { existsSync as existsSync38, mkdirSync as mkdirSync29, writeFileSync as writeFileSync26 } from "node:fs";
48398
+ import { join as join49, relative as relative7, resolve as resolve29 } from "node:path";
48309
48399
  var CANDIDATE_SCHEMA = "kxm.candidate.v1";
48310
48400
  var IMPROVEMENT_REPORT_SCHEMA = "kxm.improvement-report.v2";
48311
48401
  function classifyCandidateKind(stepId, agentRole) {
@@ -48561,7 +48651,7 @@ function groupRoutingRecords(records, options = {}) {
48561
48651
  }
48562
48652
  function buildImprovementReport(records, options = {}) {
48563
48653
  const projectRoot = options.projectRoot ? resolve29(options.projectRoot) : process.cwd();
48564
- const candidatesDir = options.candidatesDir ? resolve29(options.candidatesDir) : join48(projectRoot, ".kxm", "candidates");
48654
+ const candidatesDir = options.candidatesDir ? resolve29(options.candidatesDir) : join49(projectRoot, ".kxm", "candidates");
48565
48655
  const promotionPolicy = options.promotionPolicy ?? "manual_pr";
48566
48656
  const groups = groupRoutingRecords(records, options);
48567
48657
  const candidates = [];
@@ -48575,7 +48665,7 @@ function buildImprovementReport(records, options = {}) {
48575
48665
  group.workflowId
48576
48666
  );
48577
48667
  const diffFileName = `${group.candidateId}.diff`;
48578
- const diffFilePath = join48(candidatesDir, diffFileName);
48668
+ const diffFilePath = join49(candidatesDir, diffFileName);
48579
48669
  const relDiffPath = relative7(projectRoot, diffFilePath).replace(/\\/g, "/");
48580
48670
  const candidate = {
48581
48671
  schema: CANDIDATE_SCHEMA,
@@ -48597,11 +48687,11 @@ function buildImprovementReport(records, options = {}) {
48597
48687
  createdAt: nowIso()
48598
48688
  };
48599
48689
  if (!options.dryRun) {
48600
- if (!existsSync37(candidatesDir)) {
48690
+ if (!existsSync38(candidatesDir)) {
48601
48691
  mkdirSync29(candidatesDir, { recursive: true });
48602
48692
  }
48603
48693
  writeFileSync26(diffFilePath, diff, "utf8");
48604
- const jsonFilePath = join48(candidatesDir, `${group.candidateId}.json`);
48694
+ const jsonFilePath = join49(candidatesDir, `${group.candidateId}.json`);
48605
48695
  writeFileSync26(jsonFilePath, JSON.stringify(candidate, null, 2) + "\n", "utf8");
48606
48696
  }
48607
48697
  candidates.push(candidate);
@@ -48630,7 +48720,7 @@ function buildImprovementReport(records, options = {}) {
48630
48720
  }
48631
48721
  function writeImprovementReport(improvementsDir, report2, dryRun = false) {
48632
48722
  const stamp = report2.createdAt.replace(/[:.]/g, "-");
48633
- const path4 = join48(improvementsDir, `${stamp}.json`);
48723
+ const path4 = join49(improvementsDir, `${stamp}.json`);
48634
48724
  if (!dryRun) {
48635
48725
  mkdirSync29(improvementsDir, { recursive: true });
48636
48726
  writeFileSync26(path4, `${JSON.stringify(report2, null, 2)}
@@ -48714,7 +48804,7 @@ init_project_config();
48714
48804
  init_runtime_store();
48715
48805
  init_routing();
48716
48806
  init_telemetry();
48717
- import { existsSync as existsSync38 } from "node:fs";
48807
+ import { existsSync as existsSync39 } from "node:fs";
48718
48808
  import { resolve as resolve30 } from "node:path";
48719
48809
  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
48810
  var SIMULATED_HARNESS = "driver-simulated";
@@ -48737,7 +48827,7 @@ function readEngineRoutingRecords(path4) {
48737
48827
  undecided: 0,
48738
48828
  duplicatesDropped: 0
48739
48829
  };
48740
- if (!existsSync38(path4)) return { records: [], source };
48830
+ if (!existsSync39(path4)) return { records: [], source };
48741
48831
  source.exists = true;
48742
48832
  let rows;
48743
48833
  let database;
@@ -48813,7 +48903,7 @@ function readEngineRoutingRecords(path4) {
48813
48903
  };
48814
48904
  }
48815
48905
  function readJsonlSource(kind, path4) {
48816
- const exists = existsSync38(path4);
48906
+ const exists = existsSync39(path4);
48817
48907
  const records = exists ? readRoutingRecords(path4).map((entry) => entry.routing) : [];
48818
48908
  return { records, source: { kind, path: path4, exists, records: records.length, duplicatesDropped: 0 } };
48819
48909
  }
@@ -48858,8 +48948,8 @@ function loadRoutingSources(options) {
48858
48948
  // plugins/kxm/src/modes.ts
48859
48949
  var import_yaml17 = __toESM(require_dist(), 1);
48860
48950
  init_prices();
48861
- import { existsSync as existsSync39, readFileSync as readFileSync37 } from "node:fs";
48862
- import { join as join49 } from "node:path";
48951
+ import { existsSync as existsSync40, readFileSync as readFileSync37 } from "node:fs";
48952
+ import { join as join50 } from "node:path";
48863
48953
  var DEFAULT_MODES_CONFIG = Object.freeze({
48864
48954
  schema: "kxm.modes.v1",
48865
48955
  majorModes: {
@@ -48922,8 +49012,8 @@ function loadModesConfig(projectRoot) {
48922
49012
  if (!projectRoot) {
48923
49013
  return DEFAULT_MODES_CONFIG;
48924
49014
  }
48925
- const modesPath = join49(projectRoot, ".kxm", "modes.yaml");
48926
- if (!existsSync39(modesPath)) {
49015
+ const modesPath = join50(projectRoot, ".kxm", "modes.yaml");
49016
+ if (!existsSync40(modesPath)) {
48927
49017
  return DEFAULT_MODES_CONFIG;
48928
49018
  }
48929
49019
  try {
@@ -49013,9 +49103,9 @@ function calculatePromptFootprint(resolved, projectRoot = process.cwd(), catalog
49013
49103
  estimatedTokens: estimateTokens(baseSystemPromptChars)
49014
49104
  });
49015
49105
  for (const relPath of resolved.contextFiles) {
49016
- const fullPath = join49(projectRoot, relPath);
49106
+ const fullPath = join50(projectRoot, relPath);
49017
49107
  let chars = 0;
49018
- if (existsSync39(fullPath)) {
49108
+ if (existsSync40(fullPath)) {
49019
49109
  try {
49020
49110
  chars = readFileSync37(fullPath, "utf8").length;
49021
49111
  } catch {
@@ -49150,9 +49240,9 @@ ${divider}
49150
49240
  // plugins/kxm/src/ssh-remote.ts
49151
49241
  init_safety_integrity();
49152
49242
  import { spawnSync as spawnSync10 } from "node:child_process";
49153
- import { existsSync as existsSync40, mkdirSync as mkdirSync30, readFileSync as readFileSync38, readdirSync as readdirSync13, rmSync as rmSync12, statSync as statSync5 } from "node:fs";
49243
+ import { existsSync as existsSync41, mkdirSync as mkdirSync30, readFileSync as readFileSync38, readdirSync as readdirSync13, rmSync as rmSync12, statSync as statSync5 } from "node:fs";
49154
49244
  import { homedir as homedir8 } from "node:os";
49155
- import { join as join50, resolve as resolve31 } from "node:path";
49245
+ import { join as join51, resolve as resolve31 } from "node:path";
49156
49246
  var MAX_SSH_OUTPUT_BYTES = 50 * 1024;
49157
49247
  var MAX_SSH_OUTPUT_LINES = 2e3;
49158
49248
  var DEFAULT_SOCKET_DIR = ".kxm/run/ssh-sockets";
@@ -49178,8 +49268,8 @@ function truncateSshOutput(raw) {
49178
49268
  return { text, truncated };
49179
49269
  }
49180
49270
  function parseSshConfig(configPath) {
49181
- const targetPath = configPath ?? join50(homedir8(), ".ssh", "config");
49182
- if (!existsSync40(targetPath)) {
49271
+ const targetPath = configPath ?? join51(homedir8(), ".ssh", "config");
49272
+ if (!existsSync41(targetPath)) {
49183
49273
  return [];
49184
49274
  }
49185
49275
  try {
@@ -49261,14 +49351,14 @@ function resolveSshHostG(host, execFn = spawnSync10) {
49261
49351
  }
49262
49352
  function ensureSocketDir(socketDir = DEFAULT_SOCKET_DIR) {
49263
49353
  const resolved = resolve31(socketDir);
49264
- if (!existsSync40(resolved)) {
49354
+ if (!existsSync41(resolved)) {
49265
49355
  mkdirSync30(resolved, { recursive: true, mode: 448 });
49266
49356
  }
49267
49357
  return resolved;
49268
49358
  }
49269
49359
  function buildSshArgs(options) {
49270
49360
  const socketDir = ensureSocketDir(options.socketDir ?? DEFAULT_SOCKET_DIR);
49271
- const controlPath = join50(socketDir, "%C");
49361
+ const controlPath = join51(socketDir, "%C");
49272
49362
  const persist = options.controlPersist ?? DEFAULT_CONTROL_PERSIST;
49273
49363
  const args = [
49274
49364
  "-o",
@@ -49293,7 +49383,7 @@ function buildSshArgs(options) {
49293
49383
  }
49294
49384
  function checkControlSocket(host, socketDir = DEFAULT_SOCKET_DIR, execFn = spawnSync10) {
49295
49385
  const resolvedDir = ensureSocketDir(socketDir);
49296
- const controlPath = join50(resolvedDir, "%C");
49386
+ const controlPath = join51(resolvedDir, "%C");
49297
49387
  try {
49298
49388
  const result = execFn("ssh", ["-O", "check", "-o", `ControlPath=${controlPath}`, host], {
49299
49389
  encoding: "utf-8"
@@ -49305,7 +49395,7 @@ function checkControlSocket(host, socketDir = DEFAULT_SOCKET_DIR, execFn = spawn
49305
49395
  }
49306
49396
  function closeControlSocket(host, socketDir = DEFAULT_SOCKET_DIR, execFn = spawnSync10) {
49307
49397
  const resolvedDir = ensureSocketDir(socketDir);
49308
- const controlPath = join50(resolvedDir, "%C");
49398
+ const controlPath = join51(resolvedDir, "%C");
49309
49399
  try {
49310
49400
  const result = execFn("ssh", ["-O", "stop", "-o", `ControlPath=${controlPath}`, host], {
49311
49401
  encoding: "utf-8"
@@ -49753,9 +49843,9 @@ complete -c kxm -n "__fish_seen_subcommand_from goal" -a "create list get"
49753
49843
  }
49754
49844
 
49755
49845
  // plugins/kxm/src/completion-install.ts
49756
- import { existsSync as existsSync41, mkdirSync as mkdirSync31, readFileSync as readFileSync39, writeFileSync as writeFileSync27 } from "node:fs";
49846
+ import { existsSync as existsSync42, mkdirSync as mkdirSync31, readFileSync as readFileSync39, writeFileSync as writeFileSync27 } from "node:fs";
49757
49847
  import { homedir as homedir9 } from "node:os";
49758
- import { basename as basename10, delimiter, dirname as dirname24, isAbsolute as isAbsolute10, join as join51, resolve as resolve32 } from "node:path";
49848
+ import { basename as basename10, delimiter, dirname as dirname24, isAbsolute as isAbsolute10, join as join52, resolve as resolve32 } from "node:path";
49759
49849
  var COMPLETION_MARKER = "# kxm completion";
49760
49850
  var PATH_MARKER = "# kxm path";
49761
49851
  function detectShell(env = process.env, platform = process.platform) {
@@ -49777,25 +49867,25 @@ function completionScriptPath(shell, options = {}) {
49777
49867
  const env = options.env ?? process.env;
49778
49868
  const explicit = options.configDir ?? env.KXM_USER_CONFIG_DIR?.trim();
49779
49869
  const base = explicit && explicit.length > 0 ? resolve32(explicit) : resolve32(effectiveHome(options), ".config", "kxm");
49780
- return join51(base, "completions", `kxm.${shell}`);
49870
+ return join52(base, "completions", `kxm.${shell}`);
49781
49871
  }
49782
49872
  function bashRcCandidate(options) {
49783
49873
  const home = effectiveHome(options);
49784
- const candidates = [join51(home, ".bashrc"), join51(home, ".bash_profile")];
49785
- const existing = candidates.find((candidate) => existsSync41(candidate));
49874
+ const candidates = [join52(home, ".bashrc"), join52(home, ".bash_profile")];
49875
+ const existing = candidates.find((candidate) => existsSync42(candidate));
49786
49876
  return existing ?? candidates[0];
49787
49877
  }
49788
49878
  function zshRcCandidate(options) {
49789
49879
  const env = options.env ?? process.env;
49790
49880
  const home = effectiveHome(options);
49791
- if (env.ZDOTDIR?.trim()) return join51(resolve32(env.ZDOTDIR.trim()), ".zshrc");
49792
- return join51(home, ".zshrc");
49881
+ if (env.ZDOTDIR?.trim()) return join52(resolve32(env.ZDOTDIR.trim()), ".zshrc");
49882
+ return join52(home, ".zshrc");
49793
49883
  }
49794
49884
  function fishCompletionTarget(shell, options) {
49795
49885
  const env = options.env ?? process.env;
49796
49886
  const home = effectiveHome(options);
49797
- if (env.XDG_CONFIG_HOME?.trim()) return join51(resolve32(env.XDG_CONFIG_HOME.trim()), "fish", "completions", "kxm.fish");
49798
- return join51(home, ".config", "fish", "completions", "kxm.fish");
49887
+ if (env.XDG_CONFIG_HOME?.trim()) return join52(resolve32(env.XDG_CONFIG_HOME.trim()), "fish", "completions", "kxm.fish");
49888
+ return join52(home, ".config", "fish", "completions", "kxm.fish");
49799
49889
  }
49800
49890
  function completionRcTarget(shell, options = {}) {
49801
49891
  if (shell === "fish") {
@@ -49827,13 +49917,13 @@ function installShellCompletion(shellInput, options = {}) {
49827
49917
  const scriptPath = completionScriptPath(shell, options);
49828
49918
  const { rcFile } = completionRcTarget(shell, options);
49829
49919
  const script = generateShellCompletion(shell);
49830
- const existingScript = existsSync41(scriptPath);
49920
+ const existingScript = existsSync42(scriptPath);
49831
49921
  const existingScriptMatches = existingScript && readFileSync39(scriptPath, "utf8") === script;
49832
49922
  let rcModified = false;
49833
49923
  let alreadyInstalled = false;
49834
49924
  if (shell === "fish") {
49835
49925
  const fishTarget = fishCompletionTarget(shell, options);
49836
- const fishInstalled = existsSync41(fishTarget) && readFileSync39(fishTarget, "utf8") === script;
49926
+ const fishInstalled = existsSync42(fishTarget) && readFileSync39(fishTarget, "utf8") === script;
49837
49927
  alreadyInstalled = fishInstalled;
49838
49928
  if (!options.dryRun && (!fishInstalled || options.overwrite)) {
49839
49929
  mkdirSync31(resolve32(fishTarget, ".."), { recursive: true });
@@ -49850,7 +49940,7 @@ function installShellCompletion(shellInput, options = {}) {
49850
49940
  }
49851
49941
  if (rcFile) {
49852
49942
  const line = sourceLine(shell, scriptPath);
49853
- const rcContent = existsSync41(rcFile) ? readFileSync39(rcFile, "utf8") : "";
49943
+ const rcContent = existsSync42(rcFile) ? readFileSync39(rcFile, "utf8") : "";
49854
49944
  alreadyInstalled = rcContent.includes(line) || rcContent.includes(`${COMPLETION_MARKER}`);
49855
49945
  }
49856
49946
  if (!options.dryRun) {
@@ -49866,7 +49956,7 @@ ${marker}
49866
49956
  ${line}
49867
49957
  `;
49868
49958
  mkdirSync31(resolve32(rcFile, ".."), { recursive: true });
49869
- writeFileSync27(rcFile, (existsSync41(rcFile) ? readFileSync39(rcFile, "utf8") : "") + stanza, { encoding: "utf8" });
49959
+ writeFileSync27(rcFile, (existsSync42(rcFile) ? readFileSync39(rcFile, "utf8") : "") + stanza, { encoding: "utf8" });
49870
49960
  rcModified = true;
49871
49961
  }
49872
49962
  }
@@ -49883,13 +49973,13 @@ function kxmBinDir(env = process.env) {
49883
49973
  const argv1 = env.KXM_ENTRY ?? process.argv[1];
49884
49974
  if (argv1 && isAbsolute10(argv1)) {
49885
49975
  const dir = dirname24(argv1);
49886
- if (existsSync41(join51(dir, process.platform === "win32" ? "kxm.cmd" : "kxm"))) return dir;
49976
+ if (existsSync42(join52(dir, process.platform === "win32" ? "kxm.cmd" : "kxm"))) return dir;
49887
49977
  }
49888
49978
  const pathEnv = env.PATH ?? "";
49889
49979
  for (const part of pathEnv.split(delimiter)) {
49890
49980
  if (!part) continue;
49891
49981
  const candidate = resolve32(part, process.platform === "win32" ? "kxm.cmd" : "kxm");
49892
- if (existsSync41(candidate)) return resolve32(part);
49982
+ if (existsSync42(candidate)) return resolve32(part);
49893
49983
  }
49894
49984
  return void 0;
49895
49985
  }
@@ -49907,7 +49997,7 @@ function installPathEntry(shellInput, options = {}) {
49907
49997
  }
49908
49998
  const { rcFile } = completionRcTarget(shell, options);
49909
49999
  const line = pathLine(binDir);
49910
- const rcContent = existsSync41(rcFile ?? "") ? readFileSync39(rcFile, "utf8") : "";
50000
+ const rcContent = existsSync42(rcFile ?? "") ? readFileSync39(rcFile, "utf8") : "";
49911
50001
  const alreadyInstalled = rcContent.includes(binDir) || (options.env?.PATH ?? process.env.PATH ?? "").split(delimiter).includes(binDir);
49912
50002
  if (!options.dryRun && rcFile && !alreadyInstalled) {
49913
50003
  mkdirSync31(dirname24(rcFile), { recursive: true });
@@ -49922,8 +50012,8 @@ ${line}
49922
50012
  // plugins/kxm/src/init-guide-setup.ts
49923
50013
  var import_yaml18 = __toESM(require_dist(), 1);
49924
50014
  init_routes();
49925
- import { existsSync as existsSync42, mkdirSync as mkdirSync32, writeFileSync as writeFileSync28 } from "node:fs";
49926
- import { dirname as dirname25, join as join52 } from "node:path";
50015
+ import { existsSync as existsSync43, mkdirSync as mkdirSync32, writeFileSync as writeFileSync28 } from "node:fs";
50016
+ import { dirname as dirname25, join as join53 } from "node:path";
49927
50017
  var ADMITTED_GUIDE_BINDINGS = Object.freeze({
49928
50018
  "anthropic/claude-fable-5.1": { harness: "claude", provider: "anthropic", model: "fable" },
49929
50019
  "anthropic/fable": { harness: "claude", provider: "anthropic", model: "fable" },
@@ -50314,13 +50404,13 @@ function renderGuideSetupFiles(projectRoot, plan) {
50314
50404
  const stage = roleStages.get(role);
50315
50405
  if (!stage) continue;
50316
50406
  files.push({
50317
- path: join52(projectRoot, ".kxm", "agents", `${role}.yaml`),
50407
+ path: join53(projectRoot, ".kxm", "agents", `${role}.yaml`),
50318
50408
  content: (0, import_yaml18.stringify)(agentDocument(role, stage, binding))
50319
50409
  });
50320
50410
  }
50321
50411
  for (const workflow of plan.workflows) {
50322
50412
  files.push({
50323
- path: join52(projectRoot, ".kxm", "workflows", `${workflow.slug}.yaml`),
50413
+ path: join53(projectRoot, ".kxm", "workflows", `${workflow.slug}.yaml`),
50324
50414
  content: (0, import_yaml18.stringify)(workflowDocument(workflow))
50325
50415
  });
50326
50416
  }
@@ -50337,7 +50427,7 @@ function mergeGuideRouteAdmission(projectRoot, plan) {
50337
50427
  }
50338
50428
  if (added.length === 0) return added;
50339
50429
  policy.updatedAt = (/* @__PURE__ */ new Date()).toISOString();
50340
- const path4 = join52(projectRoot, ".kxm", "routes.yaml");
50430
+ const path4 = join53(projectRoot, ".kxm", "routes.yaml");
50341
50431
  mkdirSync32(dirname25(path4), { recursive: true });
50342
50432
  writeFileSync28(path4, (0, import_yaml18.stringify)(policy), "utf8");
50343
50433
  return added;
@@ -50346,7 +50436,7 @@ function writeGuideSetupFiles(files) {
50346
50436
  const written = [];
50347
50437
  const existed = [];
50348
50438
  for (const file of files) {
50349
- if (existsSync42(file.path)) {
50439
+ if (existsSync43(file.path)) {
50350
50440
  existed.push(file.path);
50351
50441
  continue;
50352
50442
  }
@@ -50417,7 +50507,7 @@ function applyKxmPackageUpdate(runtime, notice) {
50417
50507
  detail: `release v${notice.latest} has no sha256 digest for ${name}; refusing to install`
50418
50508
  };
50419
50509
  }
50420
- const releaseDir = mkdtempSync3(join53(tmpdir2(), "kxm-pkg-update-"));
50510
+ const releaseDir = mkdtempSync3(join54(tmpdir2(), "kxm-pkg-update-"));
50421
50511
  try {
50422
50512
  const planned = planKxmPackageUpdate(notice.source, notice.latest, releaseDir, notice.asset);
50423
50513
  if (runtime.dryRun) {
@@ -50426,7 +50516,7 @@ function applyKxmPackageUpdate(runtime, notice) {
50426
50516
  for (const step of planned) {
50427
50517
  if (step.kind === "verify") {
50428
50518
  if (!verifyReleaseAssetDigest(step.path, step.sha256)) {
50429
- const actual = existsSync43(step.path) ? createHash17("sha256").update(readFileSync40(step.path)).digest("hex") : "missing";
50519
+ const actual = existsSync44(step.path) ? createHash17("sha256").update(readFileSync40(step.path)).digest("hex") : "missing";
50430
50520
  return {
50431
50521
  ok: false,
50432
50522
  error: "release_digest_mismatch",
@@ -50704,7 +50794,7 @@ async function cmdValidate(runtime, fileFlag) {
50704
50794
  }
50705
50795
  const selectedFile = explicitFile || configuredFile;
50706
50796
  const file = selectedFile ? resolve33(runtime.cwd, selectedFile) : void 0;
50707
- if (file && !existsSync43(file)) {
50797
+ if (file && !existsSync44(file)) {
50708
50798
  printWorker(runtime, worker, { ok: false, command: "validate", error: "file_not_found", file }, `workflow file not found: ${file}`);
50709
50799
  return 1;
50710
50800
  }
@@ -50804,7 +50894,7 @@ async function cmdImprove(runtime, options = {}) {
50804
50894
  print(runtime.io, runtime.json, { ok: false, command: "improve", error: "config_invalid", detail: message }, `config_invalid: ${message}`);
50805
50895
  return 1;
50806
50896
  }
50807
- const candidatesDir = options.outDir ? resolve33(runtime.cwd, options.outDir) : join53(root, ".kxm", "candidates");
50897
+ const candidatesDir = options.outDir ? resolve33(runtime.cwd, options.outDir) : join54(root, ".kxm", "candidates");
50808
50898
  const report2 = buildImprovementReport(loaded.records, {
50809
50899
  candidatesDir,
50810
50900
  projectRoot: root,
@@ -50813,7 +50903,7 @@ async function cmdImprove(runtime, options = {}) {
50813
50903
  autoThreshold: config.improvement.autoThreshold,
50814
50904
  halfLifeDays: config.improvement.telemetryHalfLifeDays
50815
50905
  });
50816
- const reportDir = join53(runtime.dirs.assets, "improvements");
50906
+ const reportDir = join54(runtime.dirs.assets, "improvements");
50817
50907
  const reportPath = writeImprovementReport(reportDir, report2, runtime.dryRun);
50818
50908
  const text = [
50819
50909
  "Sources:",
@@ -50957,7 +51047,7 @@ async function maybeOfferCompletionInstall(runtime) {
50957
51047
  if (!pathNeeded) {
50958
51048
  const scriptPath = completionScriptPath(shell, { env: runtime.env, configDir: runtime.env.KXM_USER_CONFIG_DIR });
50959
51049
  const { rcFile } = completionRcTarget(shell, { env: runtime.env });
50960
- if (rcFile && existsSync43(rcFile)) {
51050
+ if (rcFile && existsSync44(rcFile)) {
50961
51051
  try {
50962
51052
  if (readFileSync40(rcFile, "utf8").includes(scriptPath)) return;
50963
51053
  } catch {
@@ -51122,7 +51212,7 @@ async function cmdRoutingReport(runtime, options) {
51122
51212
  let catalog;
51123
51213
  if (includeEquivalentListCost) {
51124
51214
  try {
51125
- const pricesPath = options.prices ? resolve33(runtime.cwd, options.prices) : join53(runtime.dirs.workspace, "prices.yaml");
51215
+ const pricesPath = options.prices ? resolve33(runtime.cwd, options.prices) : join54(runtime.dirs.workspace, "prices.yaml");
51126
51216
  catalog = loadPriceCatalog(pricesPath);
51127
51217
  } catch {
51128
51218
  }
@@ -51343,7 +51433,9 @@ var DRY_RUN_COMMANDS = /* @__PURE__ */ new Set([
51343
51433
  "task run",
51344
51434
  "task sync",
51345
51435
  "studio layout",
51346
- "studio serve"
51436
+ "studio serve",
51437
+ "docs build",
51438
+ "docs serve"
51347
51439
  ]);
51348
51440
  var DryRunRefused = class extends Error {
51349
51441
  code;
@@ -51623,6 +51715,14 @@ function createProgram(ctx, result) {
51623
51715
  addGlobalOptions(runCmd.command("list").description("List recent runs for the current project")).action(async function runListAction() {
51624
51716
  result.code = await cmdKxmRunList(runtimeFrom(ctx, this));
51625
51717
  });
51718
+ const docsCmd = addGlobalOptions(program2.command("docs").description("Build and serve the tailnet docs site"));
51719
+ docsCmd.helpCommand("help", "Show docs help");
51720
+ addGlobalOptions(docsCmd.command("build").description("Regenerate the docs site from the roadmap state")).action(async function docsBuildAction() {
51721
+ result.code = await cmdDocsBuild(runtimeFrom(ctx, this));
51722
+ });
51723
+ 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) {
51724
+ result.code = await cmdDocsServe(runtimeFrom(ctx, this), options);
51725
+ });
51626
51726
  const tenantCmd = addGlobalOptions(program2.command("tenant").description("Composed tenant reads for machine clients (portal)"));
51627
51727
  tenantCmd.helpCommand("help", "Show tenant help");
51628
51728
  addGlobalOptions(tenantCmd.command("status").description("Read hub metadata and authoritative Runtime run state as one labeled view")).action(async function tenantStatusAction() {