@kontextmind/kxm
Version:
KXM local-first multi-agent orchestration and operator dashboard
1,591 lines • 61.2 kB
text/typescript
import { spawnSync } from "node:child_process";
import { existsSync } from "node:fs";
import { win32 as win32Path } from "node:path";
import { defaultSpawn } from "./oneshot-process.ts";
export const DEFAULT_HARNESS = "pi";
export type HarnessMode = "headless" | "either";
export type HarnessUpdateScope = "self" | "extensions" | "models" | "all";
export interface HarnessCommandResult {
ok: boolean;
code: number | null;
stdout: string;
stderr: string;
error?: string;
}
export type OneShotPromptVia = "stdin" | "arg";
export interface OneShotUsage {
tokensIn?: number | null | undefined;
tokensOut?: number | null | undefined;
cacheReadTokens?: number | null | undefined;
cacheWriteTokens?: number | null | undefined;
contextTokens?: number | null | undefined;
costUsd?: number | null | undefined;
}
export interface OneShotParsedOutput {
text: string;
usage?: OneShotUsage | undefined;
outcome?: string | undefined;
effectiveModel?: string | undefined;
isError?: boolean | undefined;
errorMessage?: string | undefined;
}
export interface HarnessOneShotConfig {
argv: readonly string[];
promptVia: OneShotPromptVia;
outputFormat: "json" | "text" | "stream-json" | "jsonl";
usageParser: (stdout: string, stderr: string, requestedModel?: string) => OneShotParsedOutput;
}
export interface HarnessCatalogEntry {
id: string;
label: string;
default: boolean;
mode: HarnessMode;
commands: readonly string[];
versionArgs: readonly string[];
authArgs?: readonly string[];
update: {
self: readonly string[];
extensions?: readonly string[];
models?: readonly string[];
};
oneShot?: HarnessOneShotConfig | undefined;
}
export type HarnessRunCommand = (command: string, args: readonly string[], timeoutMs: number) => HarnessCommandResult;
export type HarnessRunCommandAsync = (command: string, args: readonly string[], timeoutMs: number) => HarnessCommandResult | Promise<HarnessCommandResult>;
export interface HarnessProbeOptions {
defaultHarness?: string | undefined;
env?: NodeJS.ProcessEnv | undefined;
runCommand?: HarnessRunCommand | undefined;
timeoutMs?: number | undefined;
platform?: NodeJS.Platform | undefined;
existsSync?: ((path: string) => boolean) | undefined;
}
export interface AsyncHarnessProbeOptions extends Omit<HarnessProbeOptions, "runCommand"> {
signal?: AbortSignal | undefined;
runCommand?: HarnessRunCommandAsync | undefined;
}
export interface HarnessDispatchStatus {
status: "yes" | "no";
supported: boolean;
reason?: string | undefined;
}
export interface HarnessStatus {
id: string;
label: string;
default: boolean;
mode: HarnessMode;
detected: boolean;
authenticated: boolean | null;
authMethod?: "claude.ai" | "ChatGPT" | "api-key" | "antigravity-oauth" | undefined;
dispatch?: HarnessDispatchStatus | undefined;
command?: string;
version?: string;
canUpdate: { self: boolean; extensions: boolean; models: boolean };
issues: readonly string[];
}
export interface HarnessInventory {
defaultHarness: string;
harnesses: readonly HarnessStatus[];
}
const UNKNOWN_AUTH_HARNESSES = new Set(["deepseek"]);
const GROK_LOGIN_LINE = "You are logged in with grok.com.";
/** Tab-separated `id<TAB>label` rows from the committed `agy models` probe. */
const AGY_MODEL_ROW = /^[a-z0-9]+(?:[._-][a-z0-9]+)+\s+\S/im;
const CODEX_CHATGPT_LINE = "Logged in using ChatGPT";
const CODEX_API_KEY_PREFIX = "Logged in using an API key";
const CODEX_NEGATIVE_LINE = "Not logged in";
/** Providers that have a dedicated native harness rule. */
export const NATIVE_HARNESS_PROVIDERS: Readonly<Record<string, string>> = Object.freeze({
claude: "anthropic",
codex: "openai",
grok: "xai",
agy: "google",
kimi: "moonshot",
deepseek: "deepseek",
});
/** Allowlisted Pi aggregator provider prefixes. */
export const PI_ALLOWED_PROVIDERS: readonly string[] = Object.freeze([
"openrouter",
"nous-portal",
"nous",
"nous-proxy",
]);
/** Vendors with a native harness rule. Pi must not run their models under any provider id. */
export const PI_NATIVE_BRAKE_PROVIDERS: readonly string[] = Object.freeze([
"anthropic",
"openai",
"xai",
"moonshot",
"google",
"deepseek",
]);
/** Pi provider ids that are a braked vendor's own API or subscription under another name. */
const PI_VENDOR_OWNED_PROVIDERS: Readonly<Record<string, string>> = Object.freeze({
"openai-codex": "openai",
moonshotai: "moonshot",
"moonshotai-cn": "moonshot",
"kimi-coding": "moonshot",
"google-vertex": "google",
// Claude subscription via the Agent SDK: experiment-only, never a product route.
"claude-bridge": "anthropic",
// The decided Google route, for Gemini ids only (see PI_ANTIGRAVITY_MODEL_ID).
antigravity: "google",
});
/** Aggregator spellings of braked vendors in `provider/vendor/model` ids (roster policy aliases). */
const PI_VENDOR_SEGMENT_ALIASES: Readonly<Record<string, string>> = Object.freeze({
"x-ai": "xai",
moonshotai: "moonshot",
"google-ai": "google",
});
const PI_ANTIGRAVITY_MODEL_ID = /^gemini-[a-z0-9.-]+$/;
export interface HarnessModelSpec {
provider?: string | undefined;
model?: string | undefined;
}
export interface HarnessModelValidation {
valid: boolean;
issue?: "harness_unknown" | "harness_unhosted_model" | "pi_native_impersonation_blocked";
message?: string;
}
export interface HarnessUpdateStep {
harness: string;
scope: Exclude<HarnessUpdateScope, "all">;
command: string;
args: readonly string[];
outcome: "would" | "passed" | "failed" | "skipped";
code?: number | null;
detail?: string;
}
function reportedModelId(value: unknown): string | undefined {
return typeof value === "string" && /^[a-z0-9][a-z0-9._:/-]{0,199}$/i.test(value) ? value : undefined;
}
export function parseClaudeOneShotUsage(stdout: string, stderr: string, requestedModel?: string): OneShotParsedOutput {
const trimmed = stdout.trim();
if (!trimmed) {
return {
text: "",
isError: true,
errorMessage: stderr.trim() || "empty stdout from claude",
};
}
try {
const payload = JSON.parse(trimmed) as Record<string, unknown>;
const usage = (payload.usage as Record<string, unknown> | undefined) ?? {};
const entries = payload.modelUsage && typeof payload.modelUsage === "object" && !Array.isArray(payload.modelUsage)
? Object.entries(payload.modelUsage as Record<string, unknown>).filter(([, value]) => value && typeof value === "object") : [];
const matches = entries.filter(([model]) => model === requestedModel
|| (requestedModel && (model.startsWith(`${requestedModel}-`) || model.startsWith(`claude-${requestedModel}-`))));
const selected = matches.length === 1 ? matches[0] : entries.length === 1 ? entries[0] : undefined;
const modelUsageDetail = selected?.[1] as Record<string, unknown> | undefined;
const effectiveModel = reportedModelId(payload.model) ?? reportedModelId(selected?.[0]);
// Top-level usage is the attempt total; an auxiliary model is not the task's model.
const tokensIn = (typeof usage.input_tokens === "number" ? usage.input_tokens : undefined)
?? (typeof modelUsageDetail?.inputTokens === "number" ? modelUsageDetail.inputTokens : null);
const tokensOut = (typeof usage.output_tokens === "number" ? usage.output_tokens : undefined)
?? (typeof modelUsageDetail?.outputTokens === "number" ? modelUsageDetail.outputTokens : null);
const cacheReadTokens = (typeof usage.cache_read_input_tokens === "number" ? usage.cache_read_input_tokens : undefined)
?? (typeof modelUsageDetail?.cacheReadInputTokens === "number" ? modelUsageDetail.cacheReadInputTokens : null);
const cacheWriteTokens = (typeof usage.cache_creation_input_tokens === "number" ? usage.cache_creation_input_tokens : undefined)
?? (typeof modelUsageDetail?.cacheCreationInputTokens === "number" ? modelUsageDetail.cacheCreationInputTokens : null);
const costUsd = typeof payload.total_cost_usd === "number"
? payload.total_cost_usd
: (typeof modelUsageDetail?.costUSD === "number" ? modelUsageDetail.costUSD : null);
const isError = Boolean(payload.is_error || payload.error
|| ["error", "aborted", "failed", "max_tokens", "length"].includes(String(payload.stopReason ?? payload.stop_reason ?? "")));
const text = typeof payload.result === "string" ? payload.result : (typeof payload.text === "string" ? payload.text : "");
const errorMessage = isError
? (typeof payload.error === "string"
? payload.error
: (typeof (payload.error as Record<string, unknown> | undefined)?.message === "string"
? ((payload.error as Record<string, unknown>).message as string)
: text))
: undefined;
return {
text,
effectiveModel,
isError,
errorMessage,
usage: {
tokensIn,
tokensOut,
cacheReadTokens,
cacheWriteTokens,
contextTokens: null,
costUsd,
},
};
} catch {
return {
text: trimmed,
isError: true,
errorMessage: "invalid Claude JSON response",
usage: {},
};
}
}
/** Grok's observed one-shot JSON uses the same usage/modelUsage envelope. */
export function parseGrokOneShotUsage(stdout: string, stderr: string, requestedModel?: string): OneShotParsedOutput {
return parseClaudeOneShotUsage(stdout, stderr, requestedModel);
}
export function parseCodexOneShotUsage(stdout: string, stderr: string): OneShotParsedOutput {
const lines = stdout.split(/\r?\n/).map((l) => l.trim()).filter(Boolean);
if (lines.length === 0) {
return {
text: "",
isError: true,
errorMessage: stderr.trim() || "empty stdout from codex",
};
}
const events: Record<string, unknown>[] = [];
for (const line of lines) {
try {
const parsed = JSON.parse(line);
if (parsed && typeof parsed === "object") events.push(parsed as Record<string, unknown>);
} catch {
// non-json line ignored
}
}
const messageTexts: string[] = [];
let usage: Record<string, unknown> | undefined;
let hasError = false;
let errorMessage: string | undefined;
for (const ev of events) {
if (ev.type === "turn.failed" || ev.type === "error") {
hasError = true;
errorMessage = typeof ev.message === "string"
? ev.message
: (typeof (ev.error as Record<string, unknown> | undefined)?.message === "string"
? ((ev.error as Record<string, unknown>).message as string)
: "turn_failed");
}
if (ev.type === "item.completed" && ev.item && typeof ev.item === "object" && (ev.item as Record<string, unknown>).type === "agent_message") {
const t = (ev.item as Record<string, unknown>).text;
if (typeof t === "string") messageTexts.push(t);
}
if (ev.type === "turn.completed" && ev.usage && typeof ev.usage === "object") {
usage = ev.usage as Record<string, unknown>;
}
}
const text = (messageTexts.at(-1) ?? "").trim();
if (!events.some((event) => event.type === "turn.completed") || !text) hasError = true;
const tokensIn = typeof usage?.input_tokens === "number" ? usage.input_tokens : null;
const tokensOut = typeof usage?.output_tokens === "number" ? usage.output_tokens : null;
const cacheReadTokens = typeof usage?.cached_input_tokens === "number" ? usage.cached_input_tokens : null;
const cacheWriteTokens = typeof usage?.cache_write_input_tokens === "number" ? usage.cache_write_input_tokens : null;
return {
text,
isError: hasError,
errorMessage,
usage: {
tokensIn,
tokensOut,
cacheReadTokens,
cacheWriteTokens,
contextTokens: null,
costUsd: null,
},
};
}
/**
* Parse pi's `--mode json` output: one NDJSON event object per line. The reply text is
* the text parts of the final assistant message (`message_end`/`turn_end` carry it
* complete, after the deltas); usage and the effective model ride the same message.
* Anything unparseable falls back to the raw stream so a shape change is visible in the
* recorded text rather than silently empty.
*/
export function parsePiOneShotUsage(stdout: string, _stderr: string): OneShotParsedOutput {
// Select the FINAL assistant message first, then extract every field from that one
// message atomically. Carrying text, usage or model forward from an earlier message
// let a truncated or empty final turn inherit a previous turn's PASS text and usage.
let finalMessage: Record<string, unknown> | undefined;
for (const line of stdout.split("\n")) {
const trimmed = line.trim();
if (!trimmed.startsWith("{")) continue;
try {
const event = JSON.parse(trimmed) as Record<string, unknown>;
if (event.type !== "message_end" && event.type !== "turn_end") continue;
const message = event.message as Record<string, unknown> | undefined;
if (!message || message.role !== "assistant") continue;
finalMessage = message;
} catch {
// skip malformed lines; the stream is append-only and a partial line means truncation
}
}
if (!finalMessage) {
// No assistant message at all: fail closed with empty text. Returning the raw stream
// would hand back thinking deltas or diagnostics as if they were the answer.
return { text: "", isError: true, usage: {} };
}
const content = Array.isArray(finalMessage.content) ? finalMessage.content : [];
const text = content
.map((part) => (part && typeof part === "object" && (part as Record<string, unknown>).type === "text"
? String((part as Record<string, unknown>).text ?? "")
: ""))
.filter((part) => part.length > 0)
.join("\n");
// pi can exit zero on a failed turn; the stop reason is the fact that matters.
// Metadata comes from the selected final message even on a failed turn: usage and
// model are facts about what ran, not claims about the outcome, and dropping them
// turned a real 7/3-token failure into null/null with model "unknown".
const effectiveModel = reportedModelId(finalMessage.model);
const rawUsage = finalMessage.usage as Record<string, unknown> | undefined;
const usage: OneShotUsage = rawUsage && typeof rawUsage === "object"
? {
tokensIn: typeof rawUsage.input === "number" ? rawUsage.input : null,
tokensOut: typeof rawUsage.output === "number" ? rawUsage.output : null,
cacheReadTokens: typeof rawUsage.cacheRead === "number" ? rawUsage.cacheRead : null,
cacheWriteTokens: typeof rawUsage.cacheWrite === "number" ? rawUsage.cacheWrite : null,
contextTokens: null,
costUsd: null,
}
: {};
const stopReason = typeof finalMessage.stopReason === "string" ? finalMessage.stopReason : undefined;
const terminalError = stopReason === "error" || stopReason === "aborted";
if (terminalError || text.length === 0) {
return { text, isError: true, ...(effectiveModel !== undefined ? { effectiveModel } : {}), usage };
}
return { text, ...(effectiveModel !== undefined ? { effectiveModel } : {}), usage };
}
export function parseGenericOneShotUsage(stdout: string, _stderr: string): OneShotParsedOutput {
const trimmed = stdout.trim();
try {
const parsed = JSON.parse(trimmed);
if (parsed && typeof parsed === "object" && !Array.isArray(parsed)) {
const rec = parsed as Record<string, unknown>;
const text = typeof rec.result === "string"
? rec.result
: (typeof rec.text === "string"
? rec.text
: (typeof rec.response === "string" ? rec.response : trimmed));
const u = rec.usage && typeof rec.usage === "object" ? rec.usage as Record<string, unknown> : {};
return { text, effectiveModel: reportedModelId(rec.model), isError: Boolean(rec.is_error || rec.error || rec.success === false), usage: {
tokensIn: typeof u.input_tokens === "number" ? u.input_tokens : null,
tokensOut: typeof u.output_tokens === "number" ? u.output_tokens : null,
cacheReadTokens: typeof u.cache_read_input_tokens === "number" ? u.cache_read_input_tokens : null,
cacheWriteTokens: typeof u.cache_creation_input_tokens === "number" ? u.cache_creation_input_tokens : null,
contextTokens: null,
costUsd: typeof rec.total_cost_usd === "number" ? rec.total_cost_usd : null,
} };
}
} catch {
// not json
}
return { text: trimmed, usage: {} };
}
export function parseKimiOneShotUsage(stdout: string, _stderr: string): OneShotParsedOutput {
const trimmed = stdout.trim();
const assistantTexts: string[] = [];
let isError = false;
let errorMessage: string | undefined;
for (const line of trimmed.split("\n")) {
const lineTrimmed = line.trim();
if (!lineTrimmed) continue;
try {
const parsed = JSON.parse(lineTrimmed);
if (parsed && typeof parsed === "object") {
const rec = parsed as Record<string, unknown>;
if (rec.role === "assistant" && typeof rec.content === "string") {
assistantTexts.push(rec.content);
} else if (rec.role === "error" || rec.type === "error") {
isError = true;
errorMessage = typeof rec.message === "string" ? rec.message : (typeof rec.content === "string" ? rec.content : "kimi_error");
}
}
} catch {
// non-JSON line (e.g. startup banner or markdown)
}
}
const text = assistantTexts.length > 0 ? assistantTexts.join("\n") : trimmed;
return {
text,
isError,
errorMessage,
usage: {
tokensIn: null,
tokensOut: null,
cacheReadTokens: null,
cacheWriteTokens: null,
contextTokens: null,
costUsd: null,
},
};
}
export function parseAgyOneShotUsage(stdout: string, _stderr: string): OneShotParsedOutput {
const trimmed = stdout.trim();
try {
const parsed = JSON.parse(trimmed);
if (parsed && typeof parsed === "object" && !Array.isArray(parsed)) {
const rec = parsed as Record<string, unknown>;
const text = typeof rec.response === "string"
? rec.response
: (typeof rec.result === "string" ? rec.result : trimmed);
const isError = rec.status === "ERROR";
const rawError = rec.error;
const errorMessage = isError
? (typeof rawError === "string"
? rawError
: (typeof (rawError as any)?.message === "string" ? (rawError as any).message : "agy_error"))
: undefined;
const usageRec = rec.usage && typeof rec.usage === "object" ? rec.usage as Record<string, unknown> : {};
const tokensIn = typeof usageRec.input_tokens === "number" ? usageRec.input_tokens : null;
const tokensOut = typeof usageRec.output_tokens === "number" ? usageRec.output_tokens : null;
const cacheReadTokens = typeof usageRec.cache_read_tokens === "number" ? usageRec.cache_read_tokens : null;
const contextTokens = typeof usageRec.total_tokens === "number" ? usageRec.total_tokens : tokensIn;
return {
text,
isError,
errorMessage,
usage: {
tokensIn,
tokensOut,
cacheReadTokens,
cacheWriteTokens: null,
contextTokens,
costUsd: null,
},
};
}
} catch {
// not json
}
return {
text: trimmed,
usage: {
tokensIn: null,
tokensOut: null,
cacheReadTokens: null,
cacheWriteTokens: null,
contextTokens: null,
},
};
}
/** Built-in harnesses. Unknown ids fail closed. Model lists live in `.kxm/models/*.yaml`, not here. */
const READ_ONLY_ONESHOT_ARGS = Object.freeze({
// pi: total containment for a one-shot witness — no tools (built-in, extension and
// custom), no ambient extension/hook discovery, no skills, no prompt templates, no
// AGENTS.md/CLAUDE.md context discovery, and an ephemeral session. `--no-tools` alone
// is not enough: extensions and hooks can still run with their own permissions.
pi: Object.freeze(["--no-tools", "--no-extensions", "--no-skills", "--no-prompt-templates", "--no-context-files", "--no-session"]),
omp: Object.freeze(["--no-tools", "--no-extensions", "--no-skills", "--no-prompt-templates", "--no-context-files", "--no-session"]),
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"]),
codex: Object.freeze(["--sandbox", "read-only", "--ignore-user-config", "-c", 'approval_policy="never"']),
grok: Object.freeze(["--sandbox", "read-only", "--permission-mode", "plan", "--tools", "Read,Glob,Grep", "--no-subagents", "--disable-web-search"]),
agy: Object.freeze(["--mode", "plan", "--sandbox", "--disable-slash-commands"]),
kimi: Object.freeze(["--plan"]),
});
export function oneShotReadOnlyArgs(harness: string): readonly string[] | undefined {
return Object.hasOwn(READ_ONLY_ONESHOT_ARGS, harness) ? READ_ONLY_ONESHOT_ARGS[harness as keyof typeof READ_ONLY_ONESHOT_ARGS] : undefined;
}
/**
* Audited edit profiles. These are a writer containment, not read-only flags
* with the sandbox removed. They match the assignment helper
* (`scripts/harness-run.mjs` `buildArgv` for `permission: "edit"` with hooks
* and skills refused):
*
* - Pi: `-a` auto-approves tools so the process can edit the checkout, while
* extensions, skills, prompt templates, and session persistence stay off.
* `--no-tools` is the read-only profile and is not used here.
* - Grok: `--always-approve` so edits are not an interactive prompt, with
* subagents and web search disabled. Grok has no audited read-only edit
* mix; the read-only one-shot flags stay on the read-only profile.
*
* Claude, Codex, agy, and Kimi stay read-only. A live write step on a harness
* without an entry here hands off instead of spawning unconstrained.
*/
const WRITER_ONESHOT_ARGS = Object.freeze({
pi: Object.freeze(["-a", "--no-extensions", "--no-skills", "--no-prompt-templates", "--no-session"]),
omp: Object.freeze(["-a", "--no-extensions", "--no-skills", "--no-prompt-templates", "--no-session"]),
grok: Object.freeze(["--always-approve", "--no-subagents", "--disable-web-search"]),
});
export function oneShotWriterArgs(harness: string): readonly string[] | undefined {
return Object.hasOwn(WRITER_ONESHOT_ARGS, harness) ? WRITER_ONESHOT_ARGS[harness as keyof typeof WRITER_ONESHOT_ARGS] : undefined;
}
export function oneShotPermissionArgs(harness: string, permission: "read-only" | "edit"): readonly string[] | undefined {
return permission === "edit" ? oneShotWriterArgs(harness) : oneShotReadOnlyArgs(harness);
}
export const BUILTIN_HARNESSES: readonly HarnessCatalogEntry[] = Object.freeze([
{
id: "pi",
label: "Pi",
default: true,
mode: "headless",
commands: ["pi"],
versionArgs: ["--version"],
update: {
self: ["update", "--self"],
extensions: ["update", "--extensions"],
models: ["update", "--models"],
},
oneShot: {
argv: ["-p", "--mode", "json"],
promptVia: "arg",
outputFormat: "json",
usageParser: parsePiOneShotUsage,
},
},
{
id: "omp",
label: "Oh My Pi",
default: false,
mode: "headless",
commands: ["omp"],
versionArgs: ["--version"],
authArgs: ["models", "--json"],
update: {
self: ["update"],
extensions: ["plugin", "upgrade"],
models: ["models", "refresh"],
},
oneShot: {
argv: ["-p", ...oneShotReadOnlyArgs("omp")!, "--mode", "json"],
promptVia: "arg",
outputFormat: "json",
usageParser: parsePiOneShotUsage,
},
},
{
id: "claude",
label: "Claude Code",
default: false,
mode: "either",
commands: ["claude"],
versionArgs: ["--version"],
authArgs: ["auth", "status"],
update: {
self: ["update"],
extensions: ["plugin", "update", "kxm", "-y"],
},
oneShot: {
argv: ["-p", ...oneShotReadOnlyArgs("claude")!, "--output-format", "json"],
promptVia: "stdin",
outputFormat: "json",
usageParser: parseClaudeOneShotUsage,
},
},
{
id: "kimi",
label: "Kimi Code",
default: false,
mode: "either",
commands: ["kimi"],
versionArgs: ["--version"],
authArgs: ["provider", "list"],
update: { self: ["upgrade"] },
oneShot: {
argv: [...oneShotReadOnlyArgs("kimi")!, "--output-format", "stream-json", "-p"],
promptVia: "arg",
outputFormat: "stream-json",
usageParser: parseKimiOneShotUsage,
},
},
{
id: "codex",
label: "Codex",
default: false,
mode: "either",
commands: ["codex"],
versionArgs: ["--version"],
authArgs: ["login", "status"],
update: { self: ["update"] },
oneShot: {
argv: ["exec", ...oneShotReadOnlyArgs("codex")!, "--json", "-"],
promptVia: "stdin",
outputFormat: "json",
usageParser: parseCodexOneShotUsage,
},
},
{
id: "deepseek",
label: "DeepSeek",
default: false,
mode: "either",
commands: ["deepseek"],
versionArgs: ["--version"],
update: { self: ["update"] },
oneShot: {
argv: ["--json"],
promptVia: "stdin",
outputFormat: "json",
usageParser: parseGenericOneShotUsage,
},
},
{
id: "grok",
label: "Grok CLI",
default: false,
mode: "either",
commands: ["grok"],
versionArgs: ["--version"],
authArgs: ["models"],
update: { self: ["update"] },
oneShot: {
argv: [...oneShotReadOnlyArgs("grok")!, "--output-format", "json", "--single"],
promptVia: "arg",
outputFormat: "json",
usageParser: parseGrokOneShotUsage,
},
},
{
id: "agy",
label: "Antigravity CLI",
default: false,
mode: "either",
commands: ["agy"],
versionArgs: ["--version"],
authArgs: ["models"],
update: { self: ["update"] },
oneShot: {
argv: [...oneShotReadOnlyArgs("agy")!, "--output-format", "json", "-p"],
promptVia: "arg",
outputFormat: "json",
usageParser: parseAgyOneShotUsage,
},
},
]);
export const BUILTIN_HARNESS_IDS: readonly string[] = BUILTIN_HARNESSES.map((entry) => entry.id);
export function isKnownHarnessId(id: string, extra: Iterable<string> = []): boolean {
if (BUILTIN_HARNESS_IDS.includes(id)) return true;
for (const candidate of extra) if (candidate === id) return true;
return false;
}
/** Bare catalog command ids only; never a path or shell metacharacter. */
export const SAFE_HARNESS_COMMAND_ID = /^[A-Za-z][A-Za-z0-9_-]*$/;
export function harnessCommandCandidates(
command: string,
platform: NodeJS.Platform = process.platform,
): readonly string[] {
if (platform !== "win32" || !SAFE_HARNESS_COMMAND_ID.test(command)) return [command];
return [command, `${command}.exe`, `${command}.cmd`];
}
export function isWindowsHarnessShim(command: string): boolean {
return /\.(cmd|bat)$/i.test(command.replace(/\\/g, "/").split("/").pop() ?? command);
}
/** Shell only for allowlisted `name.cmd` on win32. Bare ids stay spawn-without-shell. */
export function harnessSpawnUsesShell(command: string, platform: NodeJS.Platform = process.platform): boolean {
if (platform !== "win32") return false;
const base = command.replace(/\\/g, "/").split("/").pop() ?? "";
return /^[A-Za-z][A-Za-z0-9_-]*\.cmd$/i.test(base);
}
/** Allowlisted npm-global inner `.exe`, relative to the directory that contains `name.cmd`. */
export const WIN_NPM_INNER_EXE: Readonly<Record<string, readonly string[]>> = Object.freeze({
claude: Object.freeze(["node_modules", "@anthropic-ai", "claude-code", "bin", "claude.exe"]),
});
export function findWinNpmInnerExe(
cliId: string,
options: {
platform?: NodeJS.Platform | undefined;
pathEnv?: string | undefined;
existsSync?: ((path: string) => boolean) | undefined;
} = {},
): string | undefined {
if ((options.platform ?? process.platform) !== "win32") return undefined;
const segments = WIN_NPM_INNER_EXE[cliId];
if (!segments) return undefined;
const exists = options.existsSync ?? existsSync;
const pathEnv = options.pathEnv ?? process.env.PATH ?? "";
for (const dir of pathEnv.split(";").filter(Boolean)) {
if (!exists(win32Path.join(dir, `${cliId}.cmd`))) continue;
const inner = win32Path.join(dir, ...segments);
if (exists(inner)) return inner;
}
return undefined;
}
function defaultRunner(env: NodeJS.ProcessEnv): HarnessRunCommand {
return (command, args, timeoutMs) => {
try {
const result = spawnSync(command, [...args], {
encoding: "utf8",
timeout: timeoutMs,
windowsHide: true,
env,
shell: harnessSpawnUsesShell(command),
});
if (result.error) {
const code = (result.error as NodeJS.ErrnoException).code;
return { ok: false, code: result.status, stdout: "", stderr: result.stderr?.toString() ?? "", error: code ?? result.error.message };
}
return {
ok: result.status === 0,
code: result.status,
stdout: result.stdout?.toString() ?? "",
stderr: result.stderr?.toString() ?? "",
};
} catch (error) {
return { ok: false, code: null, stdout: "", stderr: "", error: error instanceof Error ? error.message : "spawn_failed" };
}
};
}
function commandResultFromSpawn(result: Awaited<ReturnType<typeof defaultSpawn>>): HarnessCommandResult {
const errno = result.error && "code" in result.error
? (result.error as NodeJS.ErrnoException).code
: undefined;
const error = (typeof errno === "string" && errno ? errno : undefined)
?? result.error?.message
?? (result.observedChildExit !== true ? "auth_probe_exit_unobserved" : undefined);
return {
ok: result.code === 0 && !error,
code: result.code,
stdout: result.stdout,
stderr: result.stderr,
...(error ? { error } : {}),
};
}
function defaultAsyncRunner(env: NodeJS.ProcessEnv, signal?: AbortSignal): HarnessRunCommandAsync {
return async (command, args, timeoutMs) => {
try {
return commandResultFromSpawn(await defaultSpawn(command, args, {
env,
timeoutMs,
signal,
shell: harnessSpawnUsesShell(command),
}));
} catch (error) {
return { ok: false, code: null, stdout: "", stderr: "", error: error instanceof Error ? error.message : "spawn_failed" };
}
};
}
function firstLine(text: string): string | undefined {
const line = text.split(/\r?\n/).map((candidate) => candidate.trim()).find(Boolean);
return line && line.length <= 200 ? line : undefined;
}
function boundText(text: string, max = 4000): string | undefined {
const trimmed = text.trim();
if (!trimmed) return undefined;
return trimmed.length <= max ? trimmed : `${trimmed.slice(0, max)}…`;
}
function authLines(result: HarnessCommandResult): string[] {
return `${result.stdout}\n${result.stderr}`.split(/\r?\n/).map((line) => line.trim()).filter(Boolean);
}
function parseJsonObject(text: string): Record<string, unknown> | undefined {
try {
const value: unknown = JSON.parse(text.trim());
if (value && typeof value === "object" && !Array.isArray(value)) return value as Record<string, unknown>;
} catch {
// Inventory auth is fail-closed unknown, not a dump of the raw body.
}
return undefined;
}
function authConflictIssue(result: HarnessCommandResult): string | undefined {
const fields: string[] = [];
const okTrue = result.ok === true;
const codeZero = result.code === 0;
if (okTrue !== codeZero) fields.push("ok", "code");
if (okTrue && result.error) {
if (!fields.includes("ok")) fields.push("ok");
fields.push("error");
}
return fields.length > 0 ? `auth_conflict:${fields.join(",")}` : undefined;
}
function commandSucceeded(result: HarnessCommandResult): boolean {
return result.ok === true && result.code === 0 && !result.error;
}
function isCodexApiKeyLine(line: string): boolean {
return line === CODEX_API_KEY_PREFIX || line.startsWith(`${CODEX_API_KEY_PREFIX} - `);
}
function interpretAuth(id: string, result: HarnessCommandResult): Pick<HarnessStatus, "authenticated" | "authMethod"> & { issues: string[] } {
const conflict = authConflictIssue(result);
if (conflict) return { authenticated: null, issues: [conflict] };
if (result.error) return { authenticated: null, issues: ["auth_probe_error"] };
const lines = authLines(result);
if (id === "claude") {
const payload = parseJsonObject(result.stdout);
if (payload && payload.loggedIn === false) return { authenticated: false, issues: ["not_authenticated"] };
if (commandSucceeded(result) && payload && payload.loggedIn === true) return {
authenticated: true, issues: [],
...(payload.authMethod === "claude.ai" || payload.authMethod === "api-key" ? { authMethod: payload.authMethod } : {}),
};
return { authenticated: null, issues: ["auth_unparsed"] };
}
if (id === "codex") {
if (lines.some((line) => line === CODEX_NEGATIVE_LINE || line.startsWith(`${CODEX_NEGATIVE_LINE} `))) {
return { authenticated: false, issues: ["not_authenticated"] };
}
if (commandSucceeded(result) && lines.some((line) => line === CODEX_CHATGPT_LINE)) {
return { authenticated: true, authMethod: "ChatGPT", issues: [] };
}
if (commandSucceeded(result) && lines.some((line) => isCodexApiKeyLine(line))) {
return { authenticated: true, authMethod: "api-key", issues: ["auth_api_key"] };
}
return { authenticated: null, issues: ["auth_unparsed"] };
}
if (id === "grok") {
if (commandSucceeded(result) && lines.some((line) => line === GROK_LOGIN_LINE)) return { authenticated: true, issues: [] };
return { authenticated: null, issues: ["auth_unparsed"] };
}
if (id === "omp") {
if (commandSucceeded(result)) {
const payload = parseJsonObject(result.stdout);
if (payload && Array.isArray(payload.models) && payload.models.length > 0) {
return { authenticated: true, issues: [] };
}
if (commandSucceeded(result)) return { authenticated: true, issues: [] };
}
return { authenticated: null, issues: ["auth_unparsed"] };
}
if (id === "agy") {
const text = `${result.stdout}\n${result.stderr}`;
if (!commandSucceeded(result) || !text.trim()) {
return { authenticated: false, issues: ["not_authenticated"] };
}
if (AGY_MODEL_ROW.test(text)) return { authenticated: true, authMethod: "antigravity-oauth", issues: [] };
return { authenticated: null, issues: ["auth_unparsed"] };
}
if (id === "kimi") {
if (!commandSucceeded(result)) {
return { authenticated: false, issues: ["not_authenticated"] };
}
if (lines.some((line) => /not logged in|no provider/i.test(line))) {
return { authenticated: false, issues: ["not_authenticated"] };
}
if (lines.some((line) => line.includes("managed:kimi") || line.includes("type=kimi") || line.includes("Default model:"))) {
return { authenticated: true, issues: [] };
}
return { authenticated: null, issues: ["auth_unparsed"] };
}
return { authenticated: null, issues: ["auth_unparsed"] };
}
export function resolveDispatchStatus(
entry: HarnessCatalogEntry,
detected: boolean,
authenticated: boolean | null,
issues: readonly string[],
): HarnessDispatchStatus {
if (!detected) {
return { status: "no", supported: false, reason: "not_detected" };
}
if (entry.id !== "pi" && !entry.oneShot) {
return {
status: "no",
supported: false,
reason: "no_headless_mode",
};
}
if (entry.id !== "pi" && !oneShotReadOnlyArgs(entry.id)) {
return { status: "no", supported: false, reason: "permission_profile_unaudited" };
}
if (authenticated === false) {
return { status: "no", supported: false, reason: "not_authenticated" };
}
if (authenticated === null) {
const authIssue = issues.find((issue) => issue === "auth_context_required" || issue === "auth_unknown" || issue === "auth_unparsed" || issue.startsWith("auth_"));
return { status: "no", supported: false, reason: authIssue ?? issues[0] ?? "auth_unknown" };
}
return { status: "yes", supported: true };
}
function windowsCmdReportsMissing(result: HarnessCommandResult): boolean {
if (result.ok) return false;
const text = `${result.stdout}\n${result.stderr}`;
return /not recognized as an internal or external command/i.test(text)
|| /the system cannot find the (?:file|path) specified/i.test(text);
}
function tryHarnessCommand(
candidate: string,
entry: HarnessCatalogEntry,
runCommand: (command: string, args: readonly string[], timeoutMs: number) => HarnessCommandResult,
timeoutMs: number,
): { command: string; version: string | undefined } | undefined {
const result = runCommand(candidate, entry.versionArgs, timeoutMs);
if (result.error === "ENOENT") return undefined;
if (result.error && result.code === null && !result.stdout && !result.stderr) return undefined;
// spawn with shell runs cmd.exe, which exists even when the shim does not.
// Its "not recognized" answer is a miss, not a detected harness.
if (isWindowsHarnessShim(candidate) && windowsCmdReportsMissing(result)) return undefined;
return {
command: candidate,
version: firstLine(result.stdout) ?? firstLine(result.stderr),
};
}
function detectHarnessCommand(
entry: HarnessCatalogEntry,
runCommand: (command: string, args: readonly string[], timeoutMs: number) => HarnessCommandResult,
timeoutMs: number,
platform: NodeJS.Platform,
probe: Pick<HarnessProbeOptions, "env" | "existsSync"> = {},
): { command: string; version: string | undefined } | undefined {
const candidates = entry.commands.flatMap((base) => [...harnessCommandCandidates(base, platform)]);
for (const candidate of candidates) {
if (isWindowsHarnessShim(candidate)) continue;
const found = tryHarnessCommand(candidate, entry, runCommand, timeoutMs);
if (found) return found;
}
const inner = findWinNpmInnerExe(entry.id, {
platform,
pathEnv: probe.env?.PATH ?? process.env.PATH ?? "",
existsSync: probe.existsSync,
});
if (inner) {
const found = tryHarnessCommand(inner, entry, runCommand, timeoutMs);
if (found) return found;
}
for (const candidate of candidates) {
if (!isWindowsHarnessShim(candidate)) continue;
const found = tryHarnessCommand(candidate, entry, runCommand, timeoutMs);
if (found) return found;
}
return undefined;
}
function probeEntry(
entry: HarnessCatalogEntry,
runCommand: (command: string, args: readonly string[], timeoutMs: number) => HarnessCommandResult,
timeoutMs: number,
platform: NodeJS.Platform,
probe: Pick<HarnessProbeOptions, "env" | "existsSync" | "defaultHarness"> = {},
): HarnessStatus {
const issues: string[] = [];
const found = detectHarnessCommand(entry, runCommand, timeoutMs, platform, probe);
const detected = Boolean(found);
const command = found?.command;
const version = found?.version;
let authenticated: boolean | null = null;
let authMethod: HarnessStatus["authMethod"];
if (!detected) authenticated = false;
else if (entry.id === "pi") {
authenticated = null;
issues.push("auth_context_required");
} else if (UNKNOWN_AUTH_HARNESSES.has(entry.id) || !entry.authArgs) {
authenticated = null;
if (UNKNOWN_AUTH_HARNESSES.has(entry.id)) issues.push("auth_unknown");
} else if (command) {
// Auth CLIs may initialize hooks/OAuth state and exceed the short binary-detection timeout.
// Keep detection bounded while allowing the documented auth probe to complete.
const parsed = interpretAuth(entry.id, runCommand(command, entry.authArgs, Math.max(timeoutMs, 10_000)));
authenticated = parsed.authenticated;
authMethod = parsed.authMethod;
issues.push(...parsed.issues);
}
if (command && isWindowsHarnessShim(command)) issues.push("windows_shim");
const dispatch = resolveDispatchStatus(entry, detected, authenticated, issues);
return {
id: entry.id,
label: entry.label,
default: entry.id === (probe.defaultHarness ?? DEFAULT_HARNESS),
mode: entry.mode,
detected,
authenticated,
...(authMethod ? { authMethod } : {}),
dispatch,
...(command ? { command } : {}),
...(version ? { version } : {}),
canUpdate: {
self: Boolean(entry.update.self.length),
extensions: Boolean(entry.update.extensions?.length),
models: Boolean(entry.update.models?.length),
},
issues,
};
}
export function probeHarnesses(options: HarnessProbeOptions = {}): HarnessInventory {
const timeoutMs = options.timeoutMs ?? 3000;
const runCommand = options.runCommand ?? defaultRunner(options.env ?? process.env);
const platform = options.platform ?? process.platform;
return {
defaultHarness: options.defaultHarness ?? DEFAULT_HARNESS,
harnesses: BUILTIN_HARNESSES.map((entry) => probeEntry(entry, runCommand, timeoutMs, platform, options)),
};
}
/**
* Inventory probe that never uses spawnSync. Product CLI/hub/extension paths
* must await this so capability/auth checks cannot block the event loop.
*/
export async function probeHarnessesAsync(options: AsyncHarnessProbeOptions = {}): Promise<HarnessInventory> {
return replayHarnessProbe(
options.runCommand ?? defaultAsyncRunner(options.env ?? process.env, options.signal),
(runCommand) => probeHarnesses({ ...options, runCommand }),
256,
);
}
export function eligibleHarnesses(inventory: HarnessInventory): readonly string[] {
const eligible = inventory.harnesses
.filter((entry) => entry !== undefined && entry.detected && entry.authenticated === true)
.map((entry) => entry.id);
if (eligible.length === 0) throw new Error("no_authenticated_harness");
return eligible;
}
export function validateHarnessModelPair(
harnessId: string,
modelSpec: string | HarnessModelSpec,
): HarnessModelValidation {
if (!isKnownHarnessId(harnessId)) {
return { valid: false, issue: "harness_unknown", message: `unknown harness: ${harnessId}` };
}
let provider: string | undefined;
let model: string | undefined;
if (typeof modelSpec === "string") {
const trimmed = modelSpec.trim();
if (trimmed.includes("/")) {
const idx = trimmed.indexOf("/");
provider = trimmed.slice(0, idx).toLowerCase();
model = trimmed.slice(idx + 1);
} else {
model = trimmed;
}
} else {
provider = modelSpec.provider?.trim().toLowerCase();
model = modelSpec.model?.trim();
}
if (harnessId === "claude") {
if (provider && provider !== "anthropic") {
return { valid: false, issue: "harness_unhosted_model", message: `harness claude does not host provider ${provider}` };
}
if (model && /^(gpt|o1|o3|grok|gemini|kimi|moonshot|deepseek|qwen)-/i.test(model)) {
return { valid: false, issue: "harness_unhosted_model", message: `harness claude does not host model ${model}` };
}
return { valid: true };
}
if (harnessId === "codex") {
if (provider && provider !== "openai") {
return { valid: false, issue: "harness_unhosted_model", message: `harness codex does not host provider ${provider}` };
}
if (model && /^(claude|fable|grok|gemini|kimi|moonshot|deepseek|qwen)-/i.test(model)) {
return { valid: false, issue: "harness_unhosted_model", message: `harness codex does not host model ${model}` };
}
return { valid: true };
}
if (harnessId === "grok") {
if (provider && provider !== "xai") {
return { valid: false, issue: "harness_unhosted_model", message: `harness grok does not host provider ${provider}` };
}
if (model && !/^grok-/i.test(model)) {
return { valid: false, issue: "harness_unhosted_model", message: `harness grok only hosts grok models, received ${model}` };
}
return { valid: true };
}
if (harnessId === "agy") {
if (provider && provider !== "google") {
return { valid: false, issue: "harness_unhosted_model", message: `harness ${harnessId} does not host provider ${provider}` };
}
if (model && !/^gemini-/i.test(model)) {
return { valid: false, issue: "harness_unhosted_model", message: `harness ${harnessId} only hosts gemini models, received ${model}` };
}
return { valid: true };
}
if (harnessId === "kimi") {
if (provider && provider !== "moonshot") {
return { valid: false, issue: "harness_unhosted_model", message: `harness kimi does not host provider ${provider}` };
}
if (model && !/^(kimi|moonshot)(?:-|$)/i.test(model) && !/^kimi-for-coding(?:-|$)/i.test(model)) {
return { valid: false, issue: "harness_unhosted_model", message: `harness kimi only hosts kimi/moonshot models, received ${model}` };
}
return { valid: true };
}
if (harnessId === "deepseek") {
if (provider && provider !== "deepseek") {
return { valid: false, issue: "harness_unhosted_model", message: `harness deepseek does not host provider ${provider}` };
}
if (model && !/^deepseek-/i.test(model)) {
return { valid: false, issue: "harness_unhosted_model", message: `harness deepseek only hosts deepseek models, received ${model}` };
}
return { valid: true };
}
if (harnessId === "pi" || harnessId === "omp") {
if (!provider && model?.includes("/")) {
const idx = model.indexOf("/");
provider = model.slice(0, idx).toLowerCase();
model = model.slice(idx + 1);
}
if (!provider) return { valid: true };
const blocked = (message: string): HarnessModelValidation => ({ valid: false, issue: "pi_native_impersonation_blocked", message });
if (PI_NATIVE_BRAKE_PROVIDERS.includes(provider)) {
return blocked(`${harnessId} must not impersonate native provider ${provider}; use the native harness`);
}
if (provider === "antigravity" && model && PI_ANTIGRAVITY_MODEL_ID.test(model)) return { valid: true };
const owned = Object.hasOwn(PI_VENDOR_OWNED_PROVIDERS, provider) ? PI_VENDOR_OWNED_PROVIDERS[provider] : undefined;
if (owned) {
return blocked(`${harnessId} provider ${provider} bills native vendor ${owned} for ${model ?? "this model"}; use the native harness`);
}
const segment = model?.includes("/") ? model.slice(0, model.indexOf("/")).toLowerCase() : undefined;
const vendor = segment && Object.hasOwn(PI_VENDOR_SEGMENT_ALIASES, segment) ? PI_VENDOR_SEGMENT_ALIASES[segment] : segment;
if (vendor && PI_NATIVE_BRAKE_PROVIDERS.includes(vendor)) {
return blocked(`${harnessId} must not bill native vendor ${vendor} through ${provider}; use the native harness`);
}
return { valid: true };
}
return { valid: true };
}
export interface HarnessAssignmentProbeOptions {
harness: string;
provider?: string | undefined;
model?: string | undefined;
env?: NodeJS.ProcessEnv | undefined;
runCommand?: ((command: string, args: readonly string[], timeoutMs: number) => HarnessCommandResult) | undefined;
timeoutMs?: number | undefined;
platform?: NodeJS.Platform | undefined;
existsSync?: ((path: string) => boolean) | undefined;
}
export function probeHarnessAssignment(options: HarnessAssignmentProbeOptions): HarnessStatus {
const timeoutMs = options.timeoutMs ?? 3000;
const runCommand = options.runCommand ?? defaultRunner(options.env ?? process.env);
const platform = options.platform ?? process.platform;
const entry = BUILTIN_HARNESSES.find((candidate) => candidate.id === options.harness);
if (!entry) {
return {
id: options.harness,
label: options.harness,
default: false,
mode: "either",
detected: false,
authenticated: false,
dispatch: { status: "no", supported: false, reason: "harness_unknown" },
canUpdate: { self: false, extensions: false, models: false },
issues: ["harness_unknown"],
};
}
if (options.provider || options.model) {
const validation = validateHarnessModelPair(options.harness, { provider: options.provider, model: options.model });
if (!validation.valid) {
return {
id: entry.id,
label: entry.label,
default: entry.default,
mode: entry.mode,
detected: false,
authenticated: false,
dispatch: { status: "no", supported: false, reason: validation.issue ?? "harness_unhosted_model" },
canUpdate: {
self: Boolean(entry.update.self.length),
extensions: Boolean(entry.update.extensions?.length),
models: Boolean(entry.update.models?.length),
},
issues: [validation.issue ?? "harness_unhosted_model"],
};
}
}
const found = detectHarnessCommand(entry, runCommand, timeoutMs, platform, options);
const detected = Boolean(found);
const command = found?.command;
const version = found?.version;
const shimIssue = command && isWindowsHarnessShim(command) ? ["windows_shim"] : [];
if (!detected || !command) {
return {
id: entry.id,
label: entry.label,
default: entry.default,
mode: entry.mode,
detected: false,
authenticated: false,
dispatch: { status: "no", supported: false, reason: "not_detected" },
canUpdate: {
self: Boolean(entry.update.self.length),
extensions: Boolean(entry.update.extensions?.length),
models: Boolean(entry.update.models?.length),
},
issues: [],
};
}
if (entry.id === "pi") {
if (!options.provider && !options.model) {
return {
id: entry.id,
label: entry.label,
default: entry.default,
mode: entry.mode,
detected: true,
authenticated: null,
dispatch: { status: "no", supported: false, reason: "auth_context_required" },
command,
...(version ? { version } : {}),
canUpdate: {
self: Boolean(entry.update.self.length),
extensions: Boolean(entry.update.extensions?.length),
models: Boolean(entry.update.models?.length),
},
issues: ["auth_context_required", ...shimIssue],
};
}
const authArgs = ["auth", "check"];
// `pi auth check --model` requires a provider-qualified id: a bare model answers
// status "invalid", which reads as not_authenticated and hides the real state. When
// the caller holds provider and bare model separately (the engine's request shape),
// qualify the id; a model that already carries its namespace goes through as-is.
const qualifiedModel = options.model
? (options.provider && options.model.startsWith(`${options.provider}/`)
? options.model
: options.provider ? `${options.provider}/${options.model}` : options.model)
: undefined;
if (qualifiedModel) {
authArgs.push("--model", qualifiedModel);
} else if (options.provider) {
authArgs.push("--provider", options.provider);
}
authArgs.push("--json");
const result = runCommand(command, authArgs, timeoutMs);
const parsed = parseJsonObject(result.stdout);
let authenticated: boolean | null = false;
const issues: string[] = [];
if (result.error) {
issues.push("auth_probe_error");
} else if (parsed && parsed.status === "ready") {
authenticated = true;
} else if (parsed && parsed.status === "not_ready") {
authenticated = false;
issues.push("not_authenticated");
} else if (commandSucceeded(result) && /\bready\b/i.test(`${result.stdout}\n${result.stderr}`)) {
authenticated = true;
} else {
authenticated = false;
issues.push("not_authenticated");
}
issues.push(...shimIssue);
const dispatch = resolveDispatchStatus(entry, true, authenticated, issues);
return {
id: entry.id,
label: entry.label,
default: entry.default,
mode: entry.mode,
detected: true,
authenticated,
dispatch,
command,
...(version ? { version } : {}),
canUpdate: {
self: Boolean(entry.update.self.length),
extensions: Boolean(entry.update.extensions?.length),
models: Boolean(entry.update.models?.length),
},
issues,
};
}
return probeEntry(entry, runCommand, timeoutMs, platform);
}
export interface AsyncHarnessAssignmentProbeOptions extends Omit<HarnessAssignmentProbeOptions, "runCommand"> {
signal?: AbortSignal | undefined;
runCommand?: HarnessRunCommandAsync | undefined;
}
class PendingHarnessCommand {
command: string;
args: readonly string[];
timeoutMs: number;
key: string;
constructor(command: string, args: readonly string[], timeoutMs: number, key: string) {
this.command = command;
this.args = [...args];
this.timeoutMs = timeoutMs;
this.key = key;
}
}
async function replayHarnessProbe<T>(
run: HarnessRunCommandAsync,
execute: (runCommand: HarnessRunCommand) => T,
limit: number,
): Promise<T> {
const observed = new Map<string, HarnessCommandResult>();
for (let commands = 0; commands <= limit; commands++) {
try {
return execute((command, args, timeoutMs) => {
const key = JSON.stringify([command, args, timeoutMs]);
const result = observed.get(key);
if (result) return result;
throw new PendingHarnessCommand(command, args, timeoutMs, key);
});
} catch (pending) {
if (!(pending instanceof PendingHarnessCommand)) throw pending;
if (commands === limit) throw new Error("auth_probe_command_limit");
observed.set(pending.key, await run(pending.command, pending.args, pending.timeoutMs));
}
}
throw new Error("auth_probe_command_limit");
}
/**
* Execute the existing probe policy without blocking the Runtime event loop.
* Replay pure policy decisions from per-call command observations, yielding for
* every missing observation. This reuses the exact auth/model/brake parsers,
* deduplicates repeated detection, and never caches auth across assignments.
*/
export async function probeHarnessAssignmentAsync(options: AsyncHarnessAssignmentProbeOptions): Promise<HarnessStatus> {
return replayHarnessProbe(
options.runCommand ?? defaultAsyncRunner(options.env ?? process.env, options.signal),
(runCommand) => probeHarnessAssignment({ ...options, runCommand }),
32,
);
}
export function probeHarnessesForModel(
modelSpec: HarnessModelSpec,
options: HarnessProbeOptions = {},
): HarnessInventory {
const timeoutMs = options.timeoutMs ?? 3000;
const runCommand = options.runCommand ?? defaultRunner(options.env ?? process.env);
const platform = options.platform ?? process.platform;
return {
defaultHarness: DEFAULT_HARNESS,
harnesses: BUILTIN_HARNESSES.map((entry) =>
probeHarnessAssignment({
harness: entry.id,
provider: modelSpec.provider,
model: modelSpec.model,
runCommand,
timeoutMs,
platform,
env: options.env,
existsSync: options.existsSync,
})
),
};
}
export async function probeHarnessesForModelAsync(
modelSpec: HarnessModelSpec,
options: AsyncHarnessProbeOptions = {},
): Promise<HarnessInventory> {
return replayHarnessProbe(
options.runCommand ?? defaultAsyncRunner(options.env ?? process.env, options.signal),
(runCommand) => probeHarnessesForModel(modelSpec, { ...options, runCommand }),
256,
);
}
function scopesFor(scope: HarnessUpdateScope, entry: HarnessCatalogEntry): Exclude<HarnessUpdateScope, "all">[] {
if (scope === "self") return ["self"];
if (scope === "extensions") return entry.update.extensions ? ["extensions"] : [];
if (scope === "models") return entry.update.models ? ["models"] : [];
return [
...(entry.update.self.length ? ["self" as const] : []),
...(entry.update.extensions ? ["extensions" as const] : []),
...(entry.update.models ? ["models" as const] : []),
];
}
function argsFor(entry: HarnessCatalogEntry, scope: Exclude<HarnessUpdateScope, "all">): readonly string[] | undefined {
if (scope === "self") return entry.update.self;
if (scope === "extensions") return entry.update.extensions;
return entry.update.models;
}
function detectedHarnesses(
inventory: HarnessInventory,
requestedHarness?: string,
): HarnessStatus[] {
if (requestedHarness) return inventory.harnesses.filter((entry) => entry.id === requestedHarness);
const detected = inventory.harnesses.filter((entry) => entry.detected);
const preferred = inventory.defaultHarness;
return [
...detected.filter((entry) => entry.id === preferred),
...detected.filter((entry) => entry.id !== preferred),
];
}
export function planHarnessUpdate(
inventory: HarnessInventory,
requested: { harness?: string; scope: HarnessUpdateScope },
): HarnessUpdateStep[] {
const selected = detectedHarnesses(inventory, requested.harness);
if (requested.harness && selected.length === 0) {
return [{
harness: requested.harness,
scope: "self",
command: requested.harness,
args: [],
outcome: "skipped",
detail: isKnownHarnessId(requested.harness) ? "not_detected" : "unknown_harness",
}];
}
const waves: Exclude<HarnessUpdateScope, "all">[] = requested.scope === "all"
? ["self", "extensions", "models"]
: [requested.scope];
const steps: HarnessUpdateStep[] = [];
for (const scope of waves) {
for (const status of selected) {
const entry = BUILTIN_HARNESSES.find((candidate) => candidate.id === status.id);
if (!entry) continue;
const supported = scopesFor(requested.scope === "all" ? "all" : scope, entry);
if (!supported.includes(scope)) {
if (requested.scope !== "all") {
steps.push({
harness: status.id,
scope,
command: status.command ?? entry.commands[0]!,
args: [],
outcome: "skipped",
detail: "no_updater",
});
}
continue;
}
if (!status.detected || !status.command) {
steps.push({
harness: status.id,
scope,
command: entry.commands[0]!,
args: argsFor(entry, scope) ?? [],
outcome: "skipped",
detail: "not_detected",
});
continue;
}
steps.push({
harness: status.id,
scope,
command: status.command,
args: argsFor(entry, scope) ?? [],
outcome: "would",
});
}
}
return steps;
}
export function runHarnessUpdate(
steps: readonly HarnessUpdateStep[],
options: HarnessProbeOptions & { dryRun?: boolean; updateTimeoutMs?: number } = {},
): HarnessUpdateStep[] {
if (options.dryRun) return steps.map((step) => ({ ...step, outcome: step.outcome === "would" ? "would" : step.outcome }));
const timeoutMs = options.updateTimeoutMs ?? 180_000;
const runCommand = options.runCommand ?? defaultRunner(options.env ?? process.env);
return steps.map((step) => {
if (step.outcome !== "would") return step;
const result = runCommand(step.command, step.args, timeoutMs);
const detail = boundText(result.stderr) ?? boundText(result.stdout) ?? result.error;
return {
...step,
outcome: result.ok ? "passed" : "failed",
...(result.code !== undefined && result.code !== null ? { code: result.code } : {}),
...(detail ? { detail } : {}),
};
});
}
export function formatHarnessInventory(inventory: HarnessInventory): string {
const header = [
"id".padEnd(9),
"default".padEnd(8),
"detected".padEnd(9),
"auth".padEnd(8),
"dispatch".padEnd(26),
"updates",
].join(" ");
const rows = inventory.harnesses.map((entry) => {
const auth = entry.authenticated === true ? "yes" : entry.authenticated === false ? "no" : "unknown";
const dispatchText = entry.dispatch
? (entry.dispatch.status === "yes" ? "yes" : `no (${entry.dispatch.reason ?? "unsupported"})`)
: (entry.authenticated === true ? "yes" : "no");
const updates = [
entry.canUpdate.self ? "self" : undefined,
entry.canUpdate.extensions ? "extensions" : undefined,
entry.canUpdate.models ? "models" : undefined,
].filter(Boolean).join(",") || "none";
const apiKeyNote = entry.issues.includes("auth_api_key") ? " API key" : "";
return [
entry.id.padEnd(9),
(entry.default ? "yes" : "no").padEnd(8),
(entry.detected ? "yes" : "no").padEnd(9),
auth.padEnd(8),
dispatchText.padEnd(26),
`${updates}${apiKeyNote}`,
].join(" ");
});
return [
`default harness: ${inventory.defaultHarness} (used when an agent omits harness:)`,
"enable/disable = Git YAML (.kxm/agents, .kxm/models) or the harness's own plugin CLI",
"governed kxm skills are not auto-updated",
header,
...rows,
].join("\n");
}
export function formatHarnessUpdate(steps: readonly HarnessUpdateStep[]): string {
if (steps.length === 0) return "nothing to update";
return steps.map((step) => {
const argv = [step.command, ...step.args].join(" ");
const detail = step.detail ? ` (${step.detail})` : "";
return `${step.harness} ${step.scope}: ${step.outcome} ${argv}${detail}`;
}).join("\n");
}