@agntn/harnesses 0.2.1 → 0.3.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.
Files changed (50) hide show
  1. package/README.md +48 -9
  2. package/dist/_chunks/agents.mjs +5 -3
  3. package/dist/_chunks/agents.mjs.map +1 -1
  4. package/dist/_chunks/mcp-servers.mjs +5 -3
  5. package/dist/_chunks/mcp-servers.mjs.map +1 -1
  6. package/dist/_chunks/mcp.mjs +10 -1
  7. package/dist/_chunks/mcp.mjs.map +1 -1
  8. package/dist/_chunks/output.mjs +7 -1
  9. package/dist/_chunks/output.mjs.map +1 -1
  10. package/dist/_chunks/prompts.mjs +4 -2
  11. package/dist/_chunks/prompts.mjs.map +1 -1
  12. package/dist/_chunks/{prompt-sync.d.mts → skills-sync.d.mts} +174 -57
  13. package/dist/_chunks/skills-sync.d.mts.map +1 -0
  14. package/dist/_chunks/{prompt-sync.mjs → skills-sync.mjs} +665 -148
  15. package/dist/_chunks/skills-sync.mjs.map +1 -0
  16. package/dist/_chunks/skills.mjs +30 -0
  17. package/dist/_chunks/skills.mjs.map +1 -0
  18. package/dist/_chunks/tool-operations.mjs +38 -13
  19. package/dist/_chunks/tool-operations.mjs.map +1 -1
  20. package/dist/_chunks/tool-schemas.d.mts +22 -13
  21. package/dist/_chunks/tool-schemas.d.mts.map +1 -1
  22. package/dist/_chunks/tool-schemas.mjs +18 -11
  23. package/dist/_chunks/tool-schemas.mjs.map +1 -1
  24. package/dist/_chunks/types.mjs +5 -2
  25. package/dist/_chunks/types.mjs.map +1 -1
  26. package/dist/cli.mjs +29 -9
  27. package/dist/cli.mjs.map +1 -1
  28. package/dist/index.d.mts +16 -2
  29. package/dist/index.d.mts.map +1 -1
  30. package/dist/index.mjs +5 -3
  31. package/dist/index.mjs.map +1 -1
  32. package/dist/mcp.d.mts +2 -0
  33. package/dist/mcp.d.mts.map +1 -1
  34. package/dist/mcp.mjs +6261 -5
  35. package/dist/mcp.mjs.map +1 -1
  36. package/dist/tool-operations.d.mts +21 -4
  37. package/dist/tool-operations.d.mts.map +1 -1
  38. package/dist/tool-operations.mjs +3 -3
  39. package/dist/tool-schemas.d.mts +2 -2
  40. package/dist/tool-schemas.mjs +1 -1
  41. package/dist/typebox.LICENSE +23 -0
  42. package/package.json +18 -18
  43. package/packages/omp/extensions/harnesses.ts +19 -1
  44. package/packages/pi/extensions/harnesses.ts +27 -46
  45. package/packages/shared/tui.ts +13 -0
  46. package/dist/THIRD-PARTY-LICENSES.md +0 -36
  47. package/dist/_chunks/libs/typebox.mjs +0 -5439
  48. package/dist/_chunks/libs/typebox.mjs.map +0 -1
  49. package/dist/_chunks/prompt-sync.d.mts.map +0 -1
  50. package/dist/_chunks/prompt-sync.mjs.map +0 -1
package/README.md CHANGED
@@ -26,7 +26,7 @@ The rest of it sits on [harnesses.agntn.dev](https://harnesses.agntn.dev).
26
26
  - 🔗 **One AGENTS.md behind the global files.** Symlinks, so an edit through Claude or Gemini is the same bytes.
27
27
  - 🗂️ **One prompt folder, supported harnesses.** Markdown lives under XDG data; Gemini TOML is generated from it.
28
28
  - 📜 **Session types when the format is stable.** JSONL, SQLite, JSON. Unstable shapes stay `unknown`.
29
- - 🤖 **Ten tools, three doors.** MCP, Pi and OMP call the same executors.
29
+ - 🤖 **Eleven tools, three doors.** MCP, Pi and OMP call the same executors.
30
30
 
31
31
  ## 📦 Install
32
32
 
@@ -74,9 +74,10 @@ harnesses run codex --read-only "review this"
74
74
  harnesses mcp-servers list
75
75
  harnesses agents sync --check
76
76
  harnesses prompts sync --check
77
+ harnesses skills sync --check
77
78
  ```
78
79
 
79
- `run` without `--tools` is the advisor. `--tools` is the full agent. `--read-only` asks the CLI for a sandbox and implies tools. Timeouts, `--cwd` and `--model` sit in the [CLI guide](https://harnesses.agntn.dev/guide/cli).
80
+ `run` without `--tools` is the advisor. `--tools` is the full agent. `--read-only` asks the CLI for a sandbox and implies tools, so pairing it with `--no-tools` is an error. Timeouts, `--cwd` and `--model` sit in the [CLI guide](https://harnesses.agntn.dev/guide/cli).
80
81
 
81
82
  ### Commands
82
83
 
@@ -91,6 +92,7 @@ harnesses prompts sync --check
91
92
  | `mcp-servers` | MCP servers across the config dialects | `harnesses mcp-servers list` |
92
93
  | `agents sync` | Link global instructions files to one master | `harnesses agents sync --check` |
93
94
  | `prompts sync` | Sync one Markdown prompt directory across harnesses | `harnesses prompts sync --check` |
95
+ | `skills sync` | Link every skills directory to one shared folder | `harnesses skills sync --check` |
94
96
  | `mcp` | The MCP server on stdio | `harnesses mcp` |
95
97
 
96
98
  `list`, `detect`, `info`, `paths` and `models` take `--json` or `--toon`. `run --json` is different: that one is the harness's own structured output.
@@ -103,14 +105,21 @@ import { getHarness, detectHarness } from "@agntn/harnesses";
103
105
  const claude = getHarness("claude");
104
106
  const paths = claude.resolve({ platform: "linux", homeDir: "/home/dev" });
105
107
  console.log(paths.skills);
108
+ console.log(paths.temp, claude.envOverrides);
106
109
 
107
110
  const active = detectHarness();
108
111
  if (active) console.log(active.id);
109
112
 
110
113
  await getHarness("codex").invoke("Review this patch", { readOnly: true });
114
+
115
+ const agy = getHarness("antigravity");
116
+ const [model] = (await agy.listModels({ search: "gemini" })).models;
117
+ if (model) await agy.invoke("Review this patch", { tools: true, model: agy.modelSelector(model) });
111
118
  ```
112
119
 
113
- 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. 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).
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
+
122
+ That's most of it, really. `getHarness` wants an exact id. `detectHarness` uses env vars first, then a single project marker. `invoke()` talks to the CLI. `listModels()` asks it what it can run, and `modelSelector()` turns one of those into what `model` takes, since Pi wants `provider/id` and Antigravity the bare id. A mode the CLI cannot run comes back as an error, not a quieter one. The rest: [Registry](https://harnesses.agntn.dev/guide/registry), [Invoke](https://harnesses.agntn.dev/guide/invoke), [MCP servers](https://harnesses.agntn.dev/guide/mcp-servers), [Instructions files](https://harnesses.agntn.dev/guide/agents-sync).
114
123
 
