@swmansion/argent 0.15.0 → 0.15.1-next.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.
@@ -2984,7 +2984,7 @@ var require_compile = __commonJS({
2984
2984
  const schOrFunc = root.refs[ref];
2985
2985
  if (schOrFunc)
2986
2986
  return schOrFunc;
2987
- let _sch = resolve4.call(this, root, ref);
2987
+ let _sch = resolve5.call(this, root, ref);
2988
2988
  if (_sch === void 0) {
2989
2989
  const schema = (_a3 = root.localRefs) === null || _a3 === void 0 ? void 0 : _a3[ref];
2990
2990
  const { schemaId } = this.opts;
@@ -3011,7 +3011,7 @@ var require_compile = __commonJS({
3011
3011
  function sameSchemaEnv(s1, s2) {
3012
3012
  return s1.schema === s2.schema && s1.root === s2.root && s1.baseId === s2.baseId;
3013
3013
  }
3014
- function resolve4(root, ref) {
3014
+ function resolve5(root, ref) {
3015
3015
  let sch;
3016
3016
  while (typeof (sch = this.refs[ref]) == "string")
3017
3017
  ref = sch;
@@ -3642,7 +3642,7 @@ var require_fast_uri = __commonJS({
3642
3642
  }
3643
3643
  return uri;
3644
3644
  }
3645
- function resolve4(baseURI, relativeURI, options) {
3645
+ function resolve5(baseURI, relativeURI, options) {
3646
3646
  const schemelessOptions = options ? Object.assign({ scheme: "null" }, options) : { scheme: "null" };
3647
3647
  const resolved = resolveComponent(parse3(baseURI, schemelessOptions), parse3(relativeURI, schemelessOptions), schemelessOptions, true);
3648
3648
  schemelessOptions.skipEscape = true;
@@ -3900,7 +3900,7 @@ var require_fast_uri = __commonJS({
3900
3900
  var fastUri = {
3901
3901
  SCHEMES,
3902
3902
  normalize,
3903
- resolve: resolve4,
3903
+ resolve: resolve5,
3904
3904
  resolveComponent,
3905
3905
  equal,
3906
3906
  serialize,
@@ -6891,7 +6891,7 @@ var require_dist = __commonJS({
6891
6891
 
6892
6892
  // ../argent-mcp/src/mcp-server.ts
6893
6893
  import { appendFile, mkdir as mkdir5 } from "node:fs/promises";
6894
- import { dirname as dirname4 } from "node:path";
6894
+ import { dirname as dirname5 } from "node:path";
6895
6895
  import { homedir as homedir5 } from "node:os";
6896
6896
 
6897
6897
  // ../../node_modules/@modelcontextprotocol/sdk/dist/esm/server/stdio.js
@@ -13701,12 +13701,12 @@ var StdioServerTransport = class {
13701
13701
  this.onclose?.();
13702
13702
  }
13703
13703
  send(message) {
13704
- return new Promise((resolve4) => {
13704
+ return new Promise((resolve5) => {
13705
13705
  const json = serializeMessage(message);
13706
13706
  if (this._stdout.write(json)) {
13707
- resolve4();
13707
+ resolve5();
13708
13708
  } else {
13709
- this._stdout.once("drain", resolve4);
13709
+ this._stdout.once("drain", resolve5);
13710
13710
  }
13711
13711
  });
13712
13712
  }
@@ -14304,7 +14304,7 @@ var Protocol = class {
14304
14304
  return;
14305
14305
  }
14306
14306
  const pollInterval = task2.pollInterval ?? this._options?.defaultTaskPollInterval ?? 1e3;
14307
- await new Promise((resolve4) => setTimeout(resolve4, pollInterval));
14307
+ await new Promise((resolve5) => setTimeout(resolve5, pollInterval));
14308
14308
  options?.signal?.throwIfAborted();
14309
14309
  }
14310
14310
  } catch (error2) {
@@ -14321,7 +14321,7 @@ var Protocol = class {
14321
14321
  */
14322
14322
  request(request, resultSchema, options) {
14323
14323
  const { relatedRequestId, resumptionToken, onresumptiontoken, task, relatedTask } = options ?? {};
14324
- return new Promise((resolve4, reject) => {
14324
+ return new Promise((resolve5, reject) => {
14325
14325
  const earlyReject = (error2) => {
14326
14326
  reject(error2);
14327
14327
  };
@@ -14399,7 +14399,7 @@ var Protocol = class {
14399
14399
  if (!parseResult.success) {
14400
14400
  reject(parseResult.error);
14401
14401
  } else {
14402
- resolve4(parseResult.data);
14402
+ resolve5(parseResult.data);
14403
14403
  }
14404
14404
  } catch (error2) {
14405
14405
  reject(error2);
@@ -14660,12 +14660,12 @@ var Protocol = class {
14660
14660
  }
14661
14661
  } catch {
14662
14662
  }
14663
- return new Promise((resolve4, reject) => {
14663
+ return new Promise((resolve5, reject) => {
14664
14664
  if (signal.aborted) {
14665
14665
  reject(new McpError(ErrorCode.InvalidRequest, "Request cancelled"));
14666
14666
  return;
14667
14667
  }
14668
- const timeoutId = setTimeout(resolve4, interval);
14668
+ const timeoutId = setTimeout(resolve5, interval);
14669
14669
  signal.addEventListener("abort", () => {
14670
14670
  clearTimeout(timeoutId);
14671
14671
  reject(new McpError(ErrorCode.InvalidRequest, "Request cancelled"));
@@ -15490,7 +15490,7 @@ function generateToken() {
15490
15490
  return randomBytes(AUTH_TOKEN_BYTES).toString("hex");
15491
15491
  }
15492
15492
  function findFreePort() {
15493
- return new Promise((resolve4, reject) => {
15493
+ return new Promise((resolve5, reject) => {
15494
15494
  const srv = net.createServer();
15495
15495
  srv.listen(0, "127.0.0.1", () => {
15496
15496
  const addr = srv.address();
@@ -15501,7 +15501,7 @@ function findFreePort() {
15501
15501
  const port = addr.port;
15502
15502
  srv.close((err) => {
15503
15503
  if (err) reject(err);
15504
- else resolve4(port);
15504
+ else resolve5(port);
15505
15505
  });
15506
15506
  });
15507
15507
  srv.on("error", reject);
@@ -15599,7 +15599,7 @@ function killSpawnedChild(child, pid) {
15599
15599
  }
15600
15600
  }
15601
15601
  function spawnToolsServer(paths, port, options = {}) {
15602
- return new Promise((resolve4, reject) => {
15602
+ return new Promise((resolve5, reject) => {
15603
15603
  let logFd;
15604
15604
  try {
15605
15605
  fs.mkdirSync(STATE_DIR, { recursive: true });
@@ -15636,7 +15636,7 @@ function spawnToolsServer(paths, port, options = {}) {
15636
15636
  rl.close();
15637
15637
  child.stdout?.resume();
15638
15638
  child.stdout?.unref?.();
15639
- settle(() => resolve4({ port: actualPort, pid }));
15639
+ settle(() => resolve5({ port: actualPort, pid }));
15640
15640
  }
15641
15641
  });
15642
15642
  child.on("error", (err) => {
@@ -15942,9 +15942,115 @@ async function isRemoteRouted() {
15942
15942
  }
15943
15943
 
15944
15944
  // ../argent-tools-client/src/file-inputs.ts
15945
- import { mkdir as mkdir3, stat, writeFile as writeFile3 } from "node:fs/promises";
15946
- import { readFile as readFile3 } from "node:fs/promises";
15945
+ import { createHash as createHash2, randomUUID } from "node:crypto";
15946
+ import { createReadStream } from "node:fs";
15947
+ import { mkdir as mkdir3, readFile as readFile3, rm as rm2, stat, writeFile as writeFile3 } from "node:fs/promises";
15948
+ import { tmpdir } from "node:os";
15947
15949
  import * as path3 from "node:path";
15950
+
15951
+ // ../archive/src/index.ts
15952
+ import { execFile } from "node:child_process";
15953
+ import { rm, readdir as readdir2 } from "node:fs/promises";
15954
+ import { basename, dirname as dirname2, join as join3, posix, resolve as resolve2, sep } from "node:path";
15955
+ import { promisify } from "node:util";
15956
+ var execFileAsync = promisify(execFile);
15957
+ var ArchiveError = class extends Error {
15958
+ };
15959
+ function createTarGzArgs(sourcePath, target) {
15960
+ return ["-czf", target, "-C", dirname2(sourcePath), basename(sourcePath)];
15961
+ }
15962
+ async function createTarGzFile(sourcePath, tarPath) {
15963
+ try {
15964
+ await execFileAsync("tar", createTarGzArgs(sourcePath, tarPath));
15965
+ } catch (err) {
15966
+ await rm(tarPath, { force: true }).catch(() => {
15967
+ });
15968
+ throw err;
15969
+ }
15970
+ }
15971
+ function normalizeTarMemberPath(memberPath) {
15972
+ return memberPath.replace(/^\.\//, "").replace(/\\/g, "/");
15973
+ }
15974
+ function isSafeTarMember(memberPath, destDir) {
15975
+ const normalized = normalizeTarMemberPath(memberPath);
15976
+ if (!normalized || normalized === "." || normalized === "./") return false;
15977
+ if (normalized.startsWith("/") || /^[A-Za-z]:[\\/]/.test(normalized)) return false;
15978
+ const relative2 = posix.normalize(normalized);
15979
+ if (relative2 === ".." || relative2.startsWith("../") || relative2.split("/").includes("..")) {
15980
+ return false;
15981
+ }
15982
+ const root = resolve2(destDir);
15983
+ const resolved = resolve2(destDir, relative2);
15984
+ return resolved === root || resolved.startsWith(root + sep);
15985
+ }
15986
+ async function listTarMembers(tarPath) {
15987
+ const { stdout } = await execFileAsync("tar", ["-tzf", tarPath]);
15988
+ return stdout.split("\n").map((line) => line.trim()).filter((line) => line.length > 0);
15989
+ }
15990
+ function isEscapingLinkTarget(target) {
15991
+ if (target.startsWith("/") || /^[A-Za-z]:[\\/]/.test(target)) return true;
15992
+ return posix.normalize(target.replace(/\\/g, "/")).split("/").includes("..");
15993
+ }
15994
+ async function assertSafeMemberTypes(tarPath) {
15995
+ const { stdout } = await execFileAsync("tar", ["-tzvf", tarPath]);
15996
+ for (const line of stdout.split("\n")) {
15997
+ if (!line.trim()) continue;
15998
+ const type = line[0];
15999
+ if (type === "-" || type === "d") continue;
16000
+ if (type === "l") {
16001
+ const parts = line.split(" -> ");
16002
+ const target = parts.length === 2 ? parts[1].trim() : "";
16003
+ if (parts.length !== 2 || !target || isEscapingLinkTarget(target)) {
16004
+ throw new ArchiveError(
16005
+ `Archive contains a symlink whose target could not be confirmed safe: "${line.trim()}".`
16006
+ );
16007
+ }
16008
+ continue;
16009
+ }
16010
+ throw new ArchiveError(
16011
+ `Archive contains an unsupported member type "${type}" (hardlink/device/\u2026) \u2014 refusing extraction.`
16012
+ );
16013
+ }
16014
+ }
16015
+ async function assertSafeArchive(tarPath, destDir) {
16016
+ let members;
16017
+ try {
16018
+ members = await listTarMembers(tarPath);
16019
+ } catch (err) {
16020
+ throw new ArchiveError(
16021
+ `Could not read archive: ${err instanceof Error ? err.message : String(err)}`
16022
+ );
16023
+ }
16024
+ if (members.length === 0) {
16025
+ throw new ArchiveError("Archive is empty.");
16026
+ }
16027
+ for (const member of members) {
16028
+ if (!isSafeTarMember(member, destDir)) {
16029
+ throw new ArchiveError(`Archive contains an unsafe path "${member}" \u2014 refusing extraction.`);
16030
+ }
16031
+ }
16032
+ await assertSafeMemberTypes(tarPath);
16033
+ }
16034
+ async function resolveMember(destDir, expectedName) {
16035
+ const entries = await readdir2(destDir);
16036
+ if (entries.includes(expectedName)) {
16037
+ return join3(destDir, expectedName);
16038
+ }
16039
+ const real = entries.filter((e) => !e.startsWith("._"));
16040
+ if (real.length !== 1) {
16041
+ throw new ArchiveError(
16042
+ `Could not identify the extracted member (expected "${expectedName}", found ${real.length} entries).`
16043
+ );
16044
+ }
16045
+ return join3(destDir, real[0]);
16046
+ }
16047
+ async function safeExtractTarGz(tarPath, destDir, expectedName) {
16048
+ await assertSafeArchive(tarPath, destDir);
16049
+ await execFileAsync("tar", ["-xzf", tarPath, "-C", destDir]);
16050
+ return resolveMember(destDir, expectedName);
16051
+ }
16052
+
16053
+ // ../argent-tools-client/src/file-inputs.ts
15948
16054
  var FILE_INPUT_MARKER = "__argentFileInput";
15949
16055
  var CLIENT_FILE_MARKER = "__argentClientFile";
15950
16056
  var MAX_CONTENT_BYTES = 32 * 1024 * 1024;
@@ -15960,6 +16066,34 @@ function interpolatePath(template, args) {
15960
16066
  });
15961
16067
  return missing ? null : out;
15962
16068
  }
16069
+ async function tarball(sourcePath) {
16070
+ const tarPath = path3.join(tmpdir(), `argent-upload-${randomUUID()}.tar.gz`);
16071
+ await createTarGzFile(sourcePath, tarPath);
16072
+ return tarPath;
16073
+ }
16074
+ function sha256File(filePath) {
16075
+ return new Promise((resolve5, reject) => {
16076
+ const hash = createHash2("sha256");
16077
+ createReadStream(filePath).on("data", (chunk) => hash.update(chunk)).on("end", () => resolve5(hash.digest("hex"))).on("error", reject);
16078
+ });
16079
+ }
16080
+ async function uploadTar(tarPath, endpoint) {
16081
+ const init = {
16082
+ method: "POST",
16083
+ headers: {
16084
+ "content-type": "application/gzip",
16085
+ ...endpoint.token ? { Authorization: `Bearer ${endpoint.token}` } : {}
16086
+ },
16087
+ body: createReadStream(tarPath),
16088
+ duplex: "half"
16089
+ };
16090
+ const res = await fetch(`${endpoint.url}/upload`, init);
16091
+ if (!res.ok) {
16092
+ throw new Error(`Upload to ${endpoint.url}/upload failed: ${res.status} ${res.statusText}`);
16093
+ }
16094
+ const json = await res.json();
16095
+ return json.uploadId;
16096
+ }
15963
16097
  async function prepareFileInputs(specs, args, opts) {
15964
16098
  if (!specs || specs.length === 0 || typeof args !== "object" || args === null) {
15965
16099
  return args;
@@ -15987,6 +16121,28 @@ async function prepareFileInputs(specs, args, opts) {
15987
16121
  } catch {
15988
16122
  }
15989
16123
  }
16124
+ if (spec.kind === "tar-upload") {
16125
+ const st = await stat(filePath).catch(() => null);
16126
+ if (st) {
16127
+ wire.size = st.size;
16128
+ wire.mtimeMs = st.mtimeMs;
16129
+ }
16130
+ if (opts.uploadEndpoint && st) {
16131
+ let tarPath = null;
16132
+ try {
16133
+ process.stderr.write(
16134
+ `Uploading ${path3.basename(filePath)} to the remote tool-server...
16135
+ `
16136
+ );
16137
+ tarPath = await tarball(filePath);
16138
+ wire.contentHash = await sha256File(tarPath);
16139
+ wire.uploadId = await uploadTar(tarPath, opts.uploadEndpoint);
16140
+ } finally {
16141
+ if (tarPath) await rm2(tarPath, { force: true }).catch(() => {
16142
+ });
16143
+ }
16144
+ }
16145
+ }
15990
16146
  out = out ?? { ...record2 };
15991
16147
  out[spec.target] = wire;
15992
16148
  }
@@ -16034,13 +16190,10 @@ async function applyClientFileDirectives(result) {
16034
16190
  }
16035
16191
 
16036
16192
  // ../argent-tools-client/src/artifacts.ts
16037
- import { mkdir as mkdir4, readFile as readFile4, rm, stat as stat2, writeFile as writeFile4 } from "node:fs/promises";
16038
- import { tmpdir } from "node:os";
16039
- import { basename, join as join3 } from "node:path";
16040
- import { createHash as createHash2 } from "node:crypto";
16041
- import { execFile } from "node:child_process";
16042
- import { promisify } from "node:util";
16043
- var execFileAsync = promisify(execFile);
16193
+ import { mkdir as mkdir4, readFile as readFile4, rm as rm3, stat as stat2, writeFile as writeFile4 } from "node:fs/promises";
16194
+ import { tmpdir as tmpdir2 } from "node:os";
16195
+ import { basename as basename3, join as join5 } from "node:path";
16196
+ import { createHash as createHash3 } from "node:crypto";
16044
16197
  var ARTIFACT_MARKER = "__argentArtifact";
16045
16198
  function isArtifactHandle(value) {
16046
16199
  return !!value && typeof value === "object" && value[ARTIFACT_MARKER] === true && typeof value.id === "string" && typeof value.filename === "string";
@@ -16058,17 +16211,17 @@ function sanitizeSegment(segment) {
16058
16211
  }
16059
16212
  function projectSlug() {
16060
16213
  const cwd = process.cwd();
16061
- const hash = createHash2("sha1").update(cwd).digest("hex").slice(0, 6);
16062
- const name = sanitizeSegment(basename(cwd)) || "root";
16214
+ const hash = createHash3("sha1").update(cwd).digest("hex").slice(0, 6);
16215
+ const name = sanitizeSegment(basename3(cwd)) || "root";
16063
16216
  return `${name}-${hash}`;
16064
16217
  }
16065
16218
  function artifactsRoot() {
16066
- return process.env.ARGENT_ARTIFACTS_DIR ?? join3(tmpdir(), "argent-artifacts");
16219
+ return process.env.ARGENT_ARTIFACTS_DIR ?? join5(tmpdir2(), "argent-artifacts");
16067
16220
  }
16068
16221
  function artifactDir(deviceId) {
16069
16222
  const parts = [artifactsRoot(), projectSlug(), sessionId()];
16070
16223
  if (deviceId) parts.push(sanitizeSegment(deviceId));
16071
- return join3(...parts);
16224
+ return join5(...parts);
16072
16225
  }
16073
16226
  async function resolveLocalFile(handle) {
16074
16227
  if (!handle.hostPath) return null;
@@ -16088,15 +16241,14 @@ async function resolveLocalFile(handle) {
16088
16241
  }
16089
16242
  }
16090
16243
  async function downloadAndExtractArchive(handle, data, dir) {
16091
- const tarball = join3(dir, `${sanitizeSegment(handle.filename)}.tar.gz`);
16244
+ const tarball2 = join5(dir, `${sanitizeSegment(handle.filename)}.tar.gz`);
16092
16245
  try {
16093
- await writeFile4(tarball, data);
16094
- await execFileAsync("tar", ["-xzf", tarball, "-C", dir]);
16095
- return join3(dir, handle.filename);
16246
+ await writeFile4(tarball2, data);
16247
+ return await safeExtractTarGz(tarball2, dir, handle.filename);
16096
16248
  } catch {
16097
16249
  return null;
16098
16250
  } finally {
16099
- await rm(tarball, { force: true }).catch(() => {
16251
+ await rm3(tarball2, { force: true }).catch(() => {
16100
16252
  });
16101
16253
  }
16102
16254
  }
@@ -16132,7 +16284,7 @@ async function materializeArtifacts(result, ctx) {
16132
16284
  return await downloadAndExtractArchive(value, data, dir);
16133
16285
  }
16134
16286
  if (value.size > 0 && data.length !== value.size) return null;
16135
- const downloadedPath = join3(dir, sanitizeSegment(value.filename));
16287
+ const downloadedPath = join5(dir, sanitizeSegment(value.filename));
16136
16288
  await writeFile4(downloadedPath, data);
16137
16289
  if (value.mimeType.startsWith("image/")) {
16138
16290
  images.push({ localPath: downloadedPath, data, mimeType: value.mimeType });
@@ -17307,7 +17459,7 @@ function getUtf8ByteLength(value) {
17307
17459
  }
17308
17460
 
17309
17461
  // ../../node_modules/posthog-node/dist/extensions/error-tracking/modifiers/context-lines.node.mjs
17310
- import { createReadStream } from "node:fs";
17462
+ import { createReadStream as createReadStream2 } from "node:fs";
17311
17463
  import { createInterface as createInterface2 } from "node:readline";
17312
17464
  var LRU_FILE_CONTENTS_CACHE = new error_tracking_exports.ReduceableCache(25);
17313
17465
  var LRU_FILE_CONTENTS_FS_READ_FAILED = new error_tracking_exports.ReduceableCache(20);
@@ -17381,8 +17533,8 @@ var PostHogSentryIntegration = class {
17381
17533
 
17382
17534
  // ../registry/src/artifacts.ts
17383
17535
  import { stat as stat3 } from "node:fs/promises";
17384
- import { randomUUID } from "node:crypto";
17385
- import { basename as basename2, extname } from "node:path";
17536
+ import { randomUUID as randomUUID2 } from "node:crypto";
17537
+ import { basename as basename4, extname } from "node:path";
17386
17538
 
17387
17539
  // ../registry/src/failure-codes.ts
17388
17540
  var FAILURE_CODES = {
@@ -17406,6 +17558,7 @@ var FAILURE_CODES = {
17406
17558
  TOOL_CAPABILITY_UNSUPPORTED_OPERATION: "TOOL_CAPABILITY_UNSUPPORTED_OPERATION",
17407
17559
  TOOL_PLATFORM_NOT_IMPLEMENTED: "TOOL_PLATFORM_NOT_IMPLEMENTED",
17408
17560
  TOOL_DEPENDENCY_MISSING: "TOOL_DEPENDENCY_MISSING",
17561
+ TOOL_INPUT_INVALID: "TOOL_INPUT_INVALID",
17409
17562
  TOOLSERVER_UNHANDLED_REJECTION: "TOOLSERVER_UNHANDLED_REJECTION",
17410
17563
  TOOLSERVER_UNCAUGHT_EXCEPTION: "TOOLSERVER_UNCAUGHT_EXCEPTION",
17411
17564
  INSTALL_GLOBAL_PACKAGE_FAILED: "INSTALL_GLOBAL_PACKAGE_FAILED",
@@ -17478,6 +17631,7 @@ var FAILURE_CODES = {
17478
17631
  NATIVE_DEVTOOLS_FIND_VIEWS_ERROR: "NATIVE_DEVTOOLS_FIND_VIEWS_ERROR",
17479
17632
  NATIVE_DEVTOOLS_FACTORY_OPTIONS_MISSING: "NATIVE_DEVTOOLS_FACTORY_OPTIONS_MISSING",
17480
17633
  NATIVE_DEVTOOLS_WRONG_PLATFORM: "NATIVE_DEVTOOLS_WRONG_PLATFORM",
17634
+ NATIVE_DEVTOOLS_NOT_INJECTABLE: "NATIVE_DEVTOOLS_NOT_INJECTABLE",
17481
17635
  NATIVE_DEVTOOLS_NOT_CONNECTED: "NATIVE_DEVTOOLS_NOT_CONNECTED",
17482
17636
  NATIVE_DEVTOOLS_RPC_TIMEOUT: "NATIVE_DEVTOOLS_RPC_TIMEOUT",
17483
17637
  NATIVE_DEVTOOLS_RPC_ERROR: "NATIVE_DEVTOOLS_RPC_ERROR",
@@ -17540,6 +17694,11 @@ var FAILURE_CODES = {
17540
17694
  NATIVE_PROFILER_NO_RUNNING_APPS: "NATIVE_PROFILER_NO_RUNNING_APPS",
17541
17695
  NATIVE_PROFILER_NO_RUNNING_USER_APPS: "NATIVE_PROFILER_NO_RUNNING_USER_APPS",
17542
17696
  NATIVE_PROFILER_MULTIPLE_RUNNING_USER_APPS: "NATIVE_PROFILER_MULTIPLE_RUNNING_USER_APPS",
17697
+ NATIVE_PROFILER_MALLOC_DEGRADED_XCODE: "NATIVE_PROFILER_MALLOC_DEGRADED_XCODE",
17698
+ NATIVE_PROFILER_MALLOC_STRATEGY_OVERRIDE: "NATIVE_PROFILER_MALLOC_STRATEGY_OVERRIDE",
17699
+ NATIVE_PROFILER_APP_BUNDLE_PATH_FAILED: "NATIVE_PROFILER_APP_BUNDLE_PATH_FAILED",
17700
+ NATIVE_PROFILER_LAUNCH_APP_NOT_FOUND: "NATIVE_PROFILER_LAUNCH_APP_NOT_FOUND",
17701
+ NATIVE_PROFILER_LAUNCH_APP_AMBIGUOUS: "NATIVE_PROFILER_LAUNCH_APP_AMBIGUOUS",
17543
17702
  NATIVE_PROFILER_SESSION_ALREADY_RUNNING: "NATIVE_PROFILER_SESSION_ALREADY_RUNNING",
17544
17703
  NATIVE_PROFILER_XCTRACE_NO_PID: "NATIVE_PROFILER_XCTRACE_NO_PID",
17545
17704
  NATIVE_PROFILER_XCTRACE_PROCESS_NOT_FOUND: "NATIVE_PROFILER_XCTRACE_PROCESS_NOT_FOUND",
@@ -17562,6 +17721,8 @@ var FAILURE_CODES = {
17562
17721
  FLOW_NO_ACTIVE_RECORDING: "FLOW_NO_ACTIVE_RECORDING",
17563
17722
  FLOW_FILE_INVALID: "FLOW_FILE_INVALID",
17564
17723
  FLOW_ENTRY_UNRECOGNIZED: "FLOW_ENTRY_UNRECOGNIZED",
17724
+ FLOW_E2E_HAS_PREREQUISITE: "FLOW_E2E_HAS_PREREQUISITE",
17725
+ FLOW_DEVICE_RESOLUTION: "FLOW_DEVICE_RESOLUTION",
17565
17726
  PROFILER_QUERY_MODE_INVALID: "PROFILER_QUERY_MODE_INVALID",
17566
17727
  PROFILER_QUERY_REQUIRED_PARAM_MISSING: "PROFILER_QUERY_REQUIRED_PARAM_MISSING",
17567
17728
  PROFILER_DATA_NOT_LOADED: "PROFILER_DATA_NOT_LOADED",
@@ -17656,7 +17817,7 @@ var FAILURE_SIGNAL_NAME_SET = new Set(FAILURE_SIGNAL_NAMES);
17656
17817
  var FAILURE_SPAWN_CODE_SET = new Set(FAILURE_SPAWN_CODES);
17657
17818
 
17658
17819
  // ../registry/src/registry.ts
17659
- import { randomUUID as randomUUID2 } from "node:crypto";
17820
+ import { randomUUID as randomUUID3 } from "node:crypto";
17660
17821
 
17661
17822
  // ../telemetry/src/events.ts
17662
17823
  var PLATFORMS = [
@@ -17886,11 +18047,44 @@ var ALLOWED = {
17886
18047
  uptime_ms: DURATION_MS,
17887
18048
  total_tool_calls: COUNT,
17888
18049
  ...FAILURE_SIGNAL
18050
+ },
18051
+ "lens:preview_opened": {
18052
+ round: COUNT,
18053
+ element_count: COUNT,
18054
+ variant_count: COUNT,
18055
+ is_cli_session: bool,
18056
+ platform: PLATFORM
18057
+ },
18058
+ "lens:round_completed": {
18059
+ round: COUNT,
18060
+ element_count: COUNT,
18061
+ variant_count: COUNT,
18062
+ annotation_count: COUNT,
18063
+ element_comment_count: COUNT,
18064
+ skipped_comment_count: COUNT,
18065
+ has_global_comment: bool,
18066
+ inspector_used: bool,
18067
+ offscreen_revealed: bool,
18068
+ is_cli_session: bool,
18069
+ had_parked_await: bool,
18070
+ round_duration_ms: DURATION_MS,
18071
+ platform: PLATFORM
18072
+ },
18073
+ "lens:round_abandoned": {
18074
+ round: COUNT,
18075
+ element_count: COUNT,
18076
+ variant_count: COUNT,
18077
+ had_parked_await: bool,
18078
+ is_cli_session: bool,
18079
+ platform: PLATFORM
18080
+ },
18081
+ "lens:cli_session_started": {
18082
+ agent_choice_count: COUNT
17889
18083
  }
17890
18084
  };
17891
18085
 
17892
18086
  // ../telemetry/src/base-props.ts
17893
- import { randomUUID as randomUUID3 } from "node:crypto";
18087
+ import { randomUUID as randomUUID4 } from "node:crypto";
17894
18088
 
17895
18089
  // ../telemetry/src/cloud-agent-detect.ts
17896
18090
  import { existsSync as existsSync2 } from "node:fs";
@@ -18264,7 +18458,7 @@ var vendors_default = [
18264
18458
  var _CI_VENDOR_COUNT_FOR_TEST = vendors_default.length;
18265
18459
 
18266
18460
  // ../telemetry/src/base-props.ts
18267
- var SESSION_ID2 = randomUUID3();
18461
+ var SESSION_ID2 = randomUUID4();
18268
18462
 
18269
18463
  // ../telemetry/src/identity.ts
18270
18464
  import * as crypto2 from "node:crypto";
@@ -18596,14 +18790,17 @@ async function toMcpContent(result, outputHint, ctx, args) {
18596
18790
  }
18597
18791
  return legacyImageContent(rewritten, suppressImage);
18598
18792
  }
18599
- const blocks = [{ type: "text", text: JSON.stringify(rewritten, null, 2) }];
18793
+ const blocks = [{ type: "text", text: stringifyForText(rewritten) }];
18600
18794
  if (!suppressImage) for (const img of images) blocks.push(imageBlock(img.data, img.mimeType));
18601
18795
  return blocks;
18602
18796
  }
18603
18797
  if (outputHint === "image") {
18604
18798
  return legacyImageContent(result, suppressImage);
18605
18799
  }
18606
- return [{ type: "text", text: JSON.stringify(result, null, 2) }];
18800
+ return [{ type: "text", text: stringifyForText(result) }];
18801
+ }
18802
+ function stringifyForText(value) {
18803
+ return JSON.stringify(value ?? null, null, 2);
18607
18804
  }
18608
18805
  async function legacyImageContent(result, suppressImage) {
18609
18806
  if (result && typeof result === "object" && "url" in result) {
@@ -18663,35 +18860,71 @@ async function screenshotDiffToMcpContent(result, ctx) {
18663
18860
  blocks.push({ type: "text", text: result.summary });
18664
18861
  return blocks;
18665
18862
  }
18863
+ var STATUS_GLYPH = {
18864
+ pass: "\u2713",
18865
+ fail: "\u2717",
18866
+ error: "\u2717",
18867
+ skip: "\xB7"
18868
+ };
18869
+ function stepLabel(step) {
18870
+ if (step.kind === "echo") return step.message ?? "";
18871
+ if (step.kind === "run") return `run ${step.flow ?? ""}`.trim();
18872
+ if (step.tool) return step.tool;
18873
+ if (step.target) return `${step.kind} ${step.target}`;
18874
+ return step.kind;
18875
+ }
18666
18876
  async function flowRunToMcpContent(result, ctx) {
18667
18877
  const blocks = [];
18668
18878
  if (result.executionPrerequisite) {
18669
- blocks.push({
18670
- type: "text",
18671
- text: `Prerequisite: ${result.executionPrerequisite}`
18672
- });
18879
+ blocks.push({ type: "text", text: `Prerequisite: ${result.executionPrerequisite}` });
18673
18880
  }
18674
18881
  blocks.push({
18675
18882
  type: "text",
18676
- text: `Running flow "${result.flow}" (${result.steps.length} steps)`
18883
+ text: `Running flow "${result.flow}"${result.device ? ` on ${result.device}` : ""} (${result.steps.length} steps)`
18677
18884
  });
18678
18885
  for (let i = 0; i < result.steps.length; i++) {
18679
18886
  const step = result.steps[i];
18680
- const num = i + 1;
18681
- if (step.kind === "echo") {
18682
- blocks.push({ type: "text", text: `[${num}] ${step.message}` });
18683
- } else if ("error" in step && step.error) {
18684
- blocks.push({
18685
- type: "text",
18686
- text: `[${num}] ${step.tool} ERROR: ${step.error}`
18687
- });
18688
- } else {
18689
- blocks.push({ type: "text", text: `[${num}] ${step.tool}` });
18690
- const stepContent = await toMcpContent(step.result, step.outputHint, ctx, step.args);
18691
- blocks.push(...stepContent);
18887
+ const num = step.index !== void 0 ? step.index + 1 : i + 1;
18888
+ const glyph = step.status ? `${STATUS_GLYPH[step.status] ?? "\u2022"} ` : "";
18889
+ const reason = step.reason ?? step.error;
18890
+ const suffix = reason ? ` \u2014 ${reason}` : "";
18891
+ const warning = step.warning ? ` \u26A0 ${step.warning}` : "";
18892
+ blocks.push({ type: "text", text: `[${num}] ${glyph}${stepLabel(step)}${suffix}${warning}` });
18893
+ if (step.result !== void 0) {
18894
+ blocks.push(...await toMcpContent(step.result, step.outputHint, ctx, step.args));
18895
+ }
18896
+ if (isRecord(step.artifacts)) {
18897
+ blocks.push(...await stepArtifactBlocks(step.artifacts, step.status, ctx));
18692
18898
  }
18693
18899
  }
18694
- blocks.push({ type: "text", text: `Flow "${result.flow}" complete.` });
18900
+ if (result.ok !== void 0) {
18901
+ blocks.push({
18902
+ type: "text",
18903
+ text: `${result.ok ? "PASS" : "FAIL"} \u2014 ${result.passed ?? 0} passed, ${result.failed ?? 0} failed, ${result.errored ?? 0} errored, ${result.skipped ?? 0} skipped`
18904
+ });
18905
+ } else {
18906
+ blocks.push({ type: "text", text: `Flow "${result.flow}" complete.` });
18907
+ }
18908
+ return blocks;
18909
+ }
18910
+ async function stepArtifactBlocks(artifacts, status, ctx) {
18911
+ const failed = status === "fail" || status === "error";
18912
+ const entries = [];
18913
+ let diffImage;
18914
+ for (const [k, v] of Object.entries(artifacts)) {
18915
+ if (ctx && failed && k === "diff" && isArtifactHandle(v)) {
18916
+ const { result, images } = await materializeArtifacts(v, ctx);
18917
+ entries.push([k, typeof result === "string" ? result : "(unavailable)"]);
18918
+ const img = images.find((i) => i.localPath === result);
18919
+ if (img) diffImage = imageBlock(img.data, img.mimeType);
18920
+ } else if (isArtifactHandle(v)) {
18921
+ entries.push([k, v.hostPath ?? v.filename]);
18922
+ } else if (typeof v === "string") {
18923
+ entries.push([k, v]);
18924
+ }
18925
+ }
18926
+ const blocks = entries.length > 0 ? [{ type: "text", text: entries.map(([k, v]) => ` ${k}: ${v}`).join("\n") }] : [];
18927
+ if (diffImage) blocks.push(diffImage);
18695
18928
  return blocks;
18696
18929
  }
18697
18930
 
@@ -18867,7 +19100,7 @@ async function startMcpServer(options) {
18867
19100
  async function spyLog(entry) {
18868
19101
  try {
18869
19102
  if (!logDirReady) {
18870
- await mkdir5(dirname4(LOG_FILE2), { recursive: true });
19103
+ await mkdir5(dirname5(LOG_FILE2), { recursive: true });
18871
19104
  logDirReady = true;
18872
19105
  }
18873
19106
  await appendFile(LOG_FILE2, JSON.stringify(entry) + "\n");