@agntn/harnesses 0.1.1 → 0.2.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 +152 -117
- package/dist/_chunks/agents.mjs +2 -30
- package/dist/_chunks/agents.mjs.map +1 -1
- package/dist/_chunks/libs/typebox.mjs +535 -608
- package/dist/_chunks/libs/typebox.mjs.map +1 -1
- package/dist/_chunks/mcp-servers.mjs +5 -34
- package/dist/_chunks/mcp-servers.mjs.map +1 -1
- package/dist/_chunks/mcp.mjs +13 -163
- package/dist/_chunks/mcp.mjs.map +1 -1
- package/dist/_chunks/output.mjs +28 -0
- package/dist/_chunks/output.mjs.map +1 -0
- package/dist/_chunks/{agents-sync.d.mts → prompt-sync.d.mts} +91 -44
- package/dist/_chunks/prompt-sync.d.mts.map +1 -0
- package/dist/_chunks/{agents-sync.mjs → prompt-sync.mjs} +565 -26
- package/dist/_chunks/prompt-sync.mjs.map +1 -0
- package/dist/_chunks/prompts.mjs +28 -0
- package/dist/_chunks/prompts.mjs.map +1 -0
- package/dist/_chunks/tool-operations.mjs +43 -10
- package/dist/_chunks/tool-operations.mjs.map +1 -1
- package/dist/_chunks/tool-schemas.d.mts +17 -13
- package/dist/_chunks/tool-schemas.d.mts.map +1 -1
- package/dist/_chunks/tool-schemas.mjs +4 -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 +6 -2
- package/dist/cli.mjs.map +1 -1
- package/dist/index.d.mts +26 -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/mcp.mjs +176 -1
- package/dist/mcp.mjs.map +1 -0
- package/dist/tool-operations.d.mts +42 -32
- package/dist/tool-operations.d.mts.map +1 -1
- package/dist/tool-operations.mjs +2 -2
- package/dist/tool-schemas.d.mts +2 -2
- package/package.json +24 -21
- package/packages/omp/extensions/harnesses.ts +19 -1
- package/packages/pi/extensions/harnesses.ts +26 -2
- package/packages/shared/tui.ts +22 -1
- package/dist/_chunks/agents-sync.d.mts.map +0 -1
- package/dist/_chunks/agents-sync.mjs.map +0 -1
- package/dist/_chunks/mcp2.mjs +0 -17
- package/dist/_chunks/mcp2.mjs.map +0 -1
|
@@ -1,11 +1,14 @@
|
|
|
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 { copyFileSync, existsSync, lstatSync, mkdirSync, readFileSync, readdirSync, 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
|
-
import { basename, dirname, isAbsolute, join, posix, resolve, win32 } from "node:path";
|
|
6
|
+
import { basename, dirname, extname, isAbsolute, join, posix, relative, resolve, win32 } from "node:path";
|
|
6
7
|
import os, { homedir } from "node:os";
|
|
7
8
|
import { stripVTControlCharacters } from "node:util";
|
|
8
9
|
import { parse } from "smol-toml";
|
|
10
|
+
import { randomUUID } from "node:crypto";
|
|
11
|
+
import { parse as parse$1 } from "yaml";
|
|
9
12
|
const PATH_MARKERS = /^~(?=\/|$)|\$\{HOME\}|\$\{PROJECT_ROOT\}|%([^%]+)%/g;
|
|
10
13
|
function resolvePathTemplate(template, options = {}) {
|
|
11
14
|
const homeDir = options.homeDir ?? os.homedir();
|
|
@@ -20,6 +23,10 @@ function agntnConfigDir(options = {}) {
|
|
|
20
23
|
const base = process.env.XDG_CONFIG_HOME && process.env.XDG_CONFIG_HOME !== "" ? process.env.XDG_CONFIG_HOME : join(options.homeDir ?? os.homedir(), ".config");
|
|
21
24
|
return join(base, "agntn");
|
|
22
25
|
}
|
|
26
|
+
function agntnDataDir(options = {}) {
|
|
27
|
+
const base = process.env.XDG_DATA_HOME && process.env.XDG_DATA_HOME !== "" ? process.env.XDG_DATA_HOME : join(options.homeDir ?? os.homedir(), ".local", "share");
|
|
28
|
+
return join(base, "agntn");
|
|
29
|
+
}
|
|
23
30
|
const SUPPORTED_PLATFORMS = {
|
|
24
31
|
linux: true,
|
|
25
32
|
darwin: true,
|
|
@@ -196,6 +203,8 @@ function executeCommand(command, args, options) {
|
|
|
196
203
|
});
|
|
197
204
|
}
|
|
198
205
|
var Harness = class {
|
|
206
|
+
promptTemplates = [];
|
|
207
|
+
promptTemplateSyncTarget = null;
|
|
199
208
|
modelListing = null;
|
|
200
209
|
mcpConfigs = [];
|
|
201
210
|
agentsFile = null;
|
|
@@ -324,6 +333,8 @@ var Harness = class {
|
|
|
324
333
|
instructions: this.resolveCandidates(this.instructions, options),
|
|
325
334
|
skills: this.resolveCandidates(this.skills, options),
|
|
326
335
|
commands: this.resolveCandidates(this.commands, options),
|
|
336
|
+
promptTemplates: this.resolveCandidates(this.promptTemplates, options),
|
|
337
|
+
promptTemplateSyncTarget: this.promptTemplateSyncTarget === null ? null : this.resolveCandidates([this.promptTemplateSyncTarget], options)[0] ?? null,
|
|
327
338
|
hooks: this.resolveCandidates(this.hooks, options)
|
|
328
339
|
};
|
|
329
340
|
}
|
|
@@ -601,6 +612,13 @@ var Claude = class extends Harness {
|
|
|
601
612
|
level: "official",
|
|
602
613
|
note: "Legacy global slash commands."
|
|
603
614
|
}];
|
|
615
|
+
promptTemplates = this.commands;
|
|
616
|
+
promptTemplateSyncTarget = {
|
|
617
|
+
path: "~/.claude/commands/",
|
|
618
|
+
scope: "user",
|
|
619
|
+
level: "official",
|
|
620
|
+
format: "markdown"
|
|
621
|
+
};
|
|
604
622
|
hooks = [{
|
|
605
623
|
path: ".claude/hooks/",
|
|
606
624
|
scope: "project",
|
|
@@ -622,6 +640,7 @@ var Claude = class extends Harness {
|
|
|
622
640
|
noToolsArgs: [
|
|
623
641
|
"-p",
|
|
624
642
|
"{prompt}",
|
|
643
|
+
"--strict-mcp-config",
|
|
625
644
|
"--tools",
|
|
626
645
|
""
|
|
627
646
|
],
|
|
@@ -630,6 +649,7 @@ var Claude = class extends Harness {
|
|
|
630
649
|
"--output-format",
|
|
631
650
|
"json",
|
|
632
651
|
"{prompt}",
|
|
652
|
+
"--strict-mcp-config",
|
|
633
653
|
"--tools",
|
|
634
654
|
""
|
|
635
655
|
],
|
|
@@ -652,7 +672,7 @@ var Claude = class extends Harness {
|
|
|
652
672
|
readOnlyMinVersion: "2.1.175",
|
|
653
673
|
modelArgs: ["--model", "{model}"],
|
|
654
674
|
level: "official",
|
|
655
|
-
note: "Headless print mode; add --output-format json for structured output.
|
|
675
|
+
note: "Headless print mode; add --output-format json for structured output. --tools only covers the built-in set, so every mode without the full agent adds --strict-mcp-config to drop configured MCP servers too; without it an advisor still sees every user and project MCP tool, checked on 2.1.280. Read-only runs keep the built-in Read, Glob and Grep tools, so no write tool exists whatever permission mode the settings carry; verified on 2.1.175 and 2.1.268. --permission-mode plan does not qualify: its shell commands run through the auto mode classifier, which let a file write through."
|
|
656
676
|
};
|
|
657
677
|
mcpConfigs = [{
|
|
658
678
|
path: "~/.claude.json",
|
|
@@ -807,7 +827,19 @@ var Codex = class extends Harness {
|
|
|
807
827
|
platforms: ["linux", "darwin"]
|
|
808
828
|
}
|
|
809
829
|
];
|
|
810
|
-
commands = [
|
|
830
|
+
commands = [{
|
|
831
|
+
path: "~/.codex/prompts/",
|
|
832
|
+
scope: "user",
|
|
833
|
+
level: "official",
|
|
834
|
+
note: "Deprecated Markdown prompts invoked as /prompts:name. Top-level files only; use skills for shared prompts. Base directory follows CODEX_HOME."
|
|
835
|
+
}];
|
|
836
|
+
promptTemplates = this.commands;
|
|
837
|
+
promptTemplateSyncTarget = {
|
|
838
|
+
path: "~/.codex/prompts/",
|
|
839
|
+
scope: "user",
|
|
840
|
+
level: "official",
|
|
841
|
+
format: "markdown"
|
|
842
|
+
};
|
|
811
843
|
hooks = [];
|
|
812
844
|
invocation = {
|
|
813
845
|
args: [
|
|
@@ -963,6 +995,18 @@ var Freebuff = class extends Harness {
|
|
|
963
995
|
id = "freebuff";
|
|
964
996
|
name = "Freebuff";
|
|
965
997
|
binaries = ["freebuff"];
|
|
998
|
+
get version() {
|
|
999
|
+
const configDir = join(homedir(), ".config", "manicode");
|
|
1000
|
+
const binaryName = process.platform === "win32" ? "freebuff.exe" : "freebuff";
|
|
1001
|
+
if (!existsSync(join(configDir, binaryName))) return null;
|
|
1002
|
+
try {
|
|
1003
|
+
const metadata = JSON.parse(readFileSync(join(configDir, "freebuff-metadata.json"), "utf8"));
|
|
1004
|
+
if (typeof metadata === "object" && metadata !== null && "version" in metadata && typeof metadata.version === "string" && metadata.version !== "") return metadata.version;
|
|
1005
|
+
} catch {
|
|
1006
|
+
return null;
|
|
1007
|
+
}
|
|
1008
|
+
return null;
|
|
1009
|
+
}
|
|
966
1010
|
capabilities = {
|
|
967
1011
|
mcp: true,
|
|
968
1012
|
vision: true,
|
|
@@ -1158,6 +1202,13 @@ var Gemini = class extends Harness {
|
|
|
1158
1202
|
level: "official",
|
|
1159
1203
|
note: "Global custom commands in TOML format."
|
|
1160
1204
|
}];
|
|
1205
|
+
promptTemplates = this.commands;
|
|
1206
|
+
promptTemplateSyncTarget = {
|
|
1207
|
+
path: "~/.gemini/commands/",
|
|
1208
|
+
scope: "user",
|
|
1209
|
+
level: "official",
|
|
1210
|
+
format: "gemini-toml"
|
|
1211
|
+
};
|
|
1161
1212
|
hooks = [];
|
|
1162
1213
|
invocation = {
|
|
1163
1214
|
args: ["-p", "{prompt}"],
|
|
@@ -1417,10 +1468,43 @@ var Grok = class extends Harness {
|
|
|
1417
1468
|
projectMarkers: [".grok"]
|
|
1418
1469
|
};
|
|
1419
1470
|
};
|
|
1471
|
+
function packageVersion(commandPath) {
|
|
1472
|
+
try {
|
|
1473
|
+
const require = createRequire(realpathSync(commandPath));
|
|
1474
|
+
const metadata = JSON.parse(readFileSync(require.resolve("mastracode/package.json"), "utf8"));
|
|
1475
|
+
if (typeof metadata === "object" && metadata !== null && "version" in metadata && typeof metadata.version === "string" && metadata.version !== "") return metadata.version;
|
|
1476
|
+
} catch {
|
|
1477
|
+
return null;
|
|
1478
|
+
}
|
|
1479
|
+
return null;
|
|
1480
|
+
}
|
|
1420
1481
|
var MastraCode = class extends Harness {
|
|
1421
1482
|
id = "mastracode";
|
|
1422
1483
|
name = "Mastra Code";
|
|
1423
1484
|
binaries = ["mastracode"];
|
|
1485
|
+
get version() {
|
|
1486
|
+
const locator = process.platform === "win32" ? "where" : "which";
|
|
1487
|
+
let output;
|
|
1488
|
+
try {
|
|
1489
|
+
output = execFileSync(locator, [this.binaries[0] ?? "mastracode"], {
|
|
1490
|
+
encoding: "utf8",
|
|
1491
|
+
stdio: [
|
|
1492
|
+
"pipe",
|
|
1493
|
+
"pipe",
|
|
1494
|
+
"pipe"
|
|
1495
|
+
],
|
|
1496
|
+
timeout: 5e3
|
|
1497
|
+
});
|
|
1498
|
+
} catch {
|
|
1499
|
+
return null;
|
|
1500
|
+
}
|
|
1501
|
+
const paths = output.split(/\r?\n/u).filter((path) => path !== "");
|
|
1502
|
+
for (const path of paths) {
|
|
1503
|
+
const version = packageVersion(path);
|
|
1504
|
+
if (version !== null) return version;
|
|
1505
|
+
}
|
|
1506
|
+
return null;
|
|
1507
|
+
}
|
|
1424
1508
|
capabilities = {
|
|
1425
1509
|
mcp: true,
|
|
1426
1510
|
vision: true,
|
|
@@ -1442,6 +1526,12 @@ var MastraCode = class extends Harness {
|
|
|
1442
1526
|
level: "official",
|
|
1443
1527
|
note: "Global MCP server configurations."
|
|
1444
1528
|
},
|
|
1529
|
+
{
|
|
1530
|
+
path: ".mcp.json",
|
|
1531
|
+
scope: "project",
|
|
1532
|
+
level: "official",
|
|
1533
|
+
note: "Claude Code compatible project MCP servers, read below .mastracode/mcp.json."
|
|
1534
|
+
},
|
|
1445
1535
|
{
|
|
1446
1536
|
path: ".mastracode/hooks.json",
|
|
1447
1537
|
scope: "project",
|
|
@@ -1533,16 +1623,51 @@ var MastraCode = class extends Harness {
|
|
|
1533
1623
|
note: "Claude Code compatible."
|
|
1534
1624
|
}
|
|
1535
1625
|
];
|
|
1536
|
-
commands = [
|
|
1537
|
-
|
|
1538
|
-
|
|
1539
|
-
|
|
1540
|
-
|
|
1626
|
+
commands = [
|
|
1627
|
+
{
|
|
1628
|
+
path: ".mastracode/commands/",
|
|
1629
|
+
scope: "project",
|
|
1630
|
+
level: "official",
|
|
1631
|
+
note: "Markdown prompt commands; subdirectories become colon-separated command names."
|
|
1632
|
+
},
|
|
1633
|
+
{
|
|
1634
|
+
path: "~/.mastracode/commands/",
|
|
1635
|
+
scope: "user",
|
|
1636
|
+
level: "official",
|
|
1637
|
+
note: "Global Markdown prompt commands."
|
|
1638
|
+
},
|
|
1639
|
+
{
|
|
1640
|
+
path: ".claude/commands/",
|
|
1641
|
+
scope: "project",
|
|
1642
|
+
level: "official",
|
|
1643
|
+
note: "Claude compatibility."
|
|
1644
|
+
},
|
|
1645
|
+
{
|
|
1646
|
+
path: "~/.claude/commands/",
|
|
1647
|
+
scope: "user",
|
|
1648
|
+
level: "official",
|
|
1649
|
+
note: "Claude compatibility."
|
|
1650
|
+
},
|
|
1651
|
+
{
|
|
1652
|
+
path: ".opencode/command/",
|
|
1653
|
+
scope: "project",
|
|
1654
|
+
level: "official",
|
|
1655
|
+
note: "Mastra's OpenCode compatibility loader uses the singular command directory."
|
|
1656
|
+
},
|
|
1657
|
+
{
|
|
1658
|
+
path: "~/.opencode/command/",
|
|
1659
|
+
scope: "user",
|
|
1660
|
+
level: "official",
|
|
1661
|
+
note: "Mastra's OpenCode compatibility loader uses the singular command directory."
|
|
1662
|
+
}
|
|
1663
|
+
];
|
|
1664
|
+
promptTemplates = this.commands;
|
|
1665
|
+
promptTemplateSyncTarget = {
|
|
1541
1666
|
path: "~/.mastracode/commands/",
|
|
1542
1667
|
scope: "user",
|
|
1543
1668
|
level: "official",
|
|
1544
|
-
|
|
1545
|
-
}
|
|
1669
|
+
format: "markdown"
|
|
1670
|
+
};
|
|
1546
1671
|
hooks = [{
|
|
1547
1672
|
path: ".mastracode/hooks.json",
|
|
1548
1673
|
scope: "project",
|
|
@@ -1554,6 +1679,35 @@ var MastraCode = class extends Harness {
|
|
|
1554
1679
|
note: "Global hooks."
|
|
1555
1680
|
}];
|
|
1556
1681
|
invocation = null;
|
|
1682
|
+
mcpConfigs = [
|
|
1683
|
+
{
|
|
1684
|
+
path: "~/.mastracode/mcp.json",
|
|
1685
|
+
scope: "user",
|
|
1686
|
+
level: "official",
|
|
1687
|
+
format: "json",
|
|
1688
|
+
key: ["mcpServers"],
|
|
1689
|
+
dialect: "mastracode",
|
|
1690
|
+
note: "An entry with command is stdio and one with url is HTTP, type is ignored. Loaded above mcpServers from the project's .claude/settings.local.json and below both project files, later names winning."
|
|
1691
|
+
},
|
|
1692
|
+
{
|
|
1693
|
+
path: ".mastracode/mcp.json",
|
|
1694
|
+
scope: "project",
|
|
1695
|
+
level: "official",
|
|
1696
|
+
format: "json",
|
|
1697
|
+
key: ["mcpServers"],
|
|
1698
|
+
dialect: "mastracode",
|
|
1699
|
+
note: "Highest priority, overrides the other files entry by entry."
|
|
1700
|
+
},
|
|
1701
|
+
{
|
|
1702
|
+
path: ".mcp.json",
|
|
1703
|
+
scope: "project",
|
|
1704
|
+
level: "official",
|
|
1705
|
+
format: "json",
|
|
1706
|
+
key: ["mcpServers"],
|
|
1707
|
+
dialect: "mastracode",
|
|
1708
|
+
note: "Claude Code's project file, read between the user file and .mastracode/mcp.json. Project writes go to .mastracode/mcp.json, this one is Claude's to edit."
|
|
1709
|
+
}
|
|
1710
|
+
];
|
|
1557
1711
|
detection = {
|
|
1558
1712
|
envVars: [],
|
|
1559
1713
|
projectMarkers: [".mastracode"]
|
|
@@ -1701,13 +1855,35 @@ var Omp = class extends Harness {
|
|
|
1701
1855
|
commands = [{
|
|
1702
1856
|
path: ".omp/commands/",
|
|
1703
1857
|
scope: "project",
|
|
1704
|
-
level: "official"
|
|
1858
|
+
level: "official",
|
|
1859
|
+
note: "Markdown prompt commands and TypeScript commands; only Markdown files are templates."
|
|
1705
1860
|
}, {
|
|
1706
1861
|
path: "~/.omp/agent/commands/",
|
|
1707
1862
|
scope: "user",
|
|
1708
1863
|
level: "official",
|
|
1709
|
-
note: "Global
|
|
1864
|
+
note: "Global Markdown prompt commands and TypeScript commands; only Markdown files are templates."
|
|
1710
1865
|
}];
|
|
1866
|
+
promptTemplates = [
|
|
1867
|
+
...this.commands,
|
|
1868
|
+
{
|
|
1869
|
+
path: ".omp/prompts/",
|
|
1870
|
+
scope: "project",
|
|
1871
|
+
level: "official",
|
|
1872
|
+
note: "Markdown prompt templates invoked as /name; subdirectories are scanned."
|
|
1873
|
+
},
|
|
1874
|
+
{
|
|
1875
|
+
path: "~/.omp/agent/prompts/",
|
|
1876
|
+
scope: "user",
|
|
1877
|
+
level: "official",
|
|
1878
|
+
note: "Global Markdown prompt templates, separate from executable commands."
|
|
1879
|
+
}
|
|
1880
|
+
];
|
|
1881
|
+
promptTemplateSyncTarget = {
|
|
1882
|
+
path: "~/.omp/agent/prompts/",
|
|
1883
|
+
scope: "user",
|
|
1884
|
+
level: "official",
|
|
1885
|
+
format: "markdown"
|
|
1886
|
+
};
|
|
1711
1887
|
hooks = [];
|
|
1712
1888
|
invocation = {
|
|
1713
1889
|
args: ["-p", "{prompt}"],
|
|
@@ -1850,7 +2026,24 @@ var OpenCode = class extends Harness {
|
|
|
1850
2026
|
level: "official"
|
|
1851
2027
|
}
|
|
1852
2028
|
];
|
|
1853
|
-
commands = [
|
|
2029
|
+
commands = [{
|
|
2030
|
+
path: ".opencode/commands/",
|
|
2031
|
+
scope: "project",
|
|
2032
|
+
level: "official",
|
|
2033
|
+
note: "Markdown prompt commands; also configurable through command entries in opencode.json."
|
|
2034
|
+
}, {
|
|
2035
|
+
path: "~/.config/opencode/commands/",
|
|
2036
|
+
scope: "user",
|
|
2037
|
+
level: "official",
|
|
2038
|
+
note: "Global Markdown prompt commands."
|
|
2039
|
+
}];
|
|
2040
|
+
promptTemplates = this.commands;
|
|
2041
|
+
promptTemplateSyncTarget = {
|
|
2042
|
+
path: "~/.config/opencode/commands/",
|
|
2043
|
+
scope: "user",
|
|
2044
|
+
level: "official",
|
|
2045
|
+
format: "markdown"
|
|
2046
|
+
};
|
|
1854
2047
|
hooks = [];
|
|
1855
2048
|
invocation = {
|
|
1856
2049
|
args: ["run", "{prompt}"],
|
|
@@ -2012,6 +2205,13 @@ var Pi = class extends Harness {
|
|
|
2012
2205
|
level: "official",
|
|
2013
2206
|
note: "Global user-level prompt templates."
|
|
2014
2207
|
}];
|
|
2208
|
+
promptTemplates = this.commands;
|
|
2209
|
+
promptTemplateSyncTarget = {
|
|
2210
|
+
path: "~/.pi/agent/prompts/",
|
|
2211
|
+
scope: "user",
|
|
2212
|
+
level: "official",
|
|
2213
|
+
format: "markdown"
|
|
2214
|
+
};
|
|
2015
2215
|
hooks = [];
|
|
2016
2216
|
invocation = {
|
|
2017
2217
|
args: ["-p", "{prompt}"],
|
|
@@ -2182,6 +2382,13 @@ var PrimeAgent = class extends Harness {
|
|
|
2182
2382
|
level: "official",
|
|
2183
2383
|
note: "Global user-level prompt templates."
|
|
2184
2384
|
}];
|
|
2385
|
+
promptTemplates = this.commands;
|
|
2386
|
+
promptTemplateSyncTarget = {
|
|
2387
|
+
path: "~/.prime/agent/prompts/",
|
|
2388
|
+
scope: "user",
|
|
2389
|
+
level: "official",
|
|
2390
|
+
format: "markdown"
|
|
2391
|
+
};
|
|
2185
2392
|
hooks = [];
|
|
2186
2393
|
invocation = {
|
|
2187
2394
|
args: ["-p", "{prompt}"],
|
|
@@ -2411,8 +2618,21 @@ function normalizePrime(name, raw) {
|
|
|
2411
2618
|
env: primeEnv(raw.env)
|
|
2412
2619
|
});
|
|
2413
2620
|
}
|
|
2621
|
+
function normalizeMastracode(name, raw) {
|
|
2622
|
+
const url = stringField(raw, "url");
|
|
2623
|
+
return compact({
|
|
2624
|
+
name,
|
|
2625
|
+
transport: url ? "http" : "stdio",
|
|
2626
|
+
command: stringField(raw, "command"),
|
|
2627
|
+
args: asStringArray(raw.args),
|
|
2628
|
+
env: asStringRecord(raw.env),
|
|
2629
|
+
url,
|
|
2630
|
+
headers: asStringRecord(raw.headers)
|
|
2631
|
+
});
|
|
2632
|
+
}
|
|
2414
2633
|
function normalizeEntry(name, raw, dialect) {
|
|
2415
2634
|
if (dialect === "antigravity") return normalizeAntigravity(name, raw);
|
|
2635
|
+
if (dialect === "mastracode") return normalizeMastracode(name, raw);
|
|
2416
2636
|
if (dialect === "opencode") return normalizeOpenCode(name, raw);
|
|
2417
2637
|
if (dialect === "prime") return normalizePrime(name, raw);
|
|
2418
2638
|
return normalizeStandard(name, raw);
|
|
@@ -2439,6 +2659,17 @@ function denormalizeOpenCode(server) {
|
|
|
2439
2659
|
enabled: server.enabled
|
|
2440
2660
|
});
|
|
2441
2661
|
}
|
|
2662
|
+
function denormalizeMastracode(server) {
|
|
2663
|
+
if (server.url) return compact({
|
|
2664
|
+
url: server.url,
|
|
2665
|
+
headers: server.headers
|
|
2666
|
+
});
|
|
2667
|
+
return compact({
|
|
2668
|
+
command: server.command,
|
|
2669
|
+
args: server.args?.length ? server.args : void 0,
|
|
2670
|
+
env: server.env
|
|
2671
|
+
});
|
|
2672
|
+
}
|
|
2442
2673
|
function denormalizeStandard(server) {
|
|
2443
2674
|
return compact({
|
|
2444
2675
|
type: server.transport,
|
|
@@ -2484,8 +2715,18 @@ function resolveEnvReferences(server, dialect) {
|
|
|
2484
2715
|
env
|
|
2485
2716
|
};
|
|
2486
2717
|
}
|
|
2718
|
+
function shapeForDialect(server, dialect) {
|
|
2719
|
+
const shaped = resolveEnvReferences(server, dialect);
|
|
2720
|
+
if (dialect !== "mastracode") return shaped;
|
|
2721
|
+
return compact({
|
|
2722
|
+
...shaped,
|
|
2723
|
+
transport: shaped.url ? "http" : "stdio",
|
|
2724
|
+
enabled: void 0
|
|
2725
|
+
});
|
|
2726
|
+
}
|
|
2487
2727
|
function denormalizeEntry(server, dialect) {
|
|
2488
2728
|
if (dialect === "antigravity") return denormalizeAntigravity(server);
|
|
2729
|
+
if (dialect === "mastracode") return denormalizeMastracode(server);
|
|
2489
2730
|
if (dialect === "opencode") return denormalizeOpenCode(server);
|
|
2490
2731
|
if (dialect === "prime") return denormalizePrime(server);
|
|
2491
2732
|
return denormalizeStandard(server);
|
|
@@ -2543,9 +2784,6 @@ function writeAtomically(path, content) {
|
|
|
2543
2784
|
writeFileSync(temp, content);
|
|
2544
2785
|
renameSync(temp, path);
|
|
2545
2786
|
}
|
|
2546
|
-
function escapeRegExp(value) {
|
|
2547
|
-
return value.replaceAll(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
2548
|
-
}
|
|
2549
2787
|
function tomlValue(value) {
|
|
2550
2788
|
return JSON.stringify(value);
|
|
2551
2789
|
}
|
|
@@ -2567,8 +2805,8 @@ function tomlSections(key, server) {
|
|
|
2567
2805
|
return `${lines.join("\n")}\n`;
|
|
2568
2806
|
}
|
|
2569
2807
|
function stripTomlServer(raw, key, name) {
|
|
2570
|
-
const prefix =
|
|
2571
|
-
const namePart = `(?:${
|
|
2808
|
+
const prefix = RegExp.escape(key.map(tomlKeyPart).join("."));
|
|
2809
|
+
const namePart = `(?:${RegExp.escape(tomlKeyPart(name))}|${RegExp.escape(JSON.stringify(name))})`;
|
|
2572
2810
|
const sectionRe = new RegExp(`^\\s*\\[${prefix}\\.${namePart}(\\.[^\\]]+)?\\]`);
|
|
2573
2811
|
const bareTableRe = new RegExp(`^\\s*\\[${prefix}\\]\\s*(#.*)?$`);
|
|
2574
2812
|
const anyHeaderRe = /^\s*\[/;
|
|
@@ -2624,7 +2862,7 @@ function removeTomlServer(path, key, name) {
|
|
|
2624
2862
|
}
|
|
2625
2863
|
function addMcpServer(harness, server, scope = "user", options = {}) {
|
|
2626
2864
|
const { entry, path } = writableConfig(harness, scope, options);
|
|
2627
|
-
const resolved =
|
|
2865
|
+
const resolved = shapeForDialect(server, entry.dialect);
|
|
2628
2866
|
if (entry.format === "toml") return {
|
|
2629
2867
|
path,
|
|
2630
2868
|
replaced: addTomlServer(path, entry.key, resolved)
|
|
@@ -2844,7 +3082,7 @@ function syncIncludedHarness(harness, master, existing, masterNames, initialPath
|
|
|
2844
3082
|
let path = initialPath;
|
|
2845
3083
|
const { dialect } = writableConfig(harness, "user", options).entry;
|
|
2846
3084
|
for (const server of master.servers) try {
|
|
2847
|
-
const resolved =
|
|
3085
|
+
const resolved = shapeForDialect(server, dialect);
|
|
2848
3086
|
if (existing.get(server.name) === canonical(resolved)) {
|
|
2849
3087
|
results.push({
|
|
2850
3088
|
name: server.name,
|
|
@@ -2992,6 +3230,15 @@ function relink(path, source) {
|
|
|
2992
3230
|
symlinkSync(source, temp);
|
|
2993
3231
|
renameSync(temp, path);
|
|
2994
3232
|
}
|
|
3233
|
+
function moveFile(from, to) {
|
|
3234
|
+
try {
|
|
3235
|
+
renameSync(from, to);
|
|
3236
|
+
} catch (error) {
|
|
3237
|
+
if (error.code !== "EXDEV") throw error;
|
|
3238
|
+
copyFileSync(from, to);
|
|
3239
|
+
unlinkSync(from);
|
|
3240
|
+
}
|
|
3241
|
+
}
|
|
2995
3242
|
const CHECK_ACTION = {
|
|
2996
3243
|
missing: "linked",
|
|
2997
3244
|
"correct-link": "unchanged",
|
|
@@ -3004,7 +3251,7 @@ function applyFileTarget(id, path, source, state, options) {
|
|
|
3004
3251
|
const backupDir = join(agntnConfigDir(options), "diverged");
|
|
3005
3252
|
mkdirSync(backupDir, { recursive: true });
|
|
3006
3253
|
const backup = join(backupDir, `${id}-${basename(path)}-${Date.now()}.md`);
|
|
3007
|
-
|
|
3254
|
+
moveFile(path, backup);
|
|
3008
3255
|
relink(path, source);
|
|
3009
3256
|
return {
|
|
3010
3257
|
path,
|
|
@@ -3039,7 +3286,7 @@ function syncFileTarget(id, path, source, check, options) {
|
|
|
3039
3286
|
};
|
|
3040
3287
|
return applyFileTarget(id, path, source, state, options);
|
|
3041
3288
|
}
|
|
3042
|
-
function syncTarget(harness, config, check, options) {
|
|
3289
|
+
function syncTarget$1(harness, config, check, options) {
|
|
3043
3290
|
if (config.excludes.includes(harness.id)) return {
|
|
3044
3291
|
id: harness.id,
|
|
3045
3292
|
action: "skipped",
|
|
@@ -3090,9 +3337,301 @@ function syncAgentsFiles(harnesses, check = false, options = {}) {
|
|
|
3090
3337
|
return {
|
|
3091
3338
|
source: config.source,
|
|
3092
3339
|
check,
|
|
3093
|
-
targets: harnesses.map((harness) => syncTarget(harness, config, check, options))
|
|
3340
|
+
targets: harnesses.map((harness) => syncTarget$1(harness, config, check, options))
|
|
3341
|
+
};
|
|
3342
|
+
}
|
|
3343
|
+
const GENERATED_MARKER = "# Generated by @agntn/harnesses from ";
|
|
3344
|
+
const PORTABLE_PROMPT_NAME = /^[A-Za-z0-9][A-Za-z0-9_-]*$/u;
|
|
3345
|
+
const GEMINI_ACTION = {
|
|
3346
|
+
missing: "generated",
|
|
3347
|
+
"correct-link": "adopted",
|
|
3348
|
+
"wrong-link": "adopted",
|
|
3349
|
+
"owned-file": "replaced",
|
|
3350
|
+
"unmanaged-file": "adopted",
|
|
3351
|
+
unsupported: "skipped"
|
|
3352
|
+
};
|
|
3353
|
+
const GEMINI_BACKUP = {
|
|
3354
|
+
missing: false,
|
|
3355
|
+
"correct-link": true,
|
|
3356
|
+
"wrong-link": true,
|
|
3357
|
+
"owned-file": true,
|
|
3358
|
+
"unmanaged-file": true,
|
|
3359
|
+
unsupported: false
|
|
3360
|
+
};
|
|
3361
|
+
function readTemplates(sourceDir, check) {
|
|
3362
|
+
let entries;
|
|
3363
|
+
try {
|
|
3364
|
+
entries = readdirSync(sourceDir, { withFileTypes: true });
|
|
3365
|
+
} catch (error) {
|
|
3366
|
+
if (error.code !== "ENOENT") throw error;
|
|
3367
|
+
if (!check) mkdirSync(sourceDir, { recursive: true });
|
|
3368
|
+
return [];
|
|
3369
|
+
}
|
|
3370
|
+
const templates = entries.filter((entry) => (entry.isFile() || entry.isSymbolicLink()) && extname(entry.name).toLowerCase() === ".md").map((entry) => {
|
|
3371
|
+
const name = basename(entry.name, extname(entry.name));
|
|
3372
|
+
if (!PORTABLE_PROMPT_NAME.test(name)) throw new TypeError(`Invalid prompt template filename: ${entry.name}`);
|
|
3373
|
+
const path = join(sourceDir, entry.name);
|
|
3374
|
+
return {
|
|
3375
|
+
name,
|
|
3376
|
+
path,
|
|
3377
|
+
content: readFileSync(path, "utf8")
|
|
3378
|
+
};
|
|
3379
|
+
}).sort((left, right) => left.name.localeCompare(right.name));
|
|
3380
|
+
const names = templates.map((template) => template.name.toLowerCase());
|
|
3381
|
+
if (new Set(names).size !== names.length) throw new Error(`Duplicate prompt template names in ${sourceDir}`);
|
|
3382
|
+
return templates;
|
|
3383
|
+
}
|
|
3384
|
+
function generatedSource(content) {
|
|
3385
|
+
const firstLine = content.split("\n", 1)[0] ?? "";
|
|
3386
|
+
if (!firstLine.startsWith(GENERATED_MARKER)) return null;
|
|
3387
|
+
try {
|
|
3388
|
+
const source = JSON.parse(firstLine.slice(37));
|
|
3389
|
+
return typeof source === "string" ? source : null;
|
|
3390
|
+
} catch {
|
|
3391
|
+
return null;
|
|
3392
|
+
}
|
|
3393
|
+
}
|
|
3394
|
+
function inspectDestination(path, source) {
|
|
3395
|
+
let stats;
|
|
3396
|
+
try {
|
|
3397
|
+
stats = lstatSync(path);
|
|
3398
|
+
} catch (error) {
|
|
3399
|
+
if (error.code === "ENOENT") return { kind: "missing" };
|
|
3400
|
+
throw error;
|
|
3401
|
+
}
|
|
3402
|
+
if (stats.isSymbolicLink()) {
|
|
3403
|
+
if (source === void 0) return { kind: "unmanaged-file" };
|
|
3404
|
+
const target = readlinkSync(path);
|
|
3405
|
+
return (isAbsolute(target) ? target : resolve(dirname(path), target)) === source ? { kind: "correct-link" } : { kind: "wrong-link" };
|
|
3406
|
+
}
|
|
3407
|
+
if (!stats.isFile()) return { kind: "unsupported" };
|
|
3408
|
+
const content = readFileSync(path, "utf8");
|
|
3409
|
+
if (generatedSource(content) !== null) return {
|
|
3410
|
+
kind: "owned-file",
|
|
3411
|
+
content
|
|
3412
|
+
};
|
|
3413
|
+
return { kind: "unmanaged-file" };
|
|
3414
|
+
}
|
|
3415
|
+
function tempPath(path, kind) {
|
|
3416
|
+
return join(dirname(path), `.${basename(path)}-${randomUUID()}.${kind}.tmp`);
|
|
3417
|
+
}
|
|
3418
|
+
function linkTemplate(path, source) {
|
|
3419
|
+
mkdirSync(dirname(path), { recursive: true });
|
|
3420
|
+
const temp = tempPath(path, "prompt-link");
|
|
3421
|
+
symlinkSync(source, temp);
|
|
3422
|
+
renameSync(temp, path);
|
|
3423
|
+
}
|
|
3424
|
+
function writeTemplate(path, content) {
|
|
3425
|
+
mkdirSync(dirname(path), { recursive: true });
|
|
3426
|
+
const temp = tempPath(path, "prompt-write");
|
|
3427
|
+
writeFileSync(temp, content);
|
|
3428
|
+
renameSync(temp, path);
|
|
3429
|
+
}
|
|
3430
|
+
function backupDestination(id, path, options) {
|
|
3431
|
+
const backupDir = join(agntnDataDir(options), "diverged", "prompts", id);
|
|
3432
|
+
mkdirSync(backupDir, { recursive: true });
|
|
3433
|
+
const backup = join(backupDir, `${basename(path)}-${Date.now()}-${randomUUID()}`);
|
|
3434
|
+
if (lstatSync(path).isSymbolicLink()) {
|
|
3435
|
+
const target = readlinkSync(path);
|
|
3436
|
+
symlinkSync(isAbsolute(target) ? target : resolve(dirname(path), target), backup);
|
|
3437
|
+
unlinkSync(path);
|
|
3438
|
+
return backup;
|
|
3439
|
+
}
|
|
3440
|
+
moveFile(path, backup);
|
|
3441
|
+
return backup;
|
|
3442
|
+
}
|
|
3443
|
+
function checkDetail() {
|
|
3444
|
+
return "check mode: not applied";
|
|
3445
|
+
}
|
|
3446
|
+
function syncMarkdownTemplate(id, targetDir, template, check, options) {
|
|
3447
|
+
const path = join(targetDir, `${template.name}.md`);
|
|
3448
|
+
const state = inspectDestination(path, template.path);
|
|
3449
|
+
if (state.kind === "correct-link") return {
|
|
3450
|
+
name: template.name,
|
|
3451
|
+
source: template.path,
|
|
3452
|
+
path,
|
|
3453
|
+
action: "unchanged"
|
|
3454
|
+
};
|
|
3455
|
+
if (state.kind === "unsupported") return {
|
|
3456
|
+
name: template.name,
|
|
3457
|
+
source: template.path,
|
|
3458
|
+
path,
|
|
3459
|
+
action: "skipped",
|
|
3460
|
+
detail: "destination exists and is not a file or symlink"
|
|
3461
|
+
};
|
|
3462
|
+
const action = state.kind === "missing" ? "linked" : state.kind === "wrong-link" ? "relinked" : "adopted";
|
|
3463
|
+
if (check) return {
|
|
3464
|
+
name: template.name,
|
|
3465
|
+
source: template.path,
|
|
3466
|
+
path,
|
|
3467
|
+
action,
|
|
3468
|
+
detail: checkDetail()
|
|
3469
|
+
};
|
|
3470
|
+
let detail;
|
|
3471
|
+
if (state.kind === "wrong-link") unlinkSync(path);
|
|
3472
|
+
if (state.kind === "owned-file" || state.kind === "unmanaged-file") detail = backupDestination(id, path, options);
|
|
3473
|
+
linkTemplate(path, template.path);
|
|
3474
|
+
return {
|
|
3475
|
+
name: template.name,
|
|
3476
|
+
source: template.path,
|
|
3477
|
+
path,
|
|
3478
|
+
action,
|
|
3479
|
+
detail
|
|
3480
|
+
};
|
|
3481
|
+
}
|
|
3482
|
+
function frontmatterDescription(raw, path) {
|
|
3483
|
+
const frontmatter = parse$1(raw);
|
|
3484
|
+
if (frontmatter === null) return void 0;
|
|
3485
|
+
if (typeof frontmatter !== "object" || Array.isArray(frontmatter)) throw new TypeError(`Prompt template frontmatter is not an object: ${path}`);
|
|
3486
|
+
const description = frontmatter.description;
|
|
3487
|
+
if (description !== void 0 && typeof description !== "string") throw new TypeError(`Prompt template description is not a string: ${path}`);
|
|
3488
|
+
return description;
|
|
3489
|
+
}
|
|
3490
|
+
function parseMarkdownTemplate(template) {
|
|
3491
|
+
const match = /^---\r?\n([\s\S]*?)\r?\n---(?:\r?\n|$)/.exec(template.content);
|
|
3492
|
+
if (match === null) return { prompt: template.content.replaceAll("$ARGUMENTS", "{{args}}") };
|
|
3493
|
+
const description = frontmatterDescription(match[1] ?? "", template.path);
|
|
3494
|
+
return {
|
|
3495
|
+
...description === void 0 ? {} : { description },
|
|
3496
|
+
prompt: template.content.slice(match[0].length).replaceAll("$ARGUMENTS", "{{args}}")
|
|
3497
|
+
};
|
|
3498
|
+
}
|
|
3499
|
+
function geminiContent(template) {
|
|
3500
|
+
const parsed = parseMarkdownTemplate(template);
|
|
3501
|
+
return [
|
|
3502
|
+
`${GENERATED_MARKER}${JSON.stringify(template.path)}`,
|
|
3503
|
+
...parsed.description === void 0 ? [] : [`description = ${JSON.stringify(parsed.description)}`],
|
|
3504
|
+
`prompt = ${JSON.stringify(parsed.prompt)}`,
|
|
3505
|
+
""
|
|
3506
|
+
].join("\n");
|
|
3507
|
+
}
|
|
3508
|
+
function syncGeminiTemplate(id, targetDir, template, check, options) {
|
|
3509
|
+
const path = join(targetDir, `${template.name}.toml`);
|
|
3510
|
+
const content = template.gemini ?? geminiContent(template);
|
|
3511
|
+
const state = inspectDestination(path);
|
|
3512
|
+
if (state.kind === "owned-file" && state.content === content) return {
|
|
3513
|
+
name: template.name,
|
|
3514
|
+
source: template.path,
|
|
3515
|
+
path,
|
|
3516
|
+
action: "unchanged"
|
|
3517
|
+
};
|
|
3518
|
+
if (state.kind === "unsupported") return {
|
|
3519
|
+
name: template.name,
|
|
3520
|
+
source: template.path,
|
|
3521
|
+
path,
|
|
3522
|
+
action: "skipped",
|
|
3523
|
+
detail: "destination exists and is not a file or symlink"
|
|
3524
|
+
};
|
|
3525
|
+
const action = GEMINI_ACTION[state.kind];
|
|
3526
|
+
if (check) return {
|
|
3527
|
+
name: template.name,
|
|
3528
|
+
source: template.path,
|
|
3529
|
+
path,
|
|
3530
|
+
action,
|
|
3531
|
+
detail: checkDetail()
|
|
3532
|
+
};
|
|
3533
|
+
let detail;
|
|
3534
|
+
if (GEMINI_BACKUP[state.kind]) detail = backupDestination(id, path, options);
|
|
3535
|
+
writeTemplate(path, content);
|
|
3536
|
+
return {
|
|
3537
|
+
name: template.name,
|
|
3538
|
+
source: template.path,
|
|
3539
|
+
path,
|
|
3540
|
+
action,
|
|
3541
|
+
detail
|
|
3542
|
+
};
|
|
3543
|
+
}
|
|
3544
|
+
function isInsideDirectory(path, directory) {
|
|
3545
|
+
const remainder = relative(directory, path);
|
|
3546
|
+
return remainder !== "" && !remainder.startsWith("..") && !isAbsolute(remainder);
|
|
3547
|
+
}
|
|
3548
|
+
function staleMarkdownSource(path, sourceDir) {
|
|
3549
|
+
if (inspectDestination(path).kind !== "unmanaged-file") return null;
|
|
3550
|
+
let stats;
|
|
3551
|
+
try {
|
|
3552
|
+
stats = lstatSync(path);
|
|
3553
|
+
} catch {
|
|
3554
|
+
return null;
|
|
3555
|
+
}
|
|
3556
|
+
if (!stats.isSymbolicLink()) return null;
|
|
3557
|
+
const target = readlinkSync(path);
|
|
3558
|
+
const resolved = isAbsolute(target) ? target : resolve(dirname(path), target);
|
|
3559
|
+
return isInsideDirectory(resolved, sourceDir) ? resolved : null;
|
|
3560
|
+
}
|
|
3561
|
+
function staleGeminiSource(path, sourceDir) {
|
|
3562
|
+
let content;
|
|
3563
|
+
try {
|
|
3564
|
+
content = readFileSync(path, "utf8");
|
|
3565
|
+
} catch {
|
|
3566
|
+
return null;
|
|
3567
|
+
}
|
|
3568
|
+
const source = generatedSource(content);
|
|
3569
|
+
if (source === null) return null;
|
|
3570
|
+
return isInsideDirectory(source, sourceDir) ? source : null;
|
|
3571
|
+
}
|
|
3572
|
+
function pruneTarget(targetDir, format, sourceDir, activeSources, check) {
|
|
3573
|
+
let entries;
|
|
3574
|
+
try {
|
|
3575
|
+
entries = readdirSync(targetDir, { withFileTypes: true });
|
|
3576
|
+
} catch (error) {
|
|
3577
|
+
if (error.code === "ENOENT") return [];
|
|
3578
|
+
throw error;
|
|
3579
|
+
}
|
|
3580
|
+
const extension = format === "markdown" ? ".md" : ".toml";
|
|
3581
|
+
const staleSource = format === "markdown" ? staleMarkdownSource : staleGeminiSource;
|
|
3582
|
+
return entries.filter((entry) => entry.name.toLowerCase().endsWith(extension)).flatMap((entry) => {
|
|
3583
|
+
const path = join(targetDir, entry.name);
|
|
3584
|
+
const source = staleSource(path, sourceDir);
|
|
3585
|
+
if (source === null || activeSources.has(source)) return [];
|
|
3586
|
+
if (!check) unlinkSync(path);
|
|
3587
|
+
return [{
|
|
3588
|
+
name: basename(entry.name, extension),
|
|
3589
|
+
source,
|
|
3590
|
+
path,
|
|
3591
|
+
action: "removed",
|
|
3592
|
+
...check ? { detail: checkDetail() } : {}
|
|
3593
|
+
}];
|
|
3594
|
+
});
|
|
3595
|
+
}
|
|
3596
|
+
function syncTarget(harness, templates, sourceDir, check, options) {
|
|
3597
|
+
const target = harness.promptTemplateSyncTarget;
|
|
3598
|
+
if (target === null) return {
|
|
3599
|
+
id: harness.id,
|
|
3600
|
+
detail: "no stable user-scope prompt template destination",
|
|
3601
|
+
templates: []
|
|
3602
|
+
};
|
|
3603
|
+
const resolved = harness.resolveCandidates([target], options)[0];
|
|
3604
|
+
if (resolved === void 0) return {
|
|
3605
|
+
id: harness.id,
|
|
3606
|
+
detail: "prompt template destination is unavailable on this platform",
|
|
3607
|
+
templates: []
|
|
3608
|
+
};
|
|
3609
|
+
const targetDir = resolved.path;
|
|
3610
|
+
const syncTemplate = resolved.format === "markdown" ? syncMarkdownTemplate : syncGeminiTemplate;
|
|
3611
|
+
const results = templates.map((template) => syncTemplate(harness.id, targetDir, template, check, options));
|
|
3612
|
+
const activeSources = new Set(templates.map((template) => template.path));
|
|
3613
|
+
results.push(...pruneTarget(targetDir, resolved.format, sourceDir, activeSources, check));
|
|
3614
|
+
return {
|
|
3615
|
+
id: harness.id,
|
|
3616
|
+
path: targetDir,
|
|
3617
|
+
format: resolved.format,
|
|
3618
|
+
templates: results
|
|
3619
|
+
};
|
|
3620
|
+
}
|
|
3621
|
+
function syncPromptTemplates(harnesses, check = false, options = {}) {
|
|
3622
|
+
const source = join(agntnDataDir(options), "prompts");
|
|
3623
|
+
const templates = readTemplates(source, check);
|
|
3624
|
+
const prepared = harnesses.some((harness) => harness.promptTemplateSyncTarget?.format === "gemini-toml") ? templates.map((template) => ({
|
|
3625
|
+
...template,
|
|
3626
|
+
gemini: geminiContent(template)
|
|
3627
|
+
})) : templates;
|
|
3628
|
+
return {
|
|
3629
|
+
source,
|
|
3630
|
+
check,
|
|
3631
|
+
templates: prepared.map((template) => template.name),
|
|
3632
|
+
targets: harnesses.map((harness) => syncTarget(harness, prepared, source, check, options))
|
|
3094
3633
|
};
|
|
3095
3634
|
}
|
|
3096
|
-
export { Harness, McpEnvError, addMcpServer, detectHarness, detectHarnessFromEnv, detectProjectHarnesses, getAllHarnesses, getHarness, isHarnessId, listHarnesses, listMcpServers, masterMcpPath, parseJsonc, readAgentsConfig, readMasterMcpServers, registerHarness, removeMcpServer, resolvePathTemplate, syncAgentsFiles, syncMcpServers };
|
|
3635
|
+
export { Harness, McpEnvError, addMcpServer, agntnConfigDir, agntnDataDir, detectHarness, detectHarnessFromEnv, detectProjectHarnesses, getAllHarnesses, getHarness, isHarnessId, listHarnesses, listMcpServers, masterMcpPath, parseJsonc, readAgentsConfig, readMasterMcpServers, registerHarness, removeMcpServer, resolvePathTemplate, syncAgentsFiles, syncMcpServers, syncPromptTemplates };
|
|
3097
3636
|
|
|
3098
|
-
//# sourceMappingURL=
|
|
3637
|
+
//# sourceMappingURL=prompt-sync.mjs.map
|