@agntn/harnesses 0.4.0 → 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
@@ -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
 
@@ -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. */
@@ -211,6 +217,7 @@ interface ResolvedPaths {
211
217
  //#region src/harness.d.ts
212
218
  type InvocationOptions = Readonly<{
213
219
  model?: string;
220
+ effort?: string;
214
221
  structured?: boolean;
215
222
  tools?: boolean;
216
223
  readOnly?: boolean;
@@ -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
  };
@@ -2246,6 +2304,7 @@ var Omp = class extends Harness {
2246
2304
  "{prompt}"
2247
2305
  ],
2248
2306
  modelArgs: ["--model={model}"],
2307
+ effortArgs: ["--thinking={effort}"],
2249
2308
  level: "official",
2250
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."
2251
2310
  };
@@ -2658,6 +2717,7 @@ var Pi = class extends Harness {
2658
2717
  "{prompt}"
2659
2718
  ],
2660
2719
  modelArgs: ["--model", "{model}"],
2720
+ effortArgs: ["--thinking", "{effort}"],
2661
2721
  level: "official",
2662
2722
  note: "Add --mode json for structured event output."
2663
2723
  };
@@ -4241,6 +4301,6 @@ function syncSkills(harnesses, check = false, options = {}) {
4241
4301
  };
4242
4302
  }
4243
4303
  //#endregion
4244
- export { agntnConfigDir as C, Harness as S, resolvePathTemplate 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, agntnDataDir as w, registerHarness as x, isHarnessId 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 };
4245
4305
 
4246
4306
  //# sourceMappingURL=skills-sync.mjs.map