@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 +16 -16
- package/dist/_chunks/agents.mjs +1 -1
- package/dist/_chunks/mcp-servers.mjs +1 -1
- package/dist/_chunks/output.mjs +1 -1
- package/dist/_chunks/output.mjs.map +1 -1
- package/dist/_chunks/skills-sync.d.mts +16 -4
- package/dist/_chunks/skills-sync.d.mts.map +1 -1
- package/dist/_chunks/skills-sync.mjs +169 -17
- package/dist/_chunks/skills-sync.mjs.map +1 -1
- package/dist/_chunks/tool-operations.mjs +29 -11
- package/dist/_chunks/tool-operations.mjs.map +1 -1
- package/dist/_chunks/tool-schemas.d.mts +1 -0
- package/dist/_chunks/tool-schemas.d.mts.map +1 -1
- package/dist/_chunks/tool-schemas.mjs +6 -0
- package/dist/_chunks/tool-schemas.mjs.map +1 -1
- package/dist/_chunks/types.mjs +1 -1
- package/dist/_chunks/types.mjs.map +1 -1
- package/dist/cli.mjs +34 -23
- package/dist/cli.mjs.map +1 -1
- package/dist/index.d.mts +2 -2
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +2 -2
- package/dist/index.mjs.map +1 -1
- package/dist/mcp.d.mts.map +1 -1
- package/dist/mcp.mjs +3 -2
- package/dist/mcp.mjs.map +1 -1
- package/dist/tool-operations.d.mts +14 -4
- package/dist/tool-operations.d.mts.map +1 -1
- package/package.json +2 -2
- package/packages/omp/extensions/harnesses.ts +15 -44
- package/packages/pi/extensions/harnesses.ts +8 -4
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
|
|
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.
|
|
49
|
-
โ claude Anthropic Claude Code
|
|
50
|
-
โ codex OpenAI Codex CLI
|
|
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
|
|
56
|
-
โ mastracode Mastra Code
|
|
57
|
-
โ omp OMP (oh-my-pi)
|
|
58
|
-
โ opencode OpenCode CLI
|
|
59
|
-
โ prime-agent Prime Agent
|
|
60
|
-
โ pi Pi Coding Agent
|
|
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 `--
|
|
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,
|
|
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`
|
|
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
|
|
package/dist/_chunks/agents.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
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 {
|
|
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";
|
package/dist/_chunks/output.mjs
CHANGED
|
@@ -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\
|
|
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
|
-
*
|
|
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 {
|
|
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":";cAEa;KAED;KAcA;KACA;UAEK;EACf;EACA;EACA,OAAO;EACP,YAAY;EACZ;;;KAIU;;;;;UAcK,oBAAoB;EACnC;;EAEA,WAAW;;;UAII,yBAAyB;EACxC;;;UAIe,iCAAiC;EAChD;EACA;;UAGe;EACf;EACA,OAAO;EACP;;UAGe;EACf;EACA;;EAEA;;EAEA;EACA;EACA;;;UAIe;;EAEf;;EAEA;;EAEA;;EAEA;;EAEA;;EAEA;;EAEA;;EAEA;;EAEA;;;;;;EAMA;EACA,OAAO;EACP;;;UAIe;EACf;EACA;EACA;EACA;EACA;EACA;;;UAIe;;EAEf;;;;;EAKA;EACA,OAAO;EACP;;;UAIe;EACf;EACA;;EAEA;EACA;EACA;EACA;;EAEA;;;UAIe;EACf;EACA;EACA,MAAM;;EAEN;;EAEA,SAAS;;UAGM;EACf;EACA,MAAM;;EAEN;;EAEA;;EAEA;;EAEA;;EAEA,SAAS;;EAET;;UAGe;EACf;EACA;EACA;EACA;;EAEA;EACA;;EAEA;;EAEA;;;UAIe,yBAAyB;;EAExC,QAAQ;;;UAIO;EACf;EACA;EACA;EACA;;;;;;EAMA,MAAM;EACN;EACA,UAAU;;EAEV;;;UAIe,sBAAsB;EACrC;;EAEA
|
|
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
|
|
115
|
-
const
|
|
116
|
-
if (
|
|
117
|
-
|
|
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 (
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
363
|
-
|
|
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] =
|
|
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
|
|
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 {
|
|
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
|