@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.
- package/.claude-plugin/marketplace.json +1 -1
- package/package.json +1 -1
- package/packages/core/tui/dist/index.js +478 -0
- package/packages/core/tui/src/adapters/claude.ts +131 -0
- package/packages/core/tui/src/adapters/historyExport.ts +35 -0
- package/packages/core/tui/src/adapters/omp.ts +174 -0
- package/packages/core/tui/src/adapters/pi.ts +34 -0
- package/packages/core/tui/src/exports/index.ts +8 -0
- package/packages/core/tui/src/tui/history.ts +106 -0
- package/packages/core/tui/src/tui/modelSelector.ts +43 -0
- package/packages/core/tui/src/tui/optimizer.ts +154 -0
- package/packages/core/tui/src/tui/queue.ts +90 -0
- package/packages/core/tui/src/tui/roleBudget.ts +104 -0
- package/plugins/kxm/.claude-plugin/plugin.json +1 -1
- package/plugins/kxm/dist/cli.js +220 -22
- package/plugins/kxm/dist/mcp-server.js +1 -1
- package/plugins/kxm/dist/runtime-supervisor.js +36 -4
- package/plugins/kxm/dist/runtime.js +36 -4
- package/plugins/kxm/dist/server.js +22 -0
- package/plugins/kxm/package.json +1 -1
- package/plugins/kxm/skills/kxm-harness-auth/SKILL.md +6 -0
- package/plugins/kxm/src/autocomplete.ts +3 -0
- package/plugins/kxm/src/cli/plugins.ts +201 -0
- package/plugins/kxm/src/cli.ts +14 -0
- package/plugins/kxm/src/harness.ts +36 -4
- package/plugins/kxm/src/mcp-server.ts +1 -1
- package/scripts/demo-overlay.mjs +175 -0
|
@@ -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.
|
|
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",
|
package/plugins/kxm/dist/cli.js
CHANGED
|
@@ -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(
|
|
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(
|
|
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(
|
|
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
|
|
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 =
|
|
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 =
|
|
45055
|
+
const proc = spawnSync6("clip", { input: text, encoding: "utf8", windowsHide: true });
|
|
44868
45056
|
return proc.status === 0;
|
|
44869
45057
|
}
|
|
44870
|
-
const wl =
|
|
45058
|
+
const wl = spawnSync6("wl-copy", [text], { encoding: "utf8", windowsHide: true });
|
|
44871
45059
|
if (wl.status === 0) return true;
|
|
44872
|
-
const xclip =
|
|
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 =
|
|
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
|
|
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 =
|
|
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 =
|
|
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 =
|
|
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 =
|
|
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
|
|
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
|
|
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 =
|
|
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 =
|
|
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 =
|
|
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 ??
|
|
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 =
|
|
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.
|
|
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(
|
|
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(
|
|
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(
|
|
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
|
}
|