115
124
  ### Prompt templates
116
125
 
@@ -123,15 +132,45 @@ harnesses prompts sync --check
123
132
  harnesses prompts sync
124
133
  ```
125
134
 
126
- Markdown harnesses receive symlinks to those files. Gemini receives generated
127
- TOML commands, with `$ARGUMENTS` translated to `{{args}}`. Unmanaged files at a
128
- managed name are backed up under the same XDG data tree before replacement.
135
+ For a Markdown harness, the whole prompt directory becomes one symlink to that
136
+ directory, so a template added through any harness shows up in all of them.
137
+ Gemini gets generated TOML commands, with `$ARGUMENTS` translated to `{{args}}`,
138
+ and its commands directory keeps nothing else. Whatever was there before is
139
+ backed up under the same XDG data tree first.
129
140
 
130
141
  `getHarness("pi").promptTemplates` still lists every verified reusable prompt
131
142
  location. `promptTemplateSyncTarget` is the single stable user destination the
132
143
  sync owns for that harness. Formats, frontmatter and CLI limits are in the
133
144
  [registry guide](https://harnesses.agntn.dev/guide/registry#prompt-templates).
134
145
 
146
+ ### Skills
147
+
148
+ Skills live in `$XDG_DATA_HOME/agntn/skills/`, next to the prompts, one folder
149
+ with a `SKILL.md` per skill:
150
+
151
+ ```bash
152
+ harnesses skills sync --check
153
+ harnesses skills sync
154
+ ```
155
+
156
+ ```ts
157
+ import { getAllHarnesses, syncSkills } from "@agntn/harnesses";
158
+
159
+ const report = syncSkills(getAllHarnesses(), true);
160
+ console.log(report.skills, report.targets);
161
+ ```
162
+
163
+ Every harness's user skills directory, `~/.claude/skills/`, `~/.agents/skills/`
164
+ for Codex, `~/.pi/agent/skills/` and the rest, becomes one symlink to that
165
+ folder. A skill written through Claude is already there when Pi looks. Old
166
+ setups with a symlink per skill get replaced without ceremony, and a directory
167
+ with real skills in it is backed up to `diverged/skills/` first. Already keep
168
+ skills in a dotfiles repo? Make the XDG folder a symlink to it. The sync leaves
169
+ a harness directory alone if the source points into it, instead of moving your
170
+ only copy away. `skillsSyncTarget` names the directory it links for each
171
+ harness, `null` for Copilot and Freebuff, which have no user skills directory
172
+ in the registry.
173
+
135
174
  ## 🗺️ Harnesses
136
175
 
137
176
  | ID | Name | Project skills |
@@ -168,7 +207,7 @@ omp install @agntn/harnesses
168
207
  }
169
208
  ```
170
209
 
