@kontextmind/kxm 0.7.115 → 0.7.118

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.
@@ -0,0 +1,104 @@
1
+ /**
2
+ * Role Subscription Budget Limits & Rollover Engine.
3
+ *
4
+ * Tracks per-role subscription quotas, metered run spend caps,
5
+ * and executes rollover cascades when limits are exhausted.
6
+ */
7
+
8
+ export interface RoleBudgetConfig {
9
+ readonly roleId: string;
10
+ readonly type: "subscription" | "metered" | "hybrid";
11
+ readonly runSpendCapUsd?: number | undefined;
12
+ readonly monthlySpendCapUsd?: number | undefined;
13
+ readonly monthlyTokenQuota?: number | undefined;
14
+ readonly rolloverPercent?: number | undefined; // 0 - 100
15
+ readonly onExhausted: "cascade_to_roster" | "borrow_from_pool" | "pause_for_approval" | "fail_closed";
16
+ readonly fallbackModel?: string | undefined;
17
+ readonly fallbackHarness?: string | undefined;
18
+ readonly emergencyPoolLimitUsd?: number | undefined;
19
+ }
20
+
21
+ export interface RoleBudgetState {
22
+ readonly roleId: string;
23
+ readonly currentRunSpendUsd: number;
24
+ readonly currentMonthlySpendUsd: number;
25
+ readonly usedTokens: number;
26
+ readonly rolledOverTokens: number;
27
+ readonly borrowedFromPoolUsd: number;
28
+ }
29
+
30
+ export interface BudgetEvaluationResult {
31
+ readonly status: "ok" | "near_limit" | "exhausted";
32
+ readonly nextAction: "proceed" | "cascade" | "borrow" | "pause" | "fail_closed";
33
+ readonly fallbackModel?: string | undefined;
34
+ readonly fallbackHarness?: string | undefined;
35
+ readonly warning?: string | undefined;
36
+ }
37
+
38
+ /**
39
+ * Evaluate if a role execution can proceed under its budget caps or needs rollover.
40
+ */
41
+ export function evaluateRoleBudget(
42
+ config: RoleBudgetConfig,
43
+ state: RoleBudgetState,
44
+ projectedCostUsd = 0,
45
+ ): BudgetEvaluationResult {
46
+ const projectedRunSpend = state.currentRunSpendUsd + projectedCostUsd;
47
+
48
+ // 1. Check run spend cap
49
+ if (config.runSpendCapUsd !== undefined && projectedRunSpend > config.runSpendCapUsd) {
50
+ if (config.onExhausted === "cascade_to_roster" && config.fallbackModel) {
51
+ return {
52
+ status: "exhausted",
53
+ nextAction: "cascade",
54
+ fallbackModel: config.fallbackModel,
55
+ fallbackHarness: config.fallbackHarness ?? "pi",
56
+ warning: `Role "${config.roleId}" reached run spend cap ($${config.runSpendCapUsd.toFixed(2)}); rolling over to ${config.fallbackModel}`,
57
+ };
58
+ }
59
+ if (config.onExhausted === "borrow_from_pool" && (config.emergencyPoolLimitUsd ?? 0) > state.borrowedFromPoolUsd) {
60
+ return {
61
+ status: "exhausted",
62
+ nextAction: "borrow",
63
+ warning: `Role "${config.roleId}" borrowing from project emergency buffer`,
64
+ };
65
+ }
66
+ return {
67
+ status: "exhausted",
68
+ nextAction: config.onExhausted === "pause_for_approval" ? "pause" : "fail_closed",
69
+ warning: `Role "${config.roleId}" exhausted run spend cap ($${config.runSpendCapUsd.toFixed(2)})`,
70
+ };
71
+ }
72
+
73
+ // 2. Check monthly spend cap
74
+ if (config.monthlySpendCapUsd !== undefined && (state.currentMonthlySpendUsd + projectedCostUsd) > config.monthlySpendCapUsd) {
75
+ if (config.onExhausted === "cascade_to_roster" && config.fallbackModel) {
76
+ return {
77
+ status: "exhausted",
78
+ nextAction: "cascade",
79
+ fallbackModel: config.fallbackModel,
80
+ fallbackHarness: config.fallbackHarness ?? "pi",
81
+ warning: `Role "${config.roleId}" reached monthly budget limit ($${config.monthlySpendCapUsd.toFixed(2)})`,
82
+ };
83
+ }
84
+ return {
85
+ status: "exhausted",
86
+ nextAction: "pause",
87
+ warning: `Role "${config.roleId}" reached monthly budget cap ($${config.monthlySpendCapUsd.toFixed(2)})`,
88
+ };
89
+ }
90
+
91
+ // 3. Near limit alert (>= 85% of budget)
92
+ if (config.runSpendCapUsd && (projectedRunSpend / config.runSpendCapUsd) >= 0.85) {
93
+ return {
94
+ status: "near_limit",
95
+ nextAction: "proceed",
96
+ warning: `Role "${config.roleId}" is at ${Math.round((projectedRunSpend / config.runSpendCapUsd) * 100)}% of run budget`,
97
+ };
98
+ }
99
+
100
+ return {
101
+ status: "ok",
102
+ nextAction: "proceed",
103
+ };
104
+ }
@@ -2,7 +2,7 @@
2
2
  "$schema": "https://json.schemastore.org/claude-code-plugin-manifest.json",
