zidane 5.14.4 → 6.0.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.
Files changed (202) hide show
  1. package/dist/{acp-24uU2WDs.js → acp-Irby04Us.js} +7 -8
  2. package/dist/{acp-24uU2WDs.js.map → acp-Irby04Us.js.map} +1 -1
  3. package/dist/acp-cli.js +7 -7
  4. package/dist/acp.d.ts +2 -3
  5. package/dist/acp.d.ts.map +1 -1
  6. package/dist/acp.js +1 -1
  7. package/dist/{agent-Cch2ayTt.js → agent-DkSmGkDM.js} +10871 -5411
  8. package/dist/agent-DkSmGkDM.js.map +1 -0
  9. package/dist/agent.d.ts +1 -2
  10. package/dist/agent.js +2 -2
  11. package/dist/{anthropic-RGqsJlC8.js → anthropic-CTHsdFG9.js} +46 -6
  12. package/dist/anthropic-CTHsdFG9.js.map +1 -0
  13. package/dist/{auth-C-ms5N2x.js → auth-BDSu_0t3.js} +13 -86
  14. package/dist/auth-BDSu_0t3.js.map +1 -0
  15. package/dist/chat/pure.d.ts +4 -4
  16. package/dist/chat/pure.js +4 -3
  17. package/dist/chat.d.ts +45 -8
  18. package/dist/chat.d.ts.map +1 -1
  19. package/dist/chat.js +9 -6
  20. package/dist/chat.js.map +1 -1
  21. package/dist/completion-core-CXYSVhZo.js +147 -0
  22. package/dist/completion-core-CXYSVhZo.js.map +1 -0
  23. package/dist/{context-breakdown-kO-pDsay.js → context-breakdown-Dzo25N45.js} +2 -23
  24. package/dist/context-breakdown-Dzo25N45.js.map +1 -0
  25. package/dist/contexts/daytona.d.ts +3 -3
  26. package/dist/contexts/daytona.js +1 -1
  27. package/dist/contexts/docker.d.ts +10 -2
  28. package/dist/contexts/docker.d.ts.map +1 -1
  29. package/dist/contexts/docker.js +142 -103
  30. package/dist/contexts/docker.js.map +1 -1
  31. package/dist/contexts/e2b.d.ts +2 -2
  32. package/dist/contexts/e2b.js +1 -1
  33. package/dist/contexts/sandbox.d.ts +1 -1
  34. package/dist/contexts/sandbox.js +4 -1
  35. package/dist/contexts/sandbox.js.map +1 -1
  36. package/dist/{contexts-Lzf5huID.js → contexts-Vone3qQQ.js} +26 -37
  37. package/dist/contexts-Vone3qQQ.js.map +1 -0
  38. package/dist/contexts.d.ts +3 -3
  39. package/dist/contexts.js +1 -1
  40. package/dist/errors.d.ts +1 -2
  41. package/dist/errors.js +1 -1
  42. package/dist/eval.d.ts +1 -1
  43. package/dist/eval.js +3 -3
  44. package/dist/exec-file-size-PXkr-MGA.js +63 -0
  45. package/dist/exec-file-size-PXkr-MGA.js.map +1 -0
  46. package/dist/extensions.d.ts +2 -0
  47. package/dist/extensions.js +2 -0
  48. package/dist/generate-data-WL_yGVL6.js +324 -0
  49. package/dist/generate-data-WL_yGVL6.js.map +1 -0
  50. package/dist/headless.d.ts +1 -1
  51. package/dist/headless.js +15 -10
  52. package/dist/headless.js.map +1 -1
  53. package/dist/index-B8UtiZy7.d.ts +14967 -0
  54. package/dist/index-B8UtiZy7.d.ts.map +1 -0
  55. package/dist/{index-B3ciFUZx.d.ts → index-DsPQbyUn.d.ts} +2 -2
  56. package/dist/index-DsPQbyUn.d.ts.map +1 -0
  57. package/dist/index.d.ts +6 -12
  58. package/dist/index.js +20 -43
  59. package/dist/index.js.map +1 -1
  60. package/dist/{logger-Ktm-lj1s.js → logger-DBX9uYOw.js} +108 -5
  61. package/dist/logger-DBX9uYOw.js.map +1 -0
  62. package/dist/login-DOF8pMVM.js +539 -0
  63. package/dist/login-DOF8pMVM.js.map +1 -0
  64. package/dist/{mcp-Dn5W65Lv.js → mcp-CcvuVXB9.js} +2 -2
  65. package/dist/{mcp-Dn5W65Lv.js.map → mcp-CcvuVXB9.js.map} +1 -1
  66. package/dist/mcp.d.ts +1 -1
  67. package/dist/mcp.js +1 -1
  68. package/dist/{messages-YZQLKaz2.js → messages-CwujiS74.js} +4 -4
  69. package/dist/messages-CwujiS74.js.map +1 -0
  70. package/dist/{openai-compat-0Y7jcncn.js → openai-compat-BvgYGSR1.js} +7 -6
  71. package/dist/{openai-compat-0Y7jcncn.js.map → openai-compat-BvgYGSR1.js.map} +1 -1
  72. package/dist/output/stream-json.d.ts +1 -2
  73. package/dist/output/stream-json.d.ts.map +1 -1
  74. package/dist/output/terminal.d.ts +1 -2
  75. package/dist/output/terminal.d.ts.map +1 -1
  76. package/dist/{glob-DluQFSw1.js → output-cap-kBUHBlnq.js} +50 -2
  77. package/dist/output-cap-kBUHBlnq.js.map +1 -0
  78. package/dist/presets.d.ts +1 -2
  79. package/dist/presets.js +1 -1
  80. package/dist/providers/anthropic.d.ts +2 -2
  81. package/dist/providers/anthropic.js +2 -2
  82. package/dist/providers/arcee.d.ts +1 -1
  83. package/dist/providers/arcee.js +1 -1
  84. package/dist/providers/baseten.d.ts +1 -1
  85. package/dist/providers/baseten.js +1 -1
  86. package/dist/providers/cerebras.d.ts +1 -1
  87. package/dist/providers/cerebras.js +1 -1
  88. package/dist/providers/local.d.ts +1 -1
  89. package/dist/providers/local.js +1 -1
  90. package/dist/providers/openai-compat.d.ts +1 -1
  91. package/dist/providers/openai-compat.js +1 -1
  92. package/dist/providers/openai.d.ts +1 -1
  93. package/dist/providers/openai.js +4 -4
  94. package/dist/providers/openai.js.map +1 -1
  95. package/dist/providers/openrouter.d.ts +1 -1
  96. package/dist/providers/openrouter.js +1 -1
  97. package/dist/providers/xai.d.ts +1 -1
  98. package/dist/providers/xai.js +1 -1
  99. package/dist/{providers-DgmdYGKm.js → providers-z6LDMAr3.js} +3 -3
  100. package/dist/{providers-DgmdYGKm.js.map → providers-z6LDMAr3.js.map} +1 -1
  101. package/dist/providers.d.ts +1 -1
  102. package/dist/providers.js +4 -4
  103. package/dist/{read-state-BymF41Jb.js → read-state-Dq_TXUX1.js} +2 -2
  104. package/dist/{read-state-BymF41Jb.js.map → read-state-Dq_TXUX1.js.map} +1 -1
  105. package/dist/{interpolate-BtIgcCuz.js → resolve-Cr8JSL_O.js} +562 -136
  106. package/dist/resolve-Cr8JSL_O.js.map +1 -0
  107. package/dist/restate.d.ts +2 -2
  108. package/dist/restate.js +2 -2
  109. package/dist/{sandbox-Dgy-m6UF.d.ts → sandbox-CgjG2VvQ.d.ts} +2 -2
  110. package/dist/{sandbox-Dgy-m6UF.d.ts.map → sandbox-CgjG2VvQ.d.ts.map} +1 -1
  111. package/dist/session/sqlite.d.ts +1 -1
  112. package/dist/{session-CqrAFAKJ.js → session-CsdDIPY8.js} +108 -3
  113. package/dist/session-CsdDIPY8.js.map +1 -0
  114. package/dist/session.d.ts +2 -2
  115. package/dist/session.js +3 -3
  116. package/dist/skills-Bsb0rvWI.js +295 -0
  117. package/dist/skills-Bsb0rvWI.js.map +1 -0
  118. package/dist/skills.d.ts +2 -3
  119. package/dist/skills.js +3 -24
  120. package/dist/{errors-CkTvg97v.d.ts → timeout-8vSIRjzl.d.ts} +10 -2
  121. package/dist/timeout-8vSIRjzl.d.ts.map +1 -0
  122. package/dist/{timeout-kGGSXagK.js → timeout-BDetbuN6.js} +59 -2
  123. package/dist/timeout-BDetbuN6.js.map +1 -0
  124. package/dist/tool-formatters-DY0TDb1r.d.ts +378 -0
  125. package/dist/tool-formatters-DY0TDb1r.d.ts.map +1 -0
  126. package/dist/tools/fetch-url.d.ts +1 -1
  127. package/dist/tools/web-search.d.ts +1 -1
  128. package/dist/tools.d.ts +2 -3
  129. package/dist/tools.js +3 -4
  130. package/dist/{transcript-anchors-BHIgMlPq.d.ts → transcript-anchors-Cb-bDbNH.d.ts} +233 -640
  131. package/dist/transcript-anchors-Cb-bDbNH.d.ts.map +1 -0
  132. package/dist/{transcript-anchors-DsoBHg43.js → transcript-anchors-DSRPWjiH.js} +391 -961
  133. package/dist/transcript-anchors-DSRPWjiH.js.map +1 -0
  134. package/dist/tui.d.ts +335 -11
  135. package/dist/tui.d.ts.map +1 -1
  136. package/dist/tui.js +6375 -1892
  137. package/dist/tui.js.map +1 -1
  138. package/dist/{turn-operations-Dw02ZoSQ.d.ts → turn-operations-CgMROLsr.d.ts} +29 -4
  139. package/dist/turn-operations-CgMROLsr.d.ts.map +1 -0
  140. package/dist/{turn-operations-tG0vuBNc.js → turn-operations-Dq9Kx7m2.js} +321 -81
  141. package/dist/turn-operations-Dq9Kx7m2.js.map +1 -0
  142. package/dist/{types-BqdTeBaC.d.ts → types-BDccavwj.d.ts} +42 -1
  143. package/dist/types-BDccavwj.d.ts.map +1 -0
  144. package/dist/{types-CyVGdbia.js → types-BIarq1qE.js} +90 -2
  145. package/dist/types-BIarq1qE.js.map +1 -0
  146. package/dist/types.d.ts +5 -6
  147. package/dist/types.js +1 -1
  148. package/dist/{xai-tPdbAGkq.js → xai-B_e6TOA8.js} +2 -2
  149. package/dist/{xai-tPdbAGkq.js.map → xai-B_e6TOA8.js.map} +1 -1
  150. package/docs/ARCHITECTURE.md +1 -1
  151. package/docs/CHAT.md +7 -6
  152. package/docs/EXECUTION_CONTEXT.md +16 -0
  153. package/docs/EXTENSIONS.md +1063 -0
  154. package/docs/SKILL.md +16 -0
  155. package/docs/TUI.md +10 -3
  156. package/package.json +12 -3
  157. package/dist/agent-Cch2ayTt.js.map +0 -1
  158. package/dist/agent-EFWt6uQ_.d.ts +0 -6914
  159. package/dist/agent-EFWt6uQ_.d.ts.map +0 -1
  160. package/dist/anthropic-RGqsJlC8.js.map +0 -1
  161. package/dist/auth-C-ms5N2x.js.map +0 -1
  162. package/dist/context-breakdown-kO-pDsay.js.map +0 -1
  163. package/dist/contexts-Lzf5huID.js.map +0 -1
  164. package/dist/errors-CkTvg97v.d.ts.map +0 -1
  165. package/dist/glob-DluQFSw1.js.map +0 -1
  166. package/dist/glob-shell-rJMoCIGb.js +0 -21
  167. package/dist/glob-shell-rJMoCIGb.js.map +0 -1
  168. package/dist/index-B3ciFUZx.d.ts.map +0 -1
  169. package/dist/index-BtzE3Uaq.d.ts +0 -2738
  170. package/dist/index-BtzE3Uaq.d.ts.map +0 -1
  171. package/dist/index-tSzOaWNt.d.ts +0 -316
  172. package/dist/index-tSzOaWNt.d.ts.map +0 -1
  173. package/dist/interpolate-BtIgcCuz.js.map +0 -1
  174. package/dist/logger-DGiGf7DW.d.ts +0 -102
  175. package/dist/logger-DGiGf7DW.d.ts.map +0 -1
  176. package/dist/logger-Ktm-lj1s.js.map +0 -1
  177. package/dist/login-CCA-1lgK.js +0 -267
  178. package/dist/login-CCA-1lgK.js.map +0 -1
  179. package/dist/messages-YZQLKaz2.js.map +0 -1
  180. package/dist/policy-DcGlpaNs.d.ts +0 -129
  181. package/dist/policy-DcGlpaNs.d.ts.map +0 -1
  182. package/dist/presets-BQWYMHdd.js +0 -114
  183. package/dist/presets-BQWYMHdd.js.map +0 -1
  184. package/dist/run-summary-DkN8KsHM.d.ts +0 -249
  185. package/dist/run-summary-DkN8KsHM.d.ts.map +0 -1
  186. package/dist/session-CqrAFAKJ.js.map +0 -1
  187. package/dist/shell-quote-BmnhZmdM.js +0 -33
  188. package/dist/shell-quote-BmnhZmdM.js.map +0 -1
  189. package/dist/skills.js.map +0 -1
  190. package/dist/timeout-CpFm0jJ6.d.ts +0 -10
  191. package/dist/timeout-CpFm0jJ6.d.ts.map +0 -1
  192. package/dist/timeout-kGGSXagK.js.map +0 -1
  193. package/dist/tool-formatters-C6iLgc9f.d.ts +0 -1454
  194. package/dist/tool-formatters-C6iLgc9f.d.ts.map +0 -1
  195. package/dist/tools-CCd8e-HT.js +0 -1739
  196. package/dist/tools-CCd8e-HT.js.map +0 -1
  197. package/dist/transcript-anchors-BHIgMlPq.d.ts.map +0 -1
  198. package/dist/transcript-anchors-DsoBHg43.js.map +0 -1
  199. package/dist/turn-operations-Dw02ZoSQ.d.ts.map +0 -1
  200. package/dist/turn-operations-tG0vuBNc.js.map +0 -1
  201. package/dist/types-BqdTeBaC.d.ts.map +0 -1
  202. package/dist/types-CyVGdbia.js.map +0 -1
