@swmansion/argent 0.30.2-next.2 → 0.30.2-next.20
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bin/darwin/simulator-server +0 -0
- package/bin/linux/simulator-server +0 -0
- package/bin/linux-arm64/simulator-server +0 -0
- package/bin/win32/simulator-server.exe +0 -0
- package/dist/cli-cmds.mjs +26 -9
- package/dist/client.js +23 -6
- package/dist/installer.mjs +2 -1
- package/dist/ios-device-runner/ArgentRunner/ArgentRunner.xcodeproj/project.pbxproj +80 -0
- package/dist/ios-device-runner/ArgentRunner/ArgentRunner.xcodeproj/xcshareddata/xcschemes/ArgentRunner.xcscheme +14 -0
- package/dist/ios-device-runner/ArgentRunner/ArgentRunnerUITests/Assets.xcassets/AppIcon.appiconset/AppIcon.png +0 -0
- package/dist/ios-device-runner/ArgentRunner/ArgentRunnerUITests/Assets.xcassets/AppIcon.appiconset/Contents.json +14 -0
- package/dist/ios-device-runner/ArgentRunner/ArgentRunnerUITests/Assets.xcassets/Contents.json +6 -0
- package/dist/ios-device-runner/ArgentRunner/brand-runner.sh +27 -0
- package/dist/mcp-server.mjs +149 -85
- package/dist/tool-args.generated.d.ts +2 -0
- package/dist/tool-server.cjs +358 -73
- package/package.json +1 -1
- package/rules/argent.md +9 -7
- package/skills/argent-device-interact/SKILL.md +3 -1
- package/skills/argent-device-interact/references/harmonyos.md +43 -0
- package/skills/argent-ios-device-setup/SKILL.md +1 -1
- package/skills/argent-native-profiler/SKILL.md +1 -0
- package/skills/argent-react-native-profiler/SKILL.md +2 -0
- package/skills/argent-test-ui-flow/SKILL.md +1 -2
package/dist/tool-server.cjs
CHANGED
|
@@ -1584,6 +1584,7 @@ var init_failure_codes = __esm({
|
|
|
1584
1584
|
REACT_PROFILER_DEVTOOLS_RENDERER_MISSING: "REACT_PROFILER_DEVTOOLS_RENDERER_MISSING",
|
|
1585
1585
|
REACT_PROFILER_START_FAILED: "REACT_PROFILER_START_FAILED",
|
|
1586
1586
|
REACT_PROFILER_START_VERIFY_FAILED: "REACT_PROFILER_START_VERIFY_FAILED",
|
|
1587
|
+
REACT_PROFILER_SESSION_TORN_DOWN: "REACT_PROFILER_SESSION_TORN_DOWN",
|
|
1587
1588
|
REACT_PROFILER_HOOK_ERROR: "REACT_PROFILER_HOOK_ERROR",
|
|
1588
1589
|
REACT_PROFILER_ANALYZE_NO_DATA: "REACT_PROFILER_ANALYZE_NO_DATA",
|
|
1589
1590
|
NATIVE_PROFILER_FACTORY_OPTIONS_MISSING: "NATIVE_PROFILER_FACTORY_OPTIONS_MISSING",
|
|
@@ -100944,7 +100945,7 @@ var _CI_VENDOR_COUNT_FOR_TEST = vendors_default.length;
|
|
|
100944
100945
|
var SESSION_ID = (0, import_node_crypto3.randomUUID)();
|
|
100945
100946
|
function readCliVersion() {
|
|
100946
100947
|
if (true) {
|
|
100947
|
-
return "0.30.2-next.
|
|
100948
|
+
return "0.30.2-next.20";
|
|
100948
100949
|
}
|
|
100949
100950
|
return "0.0.0";
|
|
100950
100951
|
}
|
|
@@ -122147,19 +122148,23 @@ async function openMoqClient(udid) {
|
|
|
122147
122148
|
async function openMoqClientFromInfo(info) {
|
|
122148
122149
|
await installNodeWebTransport();
|
|
122149
122150
|
const session = new MoqDeviceSession(await connectMoq(info), { publishPath: PUBLISH_PATH });
|
|
122150
|
-
|
|
122151
|
+
let closed = false;
|
|
122152
|
+
disposeWhenTransportDies(session, () => closed = true);
|
|
122151
122153
|
return {
|
|
122152
|
-
|
|
122154
|
+
// The SDK resolves sends on a closed session, reporting undelivered input as sent.
|
|
122155
|
+
sendControl: (payload) => closed ? Promise.reject(new Error("MoQ session is closed")) : session.sendControl(payload),
|
|
122153
122156
|
async screenshot(opts) {
|
|
122154
122157
|
return Buffer.from(await session.screenshot({ scale: opts?.scale }));
|
|
122155
122158
|
},
|
|
122156
122159
|
async close() {
|
|
122160
|
+
closed = true;
|
|
122157
122161
|
session.close();
|
|
122158
122162
|
}
|
|
122159
122163
|
};
|
|
122160
122164
|
}
|
|
122161
|
-
function disposeWhenTransportDies(session) {
|
|
122165
|
+
function disposeWhenTransportDies(session, onDispose) {
|
|
122162
122166
|
const dispose = () => {
|
|
122167
|
+
onDispose();
|
|
122163
122168
|
try {
|
|
122164
122169
|
session.close();
|
|
122165
122170
|
} catch {
|
|
@@ -122219,6 +122224,52 @@ function settleWithin(p, ms, signal) {
|
|
|
122219
122224
|
// ../tool-server/src/utils/simulator-client.ts
|
|
122220
122225
|
init_external_devices();
|
|
122221
122226
|
|
|
122227
|
+
// ../tool-server/src/utils/profiling-devices.ts
|
|
122228
|
+
var runs = /* @__PURE__ */ new Map();
|
|
122229
|
+
var servers = /* @__PURE__ */ new Map();
|
|
122230
|
+
function trackProfilingRun(deviceId, run2) {
|
|
122231
|
+
let set2 = runs.get(deviceId);
|
|
122232
|
+
if (!set2) {
|
|
122233
|
+
set2 = /* @__PURE__ */ new Set();
|
|
122234
|
+
runs.set(deviceId, set2);
|
|
122235
|
+
}
|
|
122236
|
+
set2.add(run2);
|
|
122237
|
+
syncCaptureOnDemand();
|
|
122238
|
+
}
|
|
122239
|
+
function isProfiling(deviceId) {
|
|
122240
|
+
syncCaptureOnDemand();
|
|
122241
|
+
return runs.has(deviceId);
|
|
122242
|
+
}
|
|
122243
|
+
function syncCaptureOnDemand() {
|
|
122244
|
+
for (const [deviceId, set2] of runs) {
|
|
122245
|
+
for (const run2 of set2) {
|
|
122246
|
+
if (!run2.profilingActive) set2.delete(run2);
|
|
122247
|
+
}
|
|
122248
|
+
if (set2.size === 0) runs.delete(deviceId);
|
|
122249
|
+
}
|
|
122250
|
+
for (const [deviceId, server] of servers) {
|
|
122251
|
+
const profiling = runs.has(deviceId);
|
|
122252
|
+
if (server.onDemand !== profiling) {
|
|
122253
|
+
server.onDemand = profiling;
|
|
122254
|
+
server.send(profiling);
|
|
122255
|
+
}
|
|
122256
|
+
}
|
|
122257
|
+
}
|
|
122258
|
+
function registerCaptureOnDemandSender(deviceId, endpoint, send) {
|
|
122259
|
+
const entry = { endpoint, send, onDemand: false };
|
|
122260
|
+
servers.set(deviceId, entry);
|
|
122261
|
+
syncCaptureOnDemand();
|
|
122262
|
+
return () => {
|
|
122263
|
+
if (servers.get(deviceId) !== entry) return;
|
|
122264
|
+
servers.delete(deviceId);
|
|
122265
|
+
if (entry.onDemand) entry.send(false);
|
|
122266
|
+
};
|
|
122267
|
+
}
|
|
122268
|
+
function captureOnDemandDropped(deviceId, endpoint) {
|
|
122269
|
+
const server = servers.get(deviceId);
|
|
122270
|
+
if (server?.endpoint === endpoint) server.onDemand = false;
|
|
122271
|
+
}
|
|
122272
|
+
|
|
122222
122273
|
// ../tool-server/src/utils/foldable.ts
|
|
122223
122274
|
var import_node_child_process13 = require("node:child_process");
|
|
122224
122275
|
var fs17 = __toESM(require("node:fs"));
|
|
@@ -122461,6 +122512,14 @@ var FIRST_FRAME_POLL_MS = 250;
|
|
|
122461
122512
|
var COMMAND_ACK_TIMEOUT_MS = 5e3;
|
|
122462
122513
|
var connections = /* @__PURE__ */ new Map();
|
|
122463
122514
|
var cmdId = 0;
|
|
122515
|
+
function pendingIdNamedBy(conn, message) {
|
|
122516
|
+
const named = message?.match(/unknown variant `([^`]+)`/)?.[1];
|
|
122517
|
+
if (named === void 0) return void 0;
|
|
122518
|
+
for (const [id, entry] of conn.pending) {
|
|
122519
|
+
if (entry.cmd === named) return id;
|
|
122520
|
+
}
|
|
122521
|
+
return void 0;
|
|
122522
|
+
}
|
|
122464
122523
|
function failAllPending(conn, makeError) {
|
|
122465
122524
|
const entries = [...conn.pending.values()];
|
|
122466
122525
|
conn.pending.clear();
|
|
@@ -122507,7 +122566,7 @@ function getOrCreateConnection(api) {
|
|
|
122507
122566
|
}
|
|
122508
122567
|
if (ack.status !== "ok" && ack.status !== "error") return;
|
|
122509
122568
|
if (ack.id != null && !conn.pending.has(ack.id)) return;
|
|
122510
|
-
const id = ack.id ?? conn.pending.keys().next().value;
|
|
122569
|
+
const id = ack.id ?? pendingIdNamedBy(conn, ack.message) ?? conn.pending.keys().next().value;
|
|
122511
122570
|
if (id == null) return;
|
|
122512
122571
|
const entry = conn.pending.get(id);
|
|
122513
122572
|
if (entry == null) return;
|
|
@@ -122536,6 +122595,7 @@ function getOrCreateConnection(api) {
|
|
|
122536
122595
|
ws.on("close", () => {
|
|
122537
122596
|
connections.delete(key2);
|
|
122538
122597
|
failAllPending(conn, (cmd) => transportError(cmd, key2, "the connection closed"));
|
|
122598
|
+
if (api.deviceId) captureOnDemandDropped(api.deviceId, key2);
|
|
122539
122599
|
});
|
|
122540
122600
|
connections.set(key2, conn);
|
|
122541
122601
|
return conn;
|
|
@@ -123211,6 +123271,19 @@ async function spawnSimulatorServerProcess(udid, subcommand) {
|
|
|
123211
123271
|
}, READY_TIMEOUT_MS);
|
|
123212
123272
|
});
|
|
123213
123273
|
}
|
|
123274
|
+
function withCaptureOnDemand(deviceId, instance) {
|
|
123275
|
+
const unregister = registerCaptureOnDemandSender(deviceId, instance.api.apiUrl, (enabled) => {
|
|
123276
|
+
sendCommand(instance.api, { cmd: "capture_on_demand", enabled }).catch(() => {
|
|
123277
|
+
});
|
|
123278
|
+
});
|
|
123279
|
+
return {
|
|
123280
|
+
...instance,
|
|
123281
|
+
dispose: async () => {
|
|
123282
|
+
unregister();
|
|
123283
|
+
await instance.dispose();
|
|
123284
|
+
}
|
|
123285
|
+
};
|
|
123286
|
+
}
|
|
123214
123287
|
var simulatorServerBlueprint = {
|
|
123215
123288
|
namespace: SIMULATOR_SERVER_NAMESPACE,
|
|
123216
123289
|
getURN(device) {
|
|
@@ -123255,7 +123328,7 @@ var simulatorServerBlueprint = {
|
|
|
123255
123328
|
}
|
|
123256
123329
|
const claim2 = externalClaimForAnyId(device.id);
|
|
123257
123330
|
if (claim2) {
|
|
123258
|
-
return buildAttachedInstance(device, claim2);
|
|
123331
|
+
return withCaptureOnDemand(device.id, await buildAttachedInstance(device, claim2));
|
|
123259
123332
|
}
|
|
123260
123333
|
if (device.platform === "ios-remote") {
|
|
123261
123334
|
return buildRemoteInstance(device);
|
|
@@ -123313,7 +123386,7 @@ var simulatorServerBlueprint = {
|
|
|
123313
123386
|
events
|
|
123314
123387
|
};
|
|
123315
123388
|
await attachFoldableDisplay(instance.api, device);
|
|
123316
|
-
return instance;
|
|
123389
|
+
return withCaptureOnDemand(device.id, instance);
|
|
123317
123390
|
}
|
|
123318
123391
|
};
|
|
123319
123392
|
|
|
@@ -125977,6 +126050,7 @@ Chromium apps are discovered by probing CDP debugging ports (default 9222; exten
|
|
|
125977
126050
|
Booted/ready devices are listed first. Platforms whose CLI is unavailable are silently omitted; an empty result usually means xcode-select, Android platform-tools, <flag:harmonyos>DevEco Studio, </flag:harmonyos>or the Vega SDK is not installed.`,
|
|
125978
126051
|
alwaysLoad: true,
|
|
125979
126052
|
searchHint: "list devices simulators emulators avd serial udid ios android chromium vega <flag:harmonyos>harmony harmonyos </flag:harmonyos>app fire tv session start",
|
|
126053
|
+
readOnly: true,
|
|
125980
126054
|
zodSchema,
|
|
125981
126055
|
services: () => ({}),
|
|
125982
126056
|
async execute(_services, _params) {
|
|
@@ -130727,6 +130801,7 @@ function createHttpApp(registry2, options) {
|
|
|
130727
130801
|
if (def.searchHint) entry.searchHint = renderFlagGated(def.searchHint, isFlagEnabled);
|
|
130728
130802
|
if (def.longRunning) entry.longRunning = true;
|
|
130729
130803
|
if (def.hideFromMcp) entry.hideFromMcp = true;
|
|
130804
|
+
if (def.readOnly) entry.readOnly = true;
|
|
130730
130805
|
const aliases = (def.aliases ?? []).map((alias) => ({
|
|
130731
130806
|
...entry,
|
|
130732
130807
|
name: alias,
|
|
@@ -130974,11 +131049,12 @@ function createHttpApp(registry2, options) {
|
|
|
130974
131049
|
const toolNote = takeToolNote(data);
|
|
130975
131050
|
if (toolNote) notes.push(toolNote);
|
|
130976
131051
|
const notePayload = notes.length > 0 ? { note: notes.join("\n\n") } : {};
|
|
131052
|
+
const profilingPayload = deviceArg && isProfiling(canonicalDeviceId(deviceArg) ?? deviceArg) ? { profiling: true } : {};
|
|
130977
131053
|
if (wantsStream) {
|
|
130978
|
-
writeLine({ event: "result", data, ...notePayload });
|
|
131054
|
+
writeLine({ event: "result", data, ...notePayload, ...profilingPayload });
|
|
130979
131055
|
res.end();
|
|
130980
131056
|
} else {
|
|
130981
|
-
res.json({ data, ...notePayload });
|
|
131057
|
+
res.json({ data, ...notePayload, ...profilingPayload });
|
|
130982
131058
|
}
|
|
130983
131059
|
} catch (err) {
|
|
130984
131060
|
const attribute = (message) => {
|
|
@@ -133830,6 +133906,7 @@ If state is connecting: do NOT restart the app. Launching it is what starts the
|
|
|
133830
133906
|
If state is indeterminate: the process could not be inspected, so restart-app is worth one attempt. If this call still reports it after that restart, do NOT restart the app again: the service is stale rather than the app uninjected, so restart the tool-server (\`argent server stop && argent server start --detach\`) and retry. Remote simulators can never inspect the process, so this is the only unconnected state a running app reaches there.
|
|
133831
133907
|
Returns { status: "init_failed", message, attempts } instead when the simulator's native-devtools environment failed to initialize.
|
|
133832
133908
|
Fails if the simulator server is not running for the given UDID.`,
|
|
133909
|
+
readOnly: true,
|
|
133833
133910
|
zodSchema: zodSchema2,
|
|
133834
133911
|
services: (params) => ({
|
|
133835
133912
|
nativeDevtools: nativeDevtoolsRef(resolveDevice(params.udid))
|
|
@@ -133987,6 +134064,7 @@ Returns { status: "ok", matches } with matching views including their frames, pr
|
|
|
133987
134064
|
At least one of className, identifier, label, tag, or nativeID must be provided.
|
|
133988
134065
|
If status is restart_required: follow the message (usually restart-app), then retry. If status is service_stale: the app is already injected, so restarting it cannot help. Restart the tool-server (\`argent server stop && argent server start --detach\`) and retry. If the same status comes back after that restart, stop restarting: follow the message, which names the terminal fallback. If status is connect_pending: the app is injected and still connecting. Do not restart it, wait a few seconds and retry. If status is init_failed: the simulator's native-devtools environment could not be initialised. Follow the message (re-boot the simulator) rather than retrying this tool.
|
|
133989
134066
|
A not-connected or not-running app comes back as one of those statuses rather than a failure. Failures are separate: an Apple system app is rejected outright (terminal: never retry it), and the hierarchy query itself can error or time out.`,
|
|
134067
|
+
readOnly: true,
|
|
133990
134068
|
zodSchema: zodSchema4,
|
|
133991
134069
|
services: (params) => ({
|
|
133992
134070
|
nativeDevtools: nativeDevtoolsRef(resolveDevice(params.udid))
|
|
@@ -134057,6 +134135,7 @@ Use when you need deep layout debugging, finding views with no accessibility lab
|
|
|
134057
134135
|
Returns { status: "ok", windows, screen } with the full view hierarchy. screen gives the screen size in points on its portrait axes, and the interfaceOrientation of the UI (portrait, portraitUpsideDown, landscapeLeft, landscapeRight). Each screenFrame uses the portrait axes of the screen. Each windowFrame uses the axes of its window, which turn with the UI.
|
|
134058
134136
|
If status is restart_required: follow the message (usually restart-app), then retry. If status is service_stale: the app is already injected, so restarting it cannot help. Restart the tool-server (\`argent server stop && argent server start --detach\`) and retry. If the same status comes back after that restart, stop restarting: follow the message, which names the terminal fallback. If status is connect_pending: the app is injected and still connecting. Do not restart it, wait a few seconds and retry. If status is init_failed: the simulator's native-devtools environment could not be initialised. Follow the message (re-boot the simulator) rather than retrying this tool.
|
|
134059
134137
|
A not-connected or not-running app comes back as one of those statuses rather than a failure. Failures are separate: an Apple system app is rejected outright (terminal: never retry it), and the hierarchy query itself can error or time out.`,
|
|
134138
|
+
readOnly: true,
|
|
134060
134139
|
zodSchema: zodSchema5,
|
|
134061
134140
|
services: (params) => ({
|
|
134062
134141
|
nativeDevtools: nativeDevtoolsRef(resolveDevice(params.udid))
|
|
@@ -134126,6 +134205,7 @@ normalized contract.
|
|
|
134126
134205
|
|
|
134127
134206
|
If status is restart_required: follow the message (usually restart-app), then retry. If status is service_stale: the app is already injected, so restarting it cannot help. Restart the tool-server (\`argent server stop && argent server start --detach\`) and retry. If the same status comes back after that restart, stop restarting: follow the message, which names the terminal fallback. If status is connect_pending: the app is injected and still connecting. Do not restart it, wait a few seconds and retry. If status is init_failed: the simulator's native-devtools environment could not be initialised. Follow the message (re-boot the simulator) rather than retrying this tool.
|
|
134128
134207
|
A not-connected or not-running app comes back as one of those statuses rather than a failure. Failures are separate: an Apple system app is rejected outright (terminal: never retry it), and the screen query itself can error or time out.`,
|
|
134208
|
+
readOnly: true,
|
|
134129
134209
|
zodSchema: zodSchema6,
|
|
134130
134210
|
services: (params) => ({
|
|
134131
134211
|
nativeDevtools: nativeDevtoolsRef(resolveDevice(params.udid))
|
|
@@ -134208,6 +134288,7 @@ the UI is landscape.
|
|
|
134208
134288
|
|
|
134209
134289
|
If status is restart_required: follow the message (usually restart-app), then retry. If status is service_stale: the app is already injected, so restarting it cannot help. Restart the tool-server (\`argent server stop && argent server start --detach\`) and retry. If the same status comes back after that restart, stop restarting: follow the message, which names the terminal fallback. If status is connect_pending: the app is injected and still connecting. Do not restart it, wait a few seconds and retry. If status is init_failed: the simulator's native-devtools environment could not be initialised. Follow the message (re-boot the simulator) rather than retrying this tool.
|
|
134210
134290
|
A not-connected or not-running app comes back as one of those statuses rather than a failure. Failures are separate: an Apple system app is rejected outright (terminal: never retry it), and the point query itself can error or time out.`,
|
|
134291
|
+
readOnly: true,
|
|
134211
134292
|
zodSchema: zodSchema7,
|
|
134212
134293
|
services: (params) => ({
|
|
134213
134294
|
nativeDevtools: nativeDevtoolsRef(resolveDevice(params.udid))
|
|
@@ -134296,6 +134377,7 @@ the UI is landscape.
|
|
|
134296
134377
|
|
|
134297
134378
|
If status is restart_required: follow the message (usually restart-app), then retry. If status is service_stale: the app is already injected, so restarting it cannot help. Restart the tool-server (\`argent server stop && argent server start --detach\`) and retry. If the same status comes back after that restart, stop restarting: follow the message, which names the terminal fallback. If status is connect_pending: the app is injected and still connecting. Do not restart it, wait a few seconds and retry. If status is init_failed: the simulator's native-devtools environment could not be initialised. Follow the message (re-boot the simulator) rather than retrying this tool.
|
|
134298
134379
|
A not-connected or not-running app comes back as one of those statuses rather than a failure. Failures are separate: an Apple system app is rejected outright (terminal: never retry it), and the point query itself can error or time out.`,
|
|
134380
|
+
readOnly: true,
|
|
134299
134381
|
zodSchema: zodSchema8,
|
|
134300
134382
|
services: (params) => ({
|
|
134301
134383
|
nativeDevtools: nativeDevtoolsRef(resolveDevice(params.udid))
|
|
@@ -136753,6 +136835,7 @@ var reactProfilerSessionBlueprint = {
|
|
|
136753
136835
|
profileStartWallMs: null,
|
|
136754
136836
|
sessionId: null,
|
|
136755
136837
|
ownerToolServerPid: null,
|
|
136838
|
+
disposed: false,
|
|
136756
136839
|
disposeSession: () => events.emit("terminated")
|
|
136757
136840
|
};
|
|
136758
136841
|
await cdp.send("Profiler.enable").catch(warnOnError("Profiler.enable"));
|
|
@@ -136815,11 +136898,25 @@ var reactProfilerSessionBlueprint = {
|
|
|
136815
136898
|
);
|
|
136816
136899
|
};
|
|
136817
136900
|
cdp.events.on("disconnected", onDisconnected);
|
|
136901
|
+
const onCdpEvent = (method) => {
|
|
136902
|
+
if (method !== "Runtime.executionContextDestroyed" && method !== "Runtime.executionContextsCleared") {
|
|
136903
|
+
return;
|
|
136904
|
+
}
|
|
136905
|
+
if (state3.profilingActive) {
|
|
136906
|
+
state3.profilingActive = false;
|
|
136907
|
+
clearCachedProfilerPaths(state3.port, state3.deviceId);
|
|
136908
|
+
stopSamplerInNextRuntime(cdp);
|
|
136909
|
+
}
|
|
136910
|
+
events.emit("terminated");
|
|
136911
|
+
};
|
|
136912
|
+
cdp.events.on("event", onCdpEvent);
|
|
136818
136913
|
return {
|
|
136819
136914
|
api: state3,
|
|
136820
136915
|
dispose: async () => {
|
|
136916
|
+
state3.disposed = true;
|
|
136821
136917
|
cdp.events.off("scriptParsed", onScriptParsed);
|
|
136822
136918
|
cdp.events.off("disconnected", onDisconnected);
|
|
136919
|
+
cdp.events.off("event", onCdpEvent);
|
|
136823
136920
|
if (state3.profilingActive) {
|
|
136824
136921
|
state3.profilingActive = false;
|
|
136825
136922
|
await cdp.send("Runtime.evaluate", {
|
|
@@ -136834,6 +136931,20 @@ var reactProfilerSessionBlueprint = {
|
|
|
136834
136931
|
};
|
|
136835
136932
|
}
|
|
136836
136933
|
};
|
|
136934
|
+
function stopSamplerInNextRuntime(cdp) {
|
|
136935
|
+
const onEvent = (method) => {
|
|
136936
|
+
if (method !== "Runtime.executionContextCreated") return;
|
|
136937
|
+
disarm();
|
|
136938
|
+
void cdp.send("Profiler.stop").catch(() => {
|
|
136939
|
+
});
|
|
136940
|
+
};
|
|
136941
|
+
const disarm = () => {
|
|
136942
|
+
cdp.events.off("event", onEvent);
|
|
136943
|
+
cdp.events.off("disconnected", disarm);
|
|
136944
|
+
};
|
|
136945
|
+
cdp.events.on("event", onEvent);
|
|
136946
|
+
cdp.events.on("disconnected", disarm);
|
|
136947
|
+
}
|
|
136837
136948
|
var profilerPathsCache = /* @__PURE__ */ new Map();
|
|
136838
136949
|
function cacheKey(port, deviceId) {
|
|
136839
136950
|
return `${port}:${deviceId}`;
|
|
@@ -136935,6 +137046,9 @@ function iosHeadlessFromEnv() {
|
|
|
136935
137046
|
function androidHeadlessFromEnv() {
|
|
136936
137047
|
return truthyEnv("ARGENT_EMULATOR_NO_WINDOW");
|
|
136937
137048
|
}
|
|
137049
|
+
function androidGuestVulkanFromEnv() {
|
|
137050
|
+
return truthyEnv("ARGENT_EMULATOR_GUEST_VULKAN");
|
|
137051
|
+
}
|
|
136938
137052
|
|
|
136939
137053
|
// ../tool-server/src/tools/devices/boot-device.ts
|
|
136940
137054
|
init_device_info();
|
|
@@ -137687,6 +137801,9 @@ var zodSchema9 = external_exports.object({
|
|
|
137687
137801
|
sound: external_exports.boolean().optional().describe(
|
|
137688
137802
|
"Android only: boot the emulator with audio output enabled. Defaults to false: argent boots emulators MUTED so several agent-driven devices don't all play sound on the host machine; pass `true` when the task involves playing, hearing, or testing audio. Takes effect at boot: if the emulator is already running muted, add `force: true` to reboot it with sound. A boot snapshot saved in the other audio mode can't be reused, so the first boot after toggling is a slower cold boot. The `boot-sound` argent flag flips this default to true. Ignored on iOS/Vega<flag:harmonyos>/HarmonyOS</flag:harmonyos>/Electron, which argent never mutes."
|
|
137689
137803
|
),
|
|
137804
|
+
guestVulkan: external_exports.boolean().optional().describe(
|
|
137805
|
+
"Android on a macOS host only: boot the emulator with guest Vulkan. Defaults to false: guest Vulkan crashes Chrome's GPU process, which breaks Chrome and Custom Tab sign-in flows. Without it apps find no Vulkan device, although the guest still lists the Vulkan features, so a Vulkan-only renderer such as WebGPU (react-native-wgpu) draws nothing; pass `true` to test one. Takes effect at boot: an emulator already running in the other mode is reused with a `note`, and `force: true` reboots it. A boot snapshot saved in the other mode can't be reused, so the first boot after toggling is a slower cold boot. The `ARGENT_EMULATOR_GUEST_VULKAN` env var flips this default to true. Ignored on other hosts and platforms."
|
|
137806
|
+
),
|
|
137690
137807
|
headless: external_exports.boolean().optional().describe(
|
|
137691
137808
|
"iOS only: boot the simulator core WITHOUT opening its GUI window (Simulator.app, or Device Hub on Xcode 27+). The device still streams via simulator-server; used by Argent Lens. Set the `ARGENT_SIMULATOR_NO_WINDOW` env var (1/true/yes) to force this host-wide without passing the flag per call (the iOS analog of `ARGENT_EMULATOR_NO_WINDOW`). Ignored on Android/Vega<flag:harmonyos>/HarmonyOS</flag:harmonyos>/Electron, which have no equivalent GUI step."
|
|
137692
137809
|
),
|
|
@@ -137754,14 +137871,27 @@ function selectGpuMode() {
|
|
|
137754
137871
|
}
|
|
137755
137872
|
return process.platform === "linux" ? "swiftshader" : "auto";
|
|
137756
137873
|
}
|
|
137874
|
+
function guestVulkanArgs(guestVulkan) {
|
|
137875
|
+
if (process.platform !== "darwin") return [];
|
|
137876
|
+
return ["-feature", guestVulkan ? "Vulkan" : "-Vulkan"];
|
|
137877
|
+
}
|
|
137878
|
+
async function runningGuestVulkanNote(serial, guestVulkan) {
|
|
137879
|
+
if (process.platform !== "darwin") return void 0;
|
|
137880
|
+
const prop = await adbShell(serial, "getprop ro.boot.hardware.vulkan", { timeoutMs: 5e3 }).then((out) => out.trim()).catch(() => null);
|
|
137881
|
+
if (prop === null || prop !== "" === guestVulkan) return void 0;
|
|
137882
|
+
return guestVulkan ? "This emulator was already running without guest Vulkan, so apps find no Vulkan device. Pass `force: true` to reboot it with guest Vulkan." : "This emulator was already running with guest Vulkan, which can crash Chrome's GPU process. Pass `force: true` to reboot it without guest Vulkan.";
|
|
137883
|
+
}
|
|
137757
137884
|
var BOOT_POLL_INTERVALS_MS = {
|
|
137758
137885
|
serialByAvd: 1500,
|
|
137759
137886
|
// findSerialByAvdName: re-scan when >1 new emulator appeared
|
|
137760
137887
|
adbRegister: 1e3,
|
|
137761
137888
|
// attemptBoot stage 2: re-scan adb devices for the new serial
|
|
137762
|
-
earlyExit: 500
|
|
137889
|
+
earlyExit: 500,
|
|
137763
137890
|
// createEarlyExitRacer: re-check the crash latch during a blocking adb call
|
|
137891
|
+
serialGone: 500
|
|
137892
|
+
// awaitEmulatorsGone: re-scan adb devices for a killed emulator
|
|
137764
137893
|
};
|
|
137894
|
+
var EMULATOR_GONE_BUDGET_MS = 3e4;
|
|
137765
137895
|
var FRAME_PROBE = "screencap -p 2>/dev/null | wc -c | awk '$1>20000{print 1;exit} {print 0}'";
|
|
137766
137896
|
async function killEmulatorQuietly(serial, child) {
|
|
137767
137897
|
if (serial) {
|
|
@@ -137841,18 +137971,28 @@ async function findSerialByAvdName(avdName, deadline) {
|
|
|
137841
137971
|
}
|
|
137842
137972
|
return null;
|
|
137843
137973
|
}
|
|
137844
|
-
async function
|
|
137974
|
+
async function listEmulatorSerials() {
|
|
137845
137975
|
const { stdout } = await runAdb(["devices"], { timeoutMs: 3e3 }).catch(() => ({
|
|
137846
137976
|
stdout: "",
|
|
137847
137977
|
stderr: ""
|
|
137848
137978
|
}));
|
|
137849
|
-
const lines = stdout.split("\n");
|
|
137850
137979
|
const now = [];
|
|
137851
|
-
for (const line of
|
|
137980
|
+
for (const line of stdout.split("\n")) {
|
|
137852
137981
|
const m = line.match(/^(emulator-\d+)\s+/);
|
|
137853
137982
|
if (m) now.push(m[1]);
|
|
137854
137983
|
}
|
|
137855
|
-
return now
|
|
137984
|
+
return now;
|
|
137985
|
+
}
|
|
137986
|
+
async function listNewEmulatorSerials(before) {
|
|
137987
|
+
return (await listEmulatorSerials()).filter((s) => !before.has(s));
|
|
137988
|
+
}
|
|
137989
|
+
async function awaitEmulatorsGone(serials) {
|
|
137990
|
+
const deadline = Date.now() + EMULATOR_GONE_BUDGET_MS;
|
|
137991
|
+
while (serials.length > 0 && Date.now() < deadline) {
|
|
137992
|
+
const listed = await listEmulatorSerials();
|
|
137993
|
+
if (!serials.some((s) => listed.includes(s))) return;
|
|
137994
|
+
await new Promise((r) => setTimeout(r, BOOT_POLL_INTERVALS_MS.serialGone));
|
|
137995
|
+
}
|
|
137856
137996
|
}
|
|
137857
137997
|
async function bootIos(udid, registry2, force, headless) {
|
|
137858
137998
|
if (process.platform !== "darwin") {
|
|
@@ -138152,7 +138292,10 @@ async function bootAndroidImpl(params) {
|
|
|
138152
138292
|
await ensureDep("adb");
|
|
138153
138293
|
await ensureDep("emulator");
|
|
138154
138294
|
const gpuMode = selectGpuMode();
|
|
138155
|
-
const extraEmulatorArgs =
|
|
138295
|
+
const extraEmulatorArgs = [
|
|
138296
|
+
...androidHeadlessFromEnv() ? ["-no-window"] : [],
|
|
138297
|
+
...guestVulkanArgs(params.guestVulkan)
|
|
138298
|
+
];
|
|
138156
138299
|
const hardeningArgs = launchHardeningArgs(params.sound);
|
|
138157
138300
|
for (const msg of linuxBootDiagnostics(params.avdName) ?? []) {
|
|
138158
138301
|
console.warn(`[boot-device:linux] ${msg}`);
|
|
@@ -138201,26 +138344,31 @@ async function bootAndroidImpl(params) {
|
|
|
138201
138344
|
});
|
|
138202
138345
|
const existingDevices = await listAndroidDevices().catch(() => []);
|
|
138203
138346
|
let hotBootFailureReason;
|
|
138347
|
+
const dropKilledEmulator = async (serial) => {
|
|
138348
|
+
await awaitEmulatorsGone([serial]);
|
|
138349
|
+
const refreshed = await listAndroidDevices().catch(() => existingDevices);
|
|
138350
|
+
existingDevices.splice(0, existingDevices.length, ...refreshed);
|
|
138351
|
+
};
|
|
138204
138352
|
const alreadyRunning = existingDevices.find(
|
|
138205
138353
|
(d) => d.isEmulator && d.avdName === params.avdName && d.state === "device"
|
|
138206
138354
|
);
|
|
138207
138355
|
if (alreadyRunning) {
|
|
138208
138356
|
if (params.force) {
|
|
138209
138357
|
await killEmulatorQuietly(alreadyRunning.serial);
|
|
138210
|
-
|
|
138211
|
-
existingDevices.splice(0, existingDevices.length, ...refreshed);
|
|
138358
|
+
await dropKilledEmulator(alreadyRunning.serial);
|
|
138212
138359
|
} else {
|
|
138213
138360
|
try {
|
|
138214
138361
|
await assertScreencapAlive(alreadyRunning.serial);
|
|
138362
|
+
const note = await runningGuestVulkanNote(alreadyRunning.serial, params.guestVulkan);
|
|
138215
138363
|
return {
|
|
138216
138364
|
platform: "android",
|
|
138217
138365
|
serial: alreadyRunning.serial,
|
|
138218
138366
|
avdName: params.avdName,
|
|
138219
|
-
booted: true
|
|
138367
|
+
booted: true,
|
|
138368
|
+
...note ? { note } : {}
|
|
138220
138369
|
};
|
|
138221
138370
|
} catch (_err) {
|
|
138222
|
-
|
|
138223
|
-
existingDevices.splice(0, existingDevices.length, ...refreshed);
|
|
138371
|
+
await dropKilledEmulator(alreadyRunning.serial);
|
|
138224
138372
|
}
|
|
138225
138373
|
}
|
|
138226
138374
|
}
|
|
@@ -138273,6 +138421,7 @@ async function bootAndroidImpl(params) {
|
|
|
138273
138421
|
};
|
|
138274
138422
|
} catch (err) {
|
|
138275
138423
|
hotBootFailureReason = err instanceof Error ? err.message : String(err);
|
|
138424
|
+
await awaitEmulatorsGone(await listNewEmulatorSerials(serialsBefore));
|
|
138276
138425
|
const refreshed = new Set(
|
|
138277
138426
|
(await listAndroidDevices().catch(() => [])).map((d) => d.serial)
|
|
138278
138427
|
);
|
|
@@ -138838,7 +138987,7 @@ function createBootDeviceTool(registry2) {
|
|
|
138838
138987
|
description: `Start an iOS simulator, launch an Android emulator, start a Vega (Fire TV) Virtual Device, <flag:harmonyos>start a HarmonyOS emulator, </flag:harmonyos>or spawn an Electron app and wait until it is ready to accept interactions.
|
|
138839
138988
|
Pick the platform by which argument you pass: 'udid' for an iOS simulator from list-devices, 'avdName' for an Android AVD (a serial is assigned automatically), 'vvdImage' for a Vega VVD (the 'vvdImage' of a vega device from list-devices, e.g. 'tv'), <flag:harmonyos>'harmonyInstance' for a HarmonyOS emulator instance (the 'name' of a harmony device from list-devices), </flag:harmonyos>or 'electronAppPath' for an Electron app (a CDP remote-debugging port is picked automatically, or pass 'electronPort' to fix one).
|
|
138840
138989
|
Use at the start of a session once you have picked a target.
|
|
138841
|
-
Returns a tagged payload: { platform: 'ios', udid, booted } or { platform: 'android', serial, avdName, booted } or { platform: 'vega', serial, vvdImage, booted } or <flag:harmonyos>{ platform: 'harmony', udid, instanceName, booted, note? } or </flag:harmonyos>{ platform: 'chromium', id, port, pid, booted } (an Electron app boots as a Chromium/CDP device).
|
|
138990
|
+
Returns a tagged payload: { platform: 'ios', udid, booted } or { platform: 'android', serial, avdName, booted, note? } or { platform: 'vega', serial, vvdImage, booted } or <flag:harmonyos>{ platform: 'harmony', udid, instanceName, booted, note? } or </flag:harmonyos>{ platform: 'chromium', id, port, pid, booted } (an Electron app boots as a Chromium/CDP device).
|
|
138842
138991
|
Android boots take 2\u201310 minutes depending on machine and cold/warm state; the tool transparently hot-boots from the AVD's default_boot snapshot when usable and falls back to cold boot otherwise. Vega starts the single SDK-managed VVD via the vega CLI (~10s) and returns once it reports running. If an Android/Electron boot stage fails, the tool terminates the device it spawned so the next retry starts clean.<flag:harmonyos>
|
|
138843
138992
|
HarmonyOS hands the instance to DevEco Studio's Emulator manager, then waits for it to register with 'hdc' and returns its connect key as 'udid', the id the interaction tools drive. The manager itself reports no readiness signal and never names a port, so an instance that is already running is left alone unless you pass 'force: true'; when the key could not be resolved the payload names the instance instead, and a 'note' is present whenever the boot left something unproven: no key and why, or a key that is not yet answering or could not be checked against the instance. Huawei serves the emulator images only within mainland China, so a host outside it usually has no instance to start; one that already has an image is started like any other.</flag:harmonyos>`,
|
|
138844
138993
|
alwaysLoad: true,
|
|
@@ -138901,7 +139050,8 @@ HarmonyOS hands the instance to DevEco Studio's Emulator manager, then waits for
|
|
|
138901
139050
|
// An explicit argument always wins; the `boot-sound` flag only moves
|
|
138902
139051
|
// the default when the caller left `sound` unset. Read live per call
|
|
138903
139052
|
// so `argent enable/disable boot-sound` applies without a restart.
|
|
138904
|
-
sound: params.sound ?? isFlagEnabled("boot-sound")
|
|
139053
|
+
sound: params.sound ?? isFlagEnabled("boot-sound"),
|
|
139054
|
+
guestVulkan: params.guestVulkan ?? androidGuestVulkanFromEnv()
|
|
138905
139055
|
});
|
|
138906
139056
|
}
|
|
138907
139057
|
if (hasVega) {
|
|
@@ -139501,7 +139651,7 @@ Returns { launched, bundleId, note? }. Fails if the app is not installed on the
|
|
|
139501
139651
|
For Chromium, the app is already running behind a CDP port; this call simply refreshes the cached viewport and acknowledges the bundleId tag. To change the visible route, use \`open-url\`.
|
|
139502
139652
|
On Vega (Fire TV), pass the interactive component app id from manifest.toml (e.g. com.example.app.main) as bundleId.
|
|
139503
139653
|
|
|
139504
|
-
Common iOS bundle ids: com.apple.MobileSMS, com.apple.mobilesafari, com.apple.Preferences, com.apple.Maps, com.apple.
|
|
139654
|
+
Common iOS bundle ids: com.apple.MobileSMS, com.apple.mobilesafari, com.apple.Preferences, com.apple.Maps, com.apple.mobileslideshow (Photos), com.apple.MobileAddressBook
|
|
139505
139655
|
Common Android packages: com.android.settings, com.android.chrome, com.google.android.apps.maps, com.google.android.gm, com.android.vending, com.google.android.dialer, com.google.android.apps.messaging`,
|
|
139506
139656
|
alwaysLoad: true,
|
|
139507
139657
|
searchHint: "open start app bundle id package simulator emulator chromium vega launch tvos apple tv fire tv",
|
|
@@ -141514,6 +141664,7 @@ Use when you need a baseline image before an interaction or to inspect the curre
|
|
|
141514
141664
|
Fails if the simulator-server / emulator backend / Chromium CDP <flag:harmonyos>/ \`hdc\` </flag:harmonyos>is not reachable for the given device.`,
|
|
141515
141665
|
alwaysLoad: true,
|
|
141516
141666
|
searchHint: "device simulator emulator chromium screen image capture baseline tvos apple tv",
|
|
141667
|
+
readOnly: true,
|
|
141517
141668
|
zodSchema: zodSchema16,
|
|
141518
141669
|
outputHint: "image",
|
|
141519
141670
|
capability: capability8,
|
|
@@ -150783,6 +150934,7 @@ after a tap/navigation to wait for the next screen, or before tapping an element
|
|
|
150783
150934
|
alwaysLoad: true,
|
|
150784
150935
|
searchHint: "wait await poll until visible hidden exists text appears disappears timeout element condition settle",
|
|
150785
150936
|
longRunning: true,
|
|
150937
|
+
readOnly: true,
|
|
150786
150938
|
zodSchema: zodSchema29,
|
|
150787
150939
|
capability: capability23,
|
|
150788
150940
|
services: (params) => {
|
|
@@ -151214,6 +151366,7 @@ function createDebuggerStatusTool(registry2) {
|
|
|
151214
151366
|
Use when you need to verify connectivity before using other debugger tools. Never fails when the runtime is simply unreachable: it returns a discriminated result instead:
|
|
151215
151367
|
- { status: "connected", ... } with port, projectRoot (empty on Chromium and on legacy Metro, e.g. Vega), deviceName, appName, logicalDeviceId (absent on Vega), isNewDebugger (false on the legacy inspector), connected flag, loadedScripts count, and sourceMapReady (always true: waits for pending source maps before returning; no-op on Chromium).
|
|
151216
151368
|
- { status: "not_connected", connected: false, reason, detail, guidance } (port omitted on Chromium) when Metro is not running (reason "metro_not_running"), no app is attached ("no_app_connected"), the device_id matches no target ("device_mismatch"), the CDP endpoint is unreachable or answered malformed ("cdp_unreachable"), the runtime accepted the connection but never answered ("runtime_unresponsive"), the cached connection went stale ("stale_connection"), or a reconnect is in flight ("reconnecting"). Follow the guidance field; do not retry in a loop.`,
|
|
151369
|
+
readOnly: true,
|
|
151217
151370
|
zodSchema: zodSchema32,
|
|
151218
151371
|
capability: DEBUGGER_TOOL_CAPABILITY,
|
|
151219
151372
|
// Resolved manually in execute so a not-connected precondition becomes a
|
|
@@ -152325,6 +152478,7 @@ Set includeSkipped=true to see a summary of all filtered components.
|
|
|
152325
152478
|
Use when you need tap coordinates for a React Native UI element. Returns a compact text tree with (tap: x,y) coords. Fails if Metro debugger is not connected.`,
|
|
152326
152479
|
alwaysLoad: true,
|
|
152327
152480
|
searchHint: "react native component tree discovery tap coordinates",
|
|
152481
|
+
readOnly: true,
|
|
152328
152482
|
zodSchema: zodSchema35,
|
|
152329
152483
|
// RN-only: needs the React DevTools backend from the dev JS bundle. Chromium has
|
|
152330
152484
|
// no equivalent — use `describe` there.
|
|
@@ -152841,6 +152995,7 @@ Uses getInspectorDataForViewAtPoint + _debugStack + Metro /symbolicate.
|
|
|
152841
152995
|
Set resolveSourceMaps to false to skip symbolication and get raw bundled locations instead.
|
|
152842
152996
|
Set includeSkipped=true to see filtered items annotated with skip reasons.
|
|
152843
152997
|
Use when you need the source file and line for a component at a tap coordinate. Fails if the app is not connected or the coordinate is outside the screen.`,
|
|
152998
|
+
readOnly: true,
|
|
152844
152999
|
zodSchema: zodSchema36,
|
|
152845
153000
|
// RN-only: needs React Native's internal getInspectorDataForViewAtPoint and
|
|
152846
153001
|
// Metro's /symbolicate; the Chromium session has no source resolver.
|
|
@@ -152958,6 +153113,7 @@ function createDebuggerLogRegistryTool(registry2) {
|
|
|
152958
153113
|
Returns the log file path, entry counts by level, and message clusters (grouped by similarity). Works against Hermes (iOS / Android / Vega) and V8 (Chromium).
|
|
152959
153114
|
Use when investigating warnings, errors, or unexpected output. Call this first for an overview, then read the returned file for details. Returns empty stats if no log data has been captured yet, but check { note }, which is present only when the stats are empty BECAUSE the previous debugger session ended: torn down (e.g. by stop-all-simulator-servers) with its log file deleted, or cut off by the app crashing with its log file kept at the path the note names. Absent that note, empty really does mean the app has logged nothing.
|
|
152960
153115
|
When the debugger cannot be reached, this tool does not fail: it returns { status: "not_connected", reason, detail, guidance } with NO log file. Follow the guidance (do not retry in a loop). Read a log file in this state only when a { note } names one kept from before the app crashed. A "connected" result's stats may come from a session whose socket has since died. Use debugger-status, not this tool, to judge debugger health.`,
|
|
153116
|
+
readOnly: true,
|
|
152961
153117
|
zodSchema: zodSchema37,
|
|
152962
153118
|
capability: DEBUGGER_TOOL_CAPABILITY,
|
|
152963
153119
|
// Resolved manually in execute so a not-connected precondition becomes a
|
|
@@ -153137,6 +153293,7 @@ Each entry includes a requestId that can be passed to view-network-request-detai
|
|
|
153137
153293
|
On React Native (iOS / Android / Vega) interception is injected into the JS runtime: it records each request once: XMLHttpRequest (axios included), React Native's fetch, Expo's fetch, and a fetch library that sends through React Native's network module itself, such as react-native-fetch-api (found in a Metro development build). Capture starts at the first network-tool call; a reload clears it. On Chromium it reads the browser's native CDP Network domain (the active tab; all request types).
|
|
153138
153294
|
Use when inspecting outbound HTTP traffic or debugging API calls in the running app.
|
|
153139
153295
|
Fails if the app is not connected (RN) or the device is not reachable (Chromium).`,
|
|
153296
|
+
readOnly: true,
|
|
153140
153297
|
zodSchema: zodSchema38,
|
|
153141
153298
|
capability: DEBUGGER_TOOL_CAPABILITY,
|
|
153142
153299
|
services: (params) => {
|
|
@@ -153254,6 +153411,7 @@ var networkRequestTool = {
|
|
|
153254
153411
|
Returns request/response headers (sensitive headers redacted), status, timing, the request body, and optionally the response body.
|
|
153255
153412
|
Request and response bodies over 1000 chars are cut to 1000 under a "[TRUNCATED: ...]" line that gives the full size; a binary response body is replaced by "[body omitted: binary <mime>, N bytes]". Use when you need headers, body, or timing for a specific request after listing logs.
|
|
153256
153413
|
Returns an error message string if the requestId is not found: use view-network-logs to get valid requestId values.`,
|
|
153414
|
+
readOnly: true,
|
|
153257
153415
|
zodSchema: zodSchema39,
|
|
153258
153416
|
capability: DEBUGGER_TOOL_CAPABILITY,
|
|
153259
153417
|
services: (params) => {
|
|
@@ -153700,6 +153858,7 @@ since a TV UI has no tap coordinates. Move the highlight with \`tv-remote\` (up/
|
|
|
153700
153858
|
back/menu/home), then call describe again to confirm where focus landed.`,
|
|
153701
153859
|
alwaysLoad: true,
|
|
153702
153860
|
searchHint: "accessibility element tree ui hierarchy tap coordinates ios android chromium vega <flag:harmonyos>harmony harmonyos </flag:harmonyos>dom tv tvos apple tv android tv fire tv focus focusable remote dpad",
|
|
153861
|
+
readOnly: true,
|
|
153703
153862
|
zodSchema: zodSchema40,
|
|
153704
153863
|
capability: capability25,
|
|
153705
153864
|
services: (params) => {
|
|
@@ -154200,6 +154359,7 @@ Use when a program needs element ancestry, such as an e2e engine's scoped select
|
|
|
154200
154359
|
Returns { schemaVersion, roots, truncated, alertVisible, keyboardVisible, foregroundApp, unsupportedFields }.
|
|
154201
154360
|
Fails if the iOS ax-service predates the tree command; update argent.`,
|
|
154202
154361
|
hideFromMcp: true,
|
|
154362
|
+
readOnly: true,
|
|
154203
154363
|
zodSchema: zodSchema41,
|
|
154204
154364
|
capability: capability26,
|
|
154205
154365
|
services: () => ({}),
|
|
@@ -154270,6 +154430,7 @@ function createForegroundAppTool(registry2) {
|
|
|
154270
154430
|
Returns { bundleId, name, alertVisible }; under a system alert, bundleId is the app it covers.
|
|
154271
154431
|
A field is unset when it is unknown.`,
|
|
154272
154432
|
hideFromMcp: true,
|
|
154433
|
+
readOnly: true,
|
|
154273
154434
|
zodSchema: zodSchema42,
|
|
154274
154435
|
capability: capability27,
|
|
154275
154436
|
services: () => ({}),
|
|
@@ -154756,6 +154917,7 @@ panel settles instantly on its last frame, and taps land nowhere until it is wok
|
|
|
154756
154917
|
</flag:harmonyos>Use after a launch/navigation to wait for the UI to render before screenshotting or tapping.`,
|
|
154757
154918
|
searchHint: "wait until screen settles idle stable stops changing animation transition rendered ready before screenshot",
|
|
154758
154919
|
longRunning: true,
|
|
154920
|
+
readOnly: true,
|
|
154759
154921
|
zodSchema: zodSchema44,
|
|
154760
154922
|
capability: capability29,
|
|
154761
154923
|
services: (params) => {
|
|
@@ -154839,6 +155001,96 @@ function classifyStaleness({
|
|
|
154839
155001
|
};
|
|
154840
155002
|
}
|
|
154841
155003
|
|
|
155004
|
+
// ../tool-server/src/utils/debugger/runtime-device.ts
|
|
155005
|
+
var import_node_crypto12 = require("node:crypto");
|
|
155006
|
+
var import_node_child_process38 = require("node:child_process");
|
|
155007
|
+
var import_node_util30 = require("node:util");
|
|
155008
|
+
init_adb();
|
|
155009
|
+
var execFileAsync30 = (0, import_node_util30.promisify)(import_node_child_process38.execFile);
|
|
155010
|
+
var LOG_READ_TIMEOUT_MS = 5e3;
|
|
155011
|
+
var RETRY_DELAY_MS = 300;
|
|
155012
|
+
async function findRuntimeDevice(cdp) {
|
|
155013
|
+
const marker = `argent-device-probe:${(0, import_node_crypto12.randomUUID)()}`;
|
|
155014
|
+
const logged = await cdp.evaluate(
|
|
155015
|
+
`(function () {
|
|
155016
|
+
if (typeof nativeLoggingHook !== "function") return false;
|
|
155017
|
+
nativeLoggingHook(${JSON.stringify(marker)}, 1);
|
|
155018
|
+
return true;
|
|
155019
|
+
})()`
|
|
155020
|
+
).catch(() => false);
|
|
155021
|
+
if (logged !== true) return void 0;
|
|
155022
|
+
const checks = [
|
|
155023
|
+
async () => firstFound((await androidSerials()).map((serial) => () => logcatHolds(serial, marker))),
|
|
155024
|
+
async () => firstFound((await bootedSimulators()).map((udid) => () => simulatorLogHolds(udid, marker)))
|
|
155025
|
+
];
|
|
155026
|
+
for (let attempt = 0; attempt < 2; attempt++) {
|
|
155027
|
+
if (attempt > 0) await new Promise((r) => setTimeout(r, RETRY_DELAY_MS));
|
|
155028
|
+
const found = await firstFound(checks);
|
|
155029
|
+
if (found !== void 0) return found;
|
|
155030
|
+
}
|
|
155031
|
+
return void 0;
|
|
155032
|
+
}
|
|
155033
|
+
function firstFound(checks) {
|
|
155034
|
+
return new Promise((resolve16) => {
|
|
155035
|
+
let left = checks.length;
|
|
155036
|
+
if (left === 0) resolve16(void 0);
|
|
155037
|
+
for (const check3 of checks) {
|
|
155038
|
+
void check3().then((id) => {
|
|
155039
|
+
if (id !== void 0) resolve16(id);
|
|
155040
|
+
else if (--left === 0) resolve16(void 0);
|
|
155041
|
+
});
|
|
155042
|
+
}
|
|
155043
|
+
});
|
|
155044
|
+
}
|
|
155045
|
+
async function androidSerials() {
|
|
155046
|
+
try {
|
|
155047
|
+
const { stdout } = await runAdb(["devices"], { timeoutMs: ADB_DEVICES_TIMEOUT_MS });
|
|
155048
|
+
return parseAdbDevices(stdout).filter((d) => d.state === "device").map((d) => d.serial);
|
|
155049
|
+
} catch {
|
|
155050
|
+
return [];
|
|
155051
|
+
}
|
|
155052
|
+
}
|
|
155053
|
+
async function bootedSimulators() {
|
|
155054
|
+
const simulators = await listIosSimulators();
|
|
155055
|
+
return simulators.filter((s) => s.state === "Booted").map((s) => s.udid);
|
|
155056
|
+
}
|
|
155057
|
+
async function logcatHolds(serial, marker) {
|
|
155058
|
+
try {
|
|
155059
|
+
const { stdout } = await runAdb(
|
|
155060
|
+
["-s", serial, "logcat", "-d", "-s", "ReactNativeJS", "-e", marker],
|
|
155061
|
+
{ timeoutMs: LOG_READ_TIMEOUT_MS }
|
|
155062
|
+
);
|
|
155063
|
+
return stdout.includes(marker) ? serial : void 0;
|
|
155064
|
+
} catch {
|
|
155065
|
+
return void 0;
|
|
155066
|
+
}
|
|
155067
|
+
}
|
|
155068
|
+
async function simulatorLogHolds(udid, marker) {
|
|
155069
|
+
try {
|
|
155070
|
+
const args = await simctlArgsForUdid(udid, [
|
|
155071
|
+
"spawn",
|
|
155072
|
+
udid,
|
|
155073
|
+
"log",
|
|
155074
|
+
"show",
|
|
155075
|
+
"--info",
|
|
155076
|
+
"--last",
|
|
155077
|
+
"1m",
|
|
155078
|
+
"--style",
|
|
155079
|
+
"compact",
|
|
155080
|
+
"--predicate",
|
|
155081
|
+
`eventMessage CONTAINS ${JSON.stringify(marker)} AND process != "log"`
|
|
155082
|
+
]);
|
|
155083
|
+
const { stdout } = await execFileAsync30("xcrun", args, {
|
|
155084
|
+
timeout: LOG_READ_TIMEOUT_MS,
|
|
155085
|
+
killSignal: SIMCTL_KILL_SIGNAL,
|
|
155086
|
+
encoding: "utf-8"
|
|
155087
|
+
});
|
|
155088
|
+
return stdout.includes(marker) ? udid : void 0;
|
|
155089
|
+
} catch {
|
|
155090
|
+
return void 0;
|
|
155091
|
+
}
|
|
155092
|
+
}
|
|
155093
|
+
|
|
154842
155094
|
// ../tool-server/src/utils/react-profiler/devtools-bootstrap.ts
|
|
154843
155095
|
function bootstrapFailureMessage(bootstrap) {
|
|
154844
155096
|
switch (bootstrap.reason) {
|
|
@@ -154861,6 +155113,7 @@ function bootstrapFailureMessage(bootstrap) {
|
|
|
154861
155113
|
// ../tool-server/src/tools/profiler/react/react-profiler-start.ts
|
|
154862
155114
|
var NO_DEVTOOLS_HOOK_ERROR = "React DevTools hook (__REACT_DEVTOOLS_GLOBAL_HOOK__) is not present in this app's JavaScript runtime. React profiling requires a development build with React DevTools enabled. Likely causes: (1) the app is a release/production build \u2014 DevTools is stripped to reduce bundle size; (2) you connected to the wrong JS runtime; (3) this isn't a React (Native) app. Fix: rebuild in debug/dev mode (e.g. `npx react-native run-ios` without --configuration Release; for Expo, run a dev client). Once the app is running with DevTools attached, call react-profiler-start again.";
|
|
154863
155115
|
var NO_RENDERERS_ATTACHED_ERROR = "React DevTools hook is present but no React renderer has registered yet. The hook is loaded but no fiber renderer has attached \u2014 typically because the app has not committed its first render, or the DevTools backend has not been bootstrapped on a bridgeless React Native dev build. Fix: ensure the app has rendered (interact with it once, then retry); if it stays empty, call react-profiler-start first \u2014 it will attempt to attach the DevTools backend automatically.";
|
|
155116
|
+
var UNKNOWN_DEVICE_NOTE = "Two or more devices share this Metro, and Argent could not tell which of them runs this app. So taps and swipes on that device still return a screenshot and an element tree, and the capture loads the app while the profiler records. To avoid this, run the app on its own Metro port.";
|
|
154864
155117
|
var zodSchema45 = external_exports.object({
|
|
154865
155118
|
port: metroPortField,
|
|
154866
155119
|
device_id: external_exports.string().describe(
|
|
@@ -155036,6 +155289,7 @@ Fails if the Hermes runtime is not reachable or the Metro CDP connection cannot
|
|
|
155036
155289
|
await cdp.send("Profiler.stop").catch(ignore);
|
|
155037
155290
|
api.profilingActive = false;
|
|
155038
155291
|
}
|
|
155292
|
+
const runtimeDevice = isLogicalKeyedDevice(api.deviceId) ? await findRuntimeDevice(cdp) : void 0;
|
|
155039
155293
|
const sessionId = crypto6.randomUUID();
|
|
155040
155294
|
const ownerPayload = {
|
|
155041
155295
|
sessionId,
|
|
@@ -155080,6 +155334,19 @@ Fails if the Hermes runtime is not reachable or the Metro CDP connection cannot
|
|
|
155080
155334
|
}
|
|
155081
155335
|
);
|
|
155082
155336
|
}
|
|
155337
|
+
if (api.disposed) {
|
|
155338
|
+
await cdp.evaluate(STOP_FOR_TAKEOVER_SCRIPT).catch(ignore);
|
|
155339
|
+
await cdp.send("Profiler.stop").catch(ignore);
|
|
155340
|
+
throw new FailureError(
|
|
155341
|
+
`The React profiler session for ${api.deviceId} was torn down while the profiler was starting, so nothing is recorded. One tool-server serves every agent using this argent install, so another agent may have run stop-all-simulator-servers. Call react-profiler-start again.`,
|
|
155342
|
+
{
|
|
155343
|
+
error_code: FAILURE_CODES.REACT_PROFILER_SESSION_TORN_DOWN,
|
|
155344
|
+
failure_stage: "react_profiler_start_session_torn_down",
|
|
155345
|
+
failure_area: "tool_server",
|
|
155346
|
+
error_kind: "not_found"
|
|
155347
|
+
}
|
|
155348
|
+
);
|
|
155349
|
+
}
|
|
155083
155350
|
const startedAtEpochMs = startResult.startedAtEpochMs ?? Date.now();
|
|
155084
155351
|
clearCachedProfilerPaths(api.port, api.deviceId);
|
|
155085
155352
|
api.sessionPaths = null;
|
|
@@ -155090,11 +155357,14 @@ Fails if the Hermes runtime is not reachable or the Metro CDP connection cannot
|
|
|
155090
155357
|
api.profileStartWallMs = startedAtEpochMs;
|
|
155091
155358
|
api.sessionId = sessionId;
|
|
155092
155359
|
api.ownerToolServerPid = process.pid;
|
|
155360
|
+
trackProfilingRun(api.deviceId, api);
|
|
155361
|
+
if (runtimeDevice) trackProfilingRun(runtimeDevice, api);
|
|
155093
155362
|
return {
|
|
155094
155363
|
started_at: new Date(startedAtEpochMs).toISOString(),
|
|
155095
155364
|
startedAtEpochMs,
|
|
155096
155365
|
hermes_version: api.hermesVersion,
|
|
155097
|
-
detected_architecture: api.detectedArchitecture
|
|
155366
|
+
detected_architecture: api.detectedArchitecture,
|
|
155367
|
+
...isLogicalKeyedDevice(api.deviceId) && !runtimeDevice ? { [RESULT_NOTE_KEY]: UNKNOWN_DEVICE_NOTE } : {}
|
|
155098
155368
|
};
|
|
155099
155369
|
}
|
|
155100
155370
|
};
|
|
@@ -155287,7 +155557,7 @@ Fails if no active profiling session exists or the CDP connection was lost durin
|
|
|
155287
155557
|
}
|
|
155288
155558
|
if (!api.profilingActive) {
|
|
155289
155559
|
throw new FailureError(
|
|
155290
|
-
"No active profiling run to stop.
|
|
155560
|
+
"No active profiling run to stop. Either the run ended without its data (a JS reload ends it: Metro's `r`, a red-box Reload, debugger-reload-metro), or Hermes CPU sampling was never started \u2014 typically because react-profiler-start failed before reaching the sampler (often on release builds without React DevTools). After a reload, call react-profiler-start again. Otherwise check the error react-profiler-start returned, address the underlying cause (rebuild in dev mode, reconnect the debugger, etc.), then call react-profiler-start again.",
|
|
155291
155561
|
{
|
|
155292
155562
|
error_code: FAILURE_CODES.REACT_PROFILER_NO_ACTIVE_SESSION,
|
|
155293
155563
|
failure_stage: "react_profiler_stop_inactive",
|
|
@@ -155493,6 +155763,7 @@ function createReactProfilerStatusTool(registry2) {
|
|
|
155493
155763
|
failedMsg: ({ failureSignal: failureSignal2 }) => `Failed to check React profiler: ${failureSignal2.error_code}`
|
|
155494
155764
|
},
|
|
155495
155765
|
description: `Check the state of the React profiler session without side effects. Use after an interruption (debugger disconnect, unexpected error, agent pause) to decide whether to continue with react-profiler-stop, start a new session, or reconnect the debugger. Ownership is verified server-side against this tool-server's in-memory session, so no token-threading is required. Returns { session_status, is_running, current_owner, \u2026 }. If this tool-server process restarted after react-profiler-start, status will report 'taken_over'; use react-profiler-start { force: true } to reclaim.`,
|
|
155766
|
+
readOnly: true,
|
|
155496
155767
|
zodSchema: zodSchema47,
|
|
155497
155768
|
// RN-only: companion to react-profiler-start.
|
|
155498
155769
|
capability: RN_ONLY_TOOL_CAPABILITY,
|
|
@@ -157295,6 +157566,7 @@ var reactProfilerComponentSourceTool = {
|
|
|
157295
157566
|
Call this per-finding after react-profiler-analyze to inspect source before proposing a fix.
|
|
157296
157567
|
Returns found: false if the component is not found in user-owned code (e.g. lives in node_modules).
|
|
157297
157568
|
When several files define a component with the same name (e.g. platform variants like List.tsx and List.web.tsx), returns the primary match and lists the rest under otherMatches[] (file/line/col). Check it before assuming the returned file is the one you meant.`,
|
|
157569
|
+
readOnly: true,
|
|
157298
157570
|
zodSchema: zodSchema49,
|
|
157299
157571
|
// Declared so the tool catalogue groups this with the other react-profiler-*
|
|
157300
157572
|
// tools; the HTTP gate itself is a no-op here, as there is no device arg to
|
|
@@ -157433,6 +157705,7 @@ Use when you specifically need to investigate JS CPU hotspots that are NOT tied
|
|
|
157433
157705
|
Call react-profiler-stop first. Reads directly from the stored cpuProfile.
|
|
157434
157706
|
Returns a markdown table of the top hotspot functions with self-time, total-time, and location.
|
|
157435
157707
|
Fails if react-profiler-stop has not been called or no CPU profile is stored.`,
|
|
157708
|
+
readOnly: true,
|
|
157436
157709
|
zodSchema: zodSchema50,
|
|
157437
157710
|
// RN-only: reads a Hermes CPU profile; Chromium's V8 sample format differs.
|
|
157438
157711
|
capability: RN_ONLY_TOOL_CAPABILITY,
|
|
@@ -157547,6 +157820,7 @@ var reactProfilerRendersTool = {
|
|
|
157547
157820
|
Returns a markdown table of the top re-rendering components. No profiling session required; works on a live connected app.
|
|
157548
157821
|
Use when you want a quick snapshot of render counts without a full profiling session.
|
|
157549
157822
|
Fails if the React DevTools hook is not present in the runtime or the app is not connected.`,
|
|
157823
|
+
readOnly: true,
|
|
157550
157824
|
zodSchema: zodSchema51,
|
|
157551
157825
|
// RN-only: queries the React DevTools backend hook on the live runtime.
|
|
157552
157826
|
capability: RN_ONLY_TOOL_CAPABILITY,
|
|
@@ -157723,6 +157997,7 @@ var reactProfilerFiberTreeTool = {
|
|
|
157723
157997
|
Use when tracing ancestry of a library component or checking for useMemoCache hook (confirms React Compiler is active on a component).
|
|
157724
157998
|
Returns a nested JSON tree of fiber nodes with name, tag, actualDuration, selfBaseDuration, and children.
|
|
157725
157999
|
Fails if the React DevTools hook is not present or no fiber roots have been committed yet.`,
|
|
158000
|
+
readOnly: true,
|
|
157726
158001
|
zodSchema: zodSchema52,
|
|
157727
158002
|
// RN-only: walks the fiber tree via the React DevTools backend hook.
|
|
157728
158003
|
capability: RN_ONLY_TOOL_CAPABILITY,
|
|
@@ -158146,8 +158421,8 @@ var import_util14 = require("util");
|
|
|
158146
158421
|
var DEFAULT_EXEC_TIMEOUT_MS = 6e4;
|
|
158147
158422
|
var DEFAULT_EXEC_MAX_BUFFER = 256 * 1024 * 1024;
|
|
158148
158423
|
async function execFileAsyncWithTimeout(file2, args, options = {}) {
|
|
158149
|
-
const
|
|
158150
|
-
const { stdout, stderr } = await
|
|
158424
|
+
const execFileAsync35 = (0, import_util14.promisify)(import_child_process2.execFile);
|
|
158425
|
+
const { stdout, stderr } = await execFileAsync35(file2, args, {
|
|
158151
158426
|
encoding: "utf-8",
|
|
158152
158427
|
...options,
|
|
158153
158428
|
// Applied after ...options so a caller cannot weaken the guards; maxBuffer
|
|
@@ -159679,7 +159954,7 @@ var STARTUP_TIMEOUT_MS = 1e4;
|
|
|
159679
159954
|
var DETECT_RUNNING_APP_TIMEOUT_MS = 1e4;
|
|
159680
159955
|
var NOTIFY_REGISTER_TIMEOUT_MS = 2e3;
|
|
159681
159956
|
var MAX_START_ATTEMPTS = 2;
|
|
159682
|
-
var
|
|
159957
|
+
var RETRY_DELAY_MS2 = 1200;
|
|
159683
159958
|
var COLD_START_SIGNATURE = "Cannot find process matching name:";
|
|
159684
159959
|
var STOP_GRACE_MS = 3e5;
|
|
159685
159960
|
var STOP_TERM_MS = 5e3;
|
|
@@ -160103,10 +160378,10 @@ async function startNativeProfilerIos(api, params) {
|
|
|
160103
160378
|
if (!isColdStart) throw err;
|
|
160104
160379
|
if (attempt >= MAX_START_ATTEMPTS) break;
|
|
160105
160380
|
process.stderr.write(
|
|
160106
|
-
`[native-profiler] xctrace could not find "${appProcess}" on attempt ${attempt}/${MAX_START_ATTEMPTS}; waiting ${
|
|
160381
|
+
`[native-profiler] xctrace could not find "${appProcess}" on attempt ${attempt}/${MAX_START_ATTEMPTS}; waiting ${RETRY_DELAY_MS2} ms for cold-start to settle, then retrying.
|
|
160107
160382
|
`
|
|
160108
160383
|
);
|
|
160109
|
-
await new Promise((r) => setTimeout(r,
|
|
160384
|
+
await new Promise((r) => setTimeout(r, RETRY_DELAY_MS2));
|
|
160110
160385
|
}
|
|
160111
160386
|
}
|
|
160112
160387
|
const totalMs = Date.now() - startMs;
|
|
@@ -161564,12 +161839,16 @@ Fails if no app is running on the device, or the profiler cannot attach to the p
|
|
|
161564
161839
|
const api = services.session;
|
|
161565
161840
|
const device = resolveDevice(params.device_id);
|
|
161566
161841
|
assertSupported("native-profiler-start", capability30, device);
|
|
161842
|
+
let started;
|
|
161567
161843
|
if (api.platform === "ios") {
|
|
161568
161844
|
await ensureDeps(["xcrun"]);
|
|
161569
|
-
|
|
161845
|
+
started = await startNativeProfilerIos(api, params);
|
|
161846
|
+
} else {
|
|
161847
|
+
await ensureDeps(["adb"]);
|
|
161848
|
+
started = await startNativeProfilerAndroid(api, params);
|
|
161570
161849
|
}
|
|
161571
|
-
|
|
161572
|
-
return
|
|
161850
|
+
trackProfilingRun(device.id, api);
|
|
161851
|
+
return started;
|
|
161573
161852
|
}
|
|
161574
161853
|
};
|
|
161575
161854
|
|
|
@@ -162196,7 +162475,7 @@ var WATERMARK_PNG_HEIGHT = 277;
|
|
|
162196
162475
|
var WATERMARK_PNG_BASE64 = "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";
|
|
162197
162476
|
|
|
162198
162477
|
// ../tool-server/src/tools/screen-recording/watermark.ts
|
|
162199
|
-
var
|
|
162478
|
+
var execFileAsync31 = (0, import_util15.promisify)(import_child_process6.execFile);
|
|
162200
162479
|
var OUTPUT_FPS = 30;
|
|
162201
162480
|
var FFMPEG_FALLBACK_PATHS = [
|
|
162202
162481
|
"/opt/homebrew/bin/ffmpeg",
|
|
@@ -162213,7 +162492,7 @@ var MASK_DARK_MAX_LUMA = 90;
|
|
|
162213
162492
|
var MASK_LIGHT_MIN_LUMA = 165;
|
|
162214
162493
|
async function resolveBinary(name, fallbacks) {
|
|
162215
162494
|
try {
|
|
162216
|
-
await
|
|
162495
|
+
await execFileAsync31("/bin/sh", ["-c", `command -v ${name}`], { timeout: 2e3 });
|
|
162217
162496
|
return name;
|
|
162218
162497
|
} catch {
|
|
162219
162498
|
}
|
|
@@ -163239,6 +163518,7 @@ Every table states how many samples it covers and how much of that was idle.
|
|
|
163239
163518
|
Use when investigating JS CPU hotspots or correlating CPU cost with specific components.
|
|
163240
163519
|
Returns a markdown table of CPU hotspots, call tree, or per-component CPU breakdown.
|
|
163241
163520
|
Fails if no CPU profile is stored; run react-profiler-stop first.`,
|
|
163521
|
+
readOnly: true,
|
|
163242
163522
|
zodSchema: zodSchema58,
|
|
163243
163523
|
// RN-only: reads Hermes-format CPU profiles; Chromium's V8 sample format differs.
|
|
163244
163524
|
capability: RN_ONLY_TOOL_CAPABILITY,
|
|
@@ -163598,6 +163878,7 @@ Modes:
|
|
|
163598
163878
|
Use when drilling into specific components or time windows after react-profiler-analyze.
|
|
163599
163879
|
Returns a markdown table or tree of commit data matching the requested mode.
|
|
163600
163880
|
Fails if react-profiler-stop has not been called or no commit data is stored.`,
|
|
163881
|
+
readOnly: true,
|
|
163601
163882
|
zodSchema: zodSchema59,
|
|
163602
163883
|
// Reads React commit data captured via the React DevTools backend.
|
|
163603
163884
|
capability: RN_ONLY_TOOL_CAPABILITY,
|
|
@@ -163987,6 +164268,7 @@ Modes:
|
|
|
163987
164268
|
Use when drilling into native hang stacks, thread CPU breakdown, or memory leaks after native-profiler-analyze.
|
|
163988
164269
|
Returns a markdown report with native call stacks, thread weights, or leak details for the selected mode.
|
|
163989
164270
|
Fails if native-profiler-analyze has not been run or no parsed trace data is in memory.`,
|
|
164271
|
+
readOnly: true,
|
|
163990
164272
|
zodSchema: zodSchema60,
|
|
163991
164273
|
// No chromium entry: it has no native trace capture.
|
|
163992
164274
|
capability: {
|
|
@@ -164074,6 +164356,7 @@ Requires both react-profiler-analyze and native-profiler-analyze to have been ca
|
|
|
164074
164356
|
Call this tool when both profilers were run in parallel on the same session.
|
|
164075
164357
|
Returns a markdown report correlating hangs with React commits, memory leaks, and investigation hints.
|
|
164076
164358
|
Fails if either react-profiler-analyze or native-profiler-analyze has not been called first.`,
|
|
164359
|
+
readOnly: true,
|
|
164077
164360
|
zodSchema: zodSchema61,
|
|
164078
164361
|
// iOS reads xctrace output; Android re-queries the Perfetto .pftrace via
|
|
164079
164362
|
// loadAndroidCombinedData. Chromium has no native trace capture.
|
|
@@ -164901,7 +165184,7 @@ function createStopSimulatorServerTool(registry2) {
|
|
|
164901
165184
|
completedMsg: ({ params }) => `Stopped simulator server for ${params.udid}`,
|
|
164902
165185
|
failedMsg: ({ params, failureSignal: failureSignal2 }) => `Failed to stop simulator server for ${params.udid}: ${failureSignal2.error_code}`
|
|
164903
165186
|
},
|
|
164904
|
-
description: `Stop the transport session for a specific device (iOS simulator / Android: simulator-server process; physical iOS: the on-device runner; Chromium: CDP WebSocket) and free its resources; on a TV target it also reaps that device's TV-control daemons. Use when
|
|
165187
|
+
description: `Stop the transport session for a specific device (iOS simulator / Android: simulator-server process; physical iOS: the on-device runner; Chromium: CDP WebSocket) and free its resources; on a TV target it also reaps that device's TV-control daemons. Use to restart a wedged transport, or when the user is done with one device but wants to keep others running - not just because a task on it finished, since the next task on that device would start cold again. On iOS / Android / TV it deliberately leaves this device's native-devtools, accessibility, profiler and debugger services running - to drain those as well, use stop-all-simulator-servers with \`devices\`. On CHROMIUM that does not hold: the JS-runtime debugger declares the CDP session as a dependency, so stopping the transport cascades to it and its captured console history goes with it - reconnect with debugger-connect afterwards. Returns { stopped, udid }. Fails silently if no session is open for the given id.`,
|
|
164905
165188
|
zodSchema: zodSchema63,
|
|
164906
165189
|
services: () => ({}),
|
|
164907
165190
|
async execute(_services, params) {
|
|
@@ -164968,7 +165251,7 @@ function createStopAllSimulatorServersTool(registry2) {
|
|
|
164968
165251
|
},
|
|
164969
165252
|
failedMsg: ({ failureSignal: failureSignal2 }) => `Failed to stop simulator servers: ${failureSignal2.error_code}`
|
|
164970
165253
|
},
|
|
164971
|
-
description: `Stop the services a device owns - simulator-server processes (iOS + Android), native devtools, the iOS accessibility service, TV-control daemons, Chromium CDP sessions, screen recordings, native profiler sessions, and JS-runtime debugger sessions along with the network inspectors and React profiler sessions that ride on them - freeing their spawned processes, sockets and ports. Call this when
|
|
165254
|
+
description: `Stop the services a device owns - simulator-server processes (iOS + Android), native devtools, the iOS accessibility service, TV-control daemons, Chromium CDP sessions, screen recordings, native profiler sessions, and JS-runtime debugger sessions along with the network inspectors and React profiler sessions that ride on them - freeing their spawned processes, sockets and ports. Call this when the user asks to clean up or ends the session, or when a skill tells you to recycle a device's services mid-flow - not just because a task finished, since the next task reuses these services and would start cold again.
|
|
164972
165255
|
PASS \`devices\` with the device ids this session used: one tool-server serves every agent, subagent and CLI call using this argent install, and an unscoped call tears down THEIR devices too (a mid-recording devtools teardown degrades another agent's e2e test to brittle coordinate taps; that agent is warned, but its recorded steps are already the worse kind). Omit \`devices\` only when a machine-wide cleanup is what you actually want. Passing an EMPTY array scopes to nothing and stops nothing - it is not a way to ask for the machine-wide sweep.
|
|
164973
165256
|
A JS-runtime debugger session is keyed by the id you called \`debugger-connect\` with. On a Metro serving two or more devices that id is not a udid or serial - connect refuses those and tells you to re-target with the \`logicalDeviceId\` it returns - so a scope built from \`list-devices\` ids cannot reach that session. Pass any such \`logicalDeviceId\` in \`devices\` ALONGSIDE the device id; { left_running } names the ones you missed.
|
|
164974
165257
|
Returns { stopped } - the URNs of the services that were actually live and got shut down; an ERROR node is disposed too but never appears there, so an empty \`stopped\` only means nothing was still running. { unmatched } lists supplied ids that own no service here, so a mistyped id - or a device NAME passed where an id was expected - does not read as a clean machine. It is NOT proof the id is wrong: a Vega device is driven through CLI/adb shell-outs, so one you only booted and drove with the remote registers no service and always lands here, as does a real device of any platform this session never started anything on. Present ONLY when \`devices\` was supplied AND at least one id matched nothing - absent on an unscoped call and when every id matched. Stopping the same device twice does not report it unmatched: ownership counts regardless of service state. { left_running } lists the URNs of live debugger sessions (and the network inspectors / React profiler sessions riding on them) whose id no device scope can name - re-call with the id after each URN's \`<namespace>:<port>:\` prefix to reap them. { aborted: true } means the caller cancelled the request part-way, so the rest of the machine was left untouched and neither of the other two fields was computed. Past the schema - which rejects an unknown key outright, so the \`udids\` slip is an error rather than a silent machine-wide sweep - the call always succeeds; reaping nothing is a result, not a failure.`,
|
|
@@ -165020,7 +165303,7 @@ Returns { stopped } - the URNs of the services that were actually live and got s
|
|
|
165020
165303
|
|
|
165021
165304
|
// ../tool-server/src/tools/simulator/stop-metro.ts
|
|
165022
165305
|
init_zod();
|
|
165023
|
-
var
|
|
165306
|
+
var import_node_child_process39 = require("node:child_process");
|
|
165024
165307
|
function parseNetstatListeningPids(netstatOutput, port) {
|
|
165025
165308
|
const pids = /* @__PURE__ */ new Set();
|
|
165026
165309
|
for (const line of netstatOutput.split(/\r?\n/)) {
|
|
@@ -165036,7 +165319,7 @@ function parseNetstatListeningPids(netstatOutput, port) {
|
|
|
165036
165319
|
}
|
|
165037
165320
|
function listeningPids(port) {
|
|
165038
165321
|
if (process.platform === "win32") {
|
|
165039
|
-
const output3 = (0,
|
|
165322
|
+
const output3 = (0, import_node_child_process39.execFileSync)("netstat", ["-ano"], {
|
|
165040
165323
|
encoding: "utf-8",
|
|
165041
165324
|
timeout: 5e3,
|
|
165042
165325
|
// `netstat -ano` dumps every socket on the host; overflowing Node's
|
|
@@ -165045,7 +165328,7 @@ function listeningPids(port) {
|
|
|
165045
165328
|
});
|
|
165046
165329
|
return parseNetstatListeningPids(output3, port);
|
|
165047
165330
|
}
|
|
165048
|
-
const output2 = (0,
|
|
165331
|
+
const output2 = (0, import_node_child_process39.execFileSync)("lsof", ["-ti", `tcp:${port}`, "-sTCP:LISTEN"], {
|
|
165049
165332
|
encoding: "utf-8",
|
|
165050
165333
|
timeout: 5e3
|
|
165051
165334
|
}).trim();
|
|
@@ -165062,7 +165345,7 @@ var stopMetroTool = {
|
|
|
165062
165345
|
completedMsg: ({ params }) => `Stopped Metro on port ${params.port}`,
|
|
165063
165346
|
failedMsg: ({ params, failureSignal: failureSignal2 }) => `Failed to stop Metro on port ${params.port}: ${failureSignal2.error_code}`
|
|
165064
165347
|
},
|
|
165065
|
-
description: `Stop the Metro bundler process listening on a given port (default 8081). Use when
|
|
165348
|
+
description: `Stop the Metro bundler process listening on a given port (default 8081). Use when the user asks to stop Metro or when Metro must be restarted - do not offer it when a task wraps up, since the next task would wait on a cold Metro start. Returns { stopped, port, pids }; stopped=false if no process is found on the port. Fails if the port lookup command times out or the process cannot be killed. This is DESTRUCTIVE: always ask the user for confirmation before calling this tool.`,
|
|
165066
165349
|
zodSchema: zodSchema65,
|
|
165067
165350
|
services: () => ({}),
|
|
165068
165351
|
async execute(_services, params) {
|
|
@@ -170802,7 +171085,7 @@ var import_node_url4 = require("node:url");
|
|
|
170802
171085
|
init_src2();
|
|
170803
171086
|
|
|
170804
171087
|
// ../tool-server/src/tools/flows/script/flow-script-executor.ts
|
|
170805
|
-
var
|
|
171088
|
+
var import_node_child_process40 = require("node:child_process");
|
|
170806
171089
|
var fs59 = __toESM(require("node:fs"));
|
|
170807
171090
|
var os17 = __toESM(require("node:os"));
|
|
170808
171091
|
var path45 = __toESM(require("node:path"));
|
|
@@ -171187,7 +171470,7 @@ var FlowScriptExecutor = class {
|
|
|
171187
171470
|
detached: process.platform !== "win32",
|
|
171188
171471
|
windowsHide: process.platform === "win32"
|
|
171189
171472
|
};
|
|
171190
|
-
child = (0,
|
|
171473
|
+
child = (0, import_node_child_process40.fork)(scriptPath, [], forkOptions);
|
|
171191
171474
|
} catch (err) {
|
|
171192
171475
|
return emptyResult(
|
|
171193
171476
|
{ kind: "spawn", message: `Could not start the script process: ${errorMessage(err)}` },
|
|
@@ -171631,7 +171914,7 @@ async function stopProcessTree(child, graceMs) {
|
|
|
171631
171914
|
if (process.platform === "win32") {
|
|
171632
171915
|
if (hasExited(child)) return;
|
|
171633
171916
|
tryKill(() => {
|
|
171634
|
-
const killer = (0,
|
|
171917
|
+
const killer = (0, import_node_child_process40.spawn)("taskkill", ["/pid", String(pid), "/t", "/f"], {
|
|
171635
171918
|
windowsHide: true,
|
|
171636
171919
|
stdio: "ignore"
|
|
171637
171920
|
});
|
|
@@ -172337,7 +172620,7 @@ init_src2();
|
|
|
172337
172620
|
init_device_info();
|
|
172338
172621
|
|
|
172339
172622
|
// ../tool-server/src/tools/flows/flow-visual.ts
|
|
172340
|
-
var
|
|
172623
|
+
var import_node_crypto13 = require("node:crypto");
|
|
172341
172624
|
var fs63 = __toESM(require("node:fs/promises"));
|
|
172342
172625
|
var os18 = __toESM(require("node:os"));
|
|
172343
172626
|
var path48 = __toESM(require("node:path"));
|
|
@@ -172353,7 +172636,7 @@ init_src2();
|
|
|
172353
172636
|
// ../tool-server/src/tools/screenshot-diff/screenshot-diff-ocr.ts
|
|
172354
172637
|
var import_child_process8 = require("child_process");
|
|
172355
172638
|
var import_util16 = require("util");
|
|
172356
|
-
var
|
|
172639
|
+
var execFileAsync32 = (0, import_util16.promisify)(import_child_process8.execFile);
|
|
172357
172640
|
var OCR_TIMEOUT_MS = 1e4;
|
|
172358
172641
|
var OCR_MAX_BUFFER_BYTES = 32 * 1024 * 1024;
|
|
172359
172642
|
var TESSERACT_BINARY = "tesseract";
|
|
@@ -172398,7 +172681,7 @@ async function extractOcrTextBlocks(imagePath) {
|
|
|
172398
172681
|
}
|
|
172399
172682
|
}
|
|
172400
172683
|
async function recognizeTsv(imagePath) {
|
|
172401
|
-
const { stdout } = await
|
|
172684
|
+
const { stdout } = await execFileAsync32(
|
|
172402
172685
|
TESSERACT_BINARY,
|
|
172403
172686
|
[
|
|
172404
172687
|
imagePath,
|
|
@@ -174508,7 +174791,7 @@ async function runSnapshot(env, opts) {
|
|
|
174508
174791
|
});
|
|
174509
174792
|
const captureWarned = shot.warning !== void 0 ? { warning: shot.warning } : {};
|
|
174510
174793
|
const { w, h } = await pngDimensions(shot.image.hostPath);
|
|
174511
|
-
const cropSuffix = opts.cropOn === void 0 ? "" : `-crop-${(0,
|
|
174794
|
+
const cropSuffix = opts.cropOn === void 0 ? "" : `-crop-${(0, import_node_crypto13.createHash)("sha256").update(cropIdentity(opts.cropOn)).digest("hex").slice(0, 8)}`;
|
|
174512
174795
|
const snapshotKey = `${opts.name}__${authoringPlatform(env.device.platform)}-${w}x${h}${cropSuffix}`;
|
|
174513
174796
|
const key2 = `${snapshotKey}.png`;
|
|
174514
174797
|
const baselinePath = opts.clientFlowPath === void 0 ? path48.join(baselineDir(opts.flowsDir, opts.flowName), key2) : clientBaselinePath(opts.clientFlowPath, opts.flowName, key2);
|
|
@@ -174644,7 +174927,7 @@ async function runSnapshot(env, opts) {
|
|
|
174644
174927
|
}
|
|
174645
174928
|
};
|
|
174646
174929
|
}
|
|
174647
|
-
const within = result.mismatchPercentage <= opts.maxMismatch;
|
|
174930
|
+
const within = result.mismatchPercentage <= opts.maxMismatch * (1 + 1e-14);
|
|
174648
174931
|
const reason2 = `diff ${result.mismatchPercentage.toFixed(2)}% ${within ? "\u2264" : ">"} ${opts.maxMismatch}% (${key2})`;
|
|
174649
174932
|
if (within) {
|
|
174650
174933
|
return { status: "pass", reason: reason2, ...captureWarned };
|
|
@@ -174680,11 +174963,11 @@ async function runSnapshot(env, opts) {
|
|
|
174680
174963
|
}
|
|
174681
174964
|
|
|
174682
174965
|
// ../tool-server/src/utils/status-bar.ts
|
|
174683
|
-
var
|
|
174684
|
-
var
|
|
174966
|
+
var import_node_child_process41 = require("node:child_process");
|
|
174967
|
+
var import_node_util31 = require("node:util");
|
|
174685
174968
|
init_adb();
|
|
174686
174969
|
init_device_info();
|
|
174687
|
-
var
|
|
174970
|
+
var execFileAsync33 = (0, import_node_util31.promisify)(import_node_child_process41.execFile);
|
|
174688
174971
|
var DEMO_BROADCAST = "am broadcast -a com.android.systemui.demo";
|
|
174689
174972
|
var IOS_STATUS_BAR_OVERRIDE = [
|
|
174690
174973
|
"override",
|
|
@@ -174708,7 +174991,7 @@ async function pinStatusBar(device, signal) {
|
|
|
174708
174991
|
if (isIosPhysicalDevice(device)) return false;
|
|
174709
174992
|
try {
|
|
174710
174993
|
if (device.platform === "ios") {
|
|
174711
|
-
await
|
|
174994
|
+
await execFileAsync33(
|
|
174712
174995
|
"xcrun",
|
|
174713
174996
|
await simctlArgsForUdid(device.id, ["status_bar", device.id, ...IOS_STATUS_BAR_OVERRIDE])
|
|
174714
174997
|
);
|
|
@@ -174744,7 +175027,7 @@ async function pinStatusBar(device, signal) {
|
|
|
174744
175027
|
async function restoreStatusBar(device) {
|
|
174745
175028
|
try {
|
|
174746
175029
|
if (device.platform === "ios") {
|
|
174747
|
-
await
|
|
175030
|
+
await execFileAsync33(
|
|
174748
175031
|
"xcrun",
|
|
174749
175032
|
await simctlArgsForUdid(device.id, ["status_bar", device.id, "clear"])
|
|
174750
175033
|
);
|
|
@@ -176328,6 +176611,7 @@ Touches no device: nothing is launched, tapped, dispatched or torn down, and no
|
|
|
176328
176611
|
needs booting, so calling this costs nothing but a file read.
|
|
176329
176612
|
Fails if the e2e test file does not exist.
|
|
176330
176613
|
Address the e2e test exactly as you will address it in e2e-execute: name or flow_path, one and only one; supplying both or neither is rejected. The name goes in \`name\`, which resolves <project_root>/.argent/e2e/<name>.yaml, else .argent/flows/<name>.yaml.`,
|
|
176614
|
+
readOnly: true,
|
|
176331
176615
|
zodSchema: zodSchema72,
|
|
176332
176616
|
fileInputs: fileInputs5,
|
|
176333
176617
|
services: () => ({}),
|
|
@@ -176352,7 +176636,7 @@ init_zod();
|
|
|
176352
176636
|
// ../tool-server/src/utils/workspace-reader.ts
|
|
176353
176637
|
var import_promises19 = require("node:fs/promises");
|
|
176354
176638
|
var import_node_path29 = require("node:path");
|
|
176355
|
-
var
|
|
176639
|
+
var import_node_child_process42 = require("node:child_process");
|
|
176356
176640
|
var import_dotenv2 = __toESM(require_dist());
|
|
176357
176641
|
async function exists2(path54) {
|
|
176358
176642
|
try {
|
|
@@ -176396,7 +176680,7 @@ async function listDir(path54) {
|
|
|
176396
176680
|
var COMMAND_TIMEOUT_MS = 3e3;
|
|
176397
176681
|
function runVersionCommand(cmd, args, cwd) {
|
|
176398
176682
|
return new Promise((resolve16) => {
|
|
176399
|
-
const child = (0,
|
|
176683
|
+
const child = (0, import_node_child_process42.execFile)(cmd, args, { cwd, timeout: COMMAND_TIMEOUT_MS }, (err, stdout) => {
|
|
176400
176684
|
if (err) {
|
|
176401
176685
|
resolve16(null);
|
|
176402
176686
|
return;
|
|
@@ -176676,6 +176960,7 @@ exploration of anything the snapshot surfaces.
|
|
|
176676
176960
|
Use when you need to inspect project configuration without manually reading multiple files.
|
|
176677
176961
|
Returns partial data if workspacePath does not exist or is not readable; missing items are represented as null or empty collections.
|
|
176678
176962
|
Fails if the workspacePath is not an absolute path or the directory cannot be accessed.`,
|
|
176963
|
+
readOnly: true,
|
|
176679
176964
|
zodSchema: zodSchema73,
|
|
176680
176965
|
fileInputs: fileInputs6,
|
|
176681
176966
|
services: () => ({}),
|
|
@@ -176685,7 +176970,7 @@ Fails if the workspacePath is not an absolute path or the directory cannot be ac
|
|
|
176685
176970
|
};
|
|
176686
176971
|
|
|
176687
176972
|
// ../tool-server/src/tools/system/update-argent.ts
|
|
176688
|
-
var
|
|
176973
|
+
var import_node_child_process43 = require("node:child_process");
|
|
176689
176974
|
var fs66 = __toESM(require("node:fs"));
|
|
176690
176975
|
var path50 = __toESM(require("node:path"));
|
|
176691
176976
|
init_zod();
|
|
@@ -176820,7 +177105,7 @@ var updateArgentTool = {
|
|
|
176820
177105
|
if (spawnRoot) updateArgs.push("--project-root", spawnRoot);
|
|
176821
177106
|
const cmd = cliEntry ? process.execPath : "argent";
|
|
176822
177107
|
const args = cliEntry ? [cliEntry, ...updateArgs] : updateArgs;
|
|
176823
|
-
const child = (0,
|
|
177108
|
+
const child = (0, import_node_child_process43.spawn)(cmd, args, {
|
|
176824
177109
|
detached: true,
|
|
176825
177110
|
stdio: "ignore",
|
|
176826
177111
|
env: { ...process.env, ARGENT_UPDATE_TRIGGER: "mcp_update" }
|
|
@@ -176872,7 +177157,7 @@ var dismissUpdateTool = {
|
|
|
176872
177157
|
};
|
|
176873
177158
|
|
|
176874
177159
|
// ../tool-server/src/tools/screenshot-diff/index.ts
|
|
176875
|
-
var
|
|
177160
|
+
var import_node_crypto14 = __toESM(require("node:crypto"));
|
|
176876
177161
|
var import_promises20 = __toESM(require("fs/promises"));
|
|
176877
177162
|
var import_node_os15 = __toESM(require("node:os"));
|
|
176878
177163
|
var import_path8 = __toESM(require("path"));
|
|
@@ -176886,10 +177171,10 @@ var zodSchema76 = external_exports.object({
|
|
|
176886
177171
|
udid: external_exports.string().min(1).describe(
|
|
176887
177172
|
"Target device id from `list-devices` (iOS UDID<flag:harmonyos>, HarmonyOS id,</flag:harmonyos> or Android serial)."
|
|
176888
177173
|
),
|
|
176889
|
-
captureBaseline: external_exports.
|
|
177174
|
+
captureBaseline: external_exports.boolean().optional().describe(
|
|
176890
177175
|
"Capture the baseline screenshot live at full resolution before diffing. Cannot be combined with captureCurrent."
|
|
176891
177176
|
),
|
|
176892
|
-
captureCurrent: external_exports.
|
|
177177
|
+
captureCurrent: external_exports.boolean().optional().describe(
|
|
176893
177178
|
"Capture the current screenshot live at full resolution before diffing. Cannot be combined with captureBaseline."
|
|
176894
177179
|
),
|
|
176895
177180
|
rotation: external_exports.enum(["Portrait", "LandscapeLeft", "LandscapeRight", "PortraitUpsideDown"]).optional().describe(
|
|
@@ -177019,7 +177304,7 @@ async function resolveOutputDir(params, options) {
|
|
|
177019
177304
|
const dir = import_path8.default.join(
|
|
177020
177305
|
import_node_os15.default.tmpdir(),
|
|
177021
177306
|
"argent-screenshot-diff",
|
|
177022
|
-
|
|
177307
|
+
import_node_crypto14.default.randomBytes(6).toString("hex")
|
|
177023
177308
|
);
|
|
177024
177309
|
await import_promises20.default.mkdir(dir, { recursive: true });
|
|
177025
177310
|
return dir;
|
|
@@ -177117,7 +177402,7 @@ function requireIosDeviceRunner(services) {
|
|
|
177117
177402
|
}
|
|
177118
177403
|
async function captureIosDeviceLiveInput(params) {
|
|
177119
177404
|
const png = await captureRunnerScreenshotPng(params.runner, RUNNER_COMMAND_TIMEOUT_MS);
|
|
177120
|
-
const suffix =
|
|
177405
|
+
const suffix = import_node_crypto14.default.randomBytes(4).toString("hex");
|
|
177121
177406
|
const destination = import_path8.default.join(params.outputDir, `${params.name}-${suffix}.live.png`);
|
|
177122
177407
|
await import_promises20.default.mkdir(params.outputDir, { recursive: true });
|
|
177123
177408
|
await import_promises20.default.writeFile(destination, png);
|
|
@@ -177135,7 +177420,7 @@ async function captureHarmonyLiveInput(params) {
|
|
|
177135
177420
|
}
|
|
177136
177421
|
await ensureDep("hdc");
|
|
177137
177422
|
const captured = await captureHarmonyScreenshotPng({ connectKey: params.connectKey, scale: 1 });
|
|
177138
|
-
const suffix =
|
|
177423
|
+
const suffix = import_node_crypto14.default.randomBytes(4).toString("hex");
|
|
177139
177424
|
const destination = import_path8.default.join(params.outputDir, `${params.name}-${suffix}.live.png`);
|
|
177140
177425
|
try {
|
|
177141
177426
|
await import_promises20.default.mkdir(params.outputDir, { recursive: true });
|
|
@@ -177171,7 +177456,7 @@ async function captureLiveInput(params) {
|
|
|
177171
177456
|
params.peekFor?.(params.device)
|
|
177172
177457
|
);
|
|
177173
177458
|
}
|
|
177174
|
-
const suffix =
|
|
177459
|
+
const suffix = import_node_crypto14.default.randomBytes(4).toString("hex");
|
|
177175
177460
|
const destination = import_path8.default.join(params.outputDir, `${params.name}-${suffix}.live.png`);
|
|
177176
177461
|
await import_promises20.default.mkdir(params.outputDir, { recursive: true });
|
|
177177
177462
|
await import_promises20.default.copyFile(capture.path, destination);
|
|
@@ -177890,13 +178175,13 @@ function probeArgentToolServer(host, port, timeoutMs = 500) {
|
|
|
177890
178175
|
|
|
177891
178176
|
// ../tool-server/src/utils/simulator-watcher.ts
|
|
177892
178177
|
var fs68 = __toESM(require("node:fs"));
|
|
177893
|
-
var
|
|
177894
|
-
var
|
|
178178
|
+
var import_node_child_process44 = require("node:child_process");
|
|
178179
|
+
var import_node_util32 = require("node:util");
|
|
177895
178180
|
init_external_devices();
|
|
177896
|
-
var
|
|
178181
|
+
var execFileAsync34 = (0, import_node_util32.promisify)(import_node_child_process44.execFile);
|
|
177897
178182
|
var POLL_INTERVAL_MS2 = 1e4;
|
|
177898
178183
|
async function getBootedUdidsInSet(deviceSet) {
|
|
177899
|
-
const { stdout } = await
|
|
178184
|
+
const { stdout } = await execFileAsync34("xcrun", [
|
|
177900
178185
|
...simctlPrefix(deviceSet),
|
|
177901
178186
|
"list",
|
|
177902
178187
|
"devices",
|
|
@@ -178015,7 +178300,7 @@ function startSimulatorWatcher(registry2) {
|
|
|
178015
178300
|
}
|
|
178016
178301
|
|
|
178017
178302
|
// ../tool-server/src/utils/preview-window.ts
|
|
178018
|
-
var
|
|
178303
|
+
var import_node_child_process45 = require("node:child_process");
|
|
178019
178304
|
var fs69 = __toESM(require("node:fs"));
|
|
178020
178305
|
var os20 = __toESM(require("node:os"));
|
|
178021
178306
|
var path52 = __toESM(require("node:path"));
|
|
@@ -178047,10 +178332,10 @@ function ensureLensAppBundle(electronBin) {
|
|
|
178047
178332
|
fs69.copyFileSync(path52.join(realContents, "Info.plist"), plist);
|
|
178048
178333
|
const setPlist = (entry, value) => {
|
|
178049
178334
|
try {
|
|
178050
|
-
(0,
|
|
178335
|
+
(0, import_node_child_process45.execFileSync)("/usr/libexec/PlistBuddy", ["-c", `Set :${entry} ${value}`, plist]);
|
|
178051
178336
|
} catch {
|
|
178052
178337
|
try {
|
|
178053
|
-
(0,
|
|
178338
|
+
(0, import_node_child_process45.execFileSync)("/usr/libexec/PlistBuddy", ["-c", `Add :${entry} string ${value}`, plist]);
|
|
178054
178339
|
} catch {
|
|
178055
178340
|
}
|
|
178056
178341
|
}
|
|
@@ -178109,7 +178394,7 @@ function createPreviewWindowManager(opts = {}) {
|
|
|
178109
178394
|
const wrapperBin = ensureLensAppBundle(electronBin);
|
|
178110
178395
|
const launchBin = wrapperBin ?? electronBin;
|
|
178111
178396
|
const launchArgs = wrapperBin ? ["--no-sandbox", mainScript] : [mainScript];
|
|
178112
|
-
const next = (0,
|
|
178397
|
+
const next = (0, import_node_child_process45.spawn)(launchBin, launchArgs, {
|
|
178113
178398
|
// Strips ELECTRON_RUN_AS_NODE, which an Electron-based MCP host leaves in
|
|
178114
178399
|
// our env, so the child boots as a GUI app instead of bare Node.
|
|
178115
178400
|
env: electronGuiChildEnv({ ARGENT_PREVIEW_URL: url2 }),
|