@swmansion/argent 0.29.1-next.8 → 0.30.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 (44) hide show
  1. package/README.md +2 -2
  2. package/bin/argent-android-devtools-0.3.0.apk +0 -0
  3. package/bin/darwin/ax-service +0 -0
  4. package/bin/darwin/simulator-server +0 -0
  5. package/bin/darwin/tvos-ax-service +0 -0
  6. package/bin/darwin/tvos-hid-daemon +0 -0
  7. package/bin/linux/simulator-server +0 -0
  8. package/bin/linux-arm64/simulator-server +0 -0
  9. package/bin/tcp/ax-service +0 -0
  10. package/bin/win32/simulator-server.exe +0 -0
  11. package/dist/cli-cmds.mjs +8978 -3419
  12. package/dist/cli.js +3 -2
  13. package/dist/cli.js.map +1 -1
  14. package/dist/client.js +798 -554
  15. package/dist/flow-script-runner.mjs +1 -1
  16. package/dist/installer.mjs +2226 -1878
  17. package/dist/mcp-server.mjs +3535 -2061
  18. package/dist/tool-args.generated.d.ts +54 -40
  19. package/dist/tool-server.cjs +28105 -13079
  20. package/dylibs/libArgentInjectionBootstrap.dylib +0 -0
  21. package/dylibs/libKeyboardPatch.dylib +0 -0
  22. package/dylibs/libNativeDevtoolsIos.dylib +0 -0
  23. package/dylibs/tcp/libArgentInjectionBootstrap.dylib +0 -0
  24. package/dylibs/tcp/libKeyboardPatch.dylib +0 -0
  25. package/dylibs/tcp/libNativeDevtoolsIos.dylib +0 -0
  26. package/dylibs/tvos/libArgentInjectionBootstrap.dylib +0 -0
  27. package/dylibs/tvos/libKeyboardPatch.dylib +0 -0
  28. package/dylibs/tvos/libNativeDevtoolsIos.dylib +0 -0
  29. package/package.json +15 -15
  30. package/rules/argent.md +10 -10
  31. package/skills/{argent-create-flow → argent-create-e2e}/SKILL.md +16 -16
  32. package/skills/{argent-create-flow/references/flow-yaml.md → argent-create-e2e/references/e2e-yaml.md} +33 -33
  33. package/skills/{argent-create-flow → argent-create-e2e}/references/live-authoring.md +62 -62
  34. package/skills/{argent-create-flow → argent-create-e2e}/references/reliability-and-recovery.md +18 -18
  35. package/skills/argent-device-interact/SKILL.md +10 -8
  36. package/skills/argent-device-interact/references/chromium.md +1 -1
  37. package/skills/argent-ios-device-interact/SKILL.md +1 -1
  38. package/skills/argent-metro-debugger/SKILL.md +1 -1
  39. package/skills/argent-native-profiler/SKILL.md +1 -1
  40. package/skills/{argent-qa-flows → argent-qa-e2e}/SKILL.md +23 -23
  41. package/skills/argent-react-native-optimization/SKILL.md +2 -2
  42. package/skills/argent-react-native-profiler/SKILL.md +3 -3
  43. package/skills/argent-screen-recording/SKILL.md +1 -1
  44. package/skills/argent-test-ui-flow/SKILL.md +4 -4
package/dist/client.js CHANGED
@@ -35,322 +35,395 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
35
35
  mod
36
36
  ));
37
37
 