@@ -1,63 +1,115 @@
1
1
  import { a as AgentToolNotAllowedError, l as errorMessage } from "./errors-DJUxZg9b.js";
2
- import { basename, dirname, join, resolve } from "node:path";
3
- import { existsSync, mkdirSync, mkdtempSync, readFileSync, readdirSync, rmSync, statSync, writeFileSync } from "node:fs";
2
+ import { basename, delimiter, dirname, join, resolve, sep } from "node:path";
3
+ import { existsSync, lstatSync, mkdirSync, mkdtempSync, readFileSync, readdirSync, realpathSync, rmSync, statSync, writeFileSync } from "node:fs";
4
4
  import { realpath } from "node:fs/promises";
5
+ import { execFile } from "node:child_process";
5
6
  import { homedir, tmpdir } from "node:os";
6
- //#region src/xml.ts
7
+ //#region src/chat/project-root.ts
7
8
  /**
8
- * Minimal XML helpers used by catalog/result builders that emit
9
- * model-facing pseudo-XML (skills catalog, searchable_tools, tool_search
10
- * results, skill_content wrappers).
9
+ * Git root detection walks parents from `cwd` looking for a `.git`
10
+ * entry, returning the absolute path of the repo root or `null` when
11
+ * the search reaches the filesystem root.
11
12
  *
12
- * Scope: attribute / text-node escaping only we do NOT emit a full XML
13
- * document, the model sees these strings as free-form text. Centralised
14
- * here so the four near-identical copies in `agent.ts`, `skills/catalog.ts`,
15
- * `tools/skills-use.ts`, and `tools/tool-search.ts` don't drift.
13
+ * Why parent-walk over `git rev-parse --show-toplevel`:
14
+ *
15
+ * - Zero dependencies (no shell-out, no git binary requirement,
16
+ * works even when `git` is missing from `PATH`).
17
+ * - Pure-sync, deterministic, easy to test against tmp dirs.
18
+ * - Equally fast in practice — most lookups are a single `existsSync`.
19
+ *
20
+ * Recognizes `.git` as either:
21
+ *
22
+ * - A directory (standard repo layout).
23
+ * - A file containing `gitdir: …` (worktrees + submodules).
24
+ *
25
+ * Bare repos (no working tree) are intentionally NOT detected here —
26
+ * the TUI's data dir contract is "project working tree", and a bare
27
+ * repo has no working files to scope sessions against.
16
28
  */