171
- Ten tools, the same ten on MCP, Pi and OMP. `harnesses_detect`, `harnesses_info` and `harnesses_mcp_list` only read. `harnesses_run` is the one that can spend tokens. `tools` is required, so the model has to pick advisor or agent. What each call returns is on the [Agents page](https://harnesses.agntn.dev/guide/agents).
210
+ Eleven tools, the same eleven on MCP, Pi and OMP. `harnesses_detect`, `harnesses_info` and `harnesses_mcp_list` only read. `harnesses_run` is the one that can spend tokens. `tools` is required, so the model has to pick advisor or agent. What each call returns is on the [Agents page](https://harnesses.agntn.dev/guide/agents).
172
211
 
173
212
  ## 🚫 What this does not do
174
213
 
@@ -182,11 +221,11 @@ Want a fourteenth? One class extending `Harness`, then `registerHarness`. `getHa
182
221
 
183
222
  ```bash
184
223
  pnpm install
185
- pnpm lint # builds first, then oxlint and oxfmt --check
224
+ pnpm lint # builds first, then vp lint and vp fmt --check
186
225
  pnpm lint:fix
187
226
  pnpm typecheck
188
227
  pnpm test:run
189
- pnpm build # obuild
228
+ pnpm build # vp pack
190
229
  pnpm docs # the Docus site, bundles src/ itself
191
230
  ```
192
231
 
@@ -1,8 +1,9 @@
1
- import { isHarnessId, listHarnesses } from "./prompt-sync.mjs";
2
- import { agentsSync } from "./tool-operations.mjs";
3
- import { formatArgs, report } from "./output.mjs";
1
+ import { v as isHarnessId, y as listHarnesses } from "./skills-sync.mjs";
2
+ import { r as agentsSync } from "./tool-operations.mjs";
3
+ import { n as formatArgs, r as report } from "./output.mjs";
4
4
  import { defineCommand } from "citty";
5
5
  import { consola } from "consola";
6
+ //#region src/commands/agents.ts
6
7
  var agents_default = defineCommand({
7
8
  meta: { description: "Manage the shared global instructions file across harnesses" },
8
9
  subCommands: { sync: defineCommand({
@@ -29,6 +30,7 @@ var agents_default = defineCommand({
29
30
  }
30
31
  }) }
31
32
  });
33
+ //#endregion
32
34
  export { agents_default as default };
33
35
 
34
36
  //# sourceMappingURL=agents.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"agents.mjs","names":[],"sources":["../../src/commands/agents.ts"],"sourcesContent":["import { defineCommand } from \"citty\";\nimport { consola } from \"consola\";\nimport { isHarnessId, listHarnesses } from \"../registry.ts\";\nimport { agentsSync } from \"../tool-operations.ts\";\nimport { formatArgs, report } from \"./output.ts\";\n\nexport default defineCommand({\n meta: { description: \"Manage the shared global instructions file across harnesses\" },\n subCommands: {\n sync: defineCommand({\n meta: {\n description:\n \"Link global instructions and declared companions (agents.jsonc: source, companions, excludes)\",\n },\n args: {\n id: { type: \"positional\" as const, description: \"Harness id\", required: false },\n check: {\n type: \"boolean\" as const,\n description: \"Report what would change without writing anything\",\n },\n ...formatArgs,\n },\n run({ args }) {\n const id = args.id === undefined ? undefined : (args.id as string);\n if (id !== undefined && !isHarnessId(id)) {\n consola.error(`Unknown harness: ${id}\\nKnown: ${listHarnesses().join(\", \")}`);\n process.exit(1);\n }\n report(agentsSync(id, args.check === true), args);\n },\n }),\n },\n});\n"],"mappings":";;;;;AAMA,IAAA,iBAAe,cAAc;CAC3B,MAAM,EAAE,aAAa,8DAA8D;CACnF,aAAa,EACX,MAAM,cAAc;EAClB,MAAM,EACJ,aACE,gGACJ;EACA,MAAM;GACJ,IAAI;IAAE,MAAM;IAAuB,aAAa;IAAc,UAAU;GAAM;GAC9E,OAAO;IACL,MAAM;IACN,aAAa;GACf;GACA,GAAG;EACL;EACA,IAAI,EAAE,QAAQ;GACZ,MAAM,KAAK,KAAK,OAAO,KAAA,IAAY,KAAA,IAAa,KAAK;GACrD,IAAI,OAAO,KAAA,KAAa,CAAC,YAAY,EAAE,GAAG;IACxC,QAAQ,MAAM,oBAAoB,GAAG,WAAW,cAAc,CAAC,CAAC,KAAK,IAAI,GAAG;IAC5E,QAAQ,KAAK,CAAC;GAChB;GACA,OAAO,WAAW,IAAI,KAAK,UAAU,IAAI,GAAG,IAAI;EAClD;CACF,CAAC,EACH;AACF,CAAC"}
1
+ {"version":3,"file":"agents.mjs","names":[],"sources":["../../src/commands/agents.ts"],"sourcesContent":["import { defineCommand } from \"citty\";\nimport { consola } from \"consola\";\nimport { isHarnessId, listHarnesses } from \"../registry.ts\";\nimport { agentsSync } from \"../tool-operations.ts\";\nimport { formatArgs, report } from \"./output.ts\";\n\nexport default defineCommand({\n meta: { description: \"Manage the shared global instructions file across harnesses\" },\n subCommands: {\n sync: defineCommand({\n meta: {\n description:\n \"Link global instructions and declared companions (agents.jsonc: source, companions, excludes)\",\n },\n args: {\n id: { type: \"positional\" as const, description: \"Harness id\", required: false },\n check: {\n type: \"boolean\" as const,\n description: \"Report what would change without writing anything\",\n },\n ...formatArgs,\n },\n run({ args }) {\n const id = args.id === undefined ? undefined : (args.id as string);\n if (id !== undefined && !isHarnessId(id)) {\n consola.error(`Unknown harness: ${id}\\nKnown: ${listHarnesses().join(\", \")}`);\n process.exit(1);\n }\n report(agentsSync(id, args.check === true), args);\n },\n }),\n },\n});\n"],"mappings":";;;;;;AAMA,IAAA,iBAAe,cAAc;CAC3B,MAAM,EAAE,aAAa,8DAA8D;CACnF,aAAa,EACX,MAAM,cAAc;EAClB,MAAM,EACJ,aACE,gGACJ;EACA,MAAM;GACJ,IAAI;IAAE,MAAM;IAAuB,aAAa;IAAc,UAAU;GAAM;GAC9E,OAAO;IACL,MAAM;IACN,aAAa;GACf;GACA,GAAG;EACL;EACA,IAAI,EAAE,QAAQ;GACZ,MAAM,KAAK,KAAK,OAAO,KAAA,IAAY,KAAA,IAAa,KAAK;GACrD,IAAI,OAAO,KAAA,KAAa,CAAC,YAAY,EAAE,GAAG;IACxC,QAAQ,MAAM,oBAAoB,GAAG,WAAW,cAAc,CAAC,CAAC,KAAK,IAAI,GAAG;IAC5E,QAAQ,KAAK,CAAC;GAChB;GACA,OAAO,WAAW,IAAI,KAAK,UAAU,IAAI,GAAG,IAAI;EAClD;CACF,CAAC,EACH;AACF,CAAC"}
@@ -1,8 +1,9 @@
1
- import { isHarnessId, listHarnesses } from "./prompt-sync.mjs";
2
- import { mcpAdd, mcpList, mcpRemove, mcpSync } from "./tool-operations.mjs";
3
- import { formatArgs, report } from "./output.mjs";
1
+ import { v as isHarnessId, y as listHarnesses } from "./skills-sync.mjs";
2
+ import { c as mcpList, l as mcpRemove, s as mcpAdd, u as mcpSync } from "./tool-operations.mjs";
3
+ import { n as formatArgs, r as report } from "./output.mjs";
4
4
  import { defineCommand } from "citty";
5
5
  import { consola } from "consola";
6
+ //#region src/commands/mcp-servers.ts
6
7
  function requireHarnessId(id) {
7
8
  if (!isHarnessId(id)) {
8
9
  consola.error(`Unknown harness: ${id}\nKnown: ${listHarnesses().join(", ")}`);
@@ -115,6 +116,7 @@ var mcp_servers_default = defineCommand({
115
116
  })
116
117
  }
117
118
  });
119
+ //#endregion
118
120
  export { mcp_servers_default as default };
119
121
 
120
122
  //# sourceMappingURL=mcp-servers.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"mcp-servers.mjs","names":[],"sources":["../../src/commands/mcp-servers.ts"],"sourcesContent":["import { defineCommand } from \"citty\";\nimport { consola } from \"consola\";\nimport { isHarnessId, listHarnesses } from \"../registry.ts\";\nimport { mcpAdd, mcpList, mcpRemove, mcpSync } from \"../tool-operations.ts\";\nimport { formatArgs, report } from \"./output.ts\";\n\nfunction requireHarnessId(id: string): string {\n if (!isHarnessId(id)) {\n consola.error(`Unknown harness: ${id}\\nKnown: ${listHarnesses().join(\", \")}`);\n process.exit(1);\n }\n return id;\n}\n\nexport default defineCommand({\n meta: { description: \"Manage MCP servers across harness configs\" },\n subCommands: {\n list: defineCommand({\n meta: { description: \"List configured MCP servers, normalized\" },\n args: {\n id: { type: \"positional\" as const, description: \"Harness id\", required: false },\n ...formatArgs,\n },\n run({ args }) {\n const id = args.id === undefined ? undefined : requireHarnessId(args.id as string);\n report(mcpList(id), args);\n },\n }),\n add: defineCommand({\n meta: { description: \"Add or replace one MCP server in a harness config\" },\n args: {\n id: { type: \"positional\" as const, description: \"Harness id\", required: true },\n name: { type: \"positional\" as const, description: \"Server name\", required: true },\n command: { type: \"string\" as const, description: \"Binary for a stdio server\" },\n args: {\n type: \"string\" as const,\n description: \"Space-separated arguments for a stdio server\",\n },\n env: { type: \"string\" as const, description: \"Comma-separated K=V environment variables\" },\n url: { type: \"string\" as const, description: \"URL for an http/sse server\" },\n scope: { type: \"string\" as const, description: \"user (default) or project\" },\n ...formatArgs,\n },\n run({ args }) {\n const env = args.env\n ? Object.fromEntries(\n args.env\n .split(\",\")\n .map((pair) => pair.split(/=(.*)/s))\n .filter((pair) => pair[0])\n .map((pair) => [pair[0] as string, pair[1] ?? \"\"]),\n )\n : undefined;\n const result = mcpAdd(\n requireHarnessId(args.id as string),\n {\n name: args.name as string,\n ...(args.command ? { command: args.command } : {}),\n ...(args.args ? { args: args.args.split(\" \").filter(Boolean) } : {}),\n ...(env ? { env } : {}),\n ...(args.url ? { url: args.url } : {}),\n },\n args.scope === \"project\" ? \"project\" : \"user\",\n );\n report(result, args);\n },\n }),\n sync: defineCommand({\n meta: {\n description: \"Reset harness configs to the master list from ~/.config/agntn/mcp.jsonc\",\n },\n args: {\n id: { type: \"positional\" as const, description: \"Harness id\", required: false },\n ...formatArgs,\n },\n run({ args }) {\n const id = args.id === undefined ? undefined : requireHarnessId(args.id as string);\n report(mcpSync(id), args);\n },\n }),\n remove: defineCommand({\n meta: { description: \"Remove one MCP server from a harness config\" },\n args: {\n id: { type: \"positional\" as const, description: \"Harness id\", required: true },\n name: { type: \"positional\" as const, description: \"Server name\", required: true },\n scope: { type: \"string\" as const, description: \"user (default) or project\" },\n ...formatArgs,\n },\n run({ args }) {\n report(\n mcpRemove(\n requireHarnessId(args.id as string),\n args.name as string,\n args.scope === \"project\" ? \"project\" : \"user\",\n ),\n args,\n );\n },\n }),\n },\n});\n"],"mappings":";;;;;AAMA,SAAS,iBAAiB,IAAoB;CAC5C,IAAI,CAAC,YAAY,EAAE,GAAG;EACpB,QAAQ,MAAM,oBAAoB,GAAG,WAAW,cAAc,CAAC,CAAC,KAAK,IAAI,GAAG;EAC5E,QAAQ,KAAK,CAAC;CAChB;CACA,OAAO;AACT;AAEA,IAAA,sBAAe,cAAc;CAC3B,MAAM,EAAE,aAAa,4CAA4C;CACjE,aAAa;EACX,MAAM,cAAc;GAClB,MAAM,EAAE,aAAa,0CAA0C;GAC/D,MAAM;IACJ,IAAI;KAAE,MAAM;KAAuB,aAAa;KAAc,UAAU;IAAM;IAC9E,GAAG;GACL;GACA,IAAI,EAAE,QAAQ;IACZ,MAAM,KAAK,KAAK,OAAO,KAAA,IAAY,KAAA,IAAY,iBAAiB,KAAK,EAAY;IACjF,OAAO,QAAQ,EAAE,GAAG,IAAI;GAC1B;EACF,CAAC;EACD,KAAK,cAAc;GACjB,MAAM,EAAE,aAAa,oDAAoD;GACzE,MAAM;IACJ,IAAI;KAAE,MAAM;KAAuB,aAAa;KAAc,UAAU;IAAK;IAC7E,MAAM;KAAE,MAAM;KAAuB,aAAa;KAAe,UAAU;IAAK;IAChF,SAAS;KAAE,MAAM;KAAmB,aAAa;IAA4B;IAC7E,MAAM;KACJ,MAAM;KACN,aAAa;IACf;IACA,KAAK;KAAE,MAAM;KAAmB,aAAa;IAA4C;IACzF,KAAK;KAAE,MAAM;KAAmB,aAAa;IAA6B;IAC1E,OAAO;KAAE,MAAM;KAAmB,aAAa;IAA4B;IAC3E,GAAG;GACL;GACA,IAAI,EAAE,QAAQ;IACZ,MAAM,MAAM,KAAK,MACb,OAAO,YACL,KAAK,IACF,MAAM,GAAG,CAAC,CACV,KAAK,SAAS,KAAK,MAAM,QAAQ,CAAC,CAAC,CACnC,QAAQ,SAAS,KAAK,EAAE,CAAC,CACzB,KAAK,SAAS,CAAC,KAAK,IAAc,KAAK,MAAM,EAAE,CAAC,CACrD,IACA,KAAA;IACJ,MAAM,SAAS,OACb,iBAAiB,KAAK,EAAY,GAClC;KACE,MAAM,KAAK;KACX,GAAI,KAAK,UAAU,EAAE,SAAS,KAAK,QAAQ,IAAI,CAAC;KAChD,GAAI,KAAK,OAAO,EAAE,MAAM,KAAK,KAAK,MAAM,GAAG,CAAC,CAAC,OAAO,OAAO,EAAE,IAAI,CAAC;KAClE,GAAI,MAAM,EAAE,IAAI,IAAI,CAAC;KACrB,GAAI,KAAK,MAAM,EAAE,KAAK,KAAK,IAAI,IAAI,CAAC;IACtC,GACA,KAAK,UAAU,YAAY,YAAY,MACzC;IACA,OAAO,QAAQ,IAAI;GACrB;EACF,CAAC;EACD,MAAM,cAAc;GAClB,MAAM,EACJ,aAAa,0EACf;GACA,MAAM;IACJ,IAAI;KAAE,MAAM;KAAuB,aAAa;KAAc,UAAU;IAAM;IAC9E,GAAG;GACL;GACA,IAAI,EAAE,QAAQ;IACZ,MAAM,KAAK,KAAK,OAAO,KAAA,IAAY,KAAA,IAAY,iBAAiB,KAAK,EAAY;IACjF,OAAO,QAAQ,EAAE,GAAG,IAAI;GAC1B;EACF,CAAC;EACD,QAAQ,cAAc;GACpB,MAAM,EAAE,aAAa,8CAA8C;GACnE,MAAM;IACJ,IAAI;KAAE,MAAM;KAAuB,aAAa;KAAc,UAAU;IAAK;IAC7E,MAAM;KAAE,MAAM;KAAuB,aAAa;KAAe,UAAU;IAAK;IAChF,OAAO;KAAE,MAAM;KAAmB,aAAa;IAA4B;IAC3E,GAAG;GACL;GACA,IAAI,EAAE,QAAQ;IACZ,OACE,UACE,iBAAiB,KAAK,EAAY,GAClC,KAAK,MACL,KAAK,UAAU,YAAY,YAAY,MACzC,GACA,IACF;GACF;EACF,CAAC;CACH;AACF,CAAC"}
1
+ {"version":3,"file":"mcp-servers.mjs","names":[],"sources":["../../src/commands/mcp-servers.ts"],"sourcesContent":["import { defineCommand } from \"citty\";\nimport { consola } from \"consola\";\nimport { isHarnessId, listHarnesses } from \"../registry.ts\";\nimport { mcpAdd, mcpList, mcpRemove, mcpSync } from \"../tool-operations.ts\";\nimport { formatArgs, report } from \"./output.ts\";\n\nfunction requireHarnessId(id: string): string {\n if (!isHarnessId(id)) {\n consola.error(`Unknown harness: ${id}\\nKnown: ${listHarnesses().join(\", \")}`);\n process.exit(1);\n }\n return id;\n}\n\nexport default defineCommand({\n meta: { description: \"Manage MCP servers across harness configs\" },\n subCommands: {\n list: defineCommand({\n meta: { description: \"List configured MCP servers, normalized\" },\n args: {\n id: { type: \"positional\" as const, description: \"Harness id\", required: false },\n ...formatArgs,\n },\n run({ args }) {\n const id = args.id === undefined ? undefined : requireHarnessId(args.id as string);\n report(mcpList(id), args);\n },\n }),\n add: defineCommand({\n meta: { description: \"Add or replace one MCP server in a harness config\" },\n args: {\n id: { type: \"positional\" as const, description: \"Harness id\", required: true },\n name: { type: \"positional\" as const, description: \"Server name\", required: true },\n command: { type: \"string\" as const, description: \"Binary for a stdio server\" },\n args: {\n type: \"string\" as const,\n description: \"Space-separated arguments for a stdio server\",\n },\n env: { type: \"string\" as const, description: \"Comma-separated K=V environment variables\" },\n url: { type: \"string\" as const, description: \"URL for an http/sse server\" },\n scope: { type: \"string\" as const, description: \"user (default) or project\" },\n ...formatArgs,\n },\n run({ args }) {\n const env = args.env\n ? Object.fromEntries(\n args.env\n .split(\",\")\n .map((pair) => pair.split(/=(.*)/s))\n .filter((pair) => pair[0])\n .map((pair) => [pair[0] as string, pair[1] ?? \"\"]),\n )\n : undefined;\n const result = mcpAdd(\n requireHarnessId(args.id as string),\n {\n name: args.name as string,\n ...(args.command ? { command: args.command } : {}),\n ...(args.args ? { args: args.args.split(\" \").filter(Boolean) } : {}),\n ...(env ? { env } : {}),\n ...(args.url ? { url: args.url } : {}),\n },\n args.scope === \"project\" ? \"project\" : \"user\",\n );\n report(result, args);\n },\n }),\n sync: defineCommand({\n meta: {\n description: \"Reset harness configs to the master list from ~/.config/agntn/mcp.jsonc\",\n },\n args: {\n id: { type: \"positional\" as const, description: \"Harness id\", required: false },\n ...formatArgs,\n },\n run({ args }) {\n const id = args.id === undefined ? undefined : requireHarnessId(args.id as string);\n report(mcpSync(id), args);\n },\n }),\n remove: defineCommand({\n meta: { description: \"Remove one MCP server from a harness config\" },\n args: {\n id: { type: \"positional\" as const, description: \"Harness id\", required: true },\n name: { type: \"positional\" as const, description: \"Server name\", required: true },\n scope: { type: \"string\" as const, description: \"user (default) or project\" },\n ...formatArgs,\n },\n run({ args }) {\n report(\n mcpRemove(\n requireHarnessId(args.id as string),\n args.name as string,\n args.scope === \"project\" ? \"project\" : \"user\",\n ),\n args,\n );\n },\n }),\n },\n});\n"],"mappings":";;;;;;AAMA,SAAS,iBAAiB,IAAoB;CAC5C,IAAI,CAAC,YAAY,EAAE,GAAG;EACpB,QAAQ,MAAM,oBAAoB,GAAG,WAAW,cAAc,CAAC,CAAC,KAAK,IAAI,GAAG;EAC5E,QAAQ,KAAK,CAAC;CAChB;CACA,OAAO;AACT;AAEA,IAAA,sBAAe,cAAc;CAC3B,MAAM,EAAE,aAAa,4CAA4C;CACjE,aAAa;EACX,MAAM,cAAc;GAClB,MAAM,EAAE,aAAa,0CAA0C;GAC/D,MAAM;IACJ,IAAI;KAAE,MAAM;KAAuB,aAAa;KAAc,UAAU;IAAM;IAC9E,GAAG;GACL;GACA,IAAI,EAAE,QAAQ;IACZ,MAAM,KAAK,KAAK,OAAO,KAAA,IAAY,KAAA,IAAY,iBAAiB,KAAK,EAAY;IACjF,OAAO,QAAQ,EAAE,GAAG,IAAI;GAC1B;EACF,CAAC;EACD,KAAK,cAAc;GACjB,MAAM,EAAE,aAAa,oDAAoD;GACzE,MAAM;IACJ,IAAI;KAAE,MAAM;KAAuB,aAAa;KAAc,UAAU;IAAK;IAC7E,MAAM;KAAE,MAAM;KAAuB,aAAa;KAAe,UAAU;IAAK;IAChF,SAAS;KAAE,MAAM;KAAmB,aAAa;IAA4B;IAC7E,MAAM;KACJ,MAAM;KACN,aAAa;IACf;IACA,KAAK;KAAE,MAAM;KAAmB,aAAa;IAA4C;IACzF,KAAK;KAAE,MAAM;KAAmB,aAAa;IAA6B;IAC1E,OAAO;KAAE,MAAM;KAAmB,aAAa;IAA4B;IAC3E,GAAG;GACL;GACA,IAAI,EAAE,QAAQ;IACZ,MAAM,MAAM,KAAK,MACb,OAAO,YACL,KAAK,IACF,MAAM,GAAG,CAAC,CACV,KAAK,SAAS,KAAK,MAAM,QAAQ,CAAC,CAAC,CACnC,QAAQ,SAAS,KAAK,EAAE,CAAC,CACzB,KAAK,SAAS,CAAC,KAAK,IAAc,KAAK,MAAM,EAAE,CAAC,CACrD,IACA,KAAA;IACJ,MAAM,SAAS,OACb,iBAAiB,KAAK,EAAY,GAClC;KACE,MAAM,KAAK;KACX,GAAI,KAAK,UAAU,EAAE,SAAS,KAAK,QAAQ,IAAI,CAAC;KAChD,GAAI,KAAK,OAAO,EAAE,MAAM,KAAK,KAAK,MAAM,GAAG,CAAC,CAAC,OAAO,OAAO,EAAE,IAAI,CAAC;KAClE,GAAI,MAAM,EAAE,IAAI,IAAI,CAAC;KACrB,GAAI,KAAK,MAAM,EAAE,KAAK,KAAK,IAAI,IAAI,CAAC;IACtC,GACA,KAAK,UAAU,YAAY,YAAY,MACzC;IACA,OAAO,QAAQ,IAAI;GACrB;EACF,CAAC;EACD,MAAM,cAAc;GAClB,MAAM,EACJ,aAAa,0EACf;GACA,MAAM;IACJ,IAAI;KAAE,MAAM;KAAuB,aAAa;KAAc,UAAU;IAAM;IAC9E,GAAG;GACL;GACA,IAAI,EAAE,QAAQ;IACZ,MAAM,KAAK,KAAK,OAAO,KAAA,IAAY,KAAA,IAAY,iBAAiB,KAAK,EAAY;IACjF,OAAO,QAAQ,EAAE,GAAG,IAAI;GAC1B;EACF,CAAC;EACD,QAAQ,cAAc;GACpB,MAAM,EAAE,aAAa,8CAA8C;GACnE,MAAM;IACJ,IAAI;KAAE,MAAM;KAAuB,aAAa;KAAc,UAAU;IAAK;IAC7E,MAAM;KAAE,MAAM;KAAuB,aAAa;KAAe,UAAU;IAAK;IAChF,OAAO;KAAE,MAAM;KAAmB,aAAa;IAA4B;IAC3E,GAAG;GACL;GACA,IAAI,EAAE,QAAQ;IACZ,OACE,UACE,iBAAiB,KAAK,EAAY,GAClC,KAAK,MACL,KAAK,UAAU,YAAY,YAAY,MACzC,GACA,IACF;GACF;EACF,CAAC;CACH;AACF,CAAC"}
@@ -1,5 +1,7 @@
1
+ import { t as exitOnClosedPipe } from "./output.mjs";
1
2
  import { defineCommand } from "citty";
2
3
  import { LogLevels, consola } from "consola";
4
+ //#region src/commands/mcp.ts
3
5
  var mcp_default = defineCommand({
4
6
  meta: {
5
7
  name: "mcp",
@@ -8,9 +10,16 @@ var mcp_default = defineCommand({
8
10
  async run() {
9
11
  consola.level = LogLevels.warn;
10
12
  const [{ createMcpServer }, { StdioServerTransport }] = await Promise.all([import("../mcp.mjs"), import("@modelcontextprotocol/sdk/server/stdio.js")]);
11
- await createMcpServer().connect(new StdioServerTransport());
13
+ const server = createMcpServer();
14
+ await server.connect(new StdioServerTransport());
15
+ process.stdin.once("end", () => void server.close());
16
+ process.stdout.off("error", exitOnClosedPipe).on("error", (error) => {
17
+ if (error.code !== "EPIPE") throw error;
18
+ server.close();
19
+ });
12
20
  }
13
21
  });
22
+ //#endregion
14
23
  export { mcp_default as default };
15
24
 
16
25
  //# sourceMappingURL=mcp.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"mcp.mjs","names":[],"sources":["../../src/commands/mcp.ts"],"sourcesContent":["import { defineCommand } from \"citty\";\nimport { consola, LogLevels } from \"consola\";\n\nexport default defineCommand({\n meta: {\n name: \"mcp\",\n description: \"Run the harnesses MCP server over stdio\",\n },\n /**\n * The server and the SDK load here, because citty resolves every subcommand\n * to print `harnesses --help` and to look for an alias of an unknown command.\n *\n * stdout carries the JSON-RPC frames. consola's default reporter sends\n * anything at log level or below to that same descriptor, and `DEBUG` in the\n * environment raises the level on import, so one stray line would corrupt\n * the stream. Warnings and errors still reach stderr.\n */\n async run() {\n consola.level = LogLevels.warn;\n\n const [{ createMcpServer }, { StdioServerTransport }] = await Promise.all([\n import(\"../mcp.ts\"),\n import(\"@modelcontextprotocol/sdk/server/stdio.js\"),\n ]);\n await createMcpServer().connect(new StdioServerTransport());\n },\n});\n"],"mappings":";;AAGA,IAAA,cAAe,cAAc;CAC3B,MAAM;EACJ,MAAM;EACN,aAAa;CACf"}
1
+ {"version":3,"file":"mcp.mjs","names":[],"sources":["../../src/commands/mcp.ts"],"sourcesContent":["import { defineCommand } from \"citty\";\nimport { consola, LogLevels } from \"consola\";\nimport { exitOnClosedPipe } from \"./output.ts\";\n\nexport default defineCommand({\n meta: {\n name: \"mcp\",\n description: \"Run the harnesses MCP server over stdio\",\n },\n /**\n * The server and the SDK load here, because citty resolves every subcommand\n * to print `harnesses --help` and to look for an alias of an unknown command.\n *\n * stdout carries the JSON-RPC frames. consola's default reporter sends\n * anything at log level or below to that same descriptor, and `DEBUG` in the\n * environment raises the level on import, so one stray line would corrupt\n * the stream. Warnings and errors still reach stderr.\n *\n * The SDK's stdio transport never watches for the end of stdin, so a client\n * that exits would leave an in-flight `harnesses_run` going until its own\n * deadline. Closing the server aborts every pending request signal, which\n * stops each run's process group the same way a cancellation does, and the\n * process then exits once that cleanup has nothing left to wait for. A\n * write to a stdout the client already closed means the same, so it closes\n * the server too instead of exiting past that cleanup.\n */\n async run() {\n consola.level = LogLevels.warn;\n\n const [{ createMcpServer }, { StdioServerTransport }] = await Promise.all([\n import(\"../mcp.ts\"),\n import(\"@modelcontextprotocol/sdk/server/stdio.js\"),\n ]);\n const server = createMcpServer();\n await server.connect(new StdioServerTransport());\n process.stdin.once(\"end\", () => void server.close());\n process.stdout\n .off(\"error\", exitOnClosedPipe)\n .on(\"error\", (error: Readonly<NodeJS.ErrnoException>) => {\n if (error.code !== \"EPIPE\") throw error;\n void server.close();\n });\n },\n});\n"],"mappings":";;;;AAIA,IAAA,cAAe,cAAc;CAC3B,MAAM;EACJ,MAAM;EACN,aAAa;CACf;CAkBA,MAAM,MAAM;EACV,QAAQ,QAAQ,UAAU;EAE1B,MAAM,CAAC,EAAE,mBAAmB,EAAE,0BAA0B,MAAM,QAAQ,IAAI,CACxE,OAAO,eACP,OAAO,4CACT,CAAC;EACD,MAAM,SAAS,gBAAgB;EAC/B,MAAM,OAAO,QAAQ,IAAI,qBAAqB,CAAC;EAC/C,QAAQ,MAAM,KAAK,aAAa,KAAK,OAAO,MAAM,CAAC;EACnD,QAAQ,OACL,IAAI,SAAS,gBAAgB,CAAC,CAC9B,GAAG,UAAU,UAA2C;GACvD,IAAI,MAAM,SAAS,SAAS,MAAM;GAClC,OAAY,MAAM;EACpB,CAAC;CACL;AACF,CAAC"}
@@ -1,6 +1,7 @@
1
1
  import { stripVTControlCharacters } from "node:util";
2
2
  import { consola } from "consola";
3
3
  import { encode } from "@toon-format/toon";
4
+ //#region src/commands/output.ts
4
5
  const formatArgs = {
5
6
  json: {
6
7
  type: "boolean",
@@ -11,6 +12,10 @@ const formatArgs = {
11
12
  description: "Output as TOON"
12
13
  }
13
14
  };
15
+ function exitOnClosedPipe(error) {
16
+ if (error.code !== "EPIPE") throw error;
17
+ process.exit();
18
+ }
14
19
  const UNSAFE_TERMINAL_CONTROLS = /[\u0000-\u0008\u000B-\u001F\u007F-\u009F]/g;
15
20
  const UNSAFE_UNICODE_FORMATTING = /[\p{Cf}\p{Zl}\p{Zp}]/gu;
16
21
  function sanitize(text) {
@@ -23,6 +28,7 @@ function report(result, args) {
23
28
  else console.log(sanitize(result.content[0]?.text));
24
29
  if (result.isError) process.exitCode = 1;
25
30
  }
26
- export { formatArgs, report };
31
+ //#endregion
32
+ export { formatArgs as n, report as r, exitOnClosedPipe as t };
27
33
 
28
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\ntype OutputFormat = Readonly<{ json?: boolean; toon?: boolean }>;\n\n/** Control bytes removed from reports because they can echo untrusted configuration values. */\n/* oxlint-disable-next-line no-control-regex */\nconst UNSAFE_TERMINAL_CONTROLS = /[\\u0000-\\u0008\\u000B-\\u001F\\u007F-\\u009F]/g;\nconst UNSAFE_UNICODE_FORMATTING = /[\\p{Cf}\\p{Zl}\\p{Zp}]/gu;\n\nfunction sanitize(text: string | undefined): string {\n return stripVTControlCharacters(text ?? \"\")\n .replace(UNSAFE_TERMINAL_CONTROLS, \" \")\n .replace(UNSAFE_UNICODE_FORMATTING, \" \");\n}\n\n/**\n * Emits one tool result in the selected machine or human format.\n *\n * @param result - Shared executor result to emit.\n * @param args - Selected output format.\n */\nexport function report(result: ToolResult<unknown>, args: OutputFormat): void {\n if (args.json) console.log(JSON.stringify(result.details, null, 2));\n else if (args.toon) console.log(toToon(result.details));\n else if (result.isError) consola.error(sanitize(result.content[0]?.text));\n else console.log(sanitize(result.content[0]?.text));\n\n if (result.isError) process.exitCode = 1;\n}\n"],"mappings":";;;AAKA,MAAa,aAAa;CACxB,MAAM;EAAE,MAAM;EAAoB,aAAa;CAAiB;CAChE,MAAM;EAAE,MAAM;EAAoB,aAAa;CAAiB;AAClE;AAMA,MAAM,2BAA2B;AACjC,MAAM,4BAA4B;AAElC,SAAS,SAAS,MAAkC;CAClD,OAAO,yBAAyB,QAAQ,EAAE,CAAC,CACxC,QAAQ,0BAA0B,GAAG,CAAC,CACtC,QAAQ,2BAA2B,GAAG;AAC3C;;;;;;CAQA,IAAA,OAAgB,SAAO,QAA6B,WAA0B;AAC5E;AAEK,SAAA,YAAW"}
1
+ {"version":3,"file":"output.mjs","names":["toToon"],"sources":["../../src/commands/output.ts"],"sourcesContent":["import { stripVTControlCharacters } from \"node:util\";\nimport { encode as toToon } from \"@toon-format/toon\";\nimport { consola } from \"consola\";\nimport type { ToolResult } from \"../tool-operations.ts\";\n\nexport const formatArgs = {\n json: { type: \"boolean\" as const, description: \"Output as JSON\" },\n toon: { type: \"boolean\" as const, description: \"Output as TOON\" },\n};\n\n/**\n * Ends the process once the reader of stdout or stderr is gone, as after\n * `| head -1` or a pager that quits early. Node ignores SIGPIPE, so without a\n * listener the next write throws `EPIPE` with a stack trace. The exit code\n * stays whatever the command set.\n *\n * @param error - The error the stream emitted.\n */\nexport function exitOnClosedPipe(error: Readonly<NodeJS.ErrnoException>): void {\n if (error.code !== \"EPIPE\") throw error;\n process.exit();\n}\n\ntype OutputFormat = Readonly<{ json?: boolean; toon?: boolean }>;\n\n/** Control bytes removed from reports because they can echo untrusted configuration values. */\n/* oxlint-disable-next-line no-control-regex */\nconst UNSAFE_TERMINAL_CONTROLS = /[\\u0000-\\u0008\\u000B-\\u001F\\u007F-\\u009F]/g;\nconst UNSAFE_UNICODE_FORMATTING = /[\\p{Cf}\\p{Zl}\\p{Zp}]/gu;\n\nfunction sanitize(text: string | undefined): string {\n return stripVTControlCharacters(text ?? \"\")\n .replace(UNSAFE_TERMINAL_CONTROLS, \" \")\n .replace(UNSAFE_UNICODE_FORMATTING, \" \");\n}\n\n/**\n * Emits one tool result in the selected machine or human format.\n *\n * @param result - Shared executor result to emit.\n * @param args - Selected output format.\n */\nexport function report(result: ToolResult<unknown>, args: OutputFormat): void {\n if (args.json) console.log(JSON.stringify(result.details, null, 2));\n else if (args.toon) console.log(toToon(result.details));\n else if (result.isError) consola.error(sanitize(result.content[0]?.text));\n else console.log(sanitize(result.content[0]?.text));\n\n if (result.isError) process.exitCode = 1;\n}\n"],"mappings":";;;;AAKA,MAAa,aAAa;CACxB,MAAM;EAAE,MAAM;EAAoB,aAAa;CAAiB;CAChE,MAAM;EAAE,MAAM;EAAoB,aAAa;CAAiB;AAClE;AAUA,SAAgB,iBAAiB,OAA8C;CAC7E,IAAI,MAAM,SAAS,SAAS,MAAM;CAClC,QAAQ,KAAK;AACf;AAMA,MAAM,2BAA2B;AACjC,MAAM,4BAA4B;AAElC,SAAS,SAAS,MAAkC;CAClD,OAAO,yBAAyB,QAAQ,EAAE,CAAC,CACxC,QAAQ,0BAA0B,GAAG,CAAC,CACtC,QAAQ,2BAA2B,GAAG;AAC3C;AAQA,SAAgB,OAAO,QAA6B,MAA0B;CAC5E,IAAI,KAAK,MAAM,QAAQ,IAAI,KAAK,UAAU,OAAO,SAAS,MAAM,CAAC,CAAC;MAC7D,IAAI,KAAK,MAAM,QAAQ,IAAIA,OAAO,OAAO,OAAO,CAAC;MACjD,IAAI,OAAO,SAAS,QAAQ,MAAM,SAAS,OAAO,QAAQ,EAAE,EAAE,IAAI,CAAC;MACnE,QAAQ,IAAI,SAAS,OAAO,QAAQ,EAAE,EAAE,IAAI,CAAC;CAElD,IAAI,OAAO,SAAS,QAAQ,WAAW;AACzC"}
@@ -1,6 +1,7 @@
1
- import { promptsSync } from "./tool-operations.mjs";
2
- import { formatArgs, report } from "./output.mjs";
1
+ import { d as promptsSync } from "./tool-operations.mjs";
2
+ import { n as formatArgs, r as report } from "./output.mjs";
3
3
  import { defineCommand } from "citty";
4
+ //#region src/commands/prompts.ts
4
5
  var prompts_default = defineCommand({
5
6
  meta: { description: "Manage shared prompt templates across harnesses" },
6
7
  subCommands: { sync: defineCommand({
@@ -23,6 +24,7 @@ var prompts_default = defineCommand({
23
24
  }
24
25
  }) }
25
26
  });
27
+ //#endregion
26
28
  export { prompts_default as default };
27
29
 
28
30
  //# sourceMappingURL=prompts.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"prompts.mjs","names":[],"sources":["../../src/commands/prompts.ts"],"sourcesContent":["import { defineCommand } from \"citty\";\nimport { promptsSync } from \"../tool-operations.ts\";\nimport { formatArgs, report } from \"./output.ts\";\n\nexport default defineCommand({\n meta: { description: \"Manage shared prompt templates across harnesses\" },\n subCommands: {\n sync: defineCommand({\n meta: {\n description:\n \"Sync Markdown templates from the agntn XDG data directory into harness destinations\",\n },\n args: {\n id: { type: \"positional\" as const, description: \"Harness id\", required: false },\n check: {\n type: \"boolean\" as const,\n description: \"Report what would change without writing anything\",\n },\n ...formatArgs,\n },\n run({ args }) {\n const id = args.id === undefined ? undefined : (args.id as string);\n report(promptsSync(id, args.check === true), args);\n },\n }),\n },\n});\n"],"mappings":";;;AAIA,IAAA,kBAAe,cAAc;CAC3B,MAAM,EAAE,aAAa,kDAAkD;CACvE,aAAa,EACX,MAAM,cAAc;EAClB,MAAM,EACJ,aACE,sFACJ;EACA,MAAM;GACJ,IAAI;IAAE,MAAM;IAAuB,aAAa;IAAc,UAAU;GAAM;GAC9E,OAAO;IACL,MAAM;IACN,aAAa;GACf;GACA,GAAG;EACL;EACA,IAAI,EAAE,QAAQ;GACZ,MAAM,KAAK,KAAK,OAAO,KAAA,IAAY,KAAA,IAAa,KAAK;GACrD,OAAO,YAAY,IAAI,KAAK,UAAU,IAAI,GAAG,IAAI;EACnD;CACF,CAAC,EACH;AACF,CAAC"}
1
+ {"version":3,"file":"prompts.mjs","names":[],"sources":["../../src/commands/prompts.ts"],"sourcesContent":["import { defineCommand } from \"citty\";\nimport { promptsSync } from \"../tool-operations.ts\";\nimport { formatArgs, report } from \"./output.ts\";\n\nexport default defineCommand({\n meta: { description: \"Manage shared prompt templates across harnesses\" },\n subCommands: {\n sync: defineCommand({\n meta: {\n description:\n \"Sync Markdown templates from the agntn XDG data directory into harness destinations\",\n },\n args: {\n id: { type: \"positional\" as const, description: \"Harness id\", required: false },\n check: {\n type: \"boolean\" as const,\n description: \"Report what would change without writing anything\",\n },\n ...formatArgs,\n },\n run({ args }) {\n const id = args.id === undefined ? undefined : (args.id as string);\n report(promptsSync(id, args.check === true), args);\n },\n }),\n },\n});\n"],"mappings":";;;;AAIA,IAAA,kBAAe,cAAc;CAC3B,MAAM,EAAE,aAAa,kDAAkD;CACvE,aAAa,EACX,MAAM,cAAc;EAClB,MAAM,EACJ,aACE,sFACJ;EACA,MAAM;GACJ,IAAI;IAAE,MAAM;IAAuB,aAAa;IAAc,UAAU;GAAM;GAC9E,OAAO;IACL,MAAM;IACN,aAAa;GACf;GACA,GAAG;EACL;EACA,IAAI,EAAE,QAAQ;GACZ,MAAM,KAAK,KAAK,OAAO,KAAA,IAAY,KAAA,IAAa,KAAK;GACrD,OAAO,YAAY,IAAI,KAAK,UAAU,IAAI,GAAG,IAAI;EACnD;CACF,CAAC,EACH;AACF,CAAC"}