38
- // ../../node_modules/dotenv/lib/main.js
39
- var require_main = __commonJS({
40
- "../../node_modules/dotenv/lib/main.js"(exports, module) {
41
- var fs7 = __require("fs");
42
- var path13 = __require("path");
43
- var os2 = __require("os");
44
- var crypto2 = __require("crypto");
45
- var TIPS = [
46
- "\u25C8 encrypted .env [www.dotenvx.com]",
47
- "\u25C8 secrets for agents [www.dotenvx.com]",
48
- "\u2301 auth for agents [www.vestauth.com]",
49
- "\u2318 custom filepath { path: '/custom/path/.env' }",
50
- "\u2318 enable debugging { debug: true }",
51
- "\u2318 override existing { override: true }",
52
- "\u2318 suppress logs { quiet: true }",
53
- "\u2318 multiple files { path: ['.env.local', '.env'] }"
54
- ];
55
- function _getRandomTip() {
56
- return TIPS[Math.floor(Math.random() * TIPS.length)];
57
- }
58
- function parseBoolean(value) {
59
- if (typeof value === "string") {
60
- return !["false", "0", "no", "off", ""].includes(value.toLowerCase());
61
- }
62
- return Boolean(value);
63
- }
64
- function supportsAnsi() {
65
- return process.stdout.isTTY;
66
- }
67
- function dim(text) {
68
- return supportsAnsi() ? `\x1B[2m${text}\x1B[0m` : text;
69
- }
70
- var LINE = /(?:^|^)\s*(?:export\s+)?([\w.-]+)(?:\s*=\s*?|:\s+?)(\s*'(?:\\'|[^'])*'|\s*"(?:\\"|[^"])*"|\s*`(?:\\`|[^`])*`|[^#\r\n]+)?\s*(?:#.*)?(?:$|$)/mg;
71
- function parse(src) {
72
- const obj = {};
73
- let lines = src.toString();
74
- lines = lines.replace(/\r\n?/mg, "\n");
75
- let match;
76
- while ((match = LINE.exec(lines)) != null) {
77
- const key = match[1];
78
- let value = match[2] || "";
79
- value = value.trim();
80
- const maybeQuote = value[0];
81
- value = value.replace(/^(['"`])([\s\S]*)\1$/mg, "$2");
82
- if (maybeQuote === '"') {
83
- value = value.replace(/\\n/g, "\n");
84
- value = value.replace(/\\r/g, "\r");
85
- }
86
- obj[key] = value;
87
- }
88
- return obj;
89
- }
90
- function _parseVault(options) {
91
- options = options || {};
92
- const vaultPath = _vaultPath(options);
93
- options.path = vaultPath;
94
- const result = DotenvModule.configDotenv(options);
95
- if (!result.parsed) {
96
- const err = new Error(`MISSING_DATA: Cannot parse ${vaultPath} for an unknown reason`);
97
- err.code = "MISSING_DATA";
98
- throw err;
99
- }
100
- const keys = _dotenvKey(options).split(",");
101
- const length = keys.length;
102
- let decrypted;
103
- for (let i = 0; i < length; i++) {
104
- try {
105
- const key = keys[i].trim();
106
- const attrs = _instructions(result, key);
107
- decrypted = DotenvModule.decrypt(attrs.ciphertext, attrs.key);
108
- break;
109
- } catch (error) {
110
- if (i + 1 >= length) {
111
- throw error;
112
- }
38
+ // ../../node_modules/dotenv/dist/index.cjs
39
+ var require_dist = __commonJS({
40
+ "../../node_modules/dotenv/dist/index.cjs"(exports, module) {
41
+ var j = (e, n) => () => {
42
+ try {
43
+ return n || e((n = { exports: {} }).exports, n), n.exports;
44
+ } catch (t) {
45
+ throw n = 0, t;
46
+ }
47
+ };
48
+ var k = j((xe, U) => {
49
+ function G(e) {
50
+ return typeof e == "string" ? !["false", "0", "no", "off", ""].includes(e.toLowerCase()) : !!e;
51
+ }
52
+ function Y(e = process.env) {
53
+ let n = {};
54
+ for (let t of ["ENCODING", "PATH", "QUIET", "DEBUG", "OVERRIDE", "FAST"]) {
55
+ let o = e[`DOTENV_${t}`] != null ? e[`DOTENV_${t}`] : e[`DOTENV_CONFIG_${t}`];
56
+ o != null && (n[t.toLowerCase()] = t === "ENCODING" || t === "PATH" ? o : G(o));
113
57
  }
58
+ return n;
114
59
  }
115
- return DotenvModule.parse(decrypted);
116
- }
117
- function _warn(message) {
118
- console.error(`\u26A0 ${message}`);
119
- }
120
- function _debug(message) {
121
- console.log(`\u2506 ${message}`);
122
- }
123
- function _log(message) {
124
- console.log(`\u25C7 ${message}`);
125
- }
126
- function _dotenvKey(options) {
127
- if (options && options.DOTENV_KEY && options.DOTENV_KEY.length > 0) {
128
- return options.DOTENV_KEY;
60
+ U.exports = { parseBoolean: G, optionsFromEnv: Y };
61
+ });
62
+ var N = j((ye, x) => {
63
+ var z = __require("fs"), I = __require("path"), Z = __require("os"), { URL: ee, fileURLToPath: te } = __require("url"), { parseBoolean: $, optionsFromEnv: B } = k(), re = /(?:^|^)\s*(?:export\s+)?([\w.-]+)(?:\s*=\s*?|:\s+?)(\s*'(?:\\'|[^'])*'|\s*"(?:\\"|[^"])*"|\s*`(?:\\`|[^`])*`|[^#\r\n]+)?\s*(?:#.*)?(?:$|$)/mg, b = new Uint8Array(256);
64
+ for (let e = 48; e <= 57; e++) b[e] = 1;
65
+ for (let e = 65; e <= 90; e++) b[e] = 1;
66
+ for (let e = 97; e <= 122; e++) b[e] = 1;
67
+ b[45] = 1;
68
+ b[46] = 1;
69
+ b[95] = 1;
70
+ function ne(e) {
71
+ let n = {}, t = e.toString();
72
+ t = t.replace(/\r\n?/mg, `
73
+ `);
74
+ let o;
75
+ for (; (o = re.exec(t)) != null; ) {
76
+ let r = o[1], s = o[2] || "";
77
+ s = s.trim();
78
+ let i = s[0];
79
+ s = s.replace(/^(['"`])([\s\S]*)\1$/mg, "$2"), i === '"' && (s = s.replace(/\\n/g, `
80
+ `), s = s.replace(/\\r/g, "\r")), n[r] = s;
81
+ }
82
+ return n;
129
83
  }
130
- if (process.env.DOTENV_KEY && process.env.DOTENV_KEY.length > 0) {
131
- return process.env.DOTENV_KEY;
84
+ function w(e) {
85
+ return e <= 32 ? e === 32 || e >= 9 && e <= 13 : e >= 160 && (e === 160 || e === 5760 || e >= 8192 && e <= 8202 || e === 8232 || e === 8233 || e === 8239 || e === 8287 || e === 12288 || e === 65279);
132
86
  }
133
- return "";
134
- }
135
- function _instructions(result, dotenvKey) {
136
- let uri;
137
- try {
138
- uri = new URL(dotenvKey);
139
- } catch (error) {
140
- if (error.code === "ERR_INVALID_URL") {
141
- const err = new Error("INVALID_DOTENV_KEY: Wrong format. Must be in valid uri format like dotenv://:key_1234@dotenvx.com/vault/.env.vault?environment=development");
142
- err.code = "INVALID_DOTENV_KEY";
143
- throw err;
144
- }
145
- throw error;
146
- }
147
- const key = uri.password;
148
- if (!key) {
149
- const err = new Error("INVALID_DOTENV_KEY: Missing key part");
150
- err.code = "INVALID_DOTENV_KEY";
151
- throw err;
152
- }
153
- const environment = uri.searchParams.get("environment");
154
- if (!environment) {
155
- const err = new Error("INVALID_DOTENV_KEY: Missing environment part");
156
- err.code = "INVALID_DOTENV_KEY";
157
- throw err;
158
- }
159
- const environmentKey = `DOTENV_VAULT_${environment.toUpperCase()}`;
160
- const ciphertext = result.parsed[environmentKey];
161
- if (!ciphertext) {
162
- const err = new Error(`NOT_FOUND_DOTENV_ENVIRONMENT: Cannot locate environment ${environmentKey} in your .env.vault file.`);
163
- err.code = "NOT_FOUND_DOTENV_ENVIRONMENT";
164
- throw err;
165
- }
166
- return { ciphertext, key };
167
- }
168
- function _vaultPath(options) {
169
- let possibleVaultPath = null;
170
- if (options && options.path && options.path.length > 0) {
171
- if (Array.isArray(options.path)) {
172
- for (const filepath of options.path) {
173
- if (fs7.existsSync(filepath)) {
174
- possibleVaultPath = filepath.endsWith(".vault") ? filepath : `${filepath}.vault`;
87
+ function q(e) {
88
+ return e === 10 || e === 8232 || e === 8233;
89
+ }
90
+ function oe(e) {
91
+ let n = {}, t = typeof e == "string" ? e : e.toString();
92
+ t.indexOf("\r") !== -1 && (t = t.replace(/\r\n?/g, `
93
+ `));
94
+ let o = t.length, r = 0;
95
+ for (; r < o; ) {
96
+ let s = t.charCodeAt(r);
97
+ for (; r < o && w(s); ) r++, s = t.charCodeAt(r);
98
+ if (r >= o) break;
99
+ if (s === 35) {
100
+ for (; r < o && !q(t.charCodeAt(r)); ) r++;
101
+ continue;
102
+ }
103
+ let i = -1;
104
+ if (s === 101 && r + 6 < o && t.charCodeAt(r + 1) === 120 && t.charCodeAt(r + 2) === 112 && t.charCodeAt(r + 3) === 111 && t.charCodeAt(r + 4) === 114 && t.charCodeAt(r + 5) === 116) {
105
+ let v = t.charCodeAt(r + 6);
106
+ if (w(v)) {
107
+ let u = r + 7;
108
+ for (; u < o && w(t.charCodeAt(u)); ) u++;
109
+ b[t.charCodeAt(u)] && (i = r + 6, r = u);
110
+ } else s = t.charCodeAt(r);
111
+ }
112
+ let l = r, d = 0;
113
+ for (; r < o && (d = t.charCodeAt(r), b[d]); ) r++;
114
+ if (r === l) {
115
+ for (; r < o && !q(t.charCodeAt(r)); ) r++;
116
+ continue;
117
+ }
118
+ let h = t.slice(l, r), f = r;
119
+ if (r >= o && (d = 0), w(d)) do
120
+ r++, d = r < o ? t.charCodeAt(r) : 0;
121
+ while (w(d));
122
+ if (d === 61) r++;
123
+ else if (d === 58 && r === f && r + 1 < o && w(t.charCodeAt(r + 1))) r += 2;
124
+ else {
125
+ for (r = i === -1 ? f : i; r < o && !q(t.charCodeAt(r)); ) r++;
126
+ continue;
127
+ }
128
+ let c = r, a = r;
129
+ for (; a < o && w(t.charCodeAt(a)); ) a++;
130
+ let g = t.charCodeAt(a), p, y = false;
131
+ if (g === 39 || g === 34 || g === 96) {
132
+ let v = t[a], u = t.indexOf(v, a + 1), m = -1, C = -1;
133
+ for (; u !== -1; ) {
134
+ let O = t.charCodeAt(u - 1) === 92, E = u + 1;
135
+ for (; E < o && !q(t.charCodeAt(E)) && w(t.charCodeAt(E)); ) E++;
136
+ if ((E === o || q(t.charCodeAt(E)) || t.charCodeAt(E) === 35) && (m = u, C = E), !O) break;
137
+ u = t.indexOf(v, u + 1);
138
+ }
139
+ if (m !== -1) {
140
+ if (p = t.slice(a + 1, m), r = C, t.charCodeAt(r) === 35) for (; r < o && !q(t.charCodeAt(r)); ) r++;
141
+ y = true;
175
142
  }
176
143
  }
177
- } else {
178
- possibleVaultPath = options.path.endsWith(".vault") ? options.path : `${options.path}.vault`;
144
+ if (!y) {
145
+ let v = t.indexOf(`
146
+ `, c);
147
+ v === -1 && (v = o);
148
+ let u;
149
+ if (o < 4096) u = t.indexOf("#", c), (u === -1 || u > v) && (u = v);
150
+ else for (u = c; u < v && t.charCodeAt(u) !== 35; ) u++;
151
+ let m = c, C = u;
152
+ for (; m < C && w(t.charCodeAt(m)); ) m++;
153
+ for (; C > m && w(t.charCodeAt(C - 1)); ) C--;
154
+ let O = t.charCodeAt(m);
155
+ if (p = t.slice(m, C), p.includes("\u2028") || p.includes("\u2029") ? p = p.replace(/^(['"`])([\s\S]*)\1$/mg, "$2") : C - m >= 2 && (O === 39 || O === 34 || O === 96) && t.charCodeAt(C - 1) === O && (p = t.slice(m + 1, C - 1)), r = u, u < v) for (; r < o && !q(t.charCodeAt(r)); ) r++;
156
+ }
157
+ g === 34 && (y || a < r) && p.indexOf("\\") !== -1 && (p = p.replace(/\\n/g, `
158
+ `).replace(/\\r/g, "\r")), n[h] = p;
179
159
  }
180
- } else {
181
- possibleVaultPath = path13.resolve(process.cwd(), ".env.vault");
160
+ return n;
182
161
  }
183
- if (fs7.existsSync(possibleVaultPath)) {
184
- return possibleVaultPath;
162
+ function se(e, n) {
163
+ return n && $(n.fast) ? oe(e) : ne(e);
185
164
  }
186
- return null;
187
- }
188
- function _resolveHome(envPath) {
189
- return envPath[0] === "~" ? path13.join(os2.homedir(), envPath.slice(1)) : envPath;
190
- }
191
- function _configVault(options) {
192
- const debug = parseBoolean(process.env.DOTENV_CONFIG_DEBUG || options && options.debug);
193
- const quiet = parseBoolean(process.env.DOTENV_CONFIG_QUIET || options && options.quiet);
194
- if (debug || !quiet) {
195
- _log("loading env from encrypted .env.vault");
196
- }
197
- const parsed = DotenvModule._parseVault(options);
198
- let processEnv = process.env;
199
- if (options && options.processEnv != null) {
200
- processEnv = options.processEnv;
201
- }
202
- DotenvModule.populate(processEnv, parsed, options);
203
- return { parsed };
204
- }
205
- function configDotenv(options) {
206
- const dotenvPath = path13.resolve(process.cwd(), ".env");
207
- let encoding = "utf8";
208
- let processEnv = process.env;
209
- if (options && options.processEnv != null) {
210
- processEnv = options.processEnv;
211
- }
212
- let debug = parseBoolean(processEnv.DOTENV_CONFIG_DEBUG || options && options.debug);
213
- let quiet = parseBoolean(processEnv.DOTENV_CONFIG_QUIET || options && options.quiet);
214
- if (options && options.encoding) {
215
- encoding = options.encoding;
216
- } else {
217
- if (debug) {
218
- _debug("no encoding is specified (UTF-8 is used by default)");
165
+ function T(e) {
166
+ console.log(`\u2506 ${e}`);
167
+ }
168
+ function ie(e) {
169
+ console.error(`\u25C7 ${e}`);
170
+ }
171
+ function V(e) {
172
+ return e[0] === "~" ? I.join(Z.homedir(), e.slice(1)) : e;
173
+ }
174
+ function ce(e = {}) {
175
+ let n = { ...e };
176
+ for (let t of Object.keys(n)) n[t] === void 0 && delete n[t];
177
+ return { ...B(), ...n };
178
+ }
179
+ function ae(e) {
180
+ e = ce(e);
181
+ let n = I.resolve(process.cwd(), ".env"), t = "utf8", o = process.env;
182
+ e && e.processEnv != null && (o = e.processEnv);
183
+ let r = $(e && e.debug);
184
+ e && e.encoding ? t = e.encoding : r && T("no encoding is specified (UTF-8 is used by default)");
185
+ let s = [n];
186
+ if (e && e.path) if (!Array.isArray(e.path)) s = [V(e.path)];
187
+ else {
188
+ s = [];
189
+ for (let c of e.path) s.push(V(c));
190
+ }
191
+ let i, l = {}, d = { fast: e.fast };
192
+ for (let c of s) try {
193
+ let a = A.parse(z.readFileSync(c, { encoding: t }), d);
194
+ A.populate(l, a, e);
195
+ } catch (a) {
196
+ r && T(`failed to load ${c} ${a.message}`), i = a;
197
+ }
198
+ let h = A.populate(o, l, e), f = $(Object.prototype.hasOwnProperty.call(e, "quiet") ? e.quiet : B(o).quiet);
199
+ if (r || !f) {
200
+ let c = Object.keys(h).length, a = [];
201
+ for (let g of s) try {
202
+ let p = I.relative(process.cwd(), g instanceof ee ? te(g) : g);
203
+ a.push(p);
204
+ } catch (p) {
205
+ r && T(`failed to load ${g} ${p.message}`), i = p;
206
+ }
207
+ ie(`injected env (${c}) from ${a.join(",")}`);
219
208
  }
209
+ return i ? { parsed: l, error: i } : { parsed: l };
220
210
  }
221
- let optionPaths = [dotenvPath];
222
- if (options && options.path) {
223
- if (!Array.isArray(options.path)) {
224
- optionPaths = [_resolveHome(options.path)];
225
- } else {
226
- optionPaths = [];
227
- for (const filepath of options.path) {
228
- optionPaths.push(_resolveHome(filepath));
211
+ function le(e) {
212
+ return A.configDotenv(e);
213
+ }
214
+ function fe(e, n, t = {}) {
215
+ let o = $(t && t.debug), r = $(t && t.override), s = {};
216
+ if (e === null || typeof e != "object" || n === null || typeof n != "object") {
217
+ let i = new Error("OBJECT_REQUIRED: Please check the processEnv argument being passed to populate");
218
+ throw i.code = "OBJECT_REQUIRED", i;
219
+ }
220
+ for (let i of Object.keys(n)) Object.prototype.hasOwnProperty.call(e, i) ? (r === true && (e[i] = n[i], s[i] = n[i]), o && T(r === true ? `"${i}" is already defined and WAS overwritten` : `"${i}" is already defined and was NOT overwritten`)) : (e[i] = n[i], s[i] = n[i]);
221
+ return s;
222
+ }
223
+ var A = { configDotenv: ae, config: le, parse: se, populate: fe };
224
+ x.exports.configDotenv = A.configDotenv;
225
+ x.exports.config = A.config;
226
+ x.exports.parse = A.parse;
227
+ x.exports.populate = A.populate;
228
+ x.exports = A;
229
+ });
230
+ var M = j((Te, W) => {
231
+ var _ = __require("child_process"), ue = __require("fs"), L = __require("path");
232
+ function de(e) {
233
+ let n = ['"'], t = 0;
234
+ for (let o of e) {
235
+ if (o === "\\") {
236
+ t++;
237
+ continue;
229
238
  }
239
+ o === '"' ? n.push("\\".repeat(t * 2 + 1), '"') : n.push("\\".repeat(t), o), t = 0;
230
240
  }
241
+ return n.push("\\".repeat(t * 2), '"'), n.join("");
231
242
  }
232
- let lastError;
233
- const parsedAll = {};
234
- for (const path14 of optionPaths) {
235
- try {
236
- const parsed = DotenvModule.parse(fs7.readFileSync(path14, { encoding }));
237
- DotenvModule.populate(parsedAll, parsed, options);
238
- } catch (e) {
239
- if (debug) {
240
- _debug(`failed to load ${path14} ${e.message}`);
241
- }
242
- lastError = e;
243
- }
244
- }
245
- const populated = DotenvModule.populate(processEnv, parsedAll, options);
246
- debug = parseBoolean(processEnv.DOTENV_CONFIG_DEBUG || debug);
247
- quiet = parseBoolean(processEnv.DOTENV_CONFIG_QUIET || quiet);
248
- if (debug || !quiet) {
249
- const keysCount = Object.keys(populated).length;
250
- const shortPaths = [];
251
- for (const filePath of optionPaths) {
252
- try {
253
- const relative2 = path13.relative(process.cwd(), filePath);
254
- shortPaths.push(relative2);
255
- } catch (e) {
256
- if (debug) {
257
- _debug(`failed to load ${filePath} ${e.message}`);
258
- }
259
- lastError = e;
243
+ function H(e, n = 1) {
244
+ for (let t = 0; t < n; t++) {
245
+ let o = [];
246
+ for (let r of e) {
247
+ let s = r.charCodeAt(0), i = s >= 48 && s <= 57 || s >= 65 && s <= 90 || s >= 97 && s <= 122, l = "\\/:._-".includes(r);
248
+ !i && !l && s < 128 && o.push("^"), o.push(r);
260
249
  }
250
+ e = o.join("");
261
251
  }
262
- _log(`injected env (${keysCount}) from ${shortPaths.join(",")} ${dim(`// tip: ${_getRandomTip()}`)}`);
252
+ return e;
263
253
  }
264
- if (lastError) {
265
- return { parsed: parsedAll, error: lastError };
266
- } else {
267
- return { parsed: parsedAll };
254
+ function P(e, n) {
255
+ let t = Object.keys(e).reverse().find((o) => o.toUpperCase() === n);
256
+ return t === void 0 ? void 0 : e[t];
268
257
  }
269
- }
270
- function config(options) {
271
- if (_dotenvKey(options).length === 0) {
272
- return DotenvModule.configDotenv(options);
258
+ function pe(e, n, t) {
259
+ let o = (P(n, "PATHEXT") || ".COM;.EXE;.BAT;.CMD").split(";").filter(Boolean), s = o.some((l) => e.toLowerCase().endsWith(l.toLowerCase())) ? ["", ...o] : [...o, ""], i = /[\\/]/.test(e) ? [t] : [t, ...(P(n, "PATH") || "").split(";")];
260
+ for (let l of i) for (let d of s) {
261
+ let h = L.resolve(t, l.replace(/^"|"$/g, ""), e + d);
262
+ try {
263
+ if (ue.statSync(h).isFile()) return h;
264
+ } catch {
265
+ }
266
+ }
273
267
  }
274
- const vaultPath = _vaultPath(options);
275
- if (!vaultPath) {
276
- _warn(`you set DOTENV_KEY but you are missing a .env.vault file at ${vaultPath}`);
277
- return DotenvModule.configDotenv(options);
268
+ function he(e, n, t) {
269
+ if (process.platform !== "win32") return _.spawn(e, n, t);
270
+ let o = t.env || process.env, r = pe(e, o, t.cwd || process.cwd());
271
+ if (r && /\.(?:exe|com)$/i.test(r)) return _.spawn(r, n, t);
272
+ let s = /\.(?:bat|cmd)$/i.test(r || e), i = [H(L.normalize(r || e))];
273
+ for (let d of n) i.push(H(de(d), s ? 2 : 1));
274
+ let l = i.join(" ");
275
+ return _.spawn(P(o, "COMSPEC") || "cmd.exe", ["/d", "/v:off", "/s", "/c", `"${l}"`], { ...t, windowsVerbatimArguments: true });
278
276
  }
279
- return DotenvModule._configVault(options);
280
- }
281
- function decrypt(encrypted, keyStr) {
282
- const key = Buffer.from(keyStr.slice(-64), "hex");
283
- let ciphertext = Buffer.from(encrypted, "base64");
284
- const nonce = ciphertext.subarray(0, 12);
285
- const authTag = ciphertext.subarray(-16);
286
- ciphertext = ciphertext.subarray(12, -16);
287
- try {
288
- const aesgcm = crypto2.createDecipheriv("aes-256-gcm", key, nonce);
289
- aesgcm.setAuthTag(authTag);
290
- return `${aesgcm.update(ciphertext)}${aesgcm.final()}`;
291
- } catch (error) {
292
- const isRange = error instanceof RangeError;
293
- const invalidKeyLength = error.message === "Invalid key length";
294
- const decryptionFailed = error.message === "Unsupported state or unable to authenticate data";
295
- if (isRange || invalidKeyLength) {
296
- const err = new Error("INVALID_DOTENV_KEY: It must be 64 characters long (or more)");
297
- err.code = "INVALID_DOTENV_KEY";
298
- throw err;
299
- } else if (decryptionFailed) {
300
- const err = new Error("DECRYPTION_FAILED: Please check your DOTENV_KEY");
301
- err.code = "DECRYPTION_FAILED";
302
- throw err;
303
- } else {
304
- throw error;
277
+ W.exports = he;
278
+ });
279
+ var X = j(($e, F) => {
280
+ var ge = __require("fs"), me = __require("os"), Q = __require("path"), ve = __require("child_process"), Ce = M(), R = N(), { optionsFromEnv: J } = k();
281
+ function D() {
282
+ console.log(["Usage: dotenv run [--help] [-q|--quiet] [--debug] [--override] [--fast] [-f|--file <paths>] [--] <command> [args...]", "", "Run a command with environment variables from a .env file.", "Place dotenv options before the command; all following arguments go to the command.", "", "Options:", " -f, --file <paths> .env paths, comma-separated or repeated (default: .env)", " -q, --quiet suppress the injected env message", " --debug enable debug logging", " --override override existing environment variables", " --fast use the faster character-scanner parser", "", "Environment variables (DOTENV_CONFIG_* names remain as fallbacks):", " DOTENV_PATH, DOTENV_ENCODING, DOTENV_QUIET,", " DOTENV_DEBUG, DOTENV_OVERRIDE,", " DOTENV_FAST"].join(`
283
+ `));
284
+ }
285
+ function we(e) {
286
+ let n = [], t = false, o, r, s, i, l = -1;
287
+ for (let h = 0; h < e.length; h++) {
288
+ let f = e[h];
289
+ if (f === "--") {
290
+ l = h + 1;
291
+ break;
292
+ }
293
+ if (f === "--help" || f === "-h") return { help: true };
294
+ if (f === "--quiet" || f === "-q") {
295
+ o = true;
296
+ continue;
297
+ }
298
+ if (f === "--debug") {
299
+ r = true;
300
+ continue;
301
+ }
302
+ if (f === "--override") {
303
+ s = true;
304
+ continue;
305
+ }
306
+ if (f === "--fast") {
307
+ i = true;
308
+ continue;
309
+ }
310
+ if (f === "-f" || f === "--file" || f.startsWith("-f=") || f.startsWith("--file=")) {
311
+ let c = f.indexOf("="), a = c === -1 ? f : f.slice(0, c), g = c === -1 ? e[++h] : f.slice(c + 1);
312
+ if (!g || g === "--") return { error: `${a} requires a path` };
313
+ let p = g.split(",").map((y) => y.trim()).filter(Boolean);
314
+ if (p.length === 0) return { error: `${a} requires a path` };
315
+ n.push(...p), t = true;
316
+ continue;
317
+ }
318
+ if (f.startsWith("-")) return { error: `unknown option: ${f}` };
319
+ l = h;
320
+ break;
305
321
  }
322
+ let d = l === -1 ? [] : e.slice(l);
323
+ return { paths: n, pathSet: t, quiet: o, debug: r, override: s, fast: i, command: d };
306
324
  }
307
- }
308
- function populate(processEnv, parsed, options = {}) {
309
- const debug = Boolean(options && options.debug);
310
- const override = Boolean(options && options.override);
311
- const populated = {};
312
- if (typeof parsed !== "object") {
313
- const err = new Error("OBJECT_REQUIRED: Please check the processEnv argument being passed to populate");
314
- err.code = "OBJECT_REQUIRED";
315
- throw err;
325
+ function Ae(e) {
326
+ return e[0] === "~" ? Q.join(me.homedir(), e.slice(1)) : e;
327
+ }
328
+ function Ee(e) {
329
+ let n = J(), t = { encoding: n.encoding || "utf8", quiet: n.quiet, debug: n.debug === true, override: n.override === true, fast: n.fast === true, paths: [".env"], defaultPath: true };
330
+ return n.path != null && (t.paths = [n.path], t.defaultPath = false), e.pathSet && (t.paths = e.paths, t.defaultPath = false), e.quiet != null && (t.quiet = e.quiet), e.debug != null && (t.debug = e.debug), e.override != null && (t.override = e.override), e.fast != null && (t.fast = e.fast), t;
316
331
  }
317
- for (const key of Object.keys(parsed)) {
318
- if (Object.prototype.hasOwnProperty.call(processEnv, key)) {
319
- if (override === true) {
320
- processEnv[key] = parsed[key];
321
- populated[key] = parsed[key];
332
+ function be(e) {
333
+ let n = {}, t = [], o = { override: e.override, debug: e.debug };
334
+ for (let s of e.paths) {
335
+ let i = Q.resolve(process.cwd(), Ae(s));
336
+ try {
337
+ let l = R.parse(ge.readFileSync(i, { encoding: e.encoding }), { fast: e.fast });
338
+ R.populate(n, l, o), t.push(s);
339
+ } catch (l) {
340
+ if (e.debug && console.log(`\u2506 failed to load ${s} ${l.message}`), !(e.defaultPath && l.code === "ENOENT")) throw l;
322
341
  }
323
- if (debug) {
324
- if (override === true) {
325
- _debug(`"${key}" is already defined and WAS overwritten`);
326
- } else {
327
- _debug(`"${key}" is already defined and was NOT overwritten`);
342
+ }
343
+ return { injected: R.populate(process.env, n, o), loadedPaths: t };
344
+ }
345
+ function K(e) {
346
+ let n = e[0];
347
+ if (n === "--help" || n === "-h") {
348
+ D();
349
+ return;
350
+ }
351
+ if (n !== "run") {
352
+ D(), process.exitCode = 1;
353
+ return;
354
+ }
355
+ let t = we(e.slice(1));
356
+ if (t.help) {
357
+ D();
358
+ return;
359
+ }
360
+ if (t.error) {
361
+ console.error(`dotenv: ${t.error}`), D(), process.exitCode = 1;
362
+ return;
363
+ }
364
+ if (t.command.length === 0) {
365
+ D(), process.exitCode = 1;
366
+ return;
367
+ }
368
+ let o = Ee(t);
369
+ try {
370
+ let c = be(o);
371
+ if (!(o.quiet == null ? J().quiet : o.quiet)) {
372
+ let g = `\u25C7 injected env (${Object.keys(c.injected).length})`;
373
+ c.loadedPaths.length > 0 && (g += ` from ${c.loadedPaths.join(", ")}`), console.error(g);
374
+ }
375
+ } catch (c) {
376
+ console.error(`dotenv: ${c.message}`), process.exitCode = 1;
377
+ return;
378
+ }
379
+ let r = !!process.stdin.isTTY, s = process.platform !== "win32" && !r, i = Ce(t.command[0], t.command.slice(1), { stdio: "inherit", detached: s }), l = /* @__PURE__ */ new Map(), d = 0;
380
+ function h(c) {
381
+ if (!(!i.pid || i.exitCode !== null || i.signalCode !== null)) {
382
+ if (process.platform === "win32") {
383
+ ve.spawnSync("taskkill", ["/pid", String(i.pid), "/T", "/F"], { stdio: "ignore" });
384
+ return;
385
+ }
386
+ try {
387
+ process.kill(s ? -i.pid : i.pid, c);
388
+ } catch (a) {
389
+ if (a.code !== "ESRCH") throw a;
328
390
  }
329
391
  }
330
- } else {
331
- processEnv[key] = parsed[key];
332
- populated[key] = parsed[key];
333
392
  }
393
+ function f() {
394
+ for (let [c, a] of l) process.removeListener(c, a);
395
+ }
396
+ for (let c of ["SIGINT", "SIGTERM", "SIGHUP", "SIGQUIT"]) {
397
+ let a = () => {
398
+ if (c === "SIGINT") {
399
+ if (d++, r && process.platform !== "win32" && d === 1) return;
400
+ if (d > 1) {
401
+ h(d === 2 ? "SIGTERM" : "SIGKILL");
402
+ return;
403
+ }
404
+ }
405
+ h(c);
406
+ };
407
+ l.set(c, a), process.on(c, a);
408
+ }
409
+ i.on("error", function(c) {
410
+ f(), console.error(`dotenv: ${c.message}`), process.exitCode = 1;
411
+ }), i.on("exit", function(c, a) {
412
+ f(), typeof c == "number" ? process.exit(c) : (setInterval(() => {
413
+ }, 1e3), process.kill(process.pid, a));
414
+ });
334
415
  }
335
- return populated;
336
- }
337
- var DotenvModule = {
338
- configDotenv,
339
- _configVault,
340
- _parseVault,
341
- config,
342
- decrypt,
343
- parse,
344
- populate
345
- };
346
- module.exports.configDotenv = DotenvModule.configDotenv;
347
- module.exports._configVault = DotenvModule._configVault;
348
- module.exports._parseVault = DotenvModule._parseVault;
349
- module.exports.config = DotenvModule.config;
350
- module.exports.decrypt = DotenvModule.decrypt;
351
- module.exports.parse = DotenvModule.parse;
352
- module.exports.populate = DotenvModule.populate;
353
- module.exports = DotenvModule;
416
+ F.exports = K;
417
+ __require.main === F && K(process.argv.slice(2));
418
+ });
419
+ var S = N();
420
+ var qe = X();
421
+ module.exports = S;
422
+ module.exports.config = S.config;
423
+ module.exports.configDotenv = S.configDotenv;
424
+ module.exports.parse = S.parse;
425
+ module.exports.populate = S.populate;
426
+ __require.main === module && qe(process.argv.slice(2));
354
427
  }
355
428
  });
356
429
 
@@ -431,17 +504,17 @@ var require_visit = __commonJS({
431
504
  visit.BREAK = BREAK;
432
505
  visit.SKIP = SKIP;
433
506
  visit.REMOVE = REMOVE;
434
- function visit_(key, node, visitor, path13) {
435
- const ctrl = callVisitor(key, node, visitor, path13);
507
+ function visit_(key, node, visitor, path14) {
508
+ const ctrl = callVisitor(key, node, visitor, path14);
436
509
  if (identity.isNode(ctrl) || identity.isPair(ctrl)) {
437
- replaceNode(key, path13, ctrl);
438
- return visit_(key, ctrl, visitor, path13);
510
+ replaceNode(key, path14, ctrl);
511
+ return visit_(key, ctrl, visitor, path14);
439
512
  }
440
513
  if (typeof ctrl !== "symbol") {
441
514
  if (identity.isCollection(node)) {
442
- path13 = Object.freeze(path13.concat(node));
515
+ path14 = Object.freeze(path14.concat(node));
443
516
  for (let i = 0; i < node.items.length; ++i) {
444
- const ci = visit_(i, node.items[i], visitor, path13);
517
+ const ci = visit_(i, node.items[i], visitor, path14);
445
518
  if (typeof ci === "number")
446
519
  i = ci - 1;
447
520
  else if (ci === BREAK)
@@ -452,13 +525,13 @@ var require_visit = __commonJS({
452
525
  }
453
526
  }
454
527
  } else if (identity.isPair(node)) {
455
- path13 = Object.freeze(path13.concat(node));
456
- const ck = visit_("key", node.key, visitor, path13);
528
+ path14 = Object.freeze(path14.concat(node));
529
+ const ck = visit_("key", node.key, visitor, path14);
457
530
  if (ck === BREAK)
458
531
  return BREAK;
459
532
  else if (ck === REMOVE)
460
533
  node.key = null;
461
- const cv = visit_("value", node.value, visitor, path13);
534
+ const cv = visit_("value", node.value, visitor, path14);
462
535
  if (cv === BREAK)
463
536
  return BREAK;
464
537
  else if (cv === REMOVE)
@@ -479,17 +552,17 @@ var require_visit = __commonJS({
479
552
  visitAsync.BREAK = BREAK;
480
553
  visitAsync.SKIP = SKIP;
481
554
  visitAsync.REMOVE = REMOVE;
482
- async function visitAsync_(key, node, visitor, path13) {
483
- const ctrl = await callVisitor(key, node, visitor, path13);
555
+ async function visitAsync_(key, node, visitor, path14) {
556
+ const ctrl = await callVisitor(key, node, visitor, path14);
484
557
  if (identity.isNode(ctrl) || identity.isPair(ctrl)) {
485
- replaceNode(key, path13, ctrl);
486
- return visitAsync_(key, ctrl, visitor, path13);
558
+ replaceNode(key, path14, ctrl);
559
+ return visitAsync_(key, ctrl, visitor, path14);
487
560
  }
488
561
  if (typeof ctrl !== "symbol") {
489
562
  if (identity.isCollection(node)) {
490
- path13 = Object.freeze(path13.concat(node));
563
+ path14 = Object.freeze(path14.concat(node));
491
564
  for (let i = 0; i < node.items.length; ++i) {
492
- const ci = await visitAsync_(i, node.items[i], visitor, path13);
565
+ const ci = await visitAsync_(i, node.items[i], visitor, path14);
493
566
  if (typeof ci === "number")
494
567
  i = ci - 1;
495
568
  else if (ci === BREAK)
@@ -500,13 +573,13 @@ var require_visit = __commonJS({
500
573
  }
501
574
  }
502
575
  } else if (identity.isPair(node)) {
503
- path13 = Object.freeze(path13.concat(node));
504
- const ck = await visitAsync_("key", node.key, visitor, path13);
576
+ path14 = Object.freeze(path14.concat(node));
577
+ const ck = await visitAsync_("key", node.key, visitor, path14);
505
578
  if (ck === BREAK)
506
579
  return BREAK;
507
580
  else if (ck === REMOVE)
508
581
  node.key = null;
509
- const cv = await visitAsync_("value", node.value, visitor, path13);
582
+ const cv = await visitAsync_("value", node.value, visitor, path14);
510
583
  if (cv === BREAK)
511
584
  return BREAK;
512
585
  else if (cv === REMOVE)
@@ -533,23 +606,23 @@ var require_visit = __commonJS({
533
606
  }
534
607
  return visitor;
535
608
  }
536
- function callVisitor(key, node, visitor, path13) {
609
+ function callVisitor(key, node, visitor, path14) {
537
610
  if (typeof visitor === "function")
538
- return visitor(key, node, path13);
611
+ return visitor(key, node, path14);
539
612
  if (identity.isMap(node))
540
- return visitor.Map?.(key, node, path13);
613
+ return visitor.Map?.(key, node, path14);
541
614
  if (identity.isSeq(node))
542
- return visitor.Seq?.(key, node, path13);
615
+ return visitor.Seq?.(key, node, path14);
543
616
  if (identity.isPair(node))
544
- return visitor.Pair?.(key, node, path13);
617
+ return visitor.Pair?.(key, node, path14);
545
618
  if (identity.isScalar(node))
546
- return visitor.Scalar?.(key, node, path13);
619
+ return visitor.Scalar?.(key, node, path14);
547
620
  if (identity.isAlias(node))
548
- return visitor.Alias?.(key, node, path13);
621
+ return visitor.Alias?.(key, node, path14);
549
622
  return void 0;
550
623
  }
551
- function replaceNode(key, path13, node) {
552
- const parent = path13[path13.length - 1];
624
+ function replaceNode(key, path14, node) {
625
+ const parent = path14[path14.length - 1];
553
626
  if (identity.isCollection(parent)) {
554
627
  parent.items[key] = node;
555
628
  } else if (identity.isPair(parent)) {
@@ -978,36 +1051,38 @@ var require_Alias = __commonJS({
978
1051
  if (node.anchor === this.source)
979
1052
  found = node;
980
1053
  }
1054
+ if (found && ctx) {
1055
+ const { anchors: anchors2, doc: doc2, maxAliasCount } = ctx;
1056
+ let data = anchors2.get(found);
1057
+ if (!data) {
1058
+ toJS.toJS(found, null, ctx);
1059
+ data = anchors2.get(found);
1060
+ }
1061
+ if (data?.res === void 0) {
1062
+ const msg = "This should not happen: Alias anchor was not resolved?";
1063
+ throw new ReferenceError(msg);
1064
+ }
1065
+ if (maxAliasCount >= 0) {
1066
+ data.count += 1;
1067
+ if (data.aliasCount === 0)
1068
+ data.aliasCount = getAliasCount(doc2, found, anchors2);
1069
+ if (data.count * data.aliasCount > maxAliasCount) {
1070
+ const msg = "Excessive alias count indicates a resource exhaustion attack";
1071
+ throw new ReferenceError(msg);
1072
+ }
1073
+ }
1074
+ }
981
1075
  return found;
982
1076
  }
983
1077
  toJSON(_arg, ctx) {
984
1078
  if (!ctx)
985
1079
  return { source: this.source };
986
- const { anchors: anchors2, doc, maxAliasCount } = ctx;
987
- const source = this.resolve(doc, ctx);
1080
+ const source = this.resolve(ctx.doc, ctx);
988
1081
  if (!source) {
989
1082
  const msg = `Unresolved alias (the anchor must be set before the alias): ${this.source}`;
990
1083
  throw new ReferenceError(msg);
991
1084
  }
992
- let data = anchors2.get(source);
993
- if (!data) {
994
- toJS.toJS(source, null, ctx);
995
- data = anchors2.get(source);
996
- }
997
- if (data?.res === void 0) {
998
- const msg = "This should not happen: Alias anchor was not resolved?";
999
- throw new ReferenceError(msg);
1000
- }
1001
- if (maxAliasCount >= 0) {
1002
- data.count += 1;
1003
- if (data.aliasCount === 0)
1004
- data.aliasCount = getAliasCount(doc, source, anchors2);
1005
- if (data.count * data.aliasCount > maxAliasCount) {
1006
- const msg = "Excessive alias count indicates a resource exhaustion attack";
1007
- throw new ReferenceError(msg);
1008
- }
1009
- }
1010
- return data.res;
1085
+ return ctx.anchors.get(source).res;
1011
1086
  }
1012
1087
  toString(ctx, _onComment, _onChompKeep) {
1013
1088
  const src = `*${this.source}`;
@@ -1159,10 +1234,10 @@ var require_Collection = __commonJS({
1159
1234
  var createNode = require_createNode();
1160
1235
  var identity = require_identity();
1161
1236
  var Node = require_Node();
1162
- function collectionFromPath(schema, path13, value) {
1237
+ function collectionFromPath(schema, path14, value) {
1163
1238
  let v = value;
1164
- for (let i = path13.length - 1; i >= 0; --i) {
1165
- const k = path13[i];
1239
+ for (let i = path14.length - 1; i >= 0; --i) {
1240
+ const k = path14[i];
1166
1241
  if (typeof k === "number" && Number.isInteger(k) && k >= 0) {
1167
1242
  const a = [];
1168
1243
  a[k] = v;
@@ -1181,7 +1256,7 @@ var require_Collection = __commonJS({
1181
1256
  sourceObjects: /* @__PURE__ */ new Map()
1182
1257
  });
1183
1258
  }
1184
- var isEmptyPath = (path13) => path13 == null || typeof path13 === "object" && !!path13[Symbol.iterator]().next().done;
1259
+ var isEmptyPath = (path14) => path14 == null || typeof path14 === "object" && !!path14[Symbol.iterator]().next().done;
1185
1260
  var Collection = class extends Node.NodeBase {
1186
1261
  constructor(type, schema) {
1187
1262
  super(type);
@@ -1211,11 +1286,11 @@ var require_Collection = __commonJS({
1211
1286
  * be a Pair instance or a `{ key, value }` object, which may not have a key
1212
1287
  * that already exists in the map.
1213
1288
  */
1214
- addIn(path13, value) {
1215
- if (isEmptyPath(path13))
1289
+ addIn(path14, value) {
1290
+ if (isEmptyPath(path14))
1216
1291
  this.add(value);
1217
1292
  else {
1218
- const [key, ...rest] = path13;
1293
+ const [key, ...rest] = path14;
1219
1294
  const node = this.get(key, true);
1220
1295
  if (identity.isCollection(node))
1221
1296
  node.addIn(rest, value);
@@ -1229,8 +1304,8 @@ var require_Collection = __commonJS({
1229
1304
  * Removes a value from the collection.
1230
1305
  * @returns `true` if the item was found and removed.
1231
1306
  */
1232
- deleteIn(path13) {
1233
- const [key, ...rest] = path13;
1307
+ deleteIn(path14) {
1308
+ const [key, ...rest] = path14;
1234
1309
  if (rest.length === 0)
1235
1310
  return this.delete(key);
1236
1311
  const node = this.get(key, true);
@@ -1244,8 +1319,8 @@ var require_Collection = __commonJS({
1244
1319
  * scalar values from their surrounding node; to disable set `keepScalar` to
1245
1320
  * `true` (collections are always returned intact).
1246
1321
  */
1247
- getIn(path13, keepScalar) {
1248
- const [key, ...rest] = path13;
1322
+ getIn(path14, keepScalar) {
1323
+ const [key, ...rest] = path14;
1249
1324
  const node = this.get(key, true);
1250
1325
  if (rest.length === 0)
1251
1326
  return !keepScalar && identity.isScalar(node) ? node.value : node;
@@ -1263,8 +1338,8 @@ var require_Collection = __commonJS({
1263
1338
  /**
1264
1339
  * Checks if the collection includes a value with the key `key`.
1265
1340
  */
1266
- hasIn(path13) {
1267
- const [key, ...rest] = path13;
1341
+ hasIn(path14) {
1342
+ const [key, ...rest] = path14;
1268
1343
  if (rest.length === 0)
1269
1344
  return this.has(key);
1270
1345
  const node = this.get(key, true);
@@ -1274,8 +1349,8 @@ var require_Collection = __commonJS({
1274
1349
  * Sets a value in this collection. For `!!set`, `value` needs to be a
1275
1350
  * boolean to add/remove the item from the set.
1276
1351
  */
1277
- setIn(path13, value) {
1278
- const [key, ...rest] = path13;
1352
+ setIn(path14, value) {
1353
+ const [key, ...rest] = path14;
1279
1354
  if (rest.length === 0) {
1280
1355
  this.set(key, value);
1281
1356
  } else {
@@ -3790,9 +3865,9 @@ var require_Document = __commonJS({
3790
3865
  this.contents.add(value);
3791
3866
  }
3792
3867
  /** Adds a value to the document. */
3793
- addIn(path13, value) {
3868
+ addIn(path14, value) {
3794
3869
  if (assertCollection(this.contents))
3795
- this.contents.addIn(path13, value);
3870
+ this.contents.addIn(path14, value);
3796
3871
  }
3797
3872
  /**
3798
3873
  * Create a new `Alias` node, ensuring that the target `node` has the required anchor.
@@ -3867,14 +3942,14 @@ var require_Document = __commonJS({
3867
3942
  * Removes a value from the document.
3868
3943
  * @returns `true` if the item was found and removed.
3869
3944
  */
3870
- deleteIn(path13) {
3871
- if (Collection.isEmptyPath(path13)) {
3945
+ deleteIn(path14) {
3946
+ if (Collection.isEmptyPath(path14)) {
3872
3947
  if (this.contents == null)
3873
3948
  return false;
3874
3949
  this.contents = null;
3875
3950
  return true;
3876
3951
  }
3877
- return assertCollection(this.contents) ? this.contents.deleteIn(path13) : false;
3952
+ return assertCollection(this.contents) ? this.contents.deleteIn(path14) : false;
3878
3953
  }
3879
3954
  /**
3880
3955
  * Returns item at `key`, or `undefined` if not found. By default unwraps
@@ -3889,10 +3964,10 @@ var require_Document = __commonJS({
3889
3964
  * scalar values from their surrounding node; to disable set `keepScalar` to
3890
3965
  * `true` (collections are always returned intact).
3891
3966
  */
3892
- getIn(path13, keepScalar) {
3893
- if (Collection.isEmptyPath(path13))
3967
+ getIn(path14, keepScalar) {
3968
+ if (Collection.isEmptyPath(path14))
3894
3969
  return !keepScalar && identity.isScalar(this.contents) ? this.contents.value : this.contents;
3895
- return identity.isCollection(this.contents) ? this.contents.getIn(path13, keepScalar) : void 0;
3970
+ return identity.isCollection(this.contents) ? this.contents.getIn(path14, keepScalar) : void 0;
3896
3971
  }
3897
3972
  /**
3898
3973
  * Checks if the document includes a value with the key `key`.
@@ -3903,10 +3978,10 @@ var require_Document = __commonJS({
3903
3978
  /**
3904
3979
  * Checks if the document includes a value at `path`.
3905
3980
  */
3906
- hasIn(path13) {
3907
- if (Collection.isEmptyPath(path13))
3981
+ hasIn(path14) {
3982
+ if (Collection.isEmptyPath(path14))
3908
3983
  return this.contents !== void 0;
3909
- return identity.isCollection(this.contents) ? this.contents.hasIn(path13) : false;
3984
+ return identity.isCollection(this.contents) ? this.contents.hasIn(path14) : false;
3910
3985
  }
3911
3986
  /**
3912
3987
  * Sets a value in this document. For `!!set`, `value` needs to be a
@@ -3923,13 +3998,13 @@ var require_Document = __commonJS({
3923
3998
  * Sets a value in this document. For `!!set`, `value` needs to be a
3924
3999
  * boolean to add/remove the item from the set.
3925
4000
  */
3926
- setIn(path13, value) {
3927
- if (Collection.isEmptyPath(path13)) {
4001
+ setIn(path14, value) {
4002
+ if (Collection.isEmptyPath(path14)) {
3928
4003
  this.contents = value;
3929
4004
  } else if (this.contents == null) {
3930
- this.contents = Collection.collectionFromPath(this.schema, Array.from(path13), value);
4005
+ this.contents = Collection.collectionFromPath(this.schema, Array.from(path14), value);
3931
4006
  } else if (assertCollection(this.contents)) {
3932
- this.contents.setIn(path13, value);
4007
+ this.contents.setIn(path14, value);
3933
4008
  }
3934
4009
  }
3935
4010
  /**
@@ -5009,37 +5084,38 @@ var require_resolve_flow_scalar = __commonJS({
5009
5084
  }
5010
5085
  if (badChar)
5011
5086
  onError(0, "BAD_SCALAR_START", `Plain value cannot start with ${badChar}`);
5012
- return foldLines(source);
5087
+ return unfoldLines(source);
5013
5088
  }
5014
5089
  function singleQuotedValue(source, onError) {
5015
5090
  if (source[source.length - 1] !== "'" || source.length === 1)
5016
5091
  onError(source.length, "MISSING_CHAR", "Missing closing 'quote");
5017
- return foldLines(source.slice(1, -1)).replace(/''/g, "'");
5092
+ return unfoldLines(source.slice(1, -1)).replace(/''/g, "'");
5018
5093
  }
5019
- function foldLines(source) {
5020
- let first, line;
5094
+ function unfoldLines(source) {
5095
+ const line = /(.*?)\r?\n/sy;
5096
+ let match = line.exec(source);
5097
+ if (!match)
5098
+ return source;
5099
+ let trimEnd, trimBoth;
5021
5100
  try {
5022
- first = new RegExp("(.*?)(?<![ ])[ ]*\r?\n", "sy");
5023
- line = new RegExp("[ ]*(.*?)(?:(?<![ ])[ ]*)?\r?\n", "sy");
5101
+ trimEnd = new RegExp("(?<![ ])[ ]+$");
5102
+ trimBoth = new RegExp("^[ ]+|(?<![ ])[ ]+$", "g");
5024
5103
  } catch {
5025
- first = /(.*?)[ \t]*\r?\n/sy;
5026
- line = /[ \t]*(.*?)[ \t]*\r?\n/sy;
5104
+ trimEnd = /[ \t]+$/;
5105
+ trimBoth = /^[ \t]+|[ \t]+$/g;
5027
5106
  }
5028
- let match = first.exec(source);
5029
- if (!match)
5030
- return source;
5031
- let res = match[1];
5107
+ let res = match[1].replace(trimEnd, "");
5032
5108
  let sep6 = " ";
5033
- let pos = first.lastIndex;
5034
- line.lastIndex = pos;
5109
+ let pos = line.lastIndex;
5035
5110
  while (match = line.exec(source)) {
5036
- if (match[1] === "") {
5111
+ const lm = match[1].replace(trimBoth, "");
5112
+ if (lm === "") {
5037
5113
  if (sep6 === "\n")
5038
5114
  res += sep6;
5039
5115
  else
5040
5116
  sep6 = "\n";
5041
5117
  } else {
5042
- res += sep6 + match[1];
5118
+ res += sep6 + lm;
5043
5119
  sep6 = " ";
5044
5120
  }
5045
5121
  pos = line.lastIndex;
@@ -5889,9 +5965,9 @@ var require_cst_visit = __commonJS({
5889
5965
  visit.BREAK = BREAK;
5890
5966
  visit.SKIP = SKIP;
5891
5967
  visit.REMOVE = REMOVE;
5892
- visit.itemAtPath = (cst, path13) => {
5968
+ visit.itemAtPath = (cst, path14) => {
5893
5969
  let item = cst;
5894
- for (const [field, index] of path13) {
5970
+ for (const [field, index] of path14) {
5895
5971
  const tok = item?.[field];
5896
5972
  if (tok && "items" in tok) {
5897
5973
  item = tok.items[index];
@@ -5900,23 +5976,23 @@ var require_cst_visit = __commonJS({
5900
5976
  }
5901
5977
  return item;
5902
5978
  };
5903
- visit.parentCollection = (cst, path13) => {
5904
- const parent = visit.itemAtPath(cst, path13.slice(0, -1));
5905
- const field = path13[path13.length - 1][0];
5979
+ visit.parentCollection = (cst, path14) => {
5980
+ const parent = visit.itemAtPath(cst, path14.slice(0, -1));
5981
+ const field = path14[path14.length - 1][0];
5906
5982
  const coll = parent?.[field];
5907
5983
  if (coll && "items" in coll)
5908
5984
  return coll;
5909
5985
  throw new Error("Parent collection not found");
5910
5986
  };
5911
- function _visit(path13, item, visitor) {
5912
- let ctrl = visitor(item, path13);
5987
+ function _visit(path14, item, visitor) {
5988
+ let ctrl = visitor(item, path14);
5913
5989
  if (typeof ctrl === "symbol")
5914
5990
  return ctrl;
5915
5991
  for (const field of ["key", "value"]) {
5916
5992
  const token = item[field];
5917
5993
  if (token && "items" in token) {
5918
5994
  for (let i = 0; i < token.items.length; ++i) {
5919
- const ci = _visit(Object.freeze(path13.concat([[field, i]])), token.items[i], visitor);
5995
+ const ci = _visit(Object.freeze(path14.concat([[field, i]])), token.items[i], visitor);
5920
5996
  if (typeof ci === "number")
5921
5997
  i = ci - 1;
5922
5998
  else if (ci === BREAK)
@@ -5927,10 +6003,10 @@ var require_cst_visit = __commonJS({
5927
6003
  }
5928
6004
  }
5929
6005
  if (typeof ctrl === "function" && field === "key")
5930
- ctrl = ctrl(item, path13);
6006
+ ctrl = ctrl(item, path14);
5931
6007
  }
5932
6008
  }
5933
- return typeof ctrl === "function" ? ctrl(item, path13) : ctrl;
6009
+ return typeof ctrl === "function" ? ctrl(item, path14) : ctrl;
5934
6010
  }
5935
6011
  exports.visit = visit;
5936
6012
  }
@@ -7232,14 +7308,14 @@ var require_parser = __commonJS({
7232
7308
  case "scalar":
7233
7309
  case "single-quoted-scalar":
7234
7310
  case "double-quoted-scalar": {
7235
- const fs7 = this.flowScalar(this.type);
7311
+ const fs8 = this.flowScalar(this.type);
7236
7312
  if (atNextItem || it.value) {
7237
- map.items.push({ start, key: fs7, sep: [] });
7313
+ map.items.push({ start, key: fs8, sep: [] });
7238
7314
  this.onKeyLine = true;
7239
7315
  } else if (it.sep) {
7240
- this.stack.push(fs7);
7316
+ this.stack.push(fs8);
7241
7317
  } else {
7242
- Object.assign(it, { key: fs7, sep: [] });
7318
+ Object.assign(it, { key: fs8, sep: [] });
7243
7319
  this.onKeyLine = true;
7244
7320
  }
7245
7321
  return;
@@ -7367,13 +7443,13 @@ var require_parser = __commonJS({
7367
7443
  case "scalar":
7368
7444
  case "single-quoted-scalar":
7369
7445
  case "double-quoted-scalar": {
7370
- const fs7 = this.flowScalar(this.type);
7446
+ const fs8 = this.flowScalar(this.type);
7371
7447
  if (!it || it.value)
7372
- fc.items.push({ start: [], key: fs7, sep: [] });
7448
+ fc.items.push({ start: [], key: fs8, sep: [] });
7373
7449
  else if (it.sep)
7374
- this.stack.push(fs7);
7450
+ this.stack.push(fs8);
7375
7451
  else
7376
- Object.assign(it, { key: fs7, sep: [] });
7452
+ Object.assign(it, { key: fs8, sep: [] });
7377
7453
  return;
7378
7454
  }
7379
7455
  case "flow-map-end":
@@ -7630,7 +7706,7 @@ var require_public_api = __commonJS({
7630
7706
  });
7631
7707
 
7632
7708
  // ../../node_modules/yaml/dist/index.js
7633
- var require_dist = __commonJS({
7709
+ var require_dist2 = __commonJS({
7634
7710
  "../../node_modules/yaml/dist/index.js"(exports) {
7635
7711
  "use strict";
7636
7712
  var composer = require_composer();
@@ -7853,7 +7929,7 @@ function getAtPath(obj, dottedKey) {
7853
7929
  }
7854
7930
 
7855
7931
  // ../configuration-core/src/secrets.ts
7856
- var import_dotenv = __toESM(require_main(), 1);
7932
+ var import_dotenv = __toESM(require_dist(), 1);
7857
7933
  import * as fs3 from "node:fs";
7858
7934
  import * as path4 from "node:path";
7859
7935
 
@@ -7999,7 +8075,7 @@ var CONFIG_SCHEMA = [
7999
8075
  // nominal here — the project scope of a global-only key is never read.
8000
8076
  {
8001
8077
  key: "scripts.maxTimeoutMs",
8002
- description: `Upper bound, in milliseconds, on the time limit a flow \`script\` step may ask for (default 300000 \u2014 five minutes). Bounds how long one script can occupy the host. Values below ${MIN_SCRIPT_TIMEOUT_MS} ms are refused: the step starts a Node process before the script runs, so a smaller ceiling ends a script that did nothing wrong.`,
8078
+ description: `Upper bound, in milliseconds, on the time limit an e2e test \`script\` step may ask for (default 300000 \u2014 five minutes). Bounds how long one script can occupy the host. Values below ${MIN_SCRIPT_TIMEOUT_MS} ms are refused: the step starts a Node process before the script runs, so a smaller ceiling ends a script that did nothing wrong.`,
8003
8079
  scopes: ["global"],
8004
8080
  parse: (raw) => {
8005
8081
  const value = asPositiveInteger(raw);
@@ -8012,7 +8088,7 @@ var CONFIG_SCHEMA = [
8012
8088
  },
8013
8089
  {
8014
8090
  key: "scripts.heapLimitMb",
8015
- description: `Old-space heap limit, in MiB, given to each flow \`script\` process (default 512). Values below ${MIN_SCRIPT_HEAP_LIMIT_MB} MiB are refused: that is already below what importing a real npm dependency needs, and under about 5 MiB the process dies inside V8's own startup before any script runs.`,
8091
+ description: `Old-space heap limit, in MiB, given to each e2e test \`script\` process (default 512). Values below ${MIN_SCRIPT_HEAP_LIMIT_MB} MiB are refused: that is already below what importing a real npm dependency needs, and under about 5 MiB the process dies inside V8's own startup before any script runs.`,
8016
8092
  scopes: ["global"],
8017
8093
  parse: (raw) => {
8018
8094
  const value = asPositiveInteger(raw);
@@ -8097,7 +8173,7 @@ function generateToken() {
8097
8173
  return randomBytes(AUTH_TOKEN_BYTES).toString("hex");
8098
8174
  }
8099
8175
  function findFreePort() {
8100
- return new Promise((resolve8, reject) => {
8176
+ return new Promise((resolve9, reject) => {
8101
8177
  const srv = net.createServer();
8102
8178
  srv.listen(0, "127.0.0.1", () => {
8103
8179
  const addr = srv.address();
@@ -8108,7 +8184,7 @@ function findFreePort() {
8108
8184
  const port = addr.port;
8109
8185
  srv.close((err) => {
8110
8186
  if (err) reject(err);
8111
- else resolve8(port);
8187
+ else resolve9(port);
8112
8188
  });
8113
8189
  });
8114
8190
  srv.on("error", reject);
@@ -8206,7 +8282,7 @@ function killSpawnedChild(child, pid) {
8206
8282
  }
8207
8283
  }
8208
8284
  function spawnToolsServer(paths, port, options = {}) {
8209
- return new Promise((resolve8, reject) => {
8285
+ return new Promise((resolve9, reject) => {
8210
8286
  let logFd;
8211
8287
  try {
8212
8288
  fs4.mkdirSync(STATE_DIR, { recursive: true });
@@ -8252,7 +8328,7 @@ function spawnToolsServer(paths, port, options = {}) {
8252
8328
  rl.close();
8253
8329
  child.stdout?.resume();
8254
8330
  child.stdout?.unref?.();
8255
- settle(() => resolve8({ port: actualPort, pid }));
8331
+ settle(() => resolve9({ port: actualPort, pid }));
8256
8332
  }
8257
8333
  });
8258
8334
  child.on("error", (err) => {
@@ -8557,10 +8633,11 @@ async function ensureToolsServer(paths) {
8557
8633
  }
8558
8634
 
8559
8635
  // ../argent-tools-client/src/tools-client.ts
8560
- import * as path11 from "node:path";
8636
+ import * as path12 from "node:path";
8561
8637
 
8562
8638
  // ../registry/src/types.ts
8563
8639
  var LINKED_CALL_HEADER = "x-argent-linked";
8640
+ var E2E_DIR_CLIENT_HEADER = "x-argent-e2e-dir";
8564
8641
 
8565
8642
  // ../registry/src/artifacts.ts
8566
8643
  import { stat } from "node:fs/promises";
@@ -8598,19 +8675,95 @@ function toolStepFiles(specs, args) {
8598
8675
  }
8599
8676
  return files;
8600
8677
  }
8601
- function isClientFileArgument({ spec, path: path13 }) {
8602
- return spec.kind === "file" && spec.path === `\${${spec.target}}` && path13.startsWith("/") && hasToolFileExtension(path13);
8678
+ function isClientFileArgument({ spec, path: path14 }) {
8679
+ return spec.kind === "file" && spec.path === `\${${spec.target}}` && path14.startsWith("/") && hasToolFileExtension(path14);
8603
8680
  }
8604
8681
 
8605
8682
  // ../registry/src/flow-file-refs.ts
8683
+ import * as fs6 from "node:fs/promises";
8684
+ import * as path8 from "node:path";
8685
+
8686
+ // ../registry/src/e2e-dirs.ts
8606
8687
  import * as fs5 from "node:fs/promises";
8607
8688
  import * as path7 from "node:path";
8689
+ var E2E_DIR = path7.join(".argent", "e2e");
8690
+ var LEGACY_E2E_DIRS = Object.freeze([path7.join(".argent", "flows")]);
8691
+ var E2E_DIRS = Object.freeze([E2E_DIR, ...LEGACY_E2E_DIRS]);
8692
+ function e2eDirFor(projectRoot) {
8693
+ return path7.join(projectRoot, E2E_DIR);
8694
+ }
8695
+ function e2eDirsFor(projectRoot) {
8696
+ return E2E_DIRS.map((dir) => path7.join(projectRoot, dir));
8697
+ }
8698
+ function e2eFileCandidates(projectRoot, name) {
8699
+ return e2eDirsFor(projectRoot).map((dir) => path7.join(dir, `${name}.yaml`));
8700
+ }
8701
+ async function exists(file) {
8702
+ return fs5.stat(file).then(
8703
+ () => true,
8704
+ () => false
8705
+ );
8706
+ }
8707
+ async function pickE2eFile(candidates) {
8708
+ for (let i = 0; i < candidates.length; i++) {
8709
+ if (!await exists(candidates[i])) continue;
8710
+ let shadowed;
8711
+ for (const later of candidates.slice(i + 1)) {
8712
+ if (await exists(later)) {
8713
+ shadowed = later;
8714
+ break;
8715
+ }
8716
+ }
8717
+ return {
8718
+ path: candidates[i],
8719
+ exists: true,
8720
+ legacy: i > 0,
8721
+ ...shadowed === void 0 ? {} : { shadowed }
8722
+ };
8723
+ }
8724
+ return { path: candidates[0], exists: false, legacy: false };
8725
+ }
8726
+ function e2eShadowWarning(used, shadowed) {
8727
+ return `${shadowed} is not used: ${used} has the same name and is read first.`;
8728
+ }
8729
+ var E2E_DIR_NAMES = E2E_DIRS.map((dir) => path7.basename(dir));
8730
+ function e2eDirProject(dir) {
8731
+ const trimmed = dir.length > 1 ? dir.replace(/[\\/]+$/, "") : dir;
8732
+ const argent = path7.dirname(trimmed);
8733
+ if (!E2E_DIR_NAMES.includes(path7.basename(trimmed)) || path7.basename(argent) !== ".argent") {
8734
+ return null;
8735
+ }
8736
+ return path7.dirname(argent);
8737
+ }
8738
+ function e2eRunFallbackDirs(anchorDir, target) {
8739
+ if (target.includes("/") || target.includes("\\")) return [];
8740
+ const project = e2eDirProject(anchorDir);
8741
+ if (project === null) return [];
8742
+ const anchor = path7.resolve(anchorDir);
8743
+ return e2eDirsFor(project).filter((dir) => path7.resolve(dir) !== anchor);
8744
+ }
8745
+
8746
+ // ../registry/src/tool-ids.ts
8747
+ var TOOL_ID_ALIASES = Object.freeze({
8748
+ "flow-start-recording": "e2e-start-recording",
8749
+ "flow-add-step": "e2e-add-step",
8750
+ "flow-add-echo": "e2e-add-echo",
8751
+ "flow-add-script": "e2e-add-script",
8752
+ "flow-finish-recording": "e2e-finish-recording",
8753
+ "flow-read-prerequisite": "e2e-read-prerequisite",
8754
+ "flow-execute": "e2e-execute"
8755
+ });
8756
+ function canonicalToolId(id) {
8757
+ return Object.hasOwn(TOOL_ID_ALIASES, id) ? TOOL_ID_ALIASES[id] : id;
8758
+ }
8759
+
8760
+ // ../registry/src/flow-file-refs.ts
8608
8761
  async function canonicalFlowPath(p) {
8609
8762
  try {
8610
- return await fs5.realpath(p);
8763
+ return await fs6.realpath(p);
8611
8764
  } catch {
8612
8765
  try {
8613
- return path7.join(await fs5.realpath(path7.dirname(p)), path7.basename(p));
8766
+ return path8.join(await fs6.realpath(path8.dirname(p)), path8.basename(p));
8614
8767
  } catch {
8615
8768
  return p;
8616
8769
  }
@@ -8619,7 +8772,7 @@ async function canonicalFlowPath(p) {
8619
8772
  function completeRunExtension(value) {
8620
8773
  if (value.endsWith(".yaml")) return value;
8621
8774
  const candidate = `${value}.yaml`;
8622
- return FLOW_FILE_NAME_PATTERN.test(path7.posix.basename(candidate)) ? candidate : value;
8775
+ return FLOW_FILE_NAME_PATTERN.test(path8.posix.basename(candidate)) ? candidate : value;
8623
8776
  }
8624
8777
  var MAX_RUN_DEPTH = 20;
8625
8778
  var MAX_BLOCK_NESTING = 64;
@@ -8638,16 +8791,16 @@ function collectFlowRequests(doc) {
8638
8791
  for (const step of steps) {
8639
8792
  if (!isRecord(step)) continue;
8640
8793
  const run = step.run;
8641
- if (typeof run === "string" && !run.includes("\\") && !path7.posix.isAbsolute(run) && !/^[A-Za-z]:/.test(run)) {
8794
+ if (typeof run === "string" && !run.includes("\\") && !path8.posix.isAbsolute(run) && !/^[A-Za-z]:/.test(run)) {
8642
8795
  const target = completeRunExtension(run);
8643
- if (FLOW_FILE_NAME_PATTERN.test(path7.posix.basename(target))) runTargets.add(target);
8796
+ if (FLOW_FILE_NAME_PATTERN.test(path8.posix.basename(target))) runTargets.add(target);
8644
8797
  }
8645
8798
  const snapshot = isRecord(step.snapshot) ? step.snapshot.name : step.snapshot;
8646
8799
  if (typeof snapshot === "string" && FLOW_NAME_PATTERN.test(snapshot)) snapshots.add(snapshot);
8647
8800
  if (typeof step.tool === "string") {
8648
8801
  const args = isRecord(step.args) ? step.args : {};
8649
8802
  toolSteps.push({ tool: step.tool, args });
8650
- const target = step.tool === "flow-execute" ? nestedFlowTarget(args) : void 0;
8803
+ const target = canonicalToolId(step.tool) === "e2e-execute" ? nestedFlowTarget(args) : void 0;
8651
8804
  if (target !== void 0) nested.push({ target, args });
8652
8805
  }
8653
8806
  visit(step.steps, depth + 1);
@@ -8657,14 +8810,14 @@ function collectFlowRequests(doc) {
8657
8810
  return { runTargets: [...runTargets], snapshots: [...snapshots], toolSteps, nested };
8658
8811
  }
8659
8812
  function baselineKeyFor(canonicalPath, flowName) {
8660
- const stem = path7.basename(canonicalPath, ".yaml");
8813
+ const stem = path8.basename(canonicalPath, ".yaml");
8661
8814
  return FLOW_NAME_PATTERN.test(stem) ? stem : flowName;
8662
8815
  }
8663
8816
  function flowMemberKey(anchorDir, target) {
8664
8817
  return `${anchorDir}\0${target}`;
8665
8818
  }
8666
8819
  async function classifyOnDiskSpelling(dir, base, addressable = FLOW_FILE_NAME_PATTERN) {
8667
- const entries = await fs5.readdir(dir).catch(() => null);
8820
+ const entries = await fs6.readdir(dir).catch(() => null);
8668
8821
  if (entries === null || entries.includes(base)) return { state: "listed" };
8669
8822
  const actual = entries.find((entry) => entry.toLowerCase() === base.toLowerCase());
8670
8823
  if (actual === void 0) return { state: "absent" };
@@ -8676,19 +8829,15 @@ function nestedFlowTarget(args) {
8676
8829
  if (flowPath === void 0) {
8677
8830
  if (typeof name !== "string" || !FLOW_NAME_PATTERN.test(name)) return void 0;
8678
8831
  if (!isResolvedAbsolute(projectRoot)) return void 0;
8679
- return {
8680
- kind: "name",
8681
- projectRoot,
8682
- name,
8683
- path: path7.join(projectRoot, ".argent", "flows", `${name}.yaml`)
8684
- };
8832
+ const paths = e2eFileCandidates(projectRoot, name);
8833
+ return { kind: "name", projectRoot, name, path: paths[0], paths };
8685
8834
  }
8686
8835
  if (name !== void 0 || !isResolvedAbsolute(flowPath)) return void 0;
8687
- if (!FLOW_FILE_NAME_PATTERN.test(path7.basename(flowPath))) return void 0;
8836
+ if (!FLOW_FILE_NAME_PATTERN.test(path8.basename(flowPath))) return void 0;
8688
8837
  return { kind: "flow_path", path: flowPath };
8689
8838
  }
8690
8839
  function isResolvedAbsolute(value) {
8691
- return typeof value === "string" && path7.isAbsolute(value) && !value.split(/[\\/]+/).includes("..");
8840
+ return typeof value === "string" && path8.isAbsolute(value) && !value.split(/[\\/]+/).includes("..");
8692
8841
  }
8693
8842
 
8694
8843
  // ../registry/src/failure-codes.ts
@@ -8808,6 +8957,11 @@ var FAILURE_CODES = {
8808
8957
  // a device that is not foldable, no hinge route, a remote simulator.
8809
8958
  IOS_FOLD_FAILED: "IOS_FOLD_FAILED",
8810
8959
  IOS_FOLD_UNSUPPORTED: "IOS_FOLD_UNSUPPORTED",
8960
+ // The hinge of a foldable Android emulator: the console refused the move or
8961
+ // the guest never committed the state vs. nothing to fold — a phone profile,
8962
+ // a physical device.
8963
+ ANDROID_FOLD_FAILED: "ANDROID_FOLD_FAILED",
8964
+ ANDROID_FOLD_UNSUPPORTED: "ANDROID_FOLD_UNSUPPORTED",
8811
8965
  PASTE_CLIPBOARD_SET_FAILED: "PASTE_CLIPBOARD_SET_FAILED",
8812
8966
  PASTE_CLIPBOARD_UNSUPPORTED: "PASTE_CLIPBOARD_UNSUPPORTED",
8813
8967
  SETTINGS_PERMISSION_UNSUPPORTED: "SETTINGS_PERMISSION_UNSUPPORTED",
@@ -9013,9 +9167,9 @@ var FAILURE_SPAWN_CODE_SET = new Set(FAILURE_SPAWN_CODES);
9013
9167
  import { randomUUID as randomUUID3 } from "node:crypto";
9014
9168
  import { AsyncLocalStorage } from "node:async_hooks";
9015
9169
  var resolvedDuringInvocation = new AsyncLocalStorage();
9016
- function valueAtPath(root, path13) {
9170
+ function valueAtPath(root, path14) {
9017
9171
  let current = root;
9018
- for (const key of path13) {
9172
+ for (const key of path14) {
9019
9173
  if (current === null || typeof current !== "object") return void 0;
9020
9174
  if (!Object.hasOwn(current, key)) return void 0;
9021
9175
  current = current[key];
@@ -9073,11 +9227,11 @@ function describeParamIssues(error, params) {
9073
9227
  }
9074
9228
 
9075
9229
  // ../argent-tools-client/src/link-config.ts
9076
- import * as path8 from "node:path";
9230
+ import * as path9 from "node:path";
9077
9231
  import { homedir as homedir4 } from "node:os";
9078
9232
  import { mkdir as mkdir2, writeFile as writeFile2, readFile as readFile2, unlink as unlink2, chmod as chmod2 } from "node:fs/promises";
9079
- var LINK_DIR = path8.join(homedir4(), ".argent");
9080
- var LINK_FILE = path8.join(LINK_DIR, "link.json");
9233
+ var LINK_DIR = path9.join(homedir4(), ".argent");
9234
+ var LINK_FILE = path9.join(LINK_DIR, "link.json");
9081
9235
  async function readLinkConfig() {
9082
9236
  try {
9083
9237
  const raw = await readFile2(LINK_FILE, "utf8");
@@ -9126,22 +9280,22 @@ import {
9126
9280
  realpath as realpath2,
9127
9281
  rename as rename2,
9128
9282
  rm as rm2,
9129
- stat as stat2,
9283
+ stat as stat3,
9130
9284
  writeFile as writeFile3
9131
9285
  } from "node:fs/promises";
9132
9286
  import { constants, tmpdir } from "node:os";
9133
- import * as path9 from "node:path";
9287
+ import * as path10 from "node:path";
9134
9288
 
9135
9289
  // ../archive/src/index.ts
9136
9290
  import { execFile } from "node:child_process";
9137
9291
  import { rm, readdir as readdir3 } from "node:fs/promises";
9138
- import { basename as basename3, dirname as dirname4, join as join8, posix as posix2, resolve as resolve5, sep as sep2 } from "node:path";
9292
+ import { basename as basename4, dirname as dirname5, join as join9, posix as posix2, resolve as resolve6, sep as sep2 } from "node:path";
9139
9293
  import { promisify } from "node:util";
9140
9294
  var execFileAsync = promisify(execFile);
9141
9295
  var ArchiveError = class extends Error {
9142
9296
  };
9143
9297
  function createTarGzArgs(sourcePath, target) {
9144
- return ["-czf", target, "-C", dirname4(sourcePath), basename3(sourcePath)];
9298
+ return ["-czf", target, "-C", dirname5(sourcePath), basename4(sourcePath)];
9145
9299
  }
9146
9300
  async function createTarGzFile(sourcePath, tarPath) {
9147
9301
  try {
@@ -9163,8 +9317,8 @@ function isSafeTarMember(memberPath, destDir) {
9163
9317
  if (relative2 === ".." || relative2.startsWith("../") || relative2.split("/").includes("..")) {
9164
9318
  return false;
9165
9319
  }
9166
- const root = resolve5(destDir);
9167
- const resolved = resolve5(destDir, relative2);
9320
+ const root = resolve6(destDir);
9321
+ const resolved = resolve6(destDir, relative2);
9168
9322
  return resolved === root || resolved.startsWith(root + sep2);
9169
9323
  }
9170
9324
  async function listTarMembers(tarPath) {
@@ -9218,7 +9372,7 @@ async function assertSafeArchive(tarPath, destDir) {
9218
9372
  async function resolveMember(destDir, expectedName) {
9219
9373
  const entries = await readdir3(destDir);
9220
9374
  if (entries.includes(expectedName)) {
9221
- return join8(destDir, expectedName);
9375
+ return join9(destDir, expectedName);
9222
9376
  }
9223
9377
  const real = entries.filter((e) => !e.startsWith("._"));
9224
9378
  if (real.length !== 1) {
@@ -9226,7 +9380,7 @@ async function resolveMember(destDir, expectedName) {
9226
9380
  `Could not identify the extracted member (expected "${expectedName}", found ${real.length} entries).`
9227
9381
  );
9228
9382
  }
9229
- return join8(destDir, real[0]);
9383
+ return join9(destDir, real[0]);
9230
9384
  }
9231
9385
  async function safeExtractTarGz(tarPath, destDir, expectedName) {
9232
9386
  await assertSafeArchive(tarPath, destDir);
@@ -9264,6 +9418,16 @@ function interpolatePath(template, args) {
9264
9418
  });
9265
9419
  return missing ? null : out;
9266
9420
  }
9421
+ async function specPath(spec, args) {
9422
+ if (spec.kind !== "file" || !spec.paths?.length) return interpolatePath(spec.path, args);
9423
+ const candidates = [];
9424
+ for (const template of spec.paths) {
9425
+ const filled = interpolatePath(template, args);
9426
+ if (filled === null) return null;
9427
+ candidates.push(filled);
9428
+ }
9429
+ return (await pickE2eFile(candidates)).path;
9430
+ }
9267
9431
  var pendingArchives = /* @__PURE__ */ new Set();
9268
9432
  var ARCHIVE_SIGNALS = ["SIGINT", "SIGTERM", "SIGHUP"];
9269
9433
  function removePendingArchives() {
@@ -9299,9 +9463,9 @@ function untrackArchive(archive) {
9299
9463
  process.removeListener("exit", removePendingArchives);
9300
9464
  }
9301
9465
  function sha256File(filePath) {
9302
- return new Promise((resolve8, reject) => {
9466
+ return new Promise((resolve9, reject) => {
9303
9467
  const hash = createHash2("sha256");
9304
- createReadStream(filePath).on("data", (chunk) => hash.update(chunk)).on("end", () => resolve8(hash.digest("hex"))).on("error", reject);
9468
+ createReadStream(filePath).on("data", (chunk) => hash.update(chunk)).on("end", () => resolve9(hash.digest("hex"))).on("error", reject);
9305
9469
  });
9306
9470
  }
9307
9471
  function toolServerError(text) {
@@ -9328,7 +9492,7 @@ function uploadFailure(url, res, text, bytes) {
9328
9492
  });
9329
9493
  }
9330
9494
  async function uploadTar(tarPath, endpoint, signal) {
9331
- const { size } = await stat2(tarPath);
9495
+ const { size } = await stat3(tarPath);
9332
9496
  const init = {
9333
9497
  method: "POST",
9334
9498
  headers: {
@@ -9352,7 +9516,7 @@ async function uploadTar(tarPath, endpoint, signal) {
9352
9516
  return json.uploadId;
9353
9517
  }
9354
9518
  async function uploadFile(sourcePath, endpoint, signal) {
9355
- const tarPath = path9.join(tmpdir(), `argent-upload-${randomUUID4()}.tar.gz`);
9519
+ const tarPath = path10.join(tmpdir(), `argent-upload-${randomUUID4()}.tar.gz`);
9356
9520
  trackArchive(tarPath);
9357
9521
  try {
9358
9522
  await createTarGzFile(await realpath2(sourcePath), tarPath);
@@ -9367,7 +9531,7 @@ async function uploadFile(sourcePath, endpoint, signal) {
9367
9531
  async function readFileInputWire(filePath, opts) {
9368
9532
  let st;
9369
9533
  try {
9370
- st = await stat2(filePath);
9534
+ st = await stat3(filePath);
9371
9535
  } catch {
9372
9536
  return null;
9373
9537
  }
@@ -9395,7 +9559,7 @@ async function prepareFileInputs(specs, args, opts) {
9395
9559
  for (const spec of specs) {
9396
9560
  if (spec.skipWhenSet && record[spec.skipWhenSet] !== void 0) continue;
9397
9561
  if (spec.target in record && typeof record[spec.target] !== "string") continue;
9398
- const filePath = interpolatePath(spec.path, record);
9562
+ const filePath = await specPath(spec, record);
9399
9563
  if (filePath === null) continue;
9400
9564
  if (spec.target in record && record[spec.target] !== filePath) continue;
9401
9565
  const wire = { [FILE_INPUT_MARKER2]: true, path: filePath };
@@ -9413,13 +9577,13 @@ async function prepareFileInputs(specs, args, opts) {
9413
9577
  wire.members = await opts.collectStepMembers(record, opts);
9414
9578
  }
9415
9579
  if (spec.kind === "tar-upload") {
9416
- const st = await stat2(filePath).catch(() => null);
9580
+ const st = await stat3(filePath).catch(() => null);
9417
9581
  if (st) {
9418
9582
  wire.size = st.size;
9419
9583
  wire.mtimeMs = st.mtimeMs;
9420
9584
  }
9421
9585
  if (opts.uploadEndpoint && st) {
9422
- process.stderr.write(`Uploading ${path9.basename(filePath)} to the remote tool-server...
9586
+ process.stderr.write(`Uploading ${path10.basename(filePath)} to the remote tool-server...
9423
9587
  `);
9424
9588
  Object.assign(wire, await uploadFile(filePath, opts.uploadEndpoint, opts.signal));
9425
9589
  }
@@ -9430,18 +9594,18 @@ async function prepareFileInputs(specs, args, opts) {
9430
9594
  return out ?? args;
9431
9595
  }
9432
9596
  function isAllowedClientFilePath(p) {
9433
- if (!path9.isAbsolute(p)) return false;
9597
+ if (!path10.isAbsolute(p)) return false;
9434
9598
  const segments = p.split(/[\\/]+/);
9435
9599
  if (segments.includes("..")) return false;
9436
9600
  const file = segments[segments.length - 1] ?? "";
9437
9601
  if (!FLOW_FILE_NAME_PATTERN.test(file)) return false;
9438
- return segments[segments.length - 3] === ".argent" && segments[segments.length - 2] === "flows";
9602
+ return e2eDirProject(segments.slice(0, -1).join("/")) !== null;
9439
9603
  }
9440
9604
  function isClientFileDirective2(value) {
9441
9605
  return !!value && typeof value === "object" && value[CLIENT_FILE_MARKER2] === true && typeof value.path === "string" && typeof value.content === "string";
9442
9606
  }
9443
9607
  async function replaceFile(target, bytes, mode) {
9444
- const temp = path9.join(path9.dirname(target), `.baseline-${randomUUID4()}.tmp`);
9608
+ const temp = path10.join(path10.dirname(target), `.baseline-${randomUUID4()}.tmp`);
9445
9609
  try {
9446
9610
  await writeFile3(temp, bytes, { flag: "wx" });
9447
9611
  if (mode !== void 0) await chmod3(temp, mode & 511);
@@ -9452,27 +9616,27 @@ async function replaceFile(target, bytes, mode) {
9452
9616
  }
9453
9617
  }
9454
9618
  async function writeBaselineFile(file, bytes, allowedDirs) {
9455
- if (!path9.isAbsolute(file) || path9.normalize(file) !== file || file.split(/[\\/]/).includes("..") || !file.endsWith(".png") || !allowedDirs.includes(path9.dirname(file))) {
9619
+ if (!path10.isAbsolute(file) || path10.normalize(file) !== file || file.split(/[\\/]/).includes("..") || !file.endsWith(".png") || !allowedDirs.includes(path10.dirname(file))) {
9456
9620
  return allowedDirs.length === 0 ? "this call writes no baselines" : `${file} is not a baseline of this call (${allowedDirs.map((d) => `${d}/<name>.png`).join(", ")})`;
9457
9621
  }
9458
9622
  if (bytes.length > MAX_CONTENT_BYTES) {
9459
9623
  return `${file}: the baseline is larger than the 32 MiB cap on a file this client writes`;
9460
9624
  }
9461
- const dir = path9.dirname(file);
9625
+ const dir = path10.dirname(file);
9462
9626
  await mkdir3(dir, { recursive: true });
9463
9627
  const link = await lstat(file).catch(() => null);
9464
9628
  const real = link === null ? null : await realpath2(file).catch(() => null);
9465
9629
  if (link !== null && real === null) return `${file} is a symbolic link to a missing file`;
9466
9630
  if (real !== null) {
9467
9631
  if (!real.endsWith(".png")) return `${file} links to a file that is not a PNG file`;
9468
- if (path9.dirname(real) !== await realpath2(dir)) {
9632
+ if (path10.dirname(real) !== await realpath2(dir)) {
9469
9633
  return `${file} links outside its baseline directory`;
9470
9634
  }
9471
9635
  }
9472
- const existing = real === null ? null : await stat2(real);
9636
+ const existing = real === null ? null : await stat3(real);
9473
9637
  if (existing !== null && !existing.isFile()) return `${file} is not a regular file`;
9474
9638
  await replaceFile(
9475
- real ?? path9.join(await realpath2(dir), path9.basename(file)),
9639
+ real ?? path10.join(await realpath2(dir), path10.basename(file)),
9476
9640
  bytes,
9477
9641
  existing?.mode
9478
9642
  );
@@ -9498,7 +9662,7 @@ async function applyClientFileDirectives(result, opts = {}) {
9498
9662
  if (isClientFileDirective2(value)) {
9499
9663
  if (!isAllowedClientFilePath(value.path)) return null;
9500
9664
  try {
9501
- await mkdir3(path9.dirname(value.path), { recursive: true });
9665
+ await mkdir3(path10.dirname(value.path), { recursive: true });
9502
9666
  await writeFile3(value.path, value.content, "utf8");
9503
9667
  written.push(value.path);
9504
9668
  return value.path;
@@ -9525,13 +9689,15 @@ async function applyClientFileDirectives(result, opts = {}) {
9525
9689
  }
9526
9690
 
9527
9691
  // ../argent-tools-client/src/flow-files.ts
9528
- var import_yaml = __toESM(require_dist(), 1);
9529
- import { readdir as readdir4, readFile as readFile4, realpath as realpath3, stat as stat3 } from "node:fs/promises";
9530
- import * as path10 from "node:path";
9692
+ var import_yaml = __toESM(require_dist2(), 1);
9693
+ import { readdir as readdir4, readFile as readFile4, realpath as realpath3, stat as stat4 } from "node:fs/promises";
9694
+ import * as path11 from "node:path";
9531
9695
  var INLINE_MEMBERS_BYTES = 256 * 1024;
9532
- var FLOW_FILES_LOG_ENV = "ARGENT_FLOW_FILES_LOG";
9696
+ function filesLogEnabled() {
9697
+ return (process.env.ARGENT_E2E_FILES_LOG ?? process.env.ARGENT_FLOW_FILES_LOG) === "1";
9698
+ }
9533
9699
  function isWithin(inner, outer) {
9534
- return inner === outer || inner.startsWith(outer.endsWith(path10.sep) ? outer : outer + path10.sep);
9700
+ return inner === outer || inner.startsWith(outer.endsWith(path11.sep) ? outer : outer + path11.sep);
9535
9701
  }
9536
9702
  function printable(text) {
9537
9703
  return [...text].map(
@@ -9539,23 +9705,21 @@ function printable(text) {
9539
9705
  ).join("");
9540
9706
  }
9541
9707
  function isResolvedAbsolute2(value) {
9542
- return typeof value === "string" && path10.isAbsolute(value) && !value.split(/[\\/]+/).includes("..");
9708
+ return typeof value === "string" && path11.isAbsolute(value) && !value.split(/[\\/]+/).includes("..");
9543
9709
  }
9544
9710
  function namesValidFlow(args) {
9545
9711
  const { project_root, flow_path, name } = args;
9546
9712
  if (!isResolvedAbsolute2(project_root)) return false;
9547
9713
  if (name === void 0) {
9548
- return isResolvedAbsolute2(flow_path) && FLOW_FILE_NAME_PATTERN.test(path10.basename(flow_path));
9714
+ return isResolvedAbsolute2(flow_path) && FLOW_FILE_NAME_PATTERN.test(path11.basename(flow_path));
9549
9715
  }
9550
9716
  return flow_path === void 0 && typeof name === "string" && FLOW_NAME_PATTERN.test(name);
9551
9717
  }
9552
9718
  function savedFlowProject(file) {
9553
- if (!path10.isAbsolute(file)) return null;
9554
- const parts = file.split(path10.sep);
9555
- for (let i = parts.length - 3; i >= 0; i--) {
9556
- if (parts[i] === ".argent" && parts[i + 1] === "flows") {
9557
- return parts.slice(0, i).join(path10.sep) || path10.sep;
9558
- }
9719
+ if (!path11.isAbsolute(file)) return null;
9720
+ for (let dir = path11.dirname(file); dir !== path11.dirname(dir); dir = path11.dirname(dir)) {
9721
+ const project = e2eDirProject(dir);
9722
+ if (project !== null) return project;
9559
9723
  }
9560
9724
  return null;
9561
9725
  }
@@ -9568,11 +9732,11 @@ async function landing(spelled) {
9568
9732
  const canonical = await canonicalFlowPath(spelled);
9569
9733
  let at = spelled;
9570
9734
  for (; ; ) {
9571
- const parent = path10.dirname(at);
9735
+ const parent = path11.dirname(at);
9572
9736
  if (parent === at) return { canonical, fence: spelled, ...failure };
9573
9737
  const real = await realpath3(parent).catch(() => null);
9574
9738
  if (real !== null) {
9575
- return { canonical, fence: path10.join(real, path10.basename(at)), ...failure };
9739
+ return { canonical, fence: path11.join(real, path11.basename(at)), ...failure };
9576
9740
  }
9577
9741
  at = parent;
9578
9742
  }
@@ -9580,10 +9744,10 @@ async function landing(spelled) {
9580
9744
  }
9581
9745
  async function closureRoots(rootPath, rootCanonical, projectRoot) {
9582
9746
  const candidates = [];
9583
- if (typeof projectRoot === "string" && path10.isAbsolute(projectRoot)) {
9584
- candidates.push(projectRoot, path10.join(projectRoot, ".argent", "flows"));
9747
+ if (typeof projectRoot === "string" && path11.isAbsolute(projectRoot)) {
9748
+ candidates.push(projectRoot, ...e2eDirsFor(projectRoot));
9585
9749
  }
9586
- candidates.push(path10.dirname(rootPath), path10.dirname(rootCanonical));
9750
+ candidates.push(path11.dirname(rootPath), path11.dirname(rootCanonical));
9587
9751
  for (const file of [rootPath, rootCanonical]) {
9588
9752
  const project = savedFlowProject(file);
9589
9753
  if (project !== null) candidates.push(project);
@@ -9596,11 +9760,11 @@ async function closureRoots(rootPath, rootCanonical, projectRoot) {
9596
9760
  return real.filter((root) => !real.some((other) => other !== root && isWithin(root, other)));
9597
9761
  }
9598
9762
  async function readFlowMember(anchorDir, target, roots, budget, opts) {
9599
- const spelled = anchorDir + path10.sep + target;
9763
+ const spelled = anchorDir + path11.sep + target;
9600
9764
  const { canonical, fence, missing, error } = await landing(spelled);
9601
9765
  const spelling = await classifyOnDiskSpelling(
9602
- path10.dirname(spelled),
9603
- path10.posix.basename(target),
9766
+ path11.dirname(spelled),
9767
+ path11.posix.basename(target),
9604
9768
  FLOW_FILE_NAME_PATTERN
9605
9769
  );
9606
9770
  const member = {
@@ -9619,13 +9783,13 @@ async function readFlowMember(anchorDir, target, roots, budget, opts) {
9619
9783
  }
9620
9784
  if (error !== void 0) return refuse(error);
9621
9785
  if (missing) return { member: { ...member, state: "missing" }, sent: "missing" };
9622
- const st = await stat3(canonical).catch((err) => err);
9786
+ const st = await stat4(canonical).catch((err) => err);
9623
9787
  if (st instanceof Error) {
9624
9788
  if (st.code !== "ENOENT") return refuse(st.message);
9625
9789
  return { member: { ...member, state: "missing" }, sent: "missing" };
9626
9790
  }
9627
9791
  if (st.isDirectory()) return refuse("EISDIR: illegal operation on a directory, read");
9628
- if (!/\.ya?ml$/i.test(path10.basename(canonical))) {
9792
+ if (!/\.ya?ml$/i.test(path11.basename(canonical))) {
9629
9793
  return refuse(`${target} links to a file that is not a YAML file`);
9630
9794
  }
9631
9795
  const sent = await sendBytes(member, canonical, budget, opts);
@@ -9644,7 +9808,7 @@ async function readToolMember(file, roots, budget, opts) {
9644
9808
  if (!hasToolFileExtension(canonical)) {
9645
9809
  return refuse(`${file} links to a file that is not one of ${TOOL_FILE_EXTENSIONS.join(", ")}`);
9646
9810
  }
9647
- const st = await stat3(canonical).catch((err) => err);
9811
+ const st = await stat4(canonical).catch((err) => err);
9648
9812
  if (st instanceof Error) {
9649
9813
  if (st.code === "ENOENT" || st.code === "ENOTDIR") {
9650
9814
  return { member: { ...member, state: "missing" }, sent: "missing" };
@@ -9668,7 +9832,7 @@ async function baselineEntry(file, roots, forWrite) {
9668
9832
  };
9669
9833
  }
9670
9834
  if (error !== void 0) return { state: "refused", error };
9671
- const st = await stat3(canonical).catch((err) => err);
9835
+ const st = await stat4(canonical).catch((err) => err);
9672
9836
  if (st instanceof Error) {
9673
9837
  if (st.code !== "ENOENT") return { state: "refused", error: st.message };
9674
9838
  return forWrite ? { state: "refused", error: `${file} is a symbolic link to a missing file` } : { state: "missing" };
@@ -9718,7 +9882,7 @@ function memberCollector(roots, opts) {
9718
9882
  const runs = /* @__PURE__ */ new Set();
9719
9883
  const baselineDirs = /* @__PURE__ */ new Map();
9720
9884
  const budget = { inline: 0 };
9721
- const logging = process.env[FLOW_FILES_LOG_ENV] === "1";
9885
+ const logging = filesLogEnabled();
9722
9886
  const log = opts.log ?? ((line) => void process.stderr.write(`${line}
9723
9887
  `));
9724
9888
  const emit = (member, sent) => {
@@ -9726,18 +9890,19 @@ function memberCollector(roots, opts) {
9726
9890
  const subject = member.role === "flow" ? member.canonical : member.key;
9727
9891
  if (logging) log(printable(`[flow-files] ${member.role} ${subject}: ${sent}`));
9728
9892
  };
9729
- async function flow(anchorDir, target) {
9893
+ async function flow(anchorDir, target, onlyPresent) {
9730
9894
  const key = flowMemberKey(anchorDir, target);
9731
9895
  const known = flows.get(key);
9732
- if (known !== void 0) return known;
9896
+ if (known !== void 0) return onlyPresent && known.text === void 0 ? void 0 : known;
9733
9897
  const { member, text, sent } = await readFlowMember(anchorDir, target, roots, budget, opts);
9898
+ if (onlyPresent && text === void 0) return void 0;
9734
9899
  const entry = { member, ...text === void 0 ? {} : { text } };
9735
9900
  flows.set(key, entry);
9736
9901
  emit(member, sent);
9737
9902
  return entry;
9738
9903
  }
9739
9904
  async function toolFiles(step) {
9740
- if (step.tool === "flow-execute") return;
9905
+ if (canonicalToolId(step.tool) === "e2e-execute") return;
9741
9906
  for (const file of toolStepFiles(opts.toolFileInputs?.(step.tool), step.args)) {
9742
9907
  const { unwrapWhenSet } = file.spec;
9743
9908
  if (unwrapWhenSet !== void 0 && step.args[unwrapWhenSet] !== void 0) continue;
@@ -9747,11 +9912,31 @@ function memberCollector(roots, opts) {
9747
9912
  emit(read.member, read.sent);
9748
9913
  }
9749
9914
  }
9915
+ async function savedTest(target) {
9916
+ for (const candidate of target.paths) {
9917
+ const found = await flow(path11.dirname(candidate), path11.basename(candidate), true);
9918
+ if (found !== void 0) return found;
9919
+ }
9920
+ let first;
9921
+ for (const candidate of target.paths) {
9922
+ first ??= await flow(path11.dirname(candidate), path11.basename(candidate));
9923
+ }
9924
+ return first;
9925
+ }
9750
9926
  async function nestedRun(target, hop, updates, platform) {
9751
- const { member, text } = await flow(path10.dirname(target.path), `${target.name}.yaml`);
9927
+ const { member, text } = await savedTest(target);
9752
9928
  if (text === void 0 || hop >= MAX_RUN_DEPTH) return void 0;
9753
9929
  return { canonical: member.canonical, text, flowName: target.name, hop, updates, platform };
9754
9930
  }
9931
+ async function runTarget(anchorDir, target) {
9932
+ const found = await flow(anchorDir, target);
9933
+ if (found.member.spelling?.state !== "absent") return found;
9934
+ for (const dir of e2eRunFallbackDirs(anchorDir, target)) {
9935
+ const other = await flow(dir, target, true);
9936
+ if (other !== void 0) return other;
9937
+ }
9938
+ return found;
9939
+ }
9755
9940
  async function walk(start) {
9756
9941
  const queue = [...start];
9757
9942
  for (let run = queue.shift(); run !== void 0; run = queue.shift()) {
@@ -9771,12 +9956,12 @@ function memberCollector(roots, opts) {
9771
9956
  const requests = collectFlowRequests(doc);
9772
9957
  for (const name of requests.snapshots) snapshots.add(name);
9773
9958
  for (const step of requests.toolSteps) await toolFiles(step);
9774
- const anchorDir = path10.dirname(file.canonical);
9959
+ const anchorDir = path11.dirname(file.canonical);
9775
9960
  for (const target of requests.runTargets) {
9776
9961
  const key = flowMemberKey(anchorDir, target);
9777
9962
  if (visited.has(key)) continue;
9778
9963
  visited.add(key);
9779
- const { member, text } = await flow(anchorDir, target);
9964
+ const { member, text } = await runTarget(anchorDir, target);
9780
9965
  if (text !== void 0 && file.hop + 1 < MAX_RUN_DEPTH) {
9781
9966
  files.push({ canonical: member.canonical, text, hop: file.hop + 1 });
9782
9967
  }
@@ -9793,8 +9978,8 @@ function memberCollector(roots, opts) {
9793
9978
  }
9794
9979
  }
9795
9980
  if (snapshots.size === 0) continue;
9796
- const dir = path10.join(
9797
- path10.dirname(run.canonical),
9981
+ const dir = path11.join(
9982
+ path11.dirname(run.canonical),
9798
9983
  "__baselines__",
9799
9984
  baselineKeyFor(run.canonical, run.flowName)
9800
9985
  );
@@ -9818,7 +10003,7 @@ function memberCollector(roots, opts) {
9818
10003
  if (!name.endsWith(".png")) continue;
9819
10004
  const compared = [...prefixes].some((prefix) => name.startsWith(prefix));
9820
10005
  if (!updates && !compared) continue;
9821
- const file = path10.join(dir, name);
10006
+ const file = path11.join(dir, name);
9822
10007
  if (tools.has(file)) continue;
9823
10008
  const member = { role: "baseline", key: file, path: file };
9824
10009
  const entry = await baselineEntry(file, roots, updates && !compared);
@@ -9841,8 +10026,8 @@ async function collectFlowMembers(rootPath, rootBytes, args, opts) {
9841
10026
  if (!namesValidFlow(args)) return {};
9842
10027
  const canonical = await canonicalFlowPath(rootPath);
9843
10028
  const spelling = await classifyOnDiskSpelling(
9844
- path10.dirname(rootPath),
9845
- path10.basename(rootPath),
10029
+ path11.dirname(rootPath),
10030
+ path11.basename(rootPath),
9846
10031
  FLOW_FILE_NAME_PATTERN
9847
10032
  );
9848
10033
  const collector = memberCollector(
@@ -9853,7 +10038,7 @@ async function collectFlowMembers(rootPath, rootBytes, args, opts) {
9853
10038
  {
9854
10039
  canonical,
9855
10040
  text: rootBytes.toString("utf8"),
9856
- flowName: path10.basename(rootPath, ".yaml"),
10041
+ flowName: path11.basename(rootPath, ".yaml"),
9857
10042
  hop: 0,
9858
10043
  updates: args.updateBaselines === true,
9859
10044
  platform: callPlatform(args)
@@ -9876,33 +10061,37 @@ function recordedStep(args) {
9876
10061
  if (typeof parsed !== "object" || parsed === null || Array.isArray(parsed)) return void 0;
9877
10062
  return { tool: command, args: parsed };
9878
10063
  }
9879
- async function collectStepMembers(args, opts) {
10064
+ async function collectStepMembers(args, opts, recordingDirFor = e2eDirFor) {
9880
10065
  const { name, project_root: projectRoot } = args;
9881
10066
  const step = recordedStep(args);
9882
- if (typeof name !== "string" || !FLOW_NAME_PATTERN.test(name) || typeof projectRoot !== "string" || !path10.isAbsolute(projectRoot) || step === void 0) {
10067
+ if (typeof name !== "string" || !FLOW_NAME_PATTERN.test(name) || typeof projectRoot !== "string" || !path11.isAbsolute(projectRoot) || step === void 0) {
9883
10068
  return [];
9884
10069
  }
9885
- const recording = path10.join(projectRoot, ".argent", "flows", `${name}.yaml`);
10070
+ const recording = path11.join(recordingDirFor(projectRoot), `${name}.yaml`);
9886
10071
  const collector = memberCollector(
9887
10072
  await closureRoots(recording, (await landing(recording)).canonical, projectRoot),
9888
10073
  opts
9889
10074
  );
9890
10075
  await collector.toolFiles(step);
9891
- if (step.tool === "flow-execute") {
9892
- const self = await collector.flow(path10.dirname(recording), path10.basename(recording));
10076
+ if (canonicalToolId(step.tool) === "e2e-execute") {
10077
+ const self = await collector.flow(path11.dirname(recording), path11.basename(recording));
9893
10078
  let runArgs = step.args;
9894
10079
  const named = nestedFlowTarget(runArgs);
9895
10080
  if (named?.kind === "flow_path") {
9896
- const stem = path10.basename(named.path, ".yaml");
9897
- if (path10.resolve(path10.dirname(named.path)) === path10.resolve(path10.dirname(recording))) {
9898
- await collector.flow(path10.dirname(recording), path10.basename(named.path));
10081
+ const stem = path11.basename(named.path, ".yaml");
10082
+ const base = path11.basename(named.path);
10083
+ const dir = path11.resolve(path11.dirname(named.path));
10084
+ const recordingDir = path11.dirname(recording);
10085
+ const dirs = [recordingDir, ...e2eRunFallbackDirs(recordingDir, base)];
10086
+ if (dirs.some((d) => path11.resolve(d) === dir)) {
10087
+ await collector.flow(path11.dirname(named.path), base);
9899
10088
  runArgs = { ...runArgs, name: stem };
9900
10089
  delete runArgs.flow_path;
9901
10090
  }
9902
10091
  }
9903
10092
  const target = nestedFlowTarget(runArgs);
9904
10093
  if (target?.kind === "name") {
9905
- await collector.flow(path10.dirname(self.member.canonical), `${target.name}.yaml`);
10094
+ await collector.flow(path11.dirname(self.member.canonical), `${target.name}.yaml`);
9906
10095
  const run = await collector.nestedRun(
9907
10096
  target,
9908
10097
  0,
@@ -9915,6 +10104,43 @@ async function collectStepMembers(args, opts) {
9915
10104
  await collector.sendBaselines();
9916
10105
  return collector.members;
9917
10106
  }
10107
+ async function nameToE2ePathForOlderServer(tool, fileInputs, args) {
10108
+ const id = canonicalToolId(tool);
10109
+ if (id !== "e2e-execute" && id !== "e2e-read-prerequisite") return args;
10110
+ const spec = fileInputs?.find((s) => s.target === "flow_file");
10111
+ if (spec === void 0 || spec.kind !== "file" || spec.paths?.length) return args;
10112
+ const target = nestedFlowTarget(args);
10113
+ if (target?.kind !== "name") return args;
10114
+ const picked = await pickE2eFile(target.paths);
10115
+ if (!picked.exists || picked.legacy) return args;
10116
+ const { name: _name, ...rest } = args;
10117
+ return { ...rest, flow_path: picked.path };
10118
+ }
10119
+ async function stepForOlderServer(args, listedId) {
10120
+ if (typeof args !== "object" || args === null || Array.isArray(args)) return args;
10121
+ const record = args;
10122
+ if (typeof record.command !== "string") return args;
10123
+ const command = listedId(record.command) ?? record.command;
10124
+ const step = recordedStep({ ...record, command });
10125
+ const target = step && canonicalToolId(step.tool) === "e2e-execute" && nestedFlowTarget(step.args);
10126
+ if (target && target.kind === "name") {
10127
+ const picked = await pickE2eFile(target.paths);
10128
+ if (picked.exists && !picked.legacy) {
10129
+ throw new Error(
10130
+ `Cannot record a nested ${record.command} of "${target.name}": the tool-server runs an older argent that records and runs nested e2e tests only from .argent/flows/, and "${target.name}" is ${picked.path}. Upgrade the tool-server to record it, or run it with e2e-execute outside the recording.`
10131
+ );
10132
+ }
10133
+ }
10134
+ return command === record.command ? args : { ...record, command };
10135
+ }
10136
+ async function e2eShadowWarningFor(tool, args) {
10137
+ const id = canonicalToolId(tool);
10138
+ if (id !== "e2e-execute" && id !== "e2e-read-prerequisite") return void 0;
10139
+ const target = nestedFlowTarget(args);
10140
+ if (target?.kind !== "name") return void 0;
10141
+ const picked = await pickE2eFile(target.paths);
10142
+ return picked.shadowed === void 0 ? void 0 : e2eShadowWarning(picked.path, picked.shadowed);
10143
+ }
9918
10144
 
9919
10145
  // ../argent-tools-client/src/tools-client.ts
9920
10146
  function authHeaders2(token) {
@@ -9992,6 +10218,10 @@ function errorBodyMessage(body) {
9992
10218
  if (Array.isArray(body.issues) && typeof body.message === "string") return body.message;
9993
10219
  return body.error ?? body.message;
9994
10220
  }
10221
+ function findTool(tools, name) {
10222
+ const id = canonicalToolId(name);
10223
+ return tools.find((t) => t.name === name) ?? tools.find((t) => canonicalToolId(t.name) === id) ?? null;
10224
+ }
9995
10225
  function assertRequiredPresent(meta, args) {
9996
10226
  const record = typeof args === "object" && args !== null ? args : {};
9997
10227
  const schema = meta.inputSchema;
@@ -10067,26 +10297,33 @@ function createToolsClient(options = {}) {
10067
10297
  return json.tools;
10068
10298
  }
10069
10299
  async function fetchTool(name, opts) {
10070
- const tools = await fetchTools(opts);
10071
- return tools.find((t) => t.name === name) ?? null;
10300
+ return findTool(await fetchTools(opts), name);
10072
10301
  }
10073
10302
  async function callTool(name, args, opts) {
10074
10303
  opts?.signal?.throwIfAborted();
10075
10304
  const { url, token, remote } = await route();
10076
10305
  let finalArgs = args;
10077
10306
  const tools = await fetchTools({ signal: opts?.signal });
10078
- const meta = tools.find((t) => t.name === name) ?? null;
10307
+ const meta = findTool(tools, name);
10308
+ const olderServer = meta !== null && !tools.some((t) => t.name === canonicalToolId(meta.name));
10309
+ if (meta) {
10310
+ finalArgs = await nameToE2ePathForOlderServer(meta.name, meta.fileInputs, args);
10311
+ }
10312
+ if (olderServer && canonicalToolId(meta.name) === "e2e-add-step") {
10313
+ finalArgs = await stepForOlderServer(finalArgs, (tool) => findTool(tools, tool)?.name);
10314
+ }
10315
+ const shadowWarning = await e2eShadowWarningFor(name, args);
10079
10316
  const baselineDirs = [];
10080
10317
  if (meta?.fileInputs?.length) {
10081
- if (remote) assertRequiredPresent(meta, args);
10082
- finalArgs = await prepareFileInputs(meta.fileInputs, args ?? {}, {
10318
+ if (remote) assertRequiredPresent(meta, finalArgs);
10319
+ finalArgs = await prepareFileInputs(meta.fileInputs, finalArgs ?? {}, {
10083
10320
  includeContent: remote,
10084
10321
  uploadEndpoint: remote ? { url, token } : void 0,
10085
10322
  log: diagnose,
10086
10323
  baselineDirs,
10087
10324
  collectMembers: collectFlowMembers,
10088
- collectStepMembers,
10089
- toolFileInputs: (tool) => tools.find((t) => t.name === tool)?.fileInputs,
10325
+ collectStepMembers: olderServer ? (record, o) => collectStepMembers(record, o, (root) => path12.join(root, LEGACY_E2E_DIRS[0])) : collectStepMembers,
10326
+ toolFileInputs: (tool) => findTool(tools, tool)?.fileInputs,
10090
10327
  signal: opts?.signal
10091
10328
  });
10092
10329
  }
@@ -10095,19 +10332,23 @@ function createToolsClient(options = {}) {
10095
10332
  for (const { path: file, error } of applied.failed) {
10096
10333
  diagnose(`The baseline ${file} was not written on this client: ${error}`);
10097
10334
  }
10098
- if (process.env.ARGENT_FLOW_FILES_LOG === "1") {
10335
+ if (filesLogEnabled()) {
10099
10336
  for (const file of applied.written) {
10100
- if (baselineDirs.includes(path11.dirname(file))) {
10337
+ if (baselineDirs.includes(path12.dirname(file))) {
10101
10338
  diagnose(`[flow-files] baseline ${file}: written`);
10102
10339
  }
10103
10340
  }
10104
10341
  }
10105
- return applied.result;
10342
+ const result = applied.result;
10343
+ if (shadowWarning === void 0 || typeof result !== "object" || result === null || Array.isArray(result) || typeof result.warning === "string") {
10344
+ return result;
10345
+ }
10346
+ return { ...result, warning: shadowWarning };
10106
10347
  };
10107
10348
  const stream = opts?.onProgress !== void 0 || carriesMembers(finalArgs);
10108
10349
  const sentOnce = carriesUpload(finalArgs);
10109
10350
  const res = await doFetch(
10110
- `${url}/tools/${encodeURIComponent(name)}`,
10351
+ `${url}/tools/${encodeURIComponent(meta?.name ?? name)}`,
10111
10352
  {
10112
10353
  method: "POST",
10113
10354
  headers: {
@@ -10115,6 +10356,9 @@ function createToolsClient(options = {}) {
10115
10356
  // Tells the tool-server the call came over a link, a link to
10116
10357
  // 127.0.0.1 included, which nothing else in the request shows.
10117
10358
  ...remote ? { [LINKED_CALL_HEADER]: "1" } : {},
10359
+ // Tells the tool-server this client writes recordings under
10360
+ // `.argent/e2e/`; an older client writes only `.argent/flows/`.
10361
+ [E2E_DIR_CLIENT_HEADER]: "1",
10118
10362
  // A proxy that compresses the stream holds each line until its buffer
10119
10363
  // fills. `identity` keeps the stream uncompressed end to end.
10120
10364
  ...stream ? { "Accept": "application/x-ndjson", "Accept-Encoding": "identity" } : {},
@@ -10172,10 +10416,10 @@ function createToolsClient(options = {}) {
10172
10416
  }
10173
10417
 
10174
10418
  // ../argent-tools-client/src/artifacts.ts
10175
- import { copyFile, mkdir as mkdir4, readFile as readFile5, realpath as realpath4, rm as rm3, stat as stat4, writeFile as writeFile4 } from "node:fs/promises";
10419
+ import { copyFile, mkdir as mkdir4, readFile as readFile5, realpath as realpath4, rm as rm3, stat as stat5, writeFile as writeFile4 } from "node:fs/promises";
10176
10420
  import { constants as fsConstants } from "node:fs";
10177
10421
  import { tmpdir as tmpdir2 } from "node:os";
10178
- import { basename as basename6, dirname as dirname8, extname as extname2, isAbsolute as isAbsolute6, join as join11, normalize as normalize2, resolve as resolve7, sep as sep4 } from "node:path";
10422
+ import { basename as basename7, dirname as dirname9, extname as extname2, isAbsolute as isAbsolute6, join as join13, normalize as normalize2, resolve as resolve8, sep as sep4 } from "node:path";
10179
10423
  import { createHash as createHash3 } from "node:crypto";
10180
10424
  var ARTIFACT_MARKER2 = "__argentArtifact";
10181
10425
  function isArtifactHandle(value) {
@@ -10195,20 +10439,20 @@ function sanitizeSegment(segment) {
10195
10439
  function projectSlug() {
10196
10440
  const cwd = process.cwd();
10197
10441
  const hash = createHash3("sha1").update(cwd).digest("hex").slice(0, 6);
10198
- const name = sanitizeSegment(basename6(cwd)) || "root";
10442
+ const name = sanitizeSegment(basename7(cwd)) || "root";
10199
10443
  return `${name}-${hash}`;
10200
10444
  }
10201
10445
  function artifactsRoot() {
10202
- return process.env.ARGENT_ARTIFACTS_DIR ?? join11(tmpdir2(), "argent-artifacts");
10446
+ return process.env.ARGENT_ARTIFACTS_DIR ?? join13(tmpdir2(), "argent-artifacts");
10203
10447
  }
10204
10448
  function artifactDir(deviceId) {
10205
10449
  const parts = [artifactsRoot(), projectSlug(), sessionId()];
10206
10450
  if (deviceId) parts.push(sanitizeSegment(deviceId));
10207
- return join11(...parts);
10451
+ return join13(...parts);
10208
10452
  }
10209
10453
  function durableBaseDir() {
10210
10454
  const projectRoot = findProjectRoot(process.cwd());
10211
- return projectRoot ?? dirname8(argentHomeDir());
10455
+ return projectRoot ?? dirname9(argentHomeDir());
10212
10456
  }
10213
10457
  var ALLOWED_SAVE_DIRS = /* @__PURE__ */ new Set([normalize2(".argent/recordings")]);
10214
10458
  var RECORDINGS_SAVE_DIR = normalize2(".argent/recordings");
@@ -10222,9 +10466,9 @@ function configuredRecordingsDir() {
10222
10466
  if (typeof value !== "string") return null;
10223
10467
  const trimmed = value.trim();
10224
10468
  if (trimmed === "") return null;
10225
- const home = dirname8(argentHomeDir());
10226
- const expanded = trimmed === "~" ? home : trimmed.startsWith("~/") || trimmed.startsWith(`~${sep4}`) ? join11(home, trimmed.slice(2)) : trimmed;
10227
- return resolve7(durableBaseDir(), expanded);
10469
+ const home = dirname9(argentHomeDir());
10470
+ const expanded = trimmed === "~" ? home : trimmed.startsWith("~/") || trimmed.startsWith(`~${sep4}`) ? join13(home, trimmed.slice(2)) : trimmed;
10471
+ return resolve8(durableBaseDir(), expanded);
10228
10472
  }
10229
10473
  var MAX_DURABLE_BYTES = 2 * 1024 * 1024 * 1024;
10230
10474
  async function readCapped(res, cap) {
@@ -10257,10 +10501,10 @@ async function writeDurableUnique(dir, filename, write) {
10257
10501
  const stem = filename.slice(0, filename.length - ext.length);
10258
10502
  for (let i = 1; i <= 1e3; i++) {
10259
10503
  const candidate = i === 1 ? filename : `${stem} (${i})${ext}`;
10260
- const path13 = join11(dir, candidate);
10504
+ const path14 = join13(dir, candidate);
10261
10505
  try {
10262
- await write(path13);
10263
- return path13;
10506
+ await write(path14);
10507
+ return path14;
10264
10508
  } catch (err) {
10265
10509
  if (err?.code === "EEXIST") continue;
10266
10510
  throw err;
@@ -10280,21 +10524,21 @@ function durableSaveTarget(handle) {
10280
10524
  if (configured) {
10281
10525
  return {
10282
10526
  dir: configured,
10283
- path: join11(configured, sanitizeSegment(handle.filename)),
10527
+ path: join13(configured, sanitizeSegment(handle.filename)),
10284
10528
  base: configured,
10285
10529
  rel: ""
10286
10530
  };
10287
10531
  }
10288
10532
  }
10289
10533
  const base = durableBaseDir();
10290
- const dir = join11(base, rel);
10291
- return { dir, path: join11(dir, sanitizeSegment(handle.filename)), base, rel };
10534
+ const dir = join13(base, rel);
10535
+ return { dir, path: join13(dir, sanitizeSegment(handle.filename)), base, rel };
10292
10536
  }
10293
10537
  async function confineToRealBase(dir, base, rel) {
10294
10538
  try {
10295
10539
  const realDir = await realpath4(dir);
10296
10540
  const realBase = await realpath4(base);
10297
- return realDir === join11(realBase, rel);
10541
+ return realDir === join13(realBase, rel);
10298
10542
  } catch {
10299
10543
  return false;
10300
10544
  }
@@ -10302,7 +10546,7 @@ async function confineToRealBase(dir, base, rel) {
10302
10546
  async function resolveLocalFile(handle) {
10303
10547
  if (!handle.hostPath) return null;
10304
10548
  try {
10305
- const st = await stat4(handle.hostPath);
10549
+ const st = await stat5(handle.hostPath);
10306
10550
  if (handle.archive) {
10307
10551
  return st.isDirectory() ? handle.hostPath : null;
10308
10552
  }
@@ -10317,7 +10561,7 @@ async function resolveLocalFile(handle) {
10317
10561
  }
10318
10562
  }
10319
10563
  async function downloadAndExtractArchive(handle, data, dir) {
10320
- const tarball = join11(dir, `${sanitizeSegment(handle.filename)}.tar.gz`);
10564
+ const tarball = join13(dir, `${sanitizeSegment(handle.filename)}.tar.gz`);
10321
10565
  try {
10322
10566
  await writeFile4(tarball, data);
10323
10567
  return await safeExtractTarGz(tarball, dir, handle.filename);
@@ -10345,7 +10589,7 @@ async function materializeArtifacts(result, ctx) {
10345
10589
  const localPath = await resolveLocalFile(value);
10346
10590
  const saveTarget = durableSaveTarget(value);
10347
10591
  if (saveTarget) {
10348
- const filename = basename6(saveTarget.path);
10592
+ const filename = basename7(saveTarget.path);
10349
10593
  try {
10350
10594
  await mkdir4(saveTarget.dir, { recursive: true });
10351
10595
  if (!await confineToRealBase(saveTarget.dir, saveTarget.base, saveTarget.rel)) {
@@ -10409,7 +10653,7 @@ async function materializeArtifacts(result, ctx) {
10409
10653
  return await downloadAndExtractArchive(value, data, dir);
10410
10654
  }
10411
10655
  if (value.size > 0 && data.length !== value.size) return null;
10412
- const downloadedPath = join11(dir, sanitizeSegment(value.filename));
10656
+ const downloadedPath = join13(dir, sanitizeSegment(value.filename));
10413
10657
  await writeFile4(downloadedPath, data);
10414
10658
  if (value.mimeType.startsWith("image/")) {
10415
10659
  images.push({ localPath: downloadedPath, data, mimeType: value.mimeType });
@@ -10443,12 +10687,12 @@ function getDeviceIdFromArgs(args) {
10443
10687
  }
10444
10688
 
10445
10689
  // src/bundled-paths.ts
10446
- import * as fs6 from "node:fs";
10447
- import * as path12 from "node:path";
10690
+ import * as fs7 from "node:fs";
10691
+ import * as path13 from "node:path";
10448
10692
  function readPackageVersion() {
10449
10693
  try {
10450
10694
  const pkg = JSON.parse(
10451
- fs6.readFileSync(path12.join(import.meta.dirname, "..", "package.json"), "utf8")
10695
+ fs7.readFileSync(path13.join(import.meta.dirname, "..", "package.json"), "utf8")
10452
10696
  );
10453
10697
  return pkg.version;
10454
10698
  } catch {
@@ -10459,15 +10703,15 @@ var PACKAGE_NAME = "@swmansion/argent";
10459
10703
  function findDeclaringRoot(startDir) {
10460
10704
  let dir = startDir;
10461
10705
  for (; ; ) {
10462
- if (fs6.existsSync(path12.join(dir, ".argent", "install.json"))) return dir;
10706
+ if (fs7.existsSync(path13.join(dir, ".argent", "install.json"))) return dir;
10463
10707
  try {
10464
- const manifest = JSON.parse(fs6.readFileSync(path12.join(dir, "package.json"), "utf8"));
10708
+ const manifest = JSON.parse(fs7.readFileSync(path13.join(dir, "package.json"), "utf8"));
10465
10709
  if (manifest.devDependencies?.[PACKAGE_NAME] || manifest.dependencies?.[PACKAGE_NAME] || manifest.optionalDependencies?.[PACKAGE_NAME]) {
10466
10710
  return dir;
10467
10711
  }
10468
10712
  } catch {
10469
10713
  }
10470
- const parent = path12.dirname(dir);
10714
+ const parent = path13.dirname(dir);
10471
10715
  if (parent === dir) return null;
10472
10716
  dir = parent;
10473
10717
  }
@@ -10475,12 +10719,12 @@ function findDeclaringRoot(startDir) {
10475
10719
  function findStablePackageDir(startDir, packageRoot) {
10476
10720
  let dir = startDir;
10477
10721
  for (; ; ) {
10478
- const candidate = path12.join(dir, "node_modules", PACKAGE_NAME);
10722
+ const candidate = path13.join(dir, "node_modules", PACKAGE_NAME);
10479
10723
  try {
10480
- if (fs6.realpathSync(candidate) === packageRoot) return candidate;
10724
+ if (fs7.realpathSync(candidate) === packageRoot) return candidate;
10481
10725
  } catch {
10482
10726
  }
10483
- const parent = path12.dirname(dir);
10727
+ const parent = path13.dirname(dir);
10484
10728
  if (parent === dir) return void 0;
10485
10729
  dir = parent;
10486
10730
  }
@@ -10490,7 +10734,7 @@ function classifyInstall() {
10490
10734
  let dir;
10491
10735
  let cwd;
10492
10736
  try {
10493
- packageRoot = fs6.realpathSync(path12.join(import.meta.dirname, ".."));
10737
+ packageRoot = fs7.realpathSync(path13.join(import.meta.dirname, ".."));
10494
10738
  cwd = process.cwd();
10495
10739
  dir = cwd;
10496
10740
  } catch {
@@ -10498,8 +10742,8 @@ function classifyInstall() {
10498
10742
  }
10499
10743
  for (; ; ) {
10500
10744
  try {
10501
- const nmReal = fs6.realpathSync(path12.join(dir, "node_modules"));
10502
- if (packageRoot === nmReal || packageRoot.startsWith(nmReal + path12.sep)) {
10745
+ const nmReal = fs7.realpathSync(path13.join(dir, "node_modules"));
10746
+ if (packageRoot === nmReal || packageRoot.startsWith(nmReal + path13.sep)) {
10503
10747
  return {
10504
10748
  kind: "local",
10505
10749
  projectRoot: findDeclaringRoot(cwd) ?? dir,
@@ -10508,22 +10752,22 @@ function classifyInstall() {
10508
10752
  }
10509
10753
  } catch {
10510
10754
  }
10511
- const parent = path12.dirname(dir);
10755
+ const parent = path13.dirname(dir);
10512
10756
  if (parent === dir) break;
10513
10757
  dir = parent;
10514
10758
  }
10515
- if (packageRoot.includes(`${path12.sep}.yarn${path12.sep}`)) {
10759
+ if (packageRoot.includes(`${path13.sep}.yarn${path13.sep}`)) {
10516
10760
  const declRoot = findDeclaringRoot(cwd);
10517
10761
  if (declRoot) return { kind: "local", projectRoot: declRoot };
10518
10762
  }
10519
10763
  return { kind: "global" };
10520
10764
  }
10521
10765
  var classifiedInstall = classifyInstall();
10522
- var packageDir = classifiedInstall.stablePackageDir ?? path12.join(import.meta.dirname, "..");
10766
+ var packageDir = classifiedInstall.stablePackageDir ?? path13.join(import.meta.dirname, "..");
10523
10767
  var BUNDLED_RUNTIME_PATHS = {
10524
- bundlePath: path12.join(packageDir, "dist", "tool-server.cjs"),
10525
- simulatorServerDir: path12.join(packageDir, "bin"),
10526
- nativeDevtoolsDir: path12.join(packageDir, "dylibs"),
10768
+ bundlePath: path13.join(packageDir, "dist", "tool-server.cjs"),
10769
+ simulatorServerDir: path13.join(packageDir, "bin"),
10770
+ nativeDevtoolsDir: path13.join(packageDir, "dylibs"),
10527
10771
  version: readPackageVersion(),
10528
10772
  installKind: classifiedInstall.kind,
10529
10773
  installProjectRoot: classifiedInstall.projectRoot
@@ -10561,7 +10805,7 @@ function createArgentClient() {
10561
10805
  }
10562
10806
  async function listTools(options) {
10563
10807
  const tools = await client.fetchTools({ signal: options?.signal });
10564
- return tools.map(({ name, description, inputSchema }) => ({ name, description, inputSchema }));
10808
+ return tools.filter((tool) => tool.aliasOf === void 0).map(({ name, description, inputSchema }) => ({ name, description, inputSchema }));
10565
10809
  }
10566
10810
  async function callTool(name, args = {}, options) {
10567
10811
  try {