@agntn/harnesses 0.3.1 โ†’ 0.4.1

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/README.md CHANGED
@@ -34,7 +34,7 @@ The rest of it sits on [harnesses.agntn.dev](https://harnesses.agntn.dev).
34
34
  pnpm add @agntn/harnesses
35
35
  ```
36
36
 
37
- Node.js 24 or newer.
37
+ Node.js 26 or newer.
38
38
 
39
39
  ## ๐Ÿš€ First call
40
40
 
@@ -45,22 +45,22 @@ npx @agntn/harnesses detect
45
45
  ```
46
46
  System Scan
47
47
 
48
- โ— antigravity Google Antigravity CLI v1.2.5
49
- โ— claude Anthropic Claude Code v2.1.276
50
- โ— codex OpenAI Codex CLI v0.154.0
48
+ โ— antigravity Google Antigravity CLI v1.2.14 agent
49
+ โ— claude Anthropic Claude Code v2.1.289 advisor ยท readOnly ยท agent
50
+ โ— codex OpenAI Codex CLI v0.160.0 readOnly ยท agent
51
51
  โ—‹ cursor Cursor
52
- โ— freebuff Freebuff
52
+ โ— freebuff Freebuff v0.0.204 no headless mode
53
53
  โ—‹ gemini Google Gemini CLI
54
54
  โ—‹ github-copilot GitHub Copilot
55
- โ— grok xAI Grok CLI v1.0.34
56
- โ— mastracode Mastra Code
57
- โ— omp OMP (oh-my-pi) v18.2.4
58
- โ— opencode OpenCode CLI v2.0.5
59
- โ— prime-agent Prime Agent v0.9.5
60
- โ— pi Pi Coding Agent v0.85.1
55
+ โ— grok xAI Grok CLI v1.0.41 readOnly ยท agent
56
+ โ— mastracode Mastra Code v0.10.2 no headless mode
57
+ โ— omp OMP (oh-my-pi) v18.6.1 agent
58
+ โ— opencode OpenCode CLI v2.0.22 agent
59
+ โ— prime-agent Prime Agent v0.9.5 advisor ยท agent
60
+ โ— pi Pi Coding Agent v1.0.2 advisor ยท readOnly ยท agent
61
61
  ```
62
62
 
63
- No key, no config. No network either. `detect` looks at `PATH`. Filled dot is installed, hollow is not. After `pnpm add`, the same command is `pnpm exec harnesses`, or install it once with `pnpm add -g @agntn/harnesses`.
63
+ No key, no config. No network either. `detect` looks at `PATH`. Filled dot is installed, hollow is not. The tail says how `run` can drive it: `advisor` without tools, `readOnly` behind the harness's own read-only lock, `agent` with everything. Codex has no advisor, and now you learn that here, not from a refused run. After `pnpm add`, the same command is `pnpm exec harnesses`, or install it once with `pnpm add -g @agntn/harnesses`.
64
64
 
65
65
  Same binary, more commands:
66
66
 
@@ -77,14 +77,14 @@ harnesses prompts sync --check
77
77
  harnesses skills sync --check
78
78
  ```
79
79
 
80
- `run` without `--tools` is the advisor. `--tools` is the full agent. `--read-only` asks the CLI for a sandbox and implies tools, so pairing it with `--no-tools` is an error. Timeouts, `--cwd` and `--model` sit in the [CLI guide](https://harnesses.agntn.dev/guide/cli).
80
+ `run` without `--tools` is the advisor. `--tools` is the full agent. `--read-only` asks the CLI for a sandbox and implies tools, so pairing it with `--no-tools` is an error. Timeouts, `--cwd`, `--model` and `--effort` sit in the [CLI guide](https://harnesses.agntn.dev/guide/cli).
81
81
 
82
82
  ### Commands
83
83
 
84
84
  | Command | What it does | Example |
85
85
  | -------------- | ------------------------------------------------------ | ------------------------------------------- |
86
86
  | `list` | Every known harness, id and name | `harnesses list` |
87
- | `detect` | Which ones are installed, with versions | `harnesses detect` |
87
+ | `detect` | Which ones are installed, and how each one runs | `harnesses detect` |
88
88
  | `info` | Registry entry: modes, capabilities, path templates | `harnesses info claude` |
89
89
  | `paths` | Those templates expanded for this machine | `harnesses paths pi` |
90
90
  | `models` | Models the harness can use, through its native listing | `harnesses models pi` |
@@ -110,7 +110,7 @@ console.log(paths.temp, claude.envOverrides);
110
110
  const active = detectHarness();
111
111
  if (active) console.log(active.id);
112
112
 
113
- await getHarness("codex").invoke("Review this patch", { readOnly: true });
113
+ await getHarness("codex").invoke("Review this patch", { readOnly: true, effort: "low" });
114
114
 
115
115
  const agy = getHarness("antigravity");
116
116
  const [model] = (await agy.listModels({ search: "gemini" })).models;
@@ -119,7 +119,7 @@ if (model) await agy.invoke("Review this patch", { tools: true, model: agy.model
119
119
 
120
120
  `temp` is where a harness drops its own temp files, and `envOverrides` names the variables that move its directories. `claude.resolve().temp` follows `CLAUDE_CODE_TMPDIR` when it's set, which is handy when `/tmp` is tmpfs and Claude's scratchpads are quietly eating RAM.
121
121
 
122
- That's most of it, really. `getHarness` wants an exact id. `detectHarness` uses env vars first, then a single project marker. `invoke()` talks to the CLI. `listModels()` asks it what it can run, and `modelSelector()` turns one of those into what `model` takes, since Pi wants `provider/id` and Antigravity the bare id. A mode the CLI cannot run comes back as an error, not a quieter one. The rest: [Registry](https://harnesses.agntn.dev/guide/registry), [Invoke](https://harnesses.agntn.dev/guide/invoke), [MCP servers](https://harnesses.agntn.dev/guide/mcp-servers), [Instructions files](https://harnesses.agntn.dev/guide/agents-sync).
122
+ That's most of it, really. `getHarness` wants an exact id. `detectHarness` uses env vars first, then a single project marker. `invoke()` talks to the CLI, and `effort` decides how hard it thinks for that one run. `listModels()` asks it what it can run, and `modelSelector()` turns one of those into what `model` takes, since Pi wants `provider/id` while Antigravity and Codex want the bare id. A mode the CLI cannot run comes back as an error, not a quieter one. The rest: [Registry](https://harnesses.agntn.dev/guide/registry), [Invoke](https://harnesses.agntn.dev/guide/invoke), [MCP servers](https://harnesses.agntn.dev/guide/mcp-servers), [Instructions files](https://harnesses.agntn.dev/guide/agents-sync).
123
123
 
124
124
  ### Prompt templates
125
125
 
@@ -1,4 +1,4 @@
1
- import { v as isHarnessId, y as listHarnesses } from "./skills-sync.mjs";
1
+ import { b as listHarnesses, y as isHarnessId } from "./skills-sync.mjs";
2
2
  import { r as agentsSync } from "./tool-operations.mjs";
3
3
  import { n as formatArgs, r as report } from "./output.mjs";
4
4
  import { defineCommand } from "citty";
@@ -1,4 +1,4 @@
1
- import { v as isHarnessId, y as listHarnesses } from "./skills-sync.mjs";
1
+ import { b as listHarnesses, y as isHarnessId } from "./skills-sync.mjs";
2
2
  import { c as mcpList, l as mcpRemove, s as mcpAdd, u as mcpSync } from "./tool-operations.mjs";
3
3
  import { n as formatArgs, r as report } from "./output.mjs";
4
4
  import { defineCommand } from "citty";
@@ -29,6 +29,6 @@ function report(result, args) {
29
29
  if (result.isError) process.exitCode = 1;
30
30
  }
31
31
  //#endregion
32
- export { formatArgs as n, report as r, exitOnClosedPipe as t };
32
+ export { sanitize as i, formatArgs as n, report as r, exitOnClosedPipe as t };
33
33
 
34
34
  //# sourceMappingURL=output.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"output.mjs","names":["toToon"],"sources":["../../src/commands/output.ts"],"sourcesContent":["import { stripVTControlCharacters } from \"node:util\";\nimport { encode as toToon } from \"@toon-format/toon\";\nimport { consola } from \"consola\";\nimport type { ToolResult } from \"../tool-operations.ts\";\n\nexport const formatArgs = {\n json: { type: \"boolean\" as const, description: \"Output as JSON\" },\n toon: { type: \"boolean\" as const, description: \"Output as TOON\" },\n};\n\n/**\n * Ends the process once the reader of stdout or stderr is gone, as after\n * `| head -1` or a pager that quits early. Node ignores SIGPIPE, so without a\n * listener the next write throws `EPIPE` with a stack trace. The exit code\n * stays whatever the command set.\n *\n * @param error - The error the stream emitted.\n */\nexport function exitOnClosedPipe(error: Readonly<NodeJS.ErrnoException>): void {\n if (error.code !== \"EPIPE\") throw error;\n process.exit();\n}\n\ntype OutputFormat = Readonly<{ json?: boolean; toon?: boolean }>;\n\n/** Control bytes removed from reports because they can echo untrusted configuration values. */\n/* oxlint-disable-next-line no-control-regex */\nconst UNSAFE_TERMINAL_CONTROLS = /[\\u0000-\\u0008\\u000B-\\u001F\\u007F-\\u009F]/g;\nconst UNSAFE_UNICODE_FORMATTING = /[\\p{Cf}\\p{Zl}\\p{Zp}]/gu;\n\nfunction sanitize(text: string | undefined): string {\n return stripVTControlCharacters(text ?? \"\")\n .replace(UNSAFE_TERMINAL_CONTROLS, \" \")\n .replace(UNSAFE_UNICODE_FORMATTING, \" \");\n}\n\n/**\n * Emits one tool result in the selected machine or human format.\n *\n * @param result - Shared executor result to emit.\n * @param args - Selected output format.\n */\nexport function report(result: ToolResult<unknown>, args: OutputFormat): void {\n if (args.json) console.log(JSON.stringify(result.details, null, 2));\n else if (args.toon) console.log(toToon(result.details));\n else if (result.isError) consola.error(sanitize(result.content[0]?.text));\n else console.log(sanitize(result.content[0]?.text));\n\n if (result.isError) process.exitCode = 1;\n}\n"],"mappings":";;;;AAKA,MAAa,aAAa;CACxB,MAAM;EAAE,MAAM;EAAoB,aAAa;CAAiB;CAChE,MAAM;EAAE,MAAM;EAAoB,aAAa;CAAiB;AAClE;AAUA,SAAgB,iBAAiB,OAA8C;CAC7E,IAAI,MAAM,SAAS,SAAS,MAAM;CAClC,QAAQ,KAAK;AACf;AAMA,MAAM,2BAA2B;AACjC,MAAM,4BAA4B;AAElC,SAAS,SAAS,MAAkC;CAClD,OAAO,yBAAyB,QAAQ,EAAE,CAAC,CACxC,QAAQ,0BAA0B,GAAG,CAAC,CACtC,QAAQ,2BAA2B,GAAG;AAC3C;AAQA,SAAgB,OAAO,QAA6B,MAA0B;CAC5E,IAAI,KAAK,MAAM,QAAQ,IAAI,KAAK,UAAU,OAAO,SAAS,MAAM,CAAC,CAAC;MAC7D,IAAI,KAAK,MAAM,QAAQ,IAAIA,OAAO,OAAO,OAAO,CAAC;MACjD,IAAI,OAAO,SAAS,QAAQ,MAAM,SAAS,OAAO,QAAQ,EAAE,EAAE,IAAI,CAAC;MACnE,QAAQ,IAAI,SAAS,OAAO,QAAQ,EAAE,EAAE,IAAI,CAAC;CAElD,IAAI,OAAO,SAAS,QAAQ,WAAW;AACzC"}
1
+ {"version":3,"file":"output.mjs","names":["toToon"],"sources":["../../src/commands/output.ts"],"sourcesContent":["import { stripVTControlCharacters } from \"node:util\";\nimport { encode as toToon } from \"@toon-format/toon\";\nimport { consola } from \"consola\";\nimport type { ToolResult } from \"../tool-operations.ts\";\n\nexport const formatArgs = {\n json: { type: \"boolean\" as const, description: \"Output as JSON\" },\n toon: { type: \"boolean\" as const, description: \"Output as TOON\" },\n};\n\n/**\n * Ends the process once the reader of stdout or stderr is gone, as after\n * `| head -1` or a pager that quits early. Node ignores SIGPIPE, so without a\n * listener the next write throws `EPIPE` with a stack trace. The exit code\n * stays whatever the command set.\n *\n * @param error - The error the stream emitted.\n */\nexport function exitOnClosedPipe(error: Readonly<NodeJS.ErrnoException>): void {\n if (error.code !== \"EPIPE\") throw error;\n process.exit();\n}\n\ntype OutputFormat = Readonly<{ json?: boolean; toon?: boolean }>;\n\n/** Control bytes removed from reports because they can echo untrusted configuration values. */\n/* oxlint-disable-next-line no-control-regex */\nconst UNSAFE_TERMINAL_CONTROLS = /[\\u0000-\\u0008\\u000B-\\u001F\\u007F-\\u009F]/g;\nconst UNSAFE_UNICODE_FORMATTING = /[\\p{Cf}\\p{Zl}\\p{Zp}]/gu;\n\n/**\n * Drops terminal sequences, control bytes and Unicode formatting from text meant for a person.\n *\n * @param text - Text that may echo an outside value.\n * @returns {string} The text, safe to print.\n */\nexport function sanitize(text: string | undefined): string {\n return stripVTControlCharacters(text ?? \"\")\n .replace(UNSAFE_TERMINAL_CONTROLS, \" \")\n .replace(UNSAFE_UNICODE_FORMATTING, \" \");\n}\n\n/**\n * Emits one tool result in the selected machine or human format.\n *\n * @param result - Shared executor result to emit.\n * @param args - Selected output format.\n */\nexport function report(result: ToolResult<unknown>, args: OutputFormat): void {\n if (args.json) console.log(JSON.stringify(result.details, null, 2));\n else if (args.toon) console.log(toToon(result.details));\n else if (result.isError) consola.error(sanitize(result.content[0]?.text));\n else console.log(sanitize(result.content[0]?.text));\n\n if (result.isError) process.exitCode = 1;\n}\n"],"mappings":";;;;AAKA,MAAa,aAAa;CACxB,MAAM;EAAE,MAAM;EAAoB,aAAa;CAAiB;CAChE,MAAM;EAAE,MAAM;EAAoB,aAAa;CAAiB;AAClE;AAUA,SAAgB,iBAAiB,OAA8C;CAC7E,IAAI,MAAM,SAAS,SAAS,MAAM;CAClC,QAAQ,KAAK;AACf;AAMA,MAAM,2BAA2B;AACjC,MAAM,4BAA4B;AAQlC,SAAgB,SAAS,MAAkC;CACzD,OAAO,yBAAyB,QAAQ,EAAE,CAAC,CACxC,QAAQ,0BAA0B,GAAG,CAAC,CACtC,QAAQ,2BAA2B,GAAG;AAC3C;AAQA,SAAgB,OAAO,QAA6B,MAA0B;CAC5E,IAAI,KAAK,MAAM,QAAQ,IAAI,KAAK,UAAU,OAAO,SAAS,MAAM,CAAC,CAAC;MAC7D,IAAI,KAAK,MAAM,QAAQ,IAAIA,OAAO,OAAO,OAAO,CAAC;MACjD,IAAI,OAAO,SAAS,QAAQ,MAAM,SAAS,OAAO,QAAQ,EAAE,EAAE,IAAI,CAAC;MACnE,QAAQ,IAAI,SAAS,OAAO,QAAQ,EAAE,EAAE,IAAI,CAAC;CAElD,IAAI,OAAO,SAAS,QAAQ,WAAW;AACzC"}
@@ -65,6 +65,8 @@ interface HarnessInvocation {
65
65
  readOnlyMinVersion?: string;
66
66
  /** Arguments appended when a model is selected; every "{model}" is replaced. */
67
67
  modelArgs?: string[];
68
+ /** Arguments appended when a reasoning effort is selected; every "{effort}" is replaced. */
69
+ effortArgs?: string[];
68
70
  /**
69
71
  * Arguments appended to a plain text run so a CLI that holds its answer until
70
72
  * the end reports it as events instead; `invoke` folds them back into that text,
@@ -99,6 +101,8 @@ interface HarnessModelListing {
99
101
  interface AvailableModel {
100
102
  provider: string;
101
103
  id: string;
104
+ /** Display name, where the adapter reads one from the listing; Codex so far. */
105
+ name?: string;
102
106
  /** Absent when the native listing prints only ids, like Grok's. */
103
107
  contextWindow?: number;
104
108
  maxOutputTokens?: number;
@@ -122,6 +126,8 @@ interface InvokeOptions {
122
126
  env?: Record<string, string>;
123
127
  /** Harness-native model id or selector. */
124
128
  model?: string;
129
+ /** Reasoning effort in the harness's own words (`low`, `high`, `max`), passed through as is. */
130
+ effort?: string;
125
131
  /** Enable the spawned harness's tools; defaults to advisor without tools mode. */
126
132
  tools?: boolean;
127
133
  /** Require native enforcement of read-only tool access. Implies `tools: true` when `tools` is omitted; `tools: false` rejects the run. */
@@ -175,10 +181,11 @@ interface McpConfigFile extends PathCandidate {
175
181
  key: string[];
176
182
  /**
177
183
  * Shape of individual entries; "standard" is the {command, args, env, url}
178
- * family, "prime" is that family with env values as {"env": "NAME"} references
179
- * and "mastracode" is that family read by its keys alone, type ignored.
184
+ * family, "prime" is that family with env values as {"env": "NAME"} references,
185
+ * "mastracode" is that family read by its keys alone, type ignored, and "pi"
186
+ * is that family without sse that keeps the entry fields it doesn't manage.
180
187
  */
181
- dialect: "standard" | "antigravity" | "mastracode" | "opencode" | "prime" | "vscode";
188
+ dialect: "standard" | "antigravity" | "mastracode" | "opencode" | "pi" | "prime" | "vscode";
182
189
  }
183
190
  interface HarnessDetection {
184
191
  /** Environment variables that indicate running inside this agent. */
@@ -210,6 +217,7 @@ interface ResolvedPaths {
210
217
  //#region src/harness.d.ts
211
218
  type InvocationOptions = Readonly<{
212
219
  model?: string;
220
+ effort?: string;
213
221
  structured?: boolean;
214
222
  tools?: boolean;
215
223
  readOnly?: boolean;
@@ -379,6 +387,10 @@ interface McpConfigListing {
379
387
  declare class McpEnvError extends Error {
380
388
  readonly name = "McpEnvError";
381
389
  }
390
+ /** Thrown when the target dialect cannot carry a server's transport. */
391
+ declare class McpTransportError extends Error {
392
+ readonly name = "McpTransportError";
393
+ }
382
394
  /**
383
395
  * Lists the MCP servers a harness has configured, per declared config file.
384
396
  * Missing files come back with `exists: false`; unparsable ones carry `error`.
@@ -608,5 +620,5 @@ interface SkillsSyncReport {
608
620
  */
609
621
  declare function syncSkills(harnesses: readonly Harness[], check?: boolean, options?: ResolveOptions): SkillsSyncReport;
610
622
  //#endregion
611
- export { version as $, AvailableModel as A, InvokeResult as B, masterMcpPath as C, syncMcpServers as D, removeMcpServer as E, HarnessId as F, PathCandidate as G, ListModelsResult as H, HarnessInvocation as I, PromptTemplateSyncTarget as J, PathCategory as K, HarnessInvocationModes as L, EvidenceLevel as M, HarnessCapabilities as N, Harness as O, HarnessDetection as P, StorageDescriptor as Q, HarnessModelListing as R, listMcpServers as S, readMasterMcpServers as T, McpConfigFile as U, ListModelsOptions as V, McpServerConfig as W, ResolvedPaths as X, ResolveOptions as Y, SkillsSyncTarget as Z, McpConfigListing as _, PromptSyncAction as a, SyncTargetResult as b, PromptTemplateTargetResult as c, AgentsConfig as d, AgentsSyncAction as f, syncAgentsFiles as g, readAgentsConfig as h, syncSkills as i, EnvOverride as j, HarnessConstructor as k, syncPromptTemplates as l, AgentsTargetResult as m, SkillsSyncReport as n, PromptSyncReport as o, AgentsSyncReport as p, Platform as q, SkillsSyncTargetResult as r, PromptSyncTargetResult as s, SkillsSyncAction as t, AgentsCompanionTargetResult as u, McpEnvError as v, parseJsonc as w, addMcpServer as x, SyncReport as y, InvokeOptions as z };
623
+ export { StorageDescriptor as $, HarnessConstructor as A, InvokeOptions as B, listMcpServers as C, removeMcpServer as D, readMasterMcpServers as E, HarnessDetection as F, McpServerConfig as G, ListModelsOptions as H, HarnessId as I, Platform as J, PathCandidate as K, HarnessInvocation as L, EnvOverride as M, EvidenceLevel as N, syncMcpServers as O, HarnessCapabilities as P, SkillsSyncTarget as Q, HarnessInvocationModes as R, addMcpServer as S, parseJsonc as T, ListModelsResult as U, InvokeResult as V, McpConfigFile as W, ResolveOptions as X, PromptTemplateSyncTarget as Y, ResolvedPaths as Z, McpConfigListing as _, PromptSyncAction as a, SyncReport as b, PromptTemplateTargetResult as c, AgentsConfig as d, version as et, AgentsSyncAction as f, syncAgentsFiles as g, readAgentsConfig as h, syncSkills as i, AvailableModel as j, Harness as k, syncPromptTemplates as l, AgentsTargetResult as m, SkillsSyncReport as n, PromptSyncReport as o, AgentsSyncReport as p, PathCategory as q, SkillsSyncTargetResult as r, PromptSyncTargetResult as s, SkillsSyncAction as t, AgentsCompanionTargetResult as u, McpEnvError as v, masterMcpPath as w, SyncTargetResult as x, McpTransportError as y, HarnessModelListing as z };
612
624
  //# sourceMappingURL=skills-sync.d.mts.map
@@ -1 +1 @@
1
- {"version":3,"file":"skills-sync.d.mts","names":[],"sources":["../../src/types.ts","../../src/harness.ts","../../src/mcp-servers.ts","../../src/agents-sync.ts","../../src/prompt-sync.ts","../../src/directory-link.ts","../../src/skills-sync.ts"],"mappings":"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"}
1
+ {"version":3,"file":"skills-sync.d.mts","names":[],"sources":["../../src/types.ts","../../src/harness.ts","../../src/mcp-servers.ts","../../src/agents-sync.ts","../../src/prompt-sync.ts","../../src/directory-link.ts","../../src/skills-sync.ts"],"mappings":"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"}
@@ -66,6 +66,13 @@ function requestedInvocationMode(options) {
66
66
  if (options.tools === true) return options.structured === true ? "agentStructured" : "agent";
67
67
  return options.structured === true ? "advisorStructured" : "advisor";
68
68
  }
69
+ const EFFORT_PATTERN = /^[a-z]+$/u;
70
+ function selectionError(id, invocation, options) {
71
+ if (options.model !== void 0 && !invocation.modelArgs) return `Harness ${id} does not support model selection`;
72
+ if (options.effort === void 0) return null;
73
+ if (!invocation.effortArgs) return `Harness ${id} does not support reasoning effort`;
74
+ return EFFORT_PATTERN.test(options.effort) ? null : "Reasoning effort must be one lowercase word, such as low or high";
75
+ }
69
76
  function accessConflictError(id, invocation, options) {
70
77
  if (options.readOnly !== true || options.tools !== false) return null;
71
78
  const retries = [];
@@ -111,10 +118,24 @@ function compareVersions(a, b) {
111
118
  }
112
119
  return Number(aPre === void 0) - Number(bPre === void 0);
113
120
  }
114
- function buildInvocationArgs(template, prompt, modelArgs, model) {
115
- const args = template.map((arg) => arg.replaceAll("{prompt}", () => prompt));
116
- if (model !== void 0 && modelArgs) args.push(...modelArgs.map((arg) => arg.replaceAll("{model}", () => model)));
117
- return args;
121
+ function readOnlyVersionError(id, invocation, installed) {
122
+ const floor = invocation?.readOnlyMinVersion;
123
+ if (floor === void 0) return null;
124
+ const error = `Harness ${id} requires version ${floor} or newer for read-only runs`;
125
+ if (installed === null) return `${error}; installed version unknown`;
126
+ if (compareVersions(installed, floor) < 0) return `${error}; installed ${installed}`;
127
+ return null;
128
+ }
129
+ function fillArgs(args, placeholder, value) {
130
+ if (value === void 0 || !args) return [];
131
+ return args.map((arg) => arg.replaceAll(placeholder, () => value));
132
+ }
133
+ function buildInvocationArgs(template, prompt, invocation, options) {
134
+ return [
135
+ ...fillArgs(template, "{prompt}", prompt),
136
+ ...fillArgs(invocation.modelArgs, "{model}", options.model),
137
+ ...fillArgs(invocation.effortArgs, "{effort}", options.effort)
138
+ ];
118
139
  }
119
140
  function signalProcessGroup(pid, signal) {
120
141
  try {
@@ -310,18 +331,19 @@ var Harness = class {
310
331
  if (!this.invocation) return null;
311
332
  const command = this.invocation.binary ?? this.binaries[0];
312
333
  if (!command) return null;
313
- if (options.model !== void 0 && !this.invocation.modelArgs) return null;
334
+ if (selectionError(this.id, this.invocation, options) !== null) return null;
314
335
  if (accessConflictError(this.id, this.invocation, options) !== null) return null;
315
336
  const template = invocationTemplate(this.invocation, requestedInvocationMode(options));
316
337
  if (!template) return null;
317
338
  return {
318
339
  command,
319
- args: buildInvocationArgs(template, prompt, this.invocation.modelArgs, options.model)
340
+ args: buildInvocationArgs(template, prompt, this.invocation, options)
320
341
  };
321
342
  }
322
343
  invocationError(options = {}) {
323
344
  if (!this.invocation) return `Harness ${this.id} has no non-interactive invocation`;
324
- if (options.model !== void 0 && !this.invocation.modelArgs) return `Harness ${this.id} does not support model selection`;
345
+ const unsupported = selectionError(this.id, this.invocation, options);
346
+ if (unsupported !== null) return unsupported;
325
347
  const conflict = accessConflictError(this.id, this.invocation, options);
326
348
  if (conflict !== null) return conflict;
327
349
  const mode = requestedInvocationMode(options);
@@ -333,6 +355,7 @@ var Harness = class {
333
355
  if (parent) return Promise.reject(/* @__PURE__ */ new Error(`Nested run refused: this process already runs inside ${parent}, started by harnesses. ${this.id} under it would stack agents, and in a read-only sandbox it gets no network and hangs until the deadline. Answer without it`));
334
356
  const invocationOptions = {
335
357
  model: options.model,
358
+ effort: options.effort,
336
359
  structured: options.structured,
337
360
  tools: options.tools,
338
361
  readOnly: options.readOnly
@@ -359,13 +382,8 @@ var Harness = class {
359
382
  throw new Error(`Harness ${this.id} does not implement stream output folding`);
360
383
  }
361
384
  readOnlyVersionError(options) {
362
- const floor = this.invocation?.readOnlyMinVersion;
363
- if (floor === void 0 || options.readOnly !== true) return null;
364
- const installed = this.version;
365
- const error = `Harness ${this.id} requires version ${floor} or newer for read-only runs`;
366
- if (installed === null) return `${error}; installed version unknown`;
367
- if (compareVersions(installed, floor) < 0) return `${error}; installed ${installed}`;
368
- return null;
385
+ if (this.invocation?.readOnlyMinVersion === void 0 || options.readOnly !== true) return null;
386
+ return readOnlyVersionError(this.id, this.invocation, this.version);
369
387
  }
370
388
  buildModelListInvocation(search) {
371
389
  if (!this.modelListing) return null;
@@ -851,6 +869,7 @@ var Claude = class extends Harness {
851
869
  ],
852
870
  readOnlyMinVersion: "2.1.175",
853
871
  modelArgs: ["--model", "{model}"],
872
+ effortArgs: ["--effort", "{effort}"],
854
873
  streamArgs: [
855
874
  "--output-format",
856
875
  "stream-json",
@@ -953,6 +972,32 @@ var Claude = class extends Harness {
953
972
  };
954
973
  //#endregion
955
974
  //#region src/harnesses/codex.ts
975
+ function isRecord$1(value) {
976
+ return typeof value === "object" && value !== null && !Array.isArray(value);
977
+ }
978
+ function codexModel(entry) {
979
+ if (!isRecord$1(entry) || typeof entry["slug"] !== "string") throw new Error(`Unexpected Codex model-list entry: ${JSON.stringify(entry)?.slice(0, 200)}`);
980
+ if (entry["visibility"] !== "list") return void 0;
981
+ const { display_name: name, context_window: contextWindow, supported_reasoning_levels: levels, input_modalities: input } = entry;
982
+ return {
983
+ provider: "openai",
984
+ id: entry["slug"],
985
+ ...typeof name === "string" ? { name } : {},
986
+ ...typeof contextWindow === "number" ? { contextWindow } : {},
987
+ ...Array.isArray(levels) ? { thinking: levels.length > 0 } : {},
988
+ ...Array.isArray(input) ? { images: input.includes("image") } : {}
989
+ };
990
+ }
991
+ function parseCodexModels(stdout) {
992
+ let parsed;
993
+ try {
994
+ parsed = JSON.parse(stdout);
995
+ } catch {
996
+ throw new Error(`Unexpected Codex model-list output: ${JSON.stringify(stdout.slice(0, 200))}`);
997
+ }
998
+ if (!isRecord$1(parsed) || !Array.isArray(parsed["models"])) throw new Error(`Unexpected Codex model-list output: ${JSON.stringify(stdout.slice(0, 200))}`);
999
+ return parsed["models"].flatMap((entry) => codexModel(entry) ?? []);
1000
+ }
956
1001
  var Codex = class extends Harness {
957
1002
  id = "codex";
958
1003
  name = "OpenAI Codex CLI";
@@ -1122,9 +1167,15 @@ var Codex = class extends Harness {
1122
1167
  "{prompt}"
1123
1168
  ],
1124
1169
  modelArgs: ["--model", "{model}"],
1170
+ effortArgs: ["-c", "model_reasoning_effort={effort}"],
1125
1171
  level: "official",
1126
1172
  note: "Non-interactive exec subcommand; add --json for structured output."
1127
1173
  };
1174
+ modelListing = {
1175
+ args: ["debug", "models"],
1176
+ level: "official",
1177
+ note: "Prints the model catalog as JSON, refreshed from OpenAI unless --bundled, with no filter of its own; only models Codex shows in its picker are kept. It lives under debug, so the shape can move between releases; verified with 0.160.0."
1178
+ };
1128
1179
  mcpConfigs = [{
1129
1180
  path: "~/.codex/config.toml",
1130
1181
  scope: "user",
@@ -1164,6 +1215,12 @@ var Codex = class extends Harness {
1164
1215
  ".agents/skills"
1165
1216
  ]
1166
1217
  };
1218
+ modelSelector(model) {
1219
+ return model.id;
1220
+ }
1221
+ parseModelListingOutput(stdout) {
1222
+ return parseCodexModels(stdout);
1223
+ }
1167
1224
  };
1168
1225
  //#endregion
1169
1226
  //#region src/harnesses/cursor.ts
@@ -1746,6 +1803,7 @@ var Grok = class extends Harness {
1746
1803
  ],
1747
1804
  readOnlyMinVersion: "1.0.13",
1748
1805
  modelArgs: ["--model", "{model}"],
1806
+ effortArgs: ["--reasoning-effort", "{effort}"],
1749
1807
  level: "official",
1750
1808
  note: "-p is short for --single; add --output-format json for structured output. --sandbox read-only is kernel-enforced (Landlock, Seatbelt) regardless of the inherited permission mode and still allows writes to ~/.grok and temp dirs; verified on Linux with 1.0.13 and 1.0.25."
1751
1809
  };
@@ -2036,6 +2094,30 @@ var MastraCode = class extends Harness {
2036
2094
  };
2037
2095
  //#endregion
2038
2096
  //#region src/harnesses/omp.ts
2097
+ function isRecord(value) {
2098
+ return typeof value === "object" && value !== null && !Array.isArray(value);
2099
+ }
2100
+ function parseOmpModels(stdout) {
2101
+ let parsed;
2102
+ try {
2103
+ parsed = JSON.parse(stdout);
2104
+ } catch {
2105
+ throw new Error(`Unexpected OMP model-list output: ${JSON.stringify(stdout.slice(0, 200))}`);
2106
+ }
2107
+ if (!isRecord(parsed) || !Array.isArray(parsed["models"])) throw new Error(`Unexpected OMP model-list output: ${JSON.stringify(stdout.slice(0, 200))}`);
2108
+ return parsed["models"].map((entry) => {
2109
+ if (!isRecord(entry) || typeof entry["provider"] !== "string" || typeof entry["id"] !== "string") throw new Error(`Unexpected OMP model-list entry: ${JSON.stringify(entry)}`);
2110
+ const { contextWindow, maxTokens, reasoning, input } = entry;
2111
+ return {
2112
+ provider: entry["provider"],
2113
+ id: entry["id"],
2114
+ ...typeof contextWindow === "number" ? { contextWindow } : {},
2115
+ ...typeof maxTokens === "number" ? { maxOutputTokens: maxTokens } : {},
2116
+ ...typeof reasoning === "boolean" ? { thinking: reasoning } : {},
2117
+ ...Array.isArray(input) ? { images: input.includes("image") } : {}
2118
+ };
2119
+ });
2120
+ }
2039
2121
  var Omp = class extends Harness {
2040
2122
  id = "omp";
2041
2123
  name = "OMP (oh-my-pi)";
@@ -2222,9 +2304,31 @@ var Omp = class extends Harness {
2222
2304
  "{prompt}"
2223
2305
  ],
2224
2306
  modelArgs: ["--model={model}"],
2307
+ effortArgs: ["--thinking={effort}"],
2225
2308
  level: "official",
2226
2309
  note: "Add --mode json for structured event output. --no-tools disables only OMP's bundled tools, so it cannot provide an advisor mode without tools."
2227
2310
  };
2311
+ modelListing = {
2312
+ args: [
2313
+ "models",
2314
+ "--json",
2315
+ "--kind",
2316
+ "chat",
2317
+ "--no-extensions"
2318
+ ],
2319
+ searchArgs: [
2320
+ "models",
2321
+ "find",
2322
+ "--json",
2323
+ "--kind",
2324
+ "chat",
2325
+ "--no-extensions",
2326
+ "--",
2327
+ "{search}"
2328
+ ],
2329
+ level: "official",
2330
+ note: "Lists chat models with configured provider authentication as JSON; find matches a substring of the provider, id or name, ignoring case. --no-extensions keeps extension load errors out of the run; verified with 18.4.10."
2331
+ };
2228
2332
  mcpConfigs = [{
2229
2333
  path: "~/.omp/agent/mcp.json",
2230
2334
  scope: "user",
@@ -2260,6 +2364,9 @@ var Omp = class extends Harness {
2260
2364
  envVars: ["OMP_PROFILE", "PI_CODING_AGENT_DIR"],
2261
2365
  projectMarkers: [".omp"]
2262
2366
  };
2367
+ parseModelListingOutput(stdout) {
2368
+ return parseOmpModels(stdout);
2369
+ }
2263
2370
  };
2264
2371
  //#endregion
2265
2372
  //#region src/harnesses/opencode.ts
@@ -2610,6 +2717,7 @@ var Pi = class extends Harness {
2610
2717
  "{prompt}"
2611
2718
  ],
2612
2719
  modelArgs: ["--model", "{model}"],
2720
+ effortArgs: ["--thinking", "{effort}"],
2613
2721
  level: "official",
2614
2722
  note: "Add --mode json for structured event output."
2615
2723
  };
@@ -2619,6 +2727,23 @@ var Pi = class extends Harness {
2619
2727
  level: "official",
2620
2728
  note: "Lists models with configured provider authentication; accepts an optional fuzzy search."
2621
2729
  };
2730
+ mcpConfigs = [{
2731
+ path: "~/.pi/agent/mcp.json",
2732
+ scope: "user",
2733
+ level: "official",
2734
+ format: "json",
2735
+ key: ["mcpServers"],
2736
+ dialect: "pi",
2737
+ note: "Read by the built-in MCP extension, which -builtin:mcp in the extensions setting turns off."
2738
+ }, {
2739
+ path: ".pi/mcp.json",
2740
+ scope: "project",
2741
+ level: "official",
2742
+ format: "json",
2743
+ key: ["mcpServers"],
2744
+ dialect: "pi",
2745
+ note: "Read only after the project is trusted."
2746
+ }];
2622
2747
  envOverrides = [{
2623
2748
  variable: "PI_CODING_AGENT_DIR",
2624
2749
  path: "~/.pi/agent",
@@ -2999,6 +3124,9 @@ const ENV_REFERENCE = /^\$\{([A-Za-z_][A-Za-z0-9_]*)\}$/;
2999
3124
  var McpEnvError = class extends Error {
3000
3125
  name = "McpEnvError";
3001
3126
  };
3127
+ var McpTransportError = class extends Error {
3128
+ name = "McpTransportError";
3129
+ };
3002
3130
  function envReference(value) {
3003
3131
  return ENV_REFERENCE.exec(value)?.[1];
3004
3132
  }
@@ -3114,6 +3242,7 @@ function resolveEnvReferences(server, dialect) {
3114
3242
  }
3115
3243
  function shapeForDialect(server, dialect) {
3116
3244
  const shaped = resolveEnvReferences(server, dialect);
3245
+ if (dialect === "pi" && shaped.transport === "sse") throw new McpTransportError(`${server.name}: Pi takes stdio and streamable HTTP servers, not sse; point url at the server's streamable HTTP endpoint`);
3117
3246
  if (dialect !== "mastracode") return shaped;
3118
3247
  return compact({
3119
3248
  ...shaped,
@@ -3128,6 +3257,26 @@ function denormalizeEntry(server, dialect) {
3128
3257
  if (dialect === "prime") return denormalizePrime(server);
3129
3258
  return denormalizeStandard(server);
3130
3259
  }
3260
+ const STANDARD_FIELDS = /* @__PURE__ */ new Set([
3261
+ "type",
3262
+ "command",
3263
+ "args",
3264
+ "env",
3265
+ "url",
3266
+ "httpUrl",
3267
+ "headers",
3268
+ "enabled"
3269
+ ]);
3270
+ function replacementEntry(previous, server, dialect) {
3271
+ const entry = denormalizeEntry(server, dialect);
3272
+ if (dialect !== "pi" || !isObjectRecord(previous)) return entry;
3273
+ if (normalizeStandard(server.name, previous).transport !== server.transport) return entry;
3274
+ const kept = Object.entries(previous).filter(([key]) => !STANDARD_FIELDS.has(key));
3275
+ return {
3276
+ ...entry,
3277
+ ...Object.fromEntries(kept)
3278
+ };
3279
+ }
3131
3280
  function listingBase(entry, path) {
3132
3281
  return compact({
3133
3282
  path,
@@ -3268,7 +3417,7 @@ function addMcpServer(harness, server, scope = "user", options = {}) {
3268
3417
  const map = drill(root, entry.key, "create");
3269
3418
  if (!map) throw new Error(`Config at ${path} has a non-object at ${entry.key.join(".")}`);
3270
3419
  const replaced = Object.hasOwn(map, server.name);
3271
- map[server.name] = denormalizeEntry(resolved, entry.dialect);
3420
+ map[server.name] = replacementEntry(map[server.name], resolved, entry.dialect);
3272
3421
  writeAtomically(path, `${JSON.stringify(root, null, 2)}\n`);
3273
3422
  return {
3274
3423
  path,
@@ -3474,6 +3623,9 @@ function withdrawMasterServersFromExcludedHarness(harness, existing, masterNames
3474
3623
  results
3475
3624
  };
3476
3625
  }
3626
+ function cannotHold(error) {
3627
+ return error instanceof McpEnvError || error instanceof McpTransportError;
3628
+ }
3477
3629
  function syncIncludedHarness(harness, master, existing, masterNames, initialPath, options) {
3478
3630
  const results = [];
3479
3631
  let path = initialPath;
@@ -3494,7 +3646,7 @@ function syncIncludedHarness(harness, master, existing, masterNames, initialPath
3494
3646
  action: written.replaced ? "replaced" : "added"
3495
3647
  });
3496
3648
  } catch (error) {
3497
- if (!(error instanceof McpEnvError)) throw error;
3649
+ if (!cannotHold(error)) throw error;
3498
3650
  results.push({
3499
3651
  name: server.name,
3500
3652
  action: "skipped",
@@ -4149,6 +4301,6 @@ function syncSkills(harnesses, check = false, options = {}) {
4149
4301
  };
4150
4302
  }
4151
4303
  //#endregion
4152
- export { agntnDataDir as C, agntnConfigDir as S, getHarness as _, McpEnvError as a, registerHarness as b, masterMcpPath as c, removeMcpServer as d, syncMcpServers as f, getAllHarnesses as g, detectProjectHarnesses as h, syncAgentsFiles as i, parseJsonc as l, detectHarnessFromEnv as m, syncPromptTemplates as n, addMcpServer as o, detectHarness as p, readAgentsConfig as r, listMcpServers as s, syncSkills as t, readMasterMcpServers as u, isHarnessId as v, resolvePathTemplate as w, Harness as x, listHarnesses as y };
4304
+ export { readOnlyVersionError as C, resolvePathTemplate as D, agntnDataDir as E, Harness as S, agntnConfigDir as T, getAllHarnesses as _, McpEnvError as a, listHarnesses as b, listMcpServers as c, readMasterMcpServers as d, removeMcpServer as f, detectProjectHarnesses as g, detectHarnessFromEnv as h, syncAgentsFiles as i, masterMcpPath as l, detectHarness as m, syncPromptTemplates as n, McpTransportError as o, syncMcpServers as p, readAgentsConfig as r, addMcpServer as s, syncSkills as t, parseJsonc as u, getHarness as v, selectionError as w, registerHarness as x, isHarnessId as y };
4153
4305
 
4154
4306
  //# sourceMappingURL=skills-sync.mjs.map