@agntn/harnesses 0.1.0 → 0.2.0
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 +130 -116
- package/dist/_chunks/agents-sync.d.mts +56 -43
- package/dist/_chunks/agents-sync.d.mts.map +1 -1
- package/dist/_chunks/agents-sync.mjs +313 -35
- package/dist/_chunks/agents-sync.mjs.map +1 -1
- package/dist/_chunks/libs/typebox.mjs +524 -600
- package/dist/_chunks/libs/typebox.mjs.map +1 -1
- package/dist/_chunks/mcp.mjs +1 -1
- package/dist/_chunks/mcp.mjs.map +1 -1
- package/dist/_chunks/tool-operations.mjs +34 -9
- package/dist/_chunks/tool-operations.mjs.map +1 -1
- package/dist/_chunks/tool-schemas.d.mts +12 -13
- package/dist/_chunks/tool-schemas.d.mts.map +1 -1
- package/dist/_chunks/types.mjs +1 -1
- package/dist/_chunks/types.mjs.map +1 -1
- package/dist/index.d.mts +12 -12
- 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 +1 -2
- package/dist/mcp.d.mts.map +1 -1
- package/dist/tool-operations.d.mts +34 -33
- package/dist/tool-operations.d.mts.map +1 -1
- package/package.json +27 -28
- package/packages/pi/extensions/harnesses.ts +3 -1
|
@@ -1,5 +1,6 @@
|
|
|
1
|
+
import { createRequire } from "node:module";
|
|
1
2
|
import { addAbortListener } from "node:events";
|
|
2
|
-
import { existsSync, lstatSync, mkdirSync, readFileSync, readlinkSync, renameSync, symlinkSync, unlinkSync, writeFileSync } from "node:fs";
|
|
3
|
+
import { existsSync, lstatSync, mkdirSync, readFileSync, readlinkSync, realpathSync, renameSync, symlinkSync, unlinkSync, writeFileSync } from "node:fs";
|
|
3
4
|
import { execFile, execFileSync, spawn } from "node:child_process";
|
|
4
5
|
import { setTimeout as setTimeout$1 } from "node:timers/promises";
|
|
5
6
|
import { basename, dirname, isAbsolute, join, posix, resolve, win32 } from "node:path";
|
|
@@ -963,6 +964,18 @@ var Freebuff = class extends Harness {
|
|
|
963
964
|
id = "freebuff";
|
|
964
965
|
name = "Freebuff";
|
|
965
966
|
binaries = ["freebuff"];
|
|
967
|
+
get version() {
|
|
968
|
+
const configDir = join(homedir(), ".config", "manicode");
|
|
969
|
+
const binaryName = process.platform === "win32" ? "freebuff.exe" : "freebuff";
|
|
970
|
+
if (!existsSync(join(configDir, binaryName))) return null;
|
|
971
|
+
try {
|
|
972
|
+
const metadata = JSON.parse(readFileSync(join(configDir, "freebuff-metadata.json"), "utf8"));
|
|
973
|
+
if (typeof metadata === "object" && metadata !== null && "version" in metadata && typeof metadata.version === "string" && metadata.version !== "") return metadata.version;
|
|
974
|
+
} catch {
|
|
975
|
+
return null;
|
|
976
|
+
}
|
|
977
|
+
return null;
|
|
978
|
+
}
|
|
966
979
|
capabilities = {
|
|
967
980
|
mcp: true,
|
|
968
981
|
vision: true,
|
|
@@ -1417,10 +1430,43 @@ var Grok = class extends Harness {
|
|
|
1417
1430
|
projectMarkers: [".grok"]
|
|
1418
1431
|
};
|
|
1419
1432
|
};
|
|
1433
|
+
function packageVersion(commandPath) {
|
|
1434
|
+
try {
|
|
1435
|
+
const require = createRequire(realpathSync(commandPath));
|
|
1436
|
+
const metadata = JSON.parse(readFileSync(require.resolve("mastracode/package.json"), "utf8"));
|
|
1437
|
+
if (typeof metadata === "object" && metadata !== null && "version" in metadata && typeof metadata.version === "string" && metadata.version !== "") return metadata.version;
|
|
1438
|
+
} catch {
|
|
1439
|
+
return null;
|
|
1440
|
+
}
|
|
1441
|
+
return null;
|
|
1442
|
+
}
|
|
1420
1443
|
var MastraCode = class extends Harness {
|
|
1421
1444
|
id = "mastracode";
|
|
1422
1445
|
name = "Mastra Code";
|
|
1423
1446
|
binaries = ["mastracode"];
|
|
1447
|
+
get version() {
|
|
1448
|
+
const locator = process.platform === "win32" ? "where" : "which";
|
|
1449
|
+
let output;
|
|
1450
|
+
try {
|
|
1451
|
+
output = execFileSync(locator, [this.binaries[0] ?? "mastracode"], {
|
|
1452
|
+
encoding: "utf8",
|
|
1453
|
+
stdio: [
|
|
1454
|
+
"pipe",
|
|
1455
|
+
"pipe",
|
|
1456
|
+
"pipe"
|
|
1457
|
+
],
|
|
1458
|
+
timeout: 5e3
|
|
1459
|
+
});
|
|
1460
|
+
} catch {
|
|
1461
|
+
return null;
|
|
1462
|
+
}
|
|
1463
|
+
const paths = output.split(/\r?\n/u).filter((path) => path !== "");
|
|
1464
|
+
for (const path of paths) {
|
|
1465
|
+
const version = packageVersion(path);
|
|
1466
|
+
if (version !== null) return version;
|
|
1467
|
+
}
|
|
1468
|
+
return null;
|
|
1469
|
+
}
|
|
1424
1470
|
capabilities = {
|
|
1425
1471
|
mcp: true,
|
|
1426
1472
|
vision: true,
|
|
@@ -1896,16 +1942,37 @@ const MODEL_HEADERS = [
|
|
|
1896
1942
|
"thinking",
|
|
1897
1943
|
"images"
|
|
1898
1944
|
];
|
|
1899
|
-
function parseTokenCount(value) {
|
|
1945
|
+
function parseTokenCount(value, harness) {
|
|
1900
1946
|
const match = /^(\d+(?:\.\d+)?)([KM])?$/.exec(value);
|
|
1901
|
-
if (!match?.[1]) throw new Error(`Invalid
|
|
1947
|
+
if (!match?.[1]) throw new Error(`Invalid ${harness} token count: ${JSON.stringify(value)}`);
|
|
1902
1948
|
const multiplier = match[2] === "M" ? 1e6 : match[2] === "K" ? 1e3 : 1;
|
|
1903
1949
|
return Number(match[1]) * multiplier;
|
|
1904
1950
|
}
|
|
1905
|
-
function parseBoolean(value, column) {
|
|
1951
|
+
function parseBoolean(value, column, harness) {
|
|
1906
1952
|
if (value === "yes") return true;
|
|
1907
1953
|
if (value === "no") return false;
|
|
1908
|
-
throw new Error(`Invalid
|
|
1954
|
+
throw new Error(`Invalid ${harness} ${column} value: ${JSON.stringify(value)}`);
|
|
1955
|
+
}
|
|
1956
|
+
function parsePiModelTable(stdout, harness) {
|
|
1957
|
+
const lines = stripVTControlCharacters(stdout).split(/\r?\n/).map((line) => line.trim()).filter(Boolean);
|
|
1958
|
+
const first = lines[0];
|
|
1959
|
+
if (!first) throw new Error(`Unexpected empty ${harness} model-list output`);
|
|
1960
|
+
if (first.startsWith("No models available.") || first.startsWith("No models matching ")) return [];
|
|
1961
|
+
const headers = first.split(/\s{2,}/);
|
|
1962
|
+
if (headers.length !== MODEL_HEADERS.length || headers.some((value, i) => value !== MODEL_HEADERS[i])) throw new Error(`Unexpected ${harness} model-list header: ${JSON.stringify(first)}`);
|
|
1963
|
+
return lines.slice(1).map((line) => {
|
|
1964
|
+
const columns = line.split(/\s{2,}/);
|
|
1965
|
+
const [provider, id, context, maxOutput, thinking, images] = columns;
|
|
1966
|
+
if (columns.length !== MODEL_HEADERS.length || !provider || !id || !context || !maxOutput || !thinking || !images) throw new Error(`Unexpected ${harness} model-list row: ${JSON.stringify(line)}`);
|
|
1967
|
+
return {
|
|
1968
|
+
provider,
|
|
1969
|
+
id,
|
|
1970
|
+
contextWindow: parseTokenCount(context, harness),
|
|
1971
|
+
maxOutputTokens: parseTokenCount(maxOutput, harness),
|
|
1972
|
+
thinking: parseBoolean(thinking, "thinking", harness),
|
|
1973
|
+
images: parseBoolean(images, "images", harness)
|
|
1974
|
+
};
|
|
1975
|
+
});
|
|
1909
1976
|
}
|
|
1910
1977
|
var Pi = class extends Harness {
|
|
1911
1978
|
id = "pi";
|
|
@@ -2046,25 +2113,172 @@ var Pi = class extends Harness {
|
|
|
2046
2113
|
projectMarkers: [".pi"]
|
|
2047
2114
|
};
|
|
2048
2115
|
parseModelListingOutput(stdout) {
|
|
2049
|
-
|
|
2050
|
-
|
|
2051
|
-
|
|
2052
|
-
|
|
2053
|
-
|
|
2054
|
-
|
|
2055
|
-
|
|
2056
|
-
|
|
2057
|
-
|
|
2058
|
-
|
|
2059
|
-
|
|
2060
|
-
|
|
2061
|
-
|
|
2062
|
-
|
|
2063
|
-
|
|
2064
|
-
|
|
2065
|
-
|
|
2066
|
-
|
|
2067
|
-
|
|
2116
|
+
return parsePiModelTable(stdout, "Pi");
|
|
2117
|
+
}
|
|
2118
|
+
};
|
|
2119
|
+
var PrimeAgent = class extends Harness {
|
|
2120
|
+
id = "prime-agent";
|
|
2121
|
+
name = "Prime Agent";
|
|
2122
|
+
binaries = ["prime-agent"];
|
|
2123
|
+
capabilities = {
|
|
2124
|
+
mcp: true,
|
|
2125
|
+
vision: true,
|
|
2126
|
+
audio: false,
|
|
2127
|
+
video: false,
|
|
2128
|
+
tools: true,
|
|
2129
|
+
streaming: true
|
|
2130
|
+
};
|
|
2131
|
+
config = [{
|
|
2132
|
+
path: "~/.prime/agent/settings.json",
|
|
2133
|
+
scope: "user",
|
|
2134
|
+
level: "official",
|
|
2135
|
+
note: "Config dir overridable with PRIME_AGENT_CODING_AGENT_DIR."
|
|
2136
|
+
}, {
|
|
2137
|
+
path: ".prime/agent/settings.json",
|
|
2138
|
+
scope: "project",
|
|
2139
|
+
level: "official"
|
|
2140
|
+
}];
|
|
2141
|
+
sessions = [{
|
|
2142
|
+
path: "~/.prime/agent/sessions/<session-id>.jsonl",
|
|
2143
|
+
scope: "data",
|
|
2144
|
+
level: "official",
|
|
2145
|
+
note: "Flat directory of JSONL transcripts whose header records the working directory; session ids are UUIDv7. Overridable with PRIME_AGENT_SESSION_DIR or --session-dir."
|
|
2146
|
+
}, {
|
|
2147
|
+
path: "~/.prime/agent/session-artifacts/<session-id>/",
|
|
2148
|
+
scope: "data",
|
|
2149
|
+
level: "official",
|
|
2150
|
+
note: "Per-session Python kernel state, scheduled jobs, harness state and child session transcripts under sub-<id>/."
|
|
2151
|
+
}];
|
|
2152
|
+
persistence = [
|
|
2153
|
+
{
|
|
2154
|
+
format: "JSON",
|
|
2155
|
+
level: "official",
|
|
2156
|
+
note: "Settings, auth, telemetry, model cache and session artifact state files."
|
|
2157
|
+
},
|
|
2158
|
+
{
|
|
2159
|
+
format: "JSONL",
|
|
2160
|
+
level: "official",
|
|
2161
|
+
note: "Session transcripts, the RLM spawn ledger and structured logs."
|
|
2162
|
+
},
|
|
2163
|
+
{
|
|
2164
|
+
format: "dill",
|
|
2165
|
+
level: "official",
|
|
2166
|
+
note: "Pickled Python REPL state (kernel-state.dill) in session artifacts."
|
|
2167
|
+
}
|
|
2168
|
+
];
|
|
2169
|
+
instructions = [
|
|
2170
|
+
{
|
|
2171
|
+
path: "AGENTS.md",
|
|
2172
|
+
scope: "project",
|
|
2173
|
+
level: "official",
|
|
2174
|
+
note: "Loaded from parent directories and cwd; CLAUDE.md accepted as an alternative."
|
|
2175
|
+
},
|
|
2176
|
+
{
|
|
2177
|
+
path: ".prime/agent/SYSTEM.md",
|
|
2178
|
+
scope: "project",
|
|
2179
|
+
level: "official",
|
|
2180
|
+
note: "Replaces the default system prompt; APPEND_SYSTEM.md appends instead."
|
|
2181
|
+
},
|
|
2182
|
+
{
|
|
2183
|
+
path: "~/.prime/agent/AGENTS.md",
|
|
2184
|
+
scope: "user",
|
|
2185
|
+
level: "official",
|
|
2186
|
+
note: "Global user-level instructions; CLAUDE.md accepted as an alternative."
|
|
2187
|
+
},
|
|
2188
|
+
{
|
|
2189
|
+
path: "~/.prime/agent/SYSTEM.md",
|
|
2190
|
+
scope: "user",
|
|
2191
|
+
level: "official",
|
|
2192
|
+
note: "Global system prompt replacement; APPEND_SYSTEM.md appends instead."
|
|
2193
|
+
}
|
|
2194
|
+
];
|
|
2195
|
+
skills = [
|
|
2196
|
+
{
|
|
2197
|
+
path: ".prime/agent/skills/",
|
|
2198
|
+
scope: "project",
|
|
2199
|
+
level: "official"
|
|
2200
|
+
},
|
|
2201
|
+
{
|
|
2202
|
+
path: ".agents/skills/",
|
|
2203
|
+
scope: "project",
|
|
2204
|
+
level: "official",
|
|
2205
|
+
note: "Also scanned in ancestor directories up to the Git repository root; root .md files are ignored there."
|
|
2206
|
+
},
|
|
2207
|
+
{
|
|
2208
|
+
path: "~/.prime/agent/skills/",
|
|
2209
|
+
scope: "user",
|
|
2210
|
+
level: "official",
|
|
2211
|
+
note: "Global user-level skills."
|
|
2212
|
+
},
|
|
2213
|
+
{
|
|
2214
|
+
path: "~/.agents/skills/",
|
|
2215
|
+
scope: "user",
|
|
2216
|
+
level: "official",
|
|
2217
|
+
note: "Shared skills directory; root .md files are ignored there."
|
|
2218
|
+
}
|
|
2219
|
+
];
|
|
2220
|
+
commands = [{
|
|
2221
|
+
path: ".prime/agent/prompts/",
|
|
2222
|
+
scope: "project",
|
|
2223
|
+
level: "official",
|
|
2224
|
+
note: "Prompt templates invoked as slash commands."
|
|
2225
|
+
}, {
|
|
2226
|
+
path: "~/.prime/agent/prompts/",
|
|
2227
|
+
scope: "user",
|
|
2228
|
+
level: "official",
|
|
2229
|
+
note: "Global user-level prompt templates."
|
|
2230
|
+
}];
|
|
2231
|
+
hooks = [];
|
|
2232
|
+
invocation = {
|
|
2233
|
+
args: ["-p", "{prompt}"],
|
|
2234
|
+
jsonArgs: [
|
|
2235
|
+
"-p",
|
|
2236
|
+
"--mode",
|
|
2237
|
+
"json",
|
|
2238
|
+
"{prompt}"
|
|
2239
|
+
],
|
|
2240
|
+
noToolsArgs: [
|
|
2241
|
+
"-p",
|
|
2242
|
+
"--no-tools",
|
|
2243
|
+
"{prompt}"
|
|
2244
|
+
],
|
|
2245
|
+
noToolsJsonArgs: [
|
|
2246
|
+
"-p",
|
|
2247
|
+
"--no-tools",
|
|
2248
|
+
"--mode",
|
|
2249
|
+
"json",
|
|
2250
|
+
"{prompt}"
|
|
2251
|
+
],
|
|
2252
|
+
modelArgs: ["--model", "{model}"],
|
|
2253
|
+
level: "official",
|
|
2254
|
+
note: "Add --mode json for structured event output. No read-only mode: the only built-in tool is a Python REPL and the worker and kernel processes are not a security sandbox."
|
|
2255
|
+
};
|
|
2256
|
+
modelListing = {
|
|
2257
|
+
args: ["model", "list"],
|
|
2258
|
+
searchArgs: [
|
|
2259
|
+
"model",
|
|
2260
|
+
"list",
|
|
2261
|
+
"{search}"
|
|
2262
|
+
],
|
|
2263
|
+
level: "official",
|
|
2264
|
+
note: "Lists models with configured provider authentication; accepts an optional fuzzy search. --list-models was removed."
|
|
2265
|
+
};
|
|
2266
|
+
mcpConfigs = [{
|
|
2267
|
+
path: "~/.prime/agent/settings.json",
|
|
2268
|
+
scope: "user",
|
|
2269
|
+
level: "official",
|
|
2270
|
+
format: "json",
|
|
2271
|
+
key: ["mcpServers"],
|
|
2272
|
+
dialect: "prime",
|
|
2273
|
+
note: "prime-agent mcp add/remove manage this map; project settings entries are ignored for execution. Stdio env values are {\"env\": \"NAME\"} references, written from \"${NAME}\" values; literals are refused because the kernel rejects them at connect time."
|
|
2274
|
+
}];
|
|
2275
|
+
agentsFile = "~/.prime/agent/AGENTS.md";
|
|
2276
|
+
detection = {
|
|
2277
|
+
envVars: ["PRIME_AGENT_KERNEL_OWNER_PID"],
|
|
2278
|
+
projectMarkers: [".prime/agent"]
|
|
2279
|
+
};
|
|
2280
|
+
parseModelListingOutput(stdout) {
|
|
2281
|
+
return parsePiModelTable(stdout, "Prime Agent");
|
|
2068
2282
|
}
|
|
2069
2283
|
};
|
|
2070
2284
|
const harnesses = [
|
|
@@ -2079,6 +2293,7 @@ const harnesses = [
|
|
|
2079
2293
|
MastraCode,
|
|
2080
2294
|
Omp,
|
|
2081
2295
|
OpenCode,
|
|
2296
|
+
PrimeAgent,
|
|
2082
2297
|
Pi
|
|
2083
2298
|
];
|
|
2084
2299
|
let registry;
|
|
@@ -2222,9 +2437,30 @@ function normalizeStandard(name, raw) {
|
|
|
2222
2437
|
enabled: booleanField(raw, "enabled")
|
|
2223
2438
|
});
|
|
2224
2439
|
}
|
|
2440
|
+
const ENV_REFERENCE = /^\$\{([A-Za-z_][A-Za-z0-9_]*)\}$/;
|
|
2441
|
+
var McpEnvError = class extends Error {
|
|
2442
|
+
name = "McpEnvError";
|
|
2443
|
+
};
|
|
2444
|
+
function envReference(value) {
|
|
2445
|
+
return ENV_REFERENCE.exec(value)?.[1];
|
|
2446
|
+
}
|
|
2447
|
+
function primeEnv(value) {
|
|
2448
|
+
if (!isObjectRecord(value) || Array.isArray(value)) return void 0;
|
|
2449
|
+
const out = {};
|
|
2450
|
+
for (const [key, raw] of Object.entries(value)) if (typeof raw === "string") out[key] = raw;
|
|
2451
|
+
else if (isObjectRecord(raw) && typeof raw.env === "string") out[key] = `\${${raw.env}}`;
|
|
2452
|
+
return Object.keys(out).length > 0 ? out : void 0;
|
|
2453
|
+
}
|
|
2454
|
+
function normalizePrime(name, raw) {
|
|
2455
|
+
return compact({
|
|
2456
|
+
...normalizeStandard(name, raw),
|
|
2457
|
+
env: primeEnv(raw.env)
|
|
2458
|
+
});
|
|
2459
|
+
}
|
|
2225
2460
|
function normalizeEntry(name, raw, dialect) {
|
|
2226
2461
|
if (dialect === "antigravity") return normalizeAntigravity(name, raw);
|
|
2227
2462
|
if (dialect === "opencode") return normalizeOpenCode(name, raw);
|
|
2463
|
+
if (dialect === "prime") return normalizePrime(name, raw);
|
|
2228
2464
|
return normalizeStandard(name, raw);
|
|
2229
2465
|
}
|
|
2230
2466
|
function denormalizeAntigravity(server) {
|
|
@@ -2260,9 +2496,44 @@ function denormalizeStandard(server) {
|
|
|
2260
2496
|
enabled: server.enabled
|
|
2261
2497
|
});
|
|
2262
2498
|
}
|
|
2499
|
+
function denormalizePrime(server) {
|
|
2500
|
+
const env = server.env ? Object.fromEntries(Object.entries(server.env).map(([key, value]) => [key, { env: requirePrimeReference(server, key, value) }])) : void 0;
|
|
2501
|
+
return compact({
|
|
2502
|
+
...denormalizeStandard(server),
|
|
2503
|
+
env
|
|
2504
|
+
});
|
|
2505
|
+
}
|
|
2506
|
+
function requirePrimeReference(server, key, value) {
|
|
2507
|
+
const reference = envReference(value);
|
|
2508
|
+
if (reference === void 0) throw new McpEnvError(`${server.name}: Prime Agent takes only environment references in env; write ${key} as "\${NAME}" and export NAME where prime-agent runs`);
|
|
2509
|
+
return reference;
|
|
2510
|
+
}
|
|
2511
|
+
function resolveEnvReferences(server, dialect) {
|
|
2512
|
+
if (!server.env) return server;
|
|
2513
|
+
if (dialect === "prime") {
|
|
2514
|
+
for (const [key, value] of Object.entries(server.env)) requirePrimeReference(server, key, value);
|
|
2515
|
+
return server;
|
|
2516
|
+
}
|
|
2517
|
+
const env = {};
|
|
2518
|
+
for (const [key, value] of Object.entries(server.env)) {
|
|
2519
|
+
const reference = envReference(value);
|
|
2520
|
+
if (reference === void 0) {
|
|
2521
|
+
env[key] = value;
|
|
2522
|
+
continue;
|
|
2523
|
+
}
|
|
2524
|
+
const resolved = Object.hasOwn(process.env, reference) ? process.env[reference] : void 0;
|
|
2525
|
+
if (typeof resolved !== "string") throw new McpEnvError(`${server.name}: env ${key} references ${reference}, which is not set in this environment`);
|
|
2526
|
+
env[key] = resolved;
|
|
2527
|
+
}
|
|
2528
|
+
return {
|
|
2529
|
+
...server,
|
|
2530
|
+
env
|
|
2531
|
+
};
|
|
2532
|
+
}
|
|
2263
2533
|
function denormalizeEntry(server, dialect) {
|
|
2264
2534
|
if (dialect === "antigravity") return denormalizeAntigravity(server);
|
|
2265
2535
|
if (dialect === "opencode") return denormalizeOpenCode(server);
|
|
2536
|
+
if (dialect === "prime") return denormalizePrime(server);
|
|
2266
2537
|
return denormalizeStandard(server);
|
|
2267
2538
|
}
|
|
2268
2539
|
function listingBase(entry, path) {
|
|
@@ -2318,9 +2589,6 @@ function writeAtomically(path, content) {
|
|
|
2318
2589
|
writeFileSync(temp, content);
|
|
2319
2590
|
renameSync(temp, path);
|
|
2320
2591
|
}
|
|
2321
|
-
function escapeRegExp(value) {
|
|
2322
|
-
return value.replaceAll(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
2323
|
-
}
|
|
2324
2592
|
function tomlValue(value) {
|
|
2325
2593
|
return JSON.stringify(value);
|
|
2326
2594
|
}
|
|
@@ -2342,8 +2610,8 @@ function tomlSections(key, server) {
|
|
|
2342
2610
|
return `${lines.join("\n")}\n`;
|
|
2343
2611
|
}
|
|
2344
2612
|
function stripTomlServer(raw, key, name) {
|
|
2345
|
-
const prefix =
|
|
2346
|
-
const namePart = `(?:${
|
|
2613
|
+
const prefix = RegExp.escape(key.map(tomlKeyPart).join("."));
|
|
2614
|
+
const namePart = `(?:${RegExp.escape(tomlKeyPart(name))}|${RegExp.escape(JSON.stringify(name))})`;
|
|
2347
2615
|
const sectionRe = new RegExp(`^\\s*\\[${prefix}\\.${namePart}(\\.[^\\]]+)?\\]`);
|
|
2348
2616
|
const bareTableRe = new RegExp(`^\\s*\\[${prefix}\\]\\s*(#.*)?$`);
|
|
2349
2617
|
const anyHeaderRe = /^\s*\[/;
|
|
@@ -2399,15 +2667,16 @@ function removeTomlServer(path, key, name) {
|
|
|
2399
2667
|
}
|
|
2400
2668
|
function addMcpServer(harness, server, scope = "user", options = {}) {
|
|
2401
2669
|
const { entry, path } = writableConfig(harness, scope, options);
|
|
2670
|
+
const resolved = resolveEnvReferences(server, entry.dialect);
|
|
2402
2671
|
if (entry.format === "toml") return {
|
|
2403
2672
|
path,
|
|
2404
|
-
replaced: addTomlServer(path, entry.key,
|
|
2673
|
+
replaced: addTomlServer(path, entry.key, resolved)
|
|
2405
2674
|
};
|
|
2406
2675
|
const root = JSON.parse(readIfExists$1(path) ?? "{}");
|
|
2407
2676
|
const map = drill(root, entry.key, "create");
|
|
2408
2677
|
if (!map) throw new Error(`Config at ${path} has a non-object at ${entry.key.join(".")}`);
|
|
2409
2678
|
const replaced = Object.hasOwn(map, server.name);
|
|
2410
|
-
map[server.name] = denormalizeEntry(
|
|
2679
|
+
map[server.name] = denormalizeEntry(resolved, entry.dialect);
|
|
2411
2680
|
writeAtomically(path, `${JSON.stringify(root, null, 2)}\n`);
|
|
2412
2681
|
return {
|
|
2413
2682
|
path,
|
|
@@ -2616,20 +2885,29 @@ function withdrawMasterServersFromExcludedHarness(harness, existing, masterNames
|
|
|
2616
2885
|
function syncIncludedHarness(harness, master, existing, masterNames, initialPath, options) {
|
|
2617
2886
|
const results = [];
|
|
2618
2887
|
let path = initialPath;
|
|
2619
|
-
|
|
2620
|
-
|
|
2888
|
+
const { dialect } = writableConfig(harness, "user", options).entry;
|
|
2889
|
+
for (const server of master.servers) try {
|
|
2890
|
+
const resolved = resolveEnvReferences(server, dialect);
|
|
2891
|
+
if (existing.get(server.name) === canonical(resolved)) {
|
|
2621
2892
|
results.push({
|
|
2622
2893
|
name: server.name,
|
|
2623
2894
|
action: "unchanged"
|
|
2624
2895
|
});
|
|
2625
2896
|
continue;
|
|
2626
2897
|
}
|
|
2627
|
-
const written = addMcpServer(harness,
|
|
2898
|
+
const written = addMcpServer(harness, resolved, "user", options);
|
|
2628
2899
|
path = written.path;
|
|
2629
2900
|
results.push({
|
|
2630
2901
|
name: server.name,
|
|
2631
2902
|
action: written.replaced ? "replaced" : "added"
|
|
2632
2903
|
});
|
|
2904
|
+
} catch (error) {
|
|
2905
|
+
if (!(error instanceof McpEnvError)) throw error;
|
|
2906
|
+
results.push({
|
|
2907
|
+
name: server.name,
|
|
2908
|
+
action: "skipped",
|
|
2909
|
+
reason: error.message
|
|
2910
|
+
});
|
|
2633
2911
|
}
|
|
2634
2912
|
for (const name of existing.keys()) {
|
|
2635
2913
|
if (masterNames.has(name)) continue;
|
|
@@ -2858,6 +3136,6 @@ function syncAgentsFiles(harnesses, check = false, options = {}) {
|
|
|
2858
3136
|
targets: harnesses.map((harness) => syncTarget(harness, config, check, options))
|
|
2859
3137
|
};
|
|
2860
3138
|
}
|
|
2861
|
-
export { Harness, addMcpServer, detectHarness, detectHarnessFromEnv, detectProjectHarnesses, getAllHarnesses, getHarness, isHarnessId, listHarnesses, listMcpServers, masterMcpPath, parseJsonc, readAgentsConfig, readMasterMcpServers, registerHarness, removeMcpServer, resolvePathTemplate, syncAgentsFiles, syncMcpServers };
|
|
3139
|
+
export { Harness, McpEnvError, addMcpServer, detectHarness, detectHarnessFromEnv, detectProjectHarnesses, getAllHarnesses, getHarness, isHarnessId, listHarnesses, listMcpServers, masterMcpPath, parseJsonc, readAgentsConfig, readMasterMcpServers, registerHarness, removeMcpServer, resolvePathTemplate, syncAgentsFiles, syncMcpServers };
|
|
2862
3140
|
|
|
2863
3141
|
//# sourceMappingURL=agents-sync.mjs.map
|