17
- const RE_AMP = /&/g;
18
- const RE_LT = /</g;
19
- const RE_GT = />/g;
20
- const RE_QUOT = /"/g;
21
- function escapeXml(str) {
22
- return str.replace(RE_AMP, "&amp;").replace(RE_LT, "&lt;").replace(RE_GT, "&gt;").replace(RE_QUOT, "&quot;");
29
+ /**
30
+ * Walk parents of `cwd` looking for a `.git` entry. Returns the
31
+ * absolute path of the directory containing `.git`, or `null` when no
32
+ * git repo is found above `cwd`.
33
+ *
34
+ * Stops at the filesystem root (`/`) — no infinite loop on `dirname`'s
35
+ * idempotent root case (`dirname('/')` returns `/`).
36
+ */
37
+ function findGitRoot(cwd = process.cwd()) {
38
+ let dir = resolve(cwd);
39
+ for (let depth = 0; depth < 64; depth++) {
40
+ if (hasGitMarker(dir)) return dir;
41
+ const parent = dirname(dir);
42
+ if (parent === dir) return null;
43
+ dir = parent;
44
+ }
45
+ return null;
46
+ }
47
+ /**
48
+ * `.git` exists as a directory (standard repo) OR as a file containing
49
+ * a `gitdir:` pointer (worktree / submodule). Tolerant on stat failures
50
+ * — a permission error on a parent directory shouldn't crash the walk.
51
+ */
52
+ function hasGitMarker(dir) {
53
+ const candidate = resolve(dir, ".git");
54
+ try {
55
+ if (!existsSync(candidate)) return false;
56
+ const stat = statSync(candidate);
57
+ return stat.isDirectory() || stat.isFile();
58
+ } catch {
59
+ return false;
60
+ }
23
61
  }
24
62
  //#endregion
25
- //#region src/skills/activation.ts
26
- function createSkillActivationState(options = {}) {
27
- const byName = /* @__PURE__ */ new Map();
28
- const maxActive = typeof options.maxActive === "number" && options.maxActive > 0 ? options.maxActive : void 0;
29
- return {
30
- active() {
31
- return [...byName.values()];
32
- },
33
- isActive(name) {
34
- return byName.has(name);
35
- },
36
- get(name) {
37
- return byName.get(name);
63
+ //#region src/chat/project-user-paths.ts
64
+ /**
65
+ * Shared search-path builder for project + user config discovery.
66
+ *
67
+ * Both Skills (`skills/<name>/SKILL.md`) and MCP servers (`mcps.json`)
68
+ * follow the same first-found-wins order:
69
+ *
70
+ * 1. `{project-root}/.agents/<sub>` — project, agnostic convention
71
+ * 2. `{project-root}/.{prefix}/<sub>` — project, zidane (`.zidane` default)
72
+ * 3. `~/.agents/<sub>` — user, agnostic
73
+ * 4. `~/.{prefix}/<sub>` — user, zidane
74
+ *
75
+ * `{project-root}` is the git root walked up from `cwd` when present,
76
+ * else `cwd` itself. This pairs with the project-scoped session
77
+ * storage (`resolveStoragePaths`) so all three project-aware surfaces
78
+ * — sessions, mcps, skills — anchor at the same `.{prefix}/`.
79
+ *
80
+ * Centralizing the pattern keeps the four paths in one place — a third
81
+ * discovery surface (hooks, rules, …) gets the same convention for free
82
+ * and stays in lock-step on a prefix bump.
83
+ */
84
+ /**
85
+ * Resolve the four search paths for a given subdirectory (`skills`,
86
+ * `mcps.json`, …). Returns absolute paths regardless of whether they
87
+ * exist — the caller chooses to `existsSync`-filter or feed straight
88
+ * into a tolerant discovery routine.
89
+ */
90
+ function projectUserPaths(opts) {
91
+ const cwd = opts.cwd ?? process.cwd();
92
+ const home = opts.home ?? homedir();
93
+ const projectRoot = findGitRoot(cwd) ?? cwd;
94
+ const prefix = (opts.prefix ?? ".zidane").replace(/^\./, "");
95
+ return [
96
+ {
97
+ path: resolve(projectRoot, `.agents/${opts.subPath}`),
98
+ source: "project"
38
99
  },
39
- activate(skill, via) {
40
- if (byName.has(skill.name)) return "already-active";
41
- if (maxActive !== void 0 && byName.size >= maxActive) return "cap-reached";
42
- byName.set(skill.name, {
43
- skill,
44
- activatedAt: Date.now(),
45
- activatedVia: via
46
- });
47
- return "ok";
100
+ {
101
+ path: resolve(projectRoot, `.${prefix}/${opts.subPath}`),
102
+ source: "project"
48
103
  },
49
- deactivate(name) {
50
- const existing = byName.get(name);
51
- if (!existing) return void 0;
52
- byName.delete(name);
53
- return existing;
104
+ {
105
+ path: resolve(home, `.agents/${opts.subPath}`),
106
+ source: "user"
54
107
  },
55
- clear() {
56
- const snapshot = [...byName.values()];
57
- byName.clear();
58
- return snapshot;
108
+ {
109
+ path: resolve(home, `.${prefix}/${opts.subPath}`),
110
+ source: "user"
59
111
  }
60
- };
112
+ ];
61
113
  }
62
114
  //#endregion
63
115
  //#region src/skills/validate.ts
@@ -274,6 +326,466 @@ function isToolAllowedByUnion(displayName, input, union) {
274
326
  return union.some((pattern) => matchesAllowedTool(displayName, input, pattern));
275
327
  }
276
328
  //#endregion
329
+ //#region src/skills/interpolate.ts
330
+ /** Regex to match !`command` patterns in skill instructions */
331
+ const SHELL_INTERPOLATION_RE = /!`([^`]+)`/g;
332
+ /**
333
+ * Replace every !\`command\` pattern with a static placeholder, without
334
+ * executing anything. Used when shell interpolation is disabled
335
+ * (`SkillsConfig.allowShellInterpolation: false`): skill content can be
336
+ * third-party input, and running its embedded commands on activation
337
+ * bypasses the allowed-tools gate.
338
+ */
339
+ function stripShellInterpolations(instructions) {
340
+ return instructions.replace(SHELL_INTERPOLATION_RE, "[shell interpolation disabled]");
341
+ }
342
+ /**
343
+ * Interpolate shell commands in skill instructions.
344
+ *
345
+ * Runs each !\`command\` through the execution context and replaces
346
+ * the placeholder with the command's stdout. If a command fails,
347
+ * the placeholder is replaced with an error message (and
348
+ * `options.onFailure` is notified when provided).
349
+ *
350
+ * @param instructions - Raw skill instructions with potential !\`command\` patterns
351
+ * @param execution - The execution context to run commands in
352
+ * @param handle - The active execution handle
353
+ * @returns Instructions with all !\`command\` patterns replaced by output
354
+ */
355
+ async function interpolateShellCommands(instructions, execution, handle, options = {}) {
356
+ const matches = [...instructions.matchAll(SHELL_INTERPOLATION_RE)];
357
+ if (matches.length === 0) return instructions;
358
+ const replacements = [];
359
+ for (const match of matches) {
360
+ const command = match[1];
361
+ const index = match.index;
362
+ const length = match[0].length;
363
+ if (options.approve) {
364
+ let approved = false;
365
+ try {
366
+ approved = await options.approve(command);
367
+ } catch {
368
+ approved = false;
369
+ }
370
+ if (!approved) {
371
+ const placeholder = "[shell interpolation not approved]";
372
+ options.onFailure?.(command, placeholder);
373
+ replacements.push({
374
+ index,
375
+ length,
376
+ output: placeholder
377
+ });
378
+ continue;
379
+ }
380
+ }
381
+ try {
382
+ const result = await execution.exec(handle, command, { timeout: 30 });
383
+ if (result.exitCode === 0) replacements.push({
384
+ index,
385
+ length,
386
+ output: result.stdout.trim()
387
+ });
388
+ else {
389
+ const placeholder = `[command failed (exit ${result.exitCode}): ${result.stderr.trim() || result.stdout.trim()}]`;
390
+ options.onFailure?.(command, placeholder);
391
+ replacements.push({
392
+ index,
393
+ length,
394
+ output: placeholder
395
+ });
396
+ }
397
+ } catch (err) {
398
+ const placeholder = `[command error: ${errorMessage(err)}]`;
399
+ options.onFailure?.(command, placeholder);
400
+ replacements.push({
401
+ index,
402
+ length,
403
+ output: placeholder
404
+ });
405
+ }
406
+ }
407
+ let result = instructions;
408
+ for (let i = replacements.length - 1; i >= 0; i--) {
409
+ const { index, length, output } = replacements[i];
410
+ result = result.slice(0, index) + output + result.slice(index + length);
411
+ }
412
+ return result;
413
+ }
414
+ //#endregion
415
+ //#region src/xml.ts
416
+ /**
417
+ * Minimal XML helpers used by catalog/result builders that emit
418
+ * model-facing pseudo-XML (skills catalog, searchable_tools, tool_search
419
+ * results, skill_content wrappers).
420
+ *
421
+ * Scope: attribute / text-node escaping only — we do NOT emit a full XML
422
+ * document, the model sees these strings as free-form text. Centralised
423
+ * here so the four near-identical copies in `agent.ts`, `skills/catalog.ts`,
424
+ * `tools/skills-use.ts`, and `tools/tool-search.ts` don't drift.
425
+ */
426
+ const RE_AMP = /&/g;
427
+ const RE_LT = /</g;
428
+ const RE_GT = />/g;
429
+ const RE_QUOT = /"/g;
430
+ function escapeXml(str) {
431
+ return str.replace(RE_AMP, "&amp;").replace(RE_LT, "&lt;").replace(RE_GT, "&gt;").replace(RE_QUOT, "&quot;");
432
+ }
433
+ //#endregion
434
+ //#region src/install/source.ts
435
+ /**
436
+ * Shared install-source layer — the source-agnostic half of "install a
437
+ * thing from github/npm". Extracted from the extensions installer so
438
+ * SKILL installs (and any future installable artifact) reuse the exact
439
+ * same spec grammar, fetch pipeline, and hardening instead of forking
440
+ * them:
441
+ *
442
+ * - Spec grammar: `owner/repo[#ref][:subdir]`, `github:owner/repo`,
443
+ * pasted GitHub URLs (including `/tree/<ref>/<path>`),
444
+ * `pkg[@version]`, `@scope/pkg[@version]`.
445
+ * - Fetch: `git clone --depth 1` (records the exact commit) with a
446
+ * codeload-tarball fallback, npm registry resolve (exact versions +
447
+ * dist-tags) + tarball download. Downloads are double-capped at
448
+ * {@link MAX_DOWNLOAD_BYTES} (content-length header AND post-hoc for
449
+ * chunked responses). Extraction requires `tar` on PATH.
450
+ * - All side effects go through the injectable {@link InstallIo} seams
451
+ * so tests stay offline and hosts can instrument.
452
+ *
453
+ * Flavor-specific concerns stay OUT of this module: candidate
454
+ * enumeration, validation, target roots, provenance files, dependency
455
+ * installs. Flavors subclass {@link InstallSourceError} to widen the
456
+ * error-code union while keeping `.code`-based handling uniform.
457
+ */
458
+ /**
459
+ * Base error for install pipelines. `code` is a plain string here so
460
+ * flavors (extensions, skills) can widen it with their own codes while
461
+ * callers keep a single `err.code` switch. The base layer itself only
462
+ * throws `'invalid-source'` and `'fetch-failed'`.
463
+ */
464
+ var InstallSourceError = class extends Error {
465
+ code;
466
+ /** Set for candidate-selection errors — the names the caller can pick from. */
467
+ candidates;
468
+ constructor(code, message, candidates) {
469
+ super(message);
470
+ this.name = "InstallSourceError";
471
+ this.code = code;
472
+ if (candidates) this.candidates = candidates;
473
+ }
474
+ };
475
+ const GITHUB_TREE_URL_RE = /^(?:https?:\/\/)?(?:www\.)?github\.com\/([^/\s]+)\/([^/\s#@:]+?)(?:\.git)?\/tree\/([^/\s:]+)(?:\/([^\s:]+?))?\/?$/;
476
+ const GITHUB_URL_RE = /^(?:https?:\/\/)?(?:www\.)?github\.com\/([^/\s]+)\/([^/\s#@:]+?)(?:\.git)?\/?$/;
477
+ const OWNER_REPO_RE = /^([\w.-]+)\/([\w.-]+)$/;
478
+ const GITHUB_REF_RE = /^[\w./-]+$/;
479
+ const NPM_NAME_RE = /^(@[\w.-]+\/[\w.-]+|[\w.-]+)(?:@([\w.^~><=*-]+))?$/;
480
+ /** Structural validation for a `:subdir` suffix — repo-relative, no escapes. */
481
+ function parseSubdir(rawSubdir, raw) {
482
+ const subdir = rawSubdir.replace(/^\.\//, "").replace(/\/+$/, "");
483
+ const segments = subdir.split("/");
484
+ if (subdir.length === 0 || subdir.startsWith("/") || subdir.includes("\\") || segments.some((s) => s.length === 0 || s === "." || s === "..")) throw new InstallSourceError("invalid-source", `"${raw}" has an invalid subdirectory — expected a repo-relative path (no leading /, no ..).`);
485
+ return subdir;
486
+ }
487
+ /**
488
+ * Classify a raw source string:
489
+ *
490
+ * - `github:owner/repo`, `owner/repo`, GitHub URLs (including
491
+ * `/tree/<ref>/<path>` links) → GitHub. Optional `#ref` (or the
492
+ * legacy `@ref`) pins a branch/tag; optional `:path/to/dir` roots the
493
+ * candidate search in a subdirectory: `owner/repo#branch:packages/x`.
494
+ * - `@scope/pkg[@version]`, `pkg[@version]` → npm (no subdir support —
495
+ * flavors expose their own selector for multi-candidate packages).
496
+ *
497
+ * The one ambiguity — `a/b` — is resolved as GitHub: npm's slash names
498
+ * are always scoped (`@scope/…`), so a bare `owner/repo` can only be a
499
+ * repo. Throws `invalid-source` on anything else.
500
+ */
501
+ function parseInstallSource(raw) {
502
+ const spec = raw.trim();
503
+ if (spec.length === 0) throw new InstallSourceError("invalid-source", "Empty source. Expected `owner/repo`, `github:owner/repo`, a GitHub URL, or an npm package name.");
504
+ const explicitGithub = spec.startsWith("github:");
505
+ const body = explicitGithub ? spec.slice(7) : spec;
506
+ const tree = GITHUB_TREE_URL_RE.exec(body);
507
+ if (tree) return {
508
+ kind: "github",
509
+ owner: tree[1],
510
+ repo: tree[2],
511
+ ref: tree[3],
512
+ ...tree[4] ? { subdir: parseSubdir(tree[4], raw) } : {}
513
+ };
514
+ const url = GITHUB_URL_RE.exec(body);
515
+ if (url) return {
516
+ kind: "github",
517
+ owner: url[1],
518
+ repo: url[2]
519
+ };
520
+ if (body.startsWith("@")) {
521
+ if (explicitGithub) throw new InstallSourceError("invalid-source", `"${raw}" mixes the github: prefix with an npm scoped name.`);
522
+ if (body.includes(":")) throw new InstallSourceError("invalid-source", `"${raw}": subdirectories (\`:path\`) are only supported for GitHub sources.`);
523
+ const m = NPM_NAME_RE.exec(body);
524
+ if (!m) throw new InstallSourceError("invalid-source", `"${raw}" is not a valid npm package spec.`);
525
+ return {
526
+ kind: "npm",
527
+ pkg: m[1],
528
+ ...m[2] ? { version: m[2] } : {}
529
+ };
530
+ }
531
+ if (body.includes("/")) {
532
+ const colonIdx = body.indexOf(":");
533
+ const specPart = colonIdx === -1 ? body : body.slice(0, colonIdx);
534
+ const subdir = colonIdx === -1 ? void 0 : parseSubdir(body.slice(colonIdx + 1), raw);
535
+ const hashIdx = specPart.indexOf("#");
536
+ const refIdx = hashIdx >= 0 ? hashIdx : specPart.indexOf("@");
537
+ const repoPart = refIdx === -1 ? specPart : specPart.slice(0, refIdx);
538
+ const ref = refIdx === -1 ? void 0 : specPart.slice(refIdx + 1);
539
+ const m = OWNER_REPO_RE.exec(repoPart);
540
+ if (!m || ref !== void 0 && !GITHUB_REF_RE.test(ref)) throw new InstallSourceError("invalid-source", `"${raw}" is not a valid GitHub repo spec (expected owner/repo, optionally #ref and :subdir).`);
541
+ return {
542
+ kind: "github",
543
+ owner: m[1],
544
+ repo: m[2],
545
+ ...ref ? { ref } : {},
546
+ ...subdir ? { subdir } : {}
547
+ };
548
+ }
549
+ if (explicitGithub) throw new InstallSourceError("invalid-source", `"${raw}" is missing the repo part (expected github:owner/repo).`);
550
+ if (body.includes(":")) throw new InstallSourceError("invalid-source", `"${raw}": subdirectories (\`:path\`) are only supported for GitHub sources.`);
551
+ const m = NPM_NAME_RE.exec(body);
552
+ if (!m) throw new InstallSourceError("invalid-source", `"${raw}" is not a valid npm package spec.`);
553
+ return {
554
+ kind: "npm",
555
+ pkg: m[1],
556
+ ...m[2] ? { version: m[2] } : {}
557
+ };
558
+ }
559
+ /**
560
+ * Materialize the source into `destDir` (created by the caller, assumed
561
+ * empty). Returns the provenance string plus, for git clones, the exact
562
+ * commit SHA (the tarball fallback can't know it — codeload doesn't
563
+ * expose the resolved commit).
564
+ */
565
+ async function fetchInstallSource(source, destDir, io = {}, onProgress) {
566
+ const exec = io.exec ?? defaultExec;
567
+ const which = io.which ?? defaultWhich;
568
+ const fetchImpl = io.fetch ?? fetch;
569
+ if (source.kind === "github") {
570
+ const label = `${source.owner}/${source.repo}${source.ref ? `@${source.ref}` : ""}${source.subdir ? `:${source.subdir}` : ""}`;
571
+ if (which("git")) {
572
+ onProgress?.(`cloning github.com/${label}…`);
573
+ const args = [
574
+ "clone",
575
+ "--depth",
576
+ "1",
577
+ "--single-branch"
578
+ ];
579
+ if (source.ref) args.push("--branch", source.ref);
580
+ args.push(`https://github.com/${source.owner}/${source.repo}.git`, destDir);
581
+ const res = await exec("git", args, {});
582
+ if (!res.ok) throw new InstallSourceError("fetch-failed", `git clone failed for ${label}: ${lastLine(res.stderr)}`);
583
+ const head = await exec("git", ["rev-parse", "HEAD"], { cwd: destDir });
584
+ const commit = head.ok && /^[0-9a-f]{40}$/.test(head.stdout.trim()) ? head.stdout.trim() : void 0;
585
+ rmSync(join(destDir, ".git"), {
586
+ recursive: true,
587
+ force: true
588
+ });
589
+ return {
590
+ provenance: `github:${label}`,
591
+ ...commit ? { commit } : {}
592
+ };
593
+ }
594
+ onProgress?.(`downloading github.com/${label} tarball…`);
595
+ const ref = source.ref ?? "HEAD";
596
+ await downloadAndExtract(`https://codeload.github.com/${source.owner}/${source.repo}/tar.gz/${ref}`, destDir, {
597
+ exec,
598
+ fetchImpl,
599
+ which,
600
+ what: label
601
+ });
602
+ return { provenance: `github:${label}` };
603
+ }
604
+ onProgress?.(`resolving npm:${source.pkg}…`);
605
+ const { version, tarball } = await resolveNpmVersion(source, fetchImpl);
606
+ onProgress?.(`downloading npm:${source.pkg}@${version}…`);
607
+ await downloadAndExtract(tarball, destDir, {
608
+ exec,
609
+ fetchImpl,
610
+ which,
611
+ what: `${source.pkg}@${version}`
612
+ });
613
+ return { provenance: `npm:${source.pkg}@${version}` };
614
+ }
615
+ /**
616
+ * Registry lookup shared by the fetch path and update no-op checks.
617
+ * Exact versions and dist-tags only — range resolution is out of scope.
618
+ */
619
+ async function resolveNpmVersion(source, fetchImpl) {
620
+ const registryUrl = `https://registry.npmjs.org/${source.pkg.replace("/", "%2F")}`;
621
+ let meta;
622
+ try {
623
+ const res = await fetchImpl(registryUrl);
624
+ if (!res.ok) throw new Error(`registry returned ${res.status}`);
625
+ meta = await res.json();
626
+ } catch (err) {
627
+ throw new InstallSourceError("fetch-failed", `Could not resolve npm package "${source.pkg}": ${errorText(err)}`);
628
+ }
629
+ const version = source.version && meta.versions?.[source.version] ? source.version : meta["dist-tags"]?.[source.version ?? "latest"];
630
+ const tarball = version ? meta.versions?.[version]?.dist?.tarball : void 0;
631
+ if (!version || !tarball) throw new InstallSourceError("fetch-failed", `npm package "${source.pkg}" has no ${source.version ? `version/tag "${source.version}"` : "latest version"} (exact versions and dist-tags only — ranges are not resolved).`);
632
+ return {
633
+ version,
634
+ tarball
635
+ };
636
+ }
637
+ /**
638
+ * OOM guard: tarballs are buffered in memory before extraction, so an
639
+ * unexpectedly huge (or hostile) URL must fail fast instead of ballooning
640
+ * RSS. Install sources are source trees — 64MB is already generous.
641
+ */
642
+ const MAX_DOWNLOAD_BYTES = 64 * 1024 * 1024;
643
+ async function downloadAndExtract(url, destDir, opts) {
644
+ let bytes;
645
+ try {
646
+ const res = await opts.fetchImpl(url);
647
+ if (!res.ok) throw new Error(`download returned ${res.status}`);
648
+ const declared = Number(res.headers.get("content-length") ?? "0");
649
+ if (declared > 67108864) throw new Error(`archive is ${Math.round(declared / 1024 / 1024)}MB — larger than the ${MAX_DOWNLOAD_BYTES / 1024 / 1024}MB limit`);
650
+ bytes = await res.arrayBuffer();
651
+ if (bytes.byteLength > 67108864) throw new Error(`archive is ${Math.round(bytes.byteLength / 1024 / 1024)}MB — larger than the ${MAX_DOWNLOAD_BYTES / 1024 / 1024}MB limit`);
652
+ } catch (err) {
653
+ throw new InstallSourceError("fetch-failed", `Download failed for ${opts.what}: ${errorText(err)}`);
654
+ }
655
+ if (!opts.which("tar")) throw new InstallSourceError("fetch-failed", `Extracting ${opts.what} requires \`tar\` on PATH (or install git for the clone path).`);
656
+ const tarPath = join(destDir, ".zidane-install.tgz");
657
+ mkdirSync(destDir, { recursive: true });
658
+ writeFileSync(tarPath, new Uint8Array(bytes));
659
+ const res = await opts.exec("tar", [
660
+ "-xzf",
661
+ tarPath,
662
+ "-C",
663
+ destDir,
664
+ "--strip-components=1"
665
+ ], {});
666
+ rmSync(tarPath, { force: true });
667
+ if (!res.ok) throw new InstallSourceError("fetch-failed", `Extracting ${opts.what} failed: ${lastLine(res.stderr)}`);
668
+ }
669
+ /**
670
+ * Resolve a `:subdir` inside a fetched tree with PHYSICAL containment:
671
+ * string-level prefix check first, then realpath both sides and re-check
672
+ * so a malicious repo shipping a symlink (`evil -> /`) can't walk the
673
+ * candidate search (and any follow-up validation) onto the local
674
+ * filesystem. Returns the physical directory, or a typed refusal the
675
+ * flavor maps onto its own error vocabulary.
676
+ */
677
+ function resolveSubdirRoot(fetchedInto, subdir) {
678
+ const resolved = resolve(fetchedInto, subdir);
679
+ if (!resolved.startsWith(fetchedInto + sep)) return {
680
+ ok: false,
681
+ reason: "escape"
682
+ };
683
+ let physical = null;
684
+ try {
685
+ physical = realpathSync(resolved);
686
+ } catch {}
687
+ if (physical === null || !isDirectory(physical)) return {
688
+ ok: false,
689
+ reason: "missing"
690
+ };
691
+ const physicalRoot = realpathSync(fetchedInto);
692
+ if (physical !== physicalRoot && !physical.startsWith(physicalRoot + sep)) return {
693
+ ok: false,
694
+ reason: "escape-symlink"
695
+ };
696
+ return {
697
+ ok: true,
698
+ dir: physical
699
+ };
700
+ }
701
+ function isDirectory(path) {
702
+ try {
703
+ return lstatSync(path).isDirectory();
704
+ } catch {
705
+ return false;
706
+ }
707
+ }
708
+ function defaultExec(cmd, args, opts) {
709
+ return new Promise((resolvePromise) => {
710
+ execFile(cmd, [...args], {
711
+ cwd: opts.cwd,
712
+ maxBuffer: 16 * 1024 * 1024
713
+ }, (err, stdout, stderr) => {
714
+ resolvePromise({
715
+ ok: !err,
716
+ stdout: String(stdout),
717
+ stderr: String(stderr)
718
+ });
719
+ });
720
+ });
721
+ }
722
+ function defaultWhich(cmd) {
723
+ const exts = process.platform === "win32" ? [
724
+ ".exe",
725
+ ".cmd",
726
+ ".bat",
727
+ ""
728
+ ] : [""];
729
+ for (const dir of (process.env.PATH ?? "").split(delimiter)) {
730
+ if (!dir) continue;
731
+ for (const ext of exts) {
732
+ const full = resolve(dir, cmd + ext);
733
+ try {
734
+ if (lstatSync(full).isFile()) return full;
735
+ } catch {
736
+ continue;
737
+ }
738
+ }
739
+ }
740
+ return null;
741
+ }
742
+ /** Last non-empty line of a command's output — the useful bit of tool noise. */
743
+ function lastLine(text) {
744
+ const lines = text.trim().split("\n").filter((l) => l.trim().length > 0);
745
+ return lines[lines.length - 1]?.trim() ?? "";
746
+ }
747
+ function errorText(err) {
748
+ return err instanceof Error ? err.message : String(err);
749
+ }
750
+ //#endregion
751
+ //#region src/skills/activation.ts
752
+ function createSkillActivationState(options = {}) {
753
+ const byName = /* @__PURE__ */ new Map();
754
+ const maxActive = typeof options.maxActive === "number" && options.maxActive > 0 ? options.maxActive : void 0;
755
+ return {
756
+ active() {
757
+ return [...byName.values()];
758
+ },
759
+ isActive(name) {
760
+ return byName.has(name);
761
+ },
762
+ get(name) {
763
+ return byName.get(name);
764
+ },
765
+ activate(skill, via) {
766
+ if (byName.has(skill.name)) return "already-active";
767
+ if (maxActive !== void 0 && byName.size >= maxActive) return "cap-reached";
768
+ byName.set(skill.name, {
769
+ skill,
770
+ activatedAt: Date.now(),
771
+ activatedVia: via
772
+ });
773
+ return "ok";
774
+ },
775
+ deactivate(name) {
776
+ const existing = byName.get(name);
777
+ if (!existing) return void 0;
778
+ byName.delete(name);
779
+ return existing;
780
+ },
781
+ clear() {
782
+ const snapshot = [...byName.values()];
783
+ byName.clear();
784
+ return snapshot;
785
+ }
786
+ };
787
+ }
788
+ //#endregion
277
789
  //#region src/skills/allowed-tools.ts
278
790
  /** Tools that are always allowed regardless of the active skills' allow-list. */
279
791
  const IMPLICITLY_ALLOWED_SKILL_TOOLS = [
@@ -1031,92 +1543,6 @@ async function resolveSkills(config) {
1031
1543
  };
1032
1544
  }
1033
1545
  //#endregion
1034
- //#region src/skills/interpolate.ts
1035
- /** Regex to match !`command` patterns in skill instructions */
1036
- const SHELL_INTERPOLATION_RE = /!`([^`]+)`/g;
1037
- /**
1038
- * Replace every !\`command\` pattern with a static placeholder, without
1039
- * executing anything. Used when shell interpolation is disabled
1040
- * (`SkillsConfig.allowShellInterpolation: false`): skill content can be
1041
- * third-party input, and running its embedded commands on activation
1042
- * bypasses the allowed-tools gate.
1043
- */
1044
- function stripShellInterpolations(instructions) {
1045
- return instructions.replace(SHELL_INTERPOLATION_RE, "[shell interpolation disabled]");
1046
- }
1047
- /**
1048
- * Interpolate shell commands in skill instructions.
1049
- *
1050
- * Runs each !\`command\` through the execution context and replaces
1051
- * the placeholder with the command's stdout. If a command fails,
1052
- * the placeholder is replaced with an error message (and
1053
- * `options.onFailure` is notified when provided).
1054
- *
1055
- * @param instructions - Raw skill instructions with potential !\`command\` patterns
1056
- * @param execution - The execution context to run commands in
1057
- * @param handle - The active execution handle
1058
- * @returns Instructions with all !\`command\` patterns replaced by output
1059
- */
1060
- async function interpolateShellCommands(instructions, execution, handle, options = {}) {
1061
- const matches = [...instructions.matchAll(SHELL_INTERPOLATION_RE)];
1062
- if (matches.length === 0) return instructions;
1063
- const replacements = [];
1064
- for (const match of matches) {
1065
- const command = match[1];
1066
- const index = match.index;
1067
- const length = match[0].length;
1068
- if (options.approve) {
1069
- let approved = false;
1070
- try {
1071
- approved = await options.approve(command);
1072
- } catch {
1073
- approved = false;
1074
- }
1075
- if (!approved) {
1076
- const placeholder = "[shell interpolation not approved]";
1077
- options.onFailure?.(command, placeholder);
1078
- replacements.push({
1079
- index,
1080
- length,
1081
- output: placeholder
1082
- });
1083
- continue;
1084
- }
1085
- }
1086
- try {
1087
- const result = await execution.exec(handle, command, { timeout: 30 });
1088
- if (result.exitCode === 0) replacements.push({
1089
- index,
1090
- length,
1091
- output: result.stdout.trim()
1092
- });
1093
- else {
1094
- const placeholder = `[command failed (exit ${result.exitCode}): ${result.stderr.trim() || result.stdout.trim()}]`;
1095
- options.onFailure?.(command, placeholder);
1096
- replacements.push({
1097
- index,
1098
- length,
1099
- output: placeholder
1100
- });
1101
- }
1102
- } catch (err) {
1103
- const placeholder = `[command error: ${errorMessage(err)}]`;
1104
- options.onFailure?.(command, placeholder);
1105
- replacements.push({
1106
- index,
1107
- length,
1108
- output: placeholder
1109
- });
1110
- }
1111
- }
1112
- let result = instructions;
1113
- for (let i = replacements.length - 1; i >= 0; i--) {
1114
- const { index, length, output } = replacements[i];
1115
- result = result.slice(0, index) + output + result.slice(index + length);
1116
- }
1117
- return result;
1118
- }
1119
- //#endregion
1120
- export { escapeXml as S, validateResourcePath as _, writeSkillsToDisk as a, validateSkillName as b, inferSource as c, buildCatalog as d, IMPLICITLY_ALLOWED_SKILL_TOOLS as f, parseAllowedToolPattern as g, matchesAllowedTool as h, writeSkillToDisk as i, parseFrontmatter as l, isToolAllowedByUnion as m, stripShellInterpolations as n, discoverSkills as o, installAllowedToolsGate as p, resolveSkills as r, getDefaultScanPaths as s, interpolateShellCommands as t, parseSkillFile as u, validateResourcePathReal as v, createSkillActivationState as x, validateSkillForWrite as y };
1546
+ export { validateSkillName as A, stripShellInterpolations as C, validateResourcePath as D, parseAllowedToolPattern as E, findGitRoot as M, validateResourcePathReal as O, interpolateShellCommands as S, matchesAllowedTool as T, lastLine as _, getDefaultScanPaths as a, resolveSubdirRoot as b, parseSkillFile as c, installAllowedToolsGate as d, createSkillActivationState as f, fetchInstallSource as g, defaultWhich as h, discoverSkills as i, projectUserPaths as j, validateSkillForWrite as k, buildCatalog as l, defaultExec as m, writeSkillToDisk as n, inferSource as o, InstallSourceError as p, writeSkillsToDisk as r, parseFrontmatter as s, resolveSkills as t, IMPLICITLY_ALLOWED_SKILL_TOOLS as u, parseInstallSource as v, isToolAllowedByUnion as w, escapeXml as x, resolveNpmVersion as y };
1121
1547
 
1122
- //# sourceMappingURL=interpolate-BtIgcCuz.js.map
1548
+ //# sourceMappingURL=resolve-Cr8JSL_O.js.map