3
3
  "name": "kxm",
4
4
  "displayName": "KXM",
5
- "version": "0.7.115",
5
+ "version": "0.7.118",
6
6
  "description": "Headless multi-agent orchestration, durable workflows, and a live operator dashboard for Pi and Claude Code",
7
7
  "author": {
8
8
  "name": "KontextMind",
@@ -21777,6 +21777,7 @@ var READ_ONLY_ONESHOT_ARGS = Object.freeze({
21777
21777
  // AGENTS.md/CLAUDE.md context discovery, and an ephemeral session. `--no-tools` alone
21778
21778
  // is not enough: extensions and hooks can still run with their own permissions.
21779
21779
  pi: Object.freeze(["--no-tools", "--no-extensions", "--no-skills", "--no-prompt-templates", "--no-context-files", "--no-session"]),
21780
+ omp: Object.freeze(["--no-tools", "--no-extensions", "--no-skills", "--no-prompt-templates", "--no-context-files", "--no-session"]),
21780
21781
  claude: Object.freeze(["--tools", "Read,Glob,Grep", "--restricted", "--safe-mode", "--permission-mode", "plan", "--permission-prompts", "none", "--strict-mcp-config", "--mcp-config", '{"mcpServers":{}}', "--disable-slash-commands", "--no-session-persistence"]),
21781
21782
  codex: Object.freeze(["--sandbox", "read-only", "--ignore-user-config", "-c", 'approval_policy="never"']),
21782
21783
  grok: Object.freeze(["--sandbox", "read-only", "--permission-mode", "plan", "--tools", "Read,Glob,Grep", "--no-subagents", "--disable-web-search"]),
@@ -21788,6 +21789,7 @@ function oneShotReadOnlyArgs(harness) {
21788
21789
  }
21789
21790
  var WRITER_ONESHOT_ARGS = Object.freeze({
21790
21791
  pi: Object.freeze(["-a", "--no-extensions", "--no-skills", "--no-prompt-templates", "--no-session"]),
21792
+ omp: Object.freeze(["-a", "--no-extensions", "--no-skills", "--no-prompt-templates", "--no-session"]),
21791
21793
  grok: Object.freeze(["--always-approve", "--no-subagents", "--disable-web-search"])
21792
21794
  });
21793
21795
  function oneShotWriterArgs(harness) {
@@ -21816,6 +21818,26 @@ var BUILTIN_HARNESSES = Object.freeze([
21816
21818
  usageParser: parsePiOneShotUsage
21817
21819
  }
21818
21820
  },
21821
+ {
21822
+ id: "omp",
21823
+ label: "Oh My Pi",
21824
+ default: false,
21825
+ mode: "headless",
21826
+ commands: ["omp"],
21827
+ versionArgs: ["--version"],
21828
+ authArgs: ["models", "--json"],
21829
+ update: {
21830
+ self: ["update"],
21831
+ extensions: ["plugin", "upgrade"],
21832
+ models: ["models", "refresh"]
21833
+ },
21834
+ oneShot: {
21835
+ argv: ["-p", ...oneShotReadOnlyArgs("omp"), "--mode", "json"],
21836
+ promptVia: "arg",
21837
+ outputFormat: "json",
21838
+ usageParser: parsePiOneShotUsage
21839
+ }
21840
+ },
21819
21841
  {
21820
21842
  id: "claude",
21821
21843
  label: "Claude Code",
@@ -22069,6 +22091,16 @@ function interpretAuth(id, result) {
22069
22091
  if (commandSucceeded(result) && lines.some((line) => line === GROK_LOGIN_LINE)) return { authenticated: true, issues: [] };
22070
22092
  return { authenticated: null, issues: ["auth_unparsed"] };
22071
22093
  }
22094
+ if (id === "omp") {
22095
+ if (commandSucceeded(result)) {
22096
+ const payload = parseJsonObject(result.stdout);
22097
+ if (payload && Array.isArray(payload.models) && payload.models.length > 0) {
22098
+ return { authenticated: true, issues: [] };
22099
+ }
22100
+ if (commandSucceeded(result)) return { authenticated: true, issues: [] };
22101
+ }
22102
+ return { authenticated: null, issues: ["auth_unparsed"] };
22103
+ }
22072
22104
  if (id === "agy") {
22073
22105
  const text = `${result.stdout}
22074
22106
  ${result.stderr}`;
@@ -22278,7 +22310,7 @@ function validateHarnessModelPair(harnessId, modelSpec) {
22278
22310
  }
22279
22311
  return { valid: true };
22280
22312
  }
22281
- if (harnessId === "pi") {
22313
+ if (harnessId === "pi" || harnessId === "omp") {
22282
22314
  if (!provider && model?.includes("/")) {
22283
22315
  const idx = model.indexOf("/");
22284
22316
  provider = model.slice(0, idx).toLowerCase();
@@ -22287,17 +22319,17 @@ function validateHarnessModelPair(harnessId, modelSpec) {
22287
22319
  if (!provider) return { valid: true };
22288
22320
  const blocked = (message) => ({ valid: false, issue: "pi_native_impersonation_blocked", message });
22289
22321
  if (PI_NATIVE_BRAKE_PROVIDERS.includes(provider)) {
22290
- return blocked(`pi must not impersonate native provider ${provider}; use the native harness`);
22322
+ return blocked(`${harnessId} must not impersonate native provider ${provider}; use the native harness`);
22291
22323
  }
22292
22324
  if (provider === "antigravity" && model && PI_ANTIGRAVITY_MODEL_ID.test(model)) return { valid: true };
22293
22325
  const owned = Object.hasOwn(PI_VENDOR_OWNED_PROVIDERS, provider) ? PI_VENDOR_OWNED_PROVIDERS[provider] : void 0;
22294
22326
  if (owned) {
22295
- return blocked(`pi provider ${provider} bills native vendor ${owned} for ${model ?? "this model"}; use the native harness`);
22327
+ return blocked(`${harnessId} provider ${provider} bills native vendor ${owned} for ${model ?? "this model"}; use the native harness`);
22296
22328
  }
22297
22329
  const segment = model?.includes("/") ? model.slice(0, model.indexOf("/")).toLowerCase() : void 0;
22298
22330
  const vendor = segment && Object.hasOwn(PI_VENDOR_SEGMENT_ALIASES, segment) ? PI_VENDOR_SEGMENT_ALIASES[segment] : segment;
22299
22331
  if (vendor && PI_NATIVE_BRAKE_PROVIDERS.includes(vendor)) {
22300
- return blocked(`pi must not bill native vendor ${vendor} through ${provider}; use the native harness`);
22332
+ return blocked(`${harnessId} must not bill native vendor ${vendor} through ${provider}; use the native harness`);
22301
22333
  }
22302
22334
  return { valid: true };
22303
22335
  }
@@ -35863,6 +35895,162 @@ ${lines.join("\n")}`
35863
35895
  }
35864
35896
  }
35865
35897
 
35898
+ // plugins/kxm/src/cli/plugins.ts
35899
+ import { spawnSync as spawnSync5 } from "node:child_process";
35900
+ var PLUGIN_SUPPORTED_HARNESSES = Object.freeze(["pi", "omp", "claude"]);
35901
+ async function cmdPluginInstall(runtime, options) {
35902
+ const repoRoot = findKxmRepoRoot(import.meta.url);
35903
+ const env = runtime.env.PATH ? runtime.env : { ...process.env, ...runtime.env };
35904
+ const inventory = probeHarnesses({ env });
35905
+ const isExplicit = Boolean(options.claude || options.omp || options.pi);
35906
+ const requestedHarnesses = [];
35907
+ if (options.pi) requestedHarnesses.push("pi");
35908
+ if (options.omp) requestedHarnesses.push("omp");
35909
+ if (options.claude) requestedHarnesses.push("claude");
35910
+ const targetHarnesses = isExplicit ? requestedHarnesses : PLUGIN_SUPPORTED_HARNESSES;
35911
+ const results = [];
35912
+ for (const harnessId of targetHarnesses) {
35913
+ const status = inventory.harnesses.find((h) => h.id === harnessId);
35914
+ const detected = Boolean(status?.detected && status?.command);
35915
+ if (!detected) {
35916
+ if (isExplicit) {
35917
+ results.push({
35918
+ harness: harnessId,
35919
+ status: "failed",
35920
+ error: "harness_not_detected",
35921
+ detail: `${harnessId} harness is not installed or not found on PATH`
35922
+ });
35923
+ }
35924
+ continue;
35925
+ }
35926
+ const command = status.command;
35927
+ if (harnessId === "pi") {
35928
+ const args = ["install", repoRoot, "-a"];
35929
+ if (runtime.dryRun) {
35930
+ results.push({
35931
+ harness: "pi",
35932
+ status: "would",
35933
+ command,
35934
+ args,
35935
+ detail: `would install kxm plugin into pi: ${command} ${args.join(" ")}`
35936
+ });
35937
+ } else {
35938
+ const run = runtime.io.spawnSync ? runtime.io.spawnSync(command, args) : spawnSync5(command, args, { encoding: "utf8", windowsHide: true, env: runtime.env });
35939
+ if (run.error || run.status !== 0 && run.status !== null) {
35940
+ results.push({
35941
+ harness: "pi",
35942
+ status: "failed",
35943
+ command,
35944
+ args,
35945
+ error: run.error?.message || "install_failed",
35946
+ detail: (run.stderr || run.stdout || "pi install exited with error").trim()
35947
+ });
35948
+ } else {
35949
+ results.push({
35950
+ harness: "pi",
35951
+ status: "passed",
35952
+ command,
35953
+ args,
35954
+ detail: "installed kxm plugin into pi"
35955
+ });
35956
+ }
35957
+ }
35958
+ } else if (harnessId === "omp") {
35959
+ const args = ["plugin", "install", repoRoot];
35960
+ if (runtime.dryRun) {
35961
+ results.push({
35962
+ harness: "omp",
35963
+ status: "would",
35964
+ command,
35965
+ args,
35966
+ detail: `would install kxm plugin into omp: ${command} ${args.join(" ")}`
35967
+ });
35968
+ } else {
35969
+ const run = runtime.io.spawnSync ? runtime.io.spawnSync(command, args) : spawnSync5(command, args, { encoding: "utf8", windowsHide: true, env: runtime.env });
35970
+ if (run.error || run.status !== 0 && run.status !== null) {
35971
+ results.push({
35972
+ harness: "omp",
35973
+ status: "failed",
35974
+ command,
35975
+ args,
35976
+ error: run.error?.message || "install_failed",
35977
+ detail: (run.stderr || run.stdout || "omp plugin install exited with error").trim()
35978
+ });
35979
+ } else {
35980
+ results.push({
35981
+ harness: "omp",
35982
+ status: "passed",
35983
+ command,
35984
+ args,
35985
+ detail: "installed kxm plugin into omp"
35986
+ });
35987
+ }
35988
+ }
35989
+ } else if (harnessId === "claude") {
35990
+ const marketplaceArgs = ["plugin", "marketplace", "add", repoRoot];
35991
+ const installArgs = ["plugin", "install", "kxm", "-y"];
35992
+ if (runtime.dryRun) {
35993
+ results.push({
35994
+ harness: "claude",
35995
+ status: "would",
35996
+ command,
35997
+ args: installArgs,
35998
+ detail: `would add marketplace and install kxm plugin into claude: ${command} ${installArgs.join(" ")}`
35999
+ });
36000
+ } else {
36001
+ if (runtime.io.spawnSync) {
36002
+ runtime.io.spawnSync(command, marketplaceArgs);
36003
+ } else {
36004
+ spawnSync5(command, marketplaceArgs, { encoding: "utf8", windowsHide: true, env: runtime.env });
36005
+ }
36006
+ const run = runtime.io.spawnSync ? runtime.io.spawnSync(command, installArgs) : spawnSync5(command, installArgs, { encoding: "utf8", windowsHide: true, env: runtime.env });
36007
+ if (run.error || run.status !== 0 && run.status !== null) {
36008
+ results.push({
36009
+ harness: "claude",
36010
+ status: "failed",
36011
+ command,
36012
+ args: installArgs,
36013
+ error: run.error?.message || "install_failed",
36014
+ detail: (run.stderr || run.stdout || "claude plugin install exited with error").trim()
36015
+ });
36016
+ } else {
36017
+ results.push({
36018
+ harness: "claude",
36019
+ status: "passed",
36020
+ command,
36021
+ args: installArgs,
36022
+ detail: "installed kxm plugin into claude"
36023
+ });
36024
+ }
36025
+ }
36026
+ }
36027
+ }
36028
+ if (results.length === 0) {
36029
+ const errorMsg = "no supported harnesses (pi, omp, claude) detected on PATH";
36030
+ print(
36031
+ runtime.io,
36032
+ runtime.json,
36033
+ { ok: false, command: "plugin install", error: "no_harnesses_detected", results: [] },
36034
+ errorMsg
36035
+ );
36036
+ return 1;
36037
+ }
36038
+ const ok = results.every((r) => r.status === "passed" || r.status === "would");
36039
+ const summary = results.map((r) => `${r.harness}: ${r.status}${r.detail ? ` (${r.detail})` : ""}`).join("\n");
36040
+ print(
36041
+ runtime.io,
36042
+ runtime.json,
36043
+ {
36044
+ ok,
36045
+ command: "plugin install",
36046
+ ...runtime.dryRun ? { dryRun: true } : {},
36047
+ results
36048
+ },
36049
+ summary
36050
+ );
36051
+ return ok ? 0 : 1;
36052
+ }
36053
+
35866
36054
  // plugins/kxm/src/cli/hub.ts
35867
36055
  import { randomUUID as randomUUID13 } from "node:crypto";
35868
36056
  import { existsSync as existsSync34, mkdirSync as mkdirSync27, readFileSync as readFileSync34, readdirSync as readdirSync12, rmSync as rmSync11, writeFileSync as writeFileSync24 } from "node:fs";
@@ -44306,7 +44494,7 @@ var MAX_RENDER_WRITE_CHARS = 1024 * 1024;
44306
44494
  // plugins/kxm/src/tui.ts
44307
44495
  import { mkdirSync as mkdirSync24 } from "node:fs";
44308
44496
  import { join as join39, resolve as resolve26, dirname as dirname19 } from "node:path";
44309
- import { spawnSync as spawnSync5 } from "node:child_process";
44497
+ import { spawnSync as spawnSync6 } from "node:child_process";
44310
44498
 
44311
44499
  // packages/core/tui/src/types/surface.ts
44312
44500
  var KXM_TUI_LIMITS = Object.freeze({
@@ -44860,16 +45048,16 @@ function applyMeshTuiKey(view, key, itemCount = 0) {
44860
45048
  function copyToClipboard(text) {
44861
45049
  try {
44862
45050
  if (process.platform === "darwin") {
44863
- const proc = spawnSync5("pbcopy", { input: text, encoding: "utf8", windowsHide: true });
45051
+ const proc = spawnSync6("pbcopy", { input: text, encoding: "utf8", windowsHide: true });
44864
45052
  return proc.status === 0;
44865
45053
  }
44866
45054
  if (process.platform === "win32") {
44867
- const proc = spawnSync5("clip", { input: text, encoding: "utf8", windowsHide: true });
45055
+ const proc = spawnSync6("clip", { input: text, encoding: "utf8", windowsHide: true });
44868
45056
  return proc.status === 0;
44869
45057
  }
44870
- const wl = spawnSync5("wl-copy", [text], { encoding: "utf8", windowsHide: true });
45058
+ const wl = spawnSync6("wl-copy", [text], { encoding: "utf8", windowsHide: true });
44871
45059
  if (wl.status === 0) return true;
44872
- const xclip = spawnSync5("xclip", ["-selection", "clipboard"], { input: text, encoding: "utf8", windowsHide: true });
45060
+ const xclip = spawnSync6("xclip", ["-selection", "clipboard"], { input: text, encoding: "utf8", windowsHide: true });
44873
45061
  return xclip.status === 0;
44874
45062
  } catch {
44875
45063
  return false;
@@ -44877,7 +45065,7 @@ function copyToClipboard(text) {
44877
45065
  }
44878
45066
  function spawnDegradeWorktree(repoRoot, runId, options) {
44879
45067
  const runner = options?.execFn ?? ((cmd, args) => {
44880
- const res = spawnSync5(cmd, args, {
45068
+ const res = spawnSync6(cmd, args, {
44881
45069
  cwd: repoRoot,
44882
45070
  encoding: "utf8",
44883
45071
  windowsHide: true,
@@ -45661,7 +45849,7 @@ async function runMeshTui(input) {
45661
45849
  }
45662
45850
 
45663
45851
  // plugins/kxm/src/session-work.ts
45664
- import { spawnSync as spawnSync6 } from "node:child_process";
45852
+ import { spawnSync as spawnSync7 } from "node:child_process";
45665
45853
  import { randomUUID as randomUUID12 } from "node:crypto";
45666
45854
  import { existsSync as existsSync30, mkdirSync as mkdirSync25, readFileSync as readFileSync30, renameSync as renameSync8, writeFileSync as writeFileSync22 } from "node:fs";
45667
45855
  import { join as join40 } from "node:path";
@@ -45720,10 +45908,10 @@ function formatShipLine(ship) {
45720
45908
  }
45721
45909
  function readGitShip(cwd) {
45722
45910
  try {
45723
- const dirty = spawnSync6("git", ["-C", cwd, "status", "--porcelain"], { encoding: "utf8", windowsHide: true });
45911
+ const dirty = spawnSync7("git", ["-C", cwd, "status", "--porcelain"], { encoding: "utf8", windowsHide: true });
45724
45912
  if (dirty.status !== 0) return void 0;
45725
45913
  const isDirty = dirty.stdout.trim().length > 0;
45726
- const upstream = spawnSync6("git", ["-C", cwd, "rev-list", "--count", "@{u}..HEAD"], { encoding: "utf8", windowsHide: true });
45914
+ const upstream = spawnSync7("git", ["-C", cwd, "rev-list", "--count", "@{u}..HEAD"], { encoding: "utf8", windowsHide: true });
45727
45915
  if (upstream.status === 0) {
45728
45916
  return {
45729
45917
  dirty: isDirty,
@@ -45731,9 +45919,9 @@ function readGitShip(cwd) {
45731
45919
  };
45732
45920
  }
45733
45921
  for (const baseRef of ["origin/HEAD", "main", "origin/main", "master", "origin/master"]) {
45734
- const mb = spawnSync6("git", ["-C", cwd, "merge-base", baseRef, "HEAD"], { encoding: "utf8", windowsHide: true });
45922
+ const mb = spawnSync7("git", ["-C", cwd, "merge-base", baseRef, "HEAD"], { encoding: "utf8", windowsHide: true });
45735
45923
  if (mb.status === 0 && mb.stdout.trim()) {
45736
- const count = spawnSync6("git", ["-C", cwd, "rev-list", "--count", `${mb.stdout.trim()}..HEAD`], { encoding: "utf8", windowsHide: true });
45924
+ const count = spawnSync7("git", ["-C", cwd, "rev-list", "--count", `${mb.stdout.trim()}..HEAD`], { encoding: "utf8", windowsHide: true });
45737
45925
  if (count.status === 0) {
45738
45926
  return {
45739
45927
  dirty: isDirty,
@@ -46915,7 +47103,7 @@ async function cmdSessionStart(runtime, options) {
46915
47103
  }
46916
47104
 
46917
47105
  // plugins/kxm/src/cli/system.ts
46918
- import { spawnSync as spawnSync8 } from "node:child_process";
47106
+ import { spawnSync as spawnSync9 } from "node:child_process";
46919
47107
  import { createHash as createHash17 } from "node:crypto";
46920
47108
  import { existsSync as existsSync41, mkdtempSync as mkdtempSync3, readFileSync as readFileSync39, rmSync as rmSync13 } from "node:fs";
46921
47109
  import { tmpdir as tmpdir2 } from "node:os";
@@ -47762,7 +47950,7 @@ ${divider}
47762
47950
  }
47763
47951
 
47764
47952
  // plugins/kxm/src/ssh-remote.ts
47765
- import { spawnSync as spawnSync7 } from "node:child_process";
47953
+ import { spawnSync as spawnSync8 } from "node:child_process";
47766
47954
  import { existsSync as existsSync38, mkdirSync as mkdirSync29, readFileSync as readFileSync37, readdirSync as readdirSync13, rmSync as rmSync12, statSync as statSync5 } from "node:fs";
47767
47955
  import { homedir as homedir8 } from "node:os";
47768
47956
  import { join as join47, resolve as resolve30 } from "node:path";
@@ -47838,7 +48026,7 @@ function parseSshConfig(configPath) {
47838
48026
  return [];
47839
48027
  }
47840
48028
  }
47841
- function resolveSshHostG(host, execFn = spawnSync7) {
48029
+ function resolveSshHostG(host, execFn = spawnSync8) {
47842
48030
  try {
47843
48031
  const result = execFn("ssh", ["-G", host], { encoding: "utf-8" });
47844
48032
  if (result.status !== 0 || !result.stdout) {
@@ -47904,7 +48092,7 @@ function buildSshArgs(options) {
47904
48092
  args.push(options.host);
47905
48093
  return args;
47906
48094
  }
47907
- function checkControlSocket(host, socketDir = DEFAULT_SOCKET_DIR, execFn = spawnSync7) {
48095
+ function checkControlSocket(host, socketDir = DEFAULT_SOCKET_DIR, execFn = spawnSync8) {
47908
48096
  const resolvedDir = ensureSocketDir(socketDir);
47909
48097
  const controlPath = join47(resolvedDir, "%C");
47910
48098
  try {
@@ -47916,7 +48104,7 @@ function checkControlSocket(host, socketDir = DEFAULT_SOCKET_DIR, execFn = spawn
47916
48104
  return false;
47917
48105
  }
47918
48106
  }
47919
- function closeControlSocket(host, socketDir = DEFAULT_SOCKET_DIR, execFn = spawnSync7) {
48107
+ function closeControlSocket(host, socketDir = DEFAULT_SOCKET_DIR, execFn = spawnSync8) {
47920
48108
  const resolvedDir = ensureSocketDir(socketDir);
47921
48109
  const controlPath = join47(resolvedDir, "%C");
47922
48110
  try {
@@ -47930,7 +48118,7 @@ function closeControlSocket(host, socketDir = DEFAULT_SOCKET_DIR, execFn = spawn
47930
48118
  }
47931
48119
  function executeSshRun(params) {
47932
48120
  const startTime = Date.now();
47933
- const execSyncFn = params.execFn ?? spawnSync7;
48121
+ const execSyncFn = params.execFn ?? spawnSync8;
47934
48122
  if (params.action === "info") {
47935
48123
  if (params.host) {
47936
48124
  const hostInfo = resolveSshHostG(params.host, execSyncFn);
@@ -48136,6 +48324,7 @@ var TOP_LEVEL_COMMANDS = [
48136
48324
  "runs",
48137
48325
  "tenant",
48138
48326
  "harness",
48327
+ "plugin",
48139
48328
  "update",
48140
48329
  "runtime",
48141
48330
  "trust",
@@ -48165,6 +48354,7 @@ var SUBCOMMANDS = {
48165
48354
  runs: ["status", "cancel", "list"],
48166
48355
  tenant: ["status"],
48167
48356
  harness: ["list"],
48357
+ plugin: ["install"],
48168
48358
  runtime: ["start", "status", "stop"],
48169
48359
  trust: ["diff", "check"],
48170
48360
  agent: ["worker"],
@@ -48260,6 +48450,7 @@ _kxm() {
48260
48450
  'run:Create a KXM workflow run'
48261
48451
  'runs:Inspect KXM runs'
48262
48452
  'harness:Detect coding-agent harnesses and auth'
48453
+ 'plugin:Install or manage KXM harness plugins'
48263
48454
  'update:Update kxm, harness CLIs, and model catalogs'
48264
48455
  'runtime:Manage the KXM Runtime supervisor'
48265
48456
  'trust:Permission-diff trust review'
@@ -48985,7 +49176,7 @@ function parseGuideSelection(input, catalog = GUIDE_WORKFLOWS) {
48985
49176
  // plugins/kxm/src/cli/system.ts
48986
49177
  function cliSpawn(runtime, command, args, extra) {
48987
49178
  if (runtime.io.spawnSync) return runtime.io.spawnSync(command, args);
48988
- const result = spawnSync8(command, [...args], {
49179
+ const result = spawnSync9(command, [...args], {
48989
49180
  encoding: "utf8",
48990
49181
  windowsHide: true,
48991
49182
  shell: process.platform === "win32",
@@ -49836,6 +50027,8 @@ var DRY_RUN_COMMANDS = /* @__PURE__ */ new Set([
49836
50027
  "dash",
49837
50028
  "completion",
49838
50029
  "completion install",
50030
+ "plugin install",
50031
+ "plugin",
49839
50032
  "runs status",
49840
50033
  "runs drive",
49841
50034
  "runs receipt",
@@ -50169,6 +50362,11 @@ function createProgram(ctx, result) {
50169
50362
  const harnessCmd = addGlobalOptions(program2.command("harness").description("Detect coding-agent harnesses and authentication"));
50170
50363
  harnessCmd.helpCommand("help", "Show harness help");
50171
50364
  addGlobalOptions(harnessCmd.command("list").description("Show installed harnesses, auth, and native updaters")).action(bind(cmdHarnessList));
50365
+ const pluginCmd = addGlobalOptions(program2.command("plugin").description("Install or manage KXM harness plugins"));
50366
+ pluginCmd.helpCommand("help", "Show plugin help");
50367
+ addGlobalOptions(pluginCmd.command("install", { isDefault: true }).description("Install the KXM plugin into discovered or specified harnesses")).option("--all", "Install plugin for all discovered harnesses (default)").option("--claude", "Install plugin for Claude Code").option("--omp", "Install plugin for Oh My Pi (OMP)").option("--pi", "Install plugin for Pi").action(async function pluginInstallAction(options) {
50368
+ result.code = await cmdPluginInstall(runtimeFrom(ctx, this), options);
50369
+ });
50172
50370
  const authCmd = addGlobalOptions(program2.command("auth").description("Manage credentials, tokens, and authorization"));
50173
50371
  authCmd.helpCommand("help", "Show auth help");
50174
50372
  addGlobalOptions(authCmd.command("token").description("Inspect, issue, or clear local disk session tokens")).option("--status", "Check status of the active session token").option("--clear", "Clear persisted disk session token").option("--issue", "Force issuing a fresh session token").action(async function authTokenAction(options) {
@@ -17313,7 +17313,7 @@ function sessionTokenFixHint(policy) {
17313
17313
  }
17314
17314
 
17315
17315
  // plugins/kxm/src/mcp-server.ts
17316
- var VERSION = "0.7.115";
17316
+ var VERSION = "0.7.118";
17317
17317
  var CONFIGURE_PLUGIN = "/plugin configure kxm@kxm";
17318
17318
  var inbox = /* @__PURE__ */ new Map();
17319
17319
  var notifiedInbox = /* @__PURE__ */ new Set();
@@ -15624,6 +15624,7 @@ var READ_ONLY_ONESHOT_ARGS = Object.freeze({
15624
15624
  // AGENTS.md/CLAUDE.md context discovery, and an ephemeral session. `--no-tools` alone
15625
15625
  // is not enough: extensions and hooks can still run with their own permissions.
15626
15626
  pi: Object.freeze(["--no-tools", "--no-extensions", "--no-skills", "--no-prompt-templates", "--no-context-files", "--no-session"]),
15627
+ omp: Object.freeze(["--no-tools", "--no-extensions", "--no-skills", "--no-prompt-templates", "--no-context-files", "--no-session"]),
15627
15628
  claude: Object.freeze(["--tools", "Read,Glob,Grep", "--restricted", "--safe-mode", "--permission-mode", "plan", "--permission-prompts", "none", "--strict-mcp-config", "--mcp-config", '{"mcpServers":{}}', "--disable-slash-commands", "--no-session-persistence"]),
15628
15629
  codex: Object.freeze(["--sandbox", "read-only", "--ignore-user-config", "-c", 'approval_policy="never"']),
15629
15630
  grok: Object.freeze(["--sandbox", "read-only", "--permission-mode", "plan", "--tools", "Read,Glob,Grep", "--no-subagents", "--disable-web-search"]),
@@ -15635,6 +15636,7 @@ function oneShotReadOnlyArgs(harness) {
15635
15636
  }
15636
15637
  var WRITER_ONESHOT_ARGS = Object.freeze({
15637
15638
  pi: Object.freeze(["-a", "--no-extensions", "--no-skills", "--no-prompt-templates", "--no-session"]),
15639
+ omp: Object.freeze(["-a", "--no-extensions", "--no-skills", "--no-prompt-templates", "--no-session"]),
15638
15640
  grok: Object.freeze(["--always-approve", "--no-subagents", "--disable-web-search"])
15639
15641
  });
15640
15642
  function oneShotWriterArgs(harness) {
@@ -15663,6 +15665,26 @@ var BUILTIN_HARNESSES = Object.freeze([
15663
15665
  usageParser: parsePiOneShotUsage
15664
15666
  }
15665
15667
  },
15668
+ {
15669
+ id: "omp",
15670
+ label: "Oh My Pi",
15671
+ default: false,
15672
+ mode: "headless",
15673
+ commands: ["omp"],
15674
+ versionArgs: ["--version"],
15675
+ authArgs: ["models", "--json"],
15676
+ update: {
15677
+ self: ["update"],
15678
+ extensions: ["plugin", "upgrade"],
15679
+ models: ["models", "refresh"]
15680
+ },
15681
+ oneShot: {
15682
+ argv: ["-p", ...oneShotReadOnlyArgs("omp"), "--mode", "json"],
15683
+ promptVia: "arg",
15684
+ outputFormat: "json",
15685
+ usageParser: parsePiOneShotUsage
15686
+ }
15687
+ },
15666
15688
  {
15667
15689
  id: "claude",
15668
15690
  label: "Claude Code",
@@ -15911,6 +15933,16 @@ function interpretAuth(id, result) {
15911
15933
  if (commandSucceeded(result) && lines.some((line) => line === GROK_LOGIN_LINE)) return { authenticated: true, issues: [] };
15912
15934
  return { authenticated: null, issues: ["auth_unparsed"] };
15913
15935
  }
15936
+ if (id === "omp") {
15937
+ if (commandSucceeded(result)) {
15938
+ const payload = parseJsonObject(result.stdout);
15939
+ if (payload && Array.isArray(payload.models) && payload.models.length > 0) {
15940
+ return { authenticated: true, issues: [] };
15941
+ }
15942
+ if (commandSucceeded(result)) return { authenticated: true, issues: [] };
15943
+ }
15944
+ return { authenticated: null, issues: ["auth_unparsed"] };
15945
+ }
15914
15946
  if (id === "agy") {
15915
15947
  const text = `${result.stdout}
15916
15948
  ${result.stderr}`;
@@ -16104,7 +16136,7 @@ function validateHarnessModelPair(harnessId, modelSpec) {
16104
16136
  }
16105
16137
  return { valid: true };
16106
16138
  }
16107
- if (harnessId === "pi") {
16139
+ if (harnessId === "pi" || harnessId === "omp") {
16108
16140
  if (!provider && model?.includes("/")) {
16109
16141
  const idx = model.indexOf("/");
16110
16142
  provider = model.slice(0, idx).toLowerCase();
@@ -16113,17 +16145,17 @@ function validateHarnessModelPair(harnessId, modelSpec) {
16113
16145
  if (!provider) return { valid: true };
16114
16146
  const blocked = (message) => ({ valid: false, issue: "pi_native_impersonation_blocked", message });
16115
16147
  if (PI_NATIVE_BRAKE_PROVIDERS.includes(provider)) {
16116
- return blocked(`pi must not impersonate native provider ${provider}; use the native harness`);
16148
+ return blocked(`${harnessId} must not impersonate native provider ${provider}; use the native harness`);
16117
16149
  }
16118
16150
  if (provider === "antigravity" && model && PI_ANTIGRAVITY_MODEL_ID.test(model)) return { valid: true };
16119
16151
  const owned = Object.hasOwn(PI_VENDOR_OWNED_PROVIDERS, provider) ? PI_VENDOR_OWNED_PROVIDERS[provider] : void 0;
16120
16152
  if (owned) {
16121
- return blocked(`pi provider ${provider} bills native vendor ${owned} for ${model ?? "this model"}; use the native harness`);
16153
+ return blocked(`${harnessId} provider ${provider} bills native vendor ${owned} for ${model ?? "this model"}; use the native harness`);
16122
16154
  }
16123
16155
  const segment = model?.includes("/") ? model.slice(0, model.indexOf("/")).toLowerCase() : void 0;
16124
16156
  const vendor = segment && Object.hasOwn(PI_VENDOR_SEGMENT_ALIASES, segment) ? PI_VENDOR_SEGMENT_ALIASES[segment] : segment;
16125
16157
  if (vendor && PI_NATIVE_BRAKE_PROVIDERS.includes(vendor)) {
16126
- return blocked(`pi must not bill native vendor ${vendor} through ${provider}; use the native harness`);
16158
+ return blocked(`${harnessId} must not bill native vendor ${vendor} through ${provider}; use the native harness`);
16127
16159
  }
16128
16160
  return { valid: true };
16129
16161
  }