@swmansion/argent 0.22.1-next.2 → 0.22.1-next.4
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/argent-simulator-server.cjs +12 -19
- package/dist/bundled-paths.js +21 -28
- package/dist/bundled-paths.js.map +1 -1
- package/dist/cli-cmds.mjs +28 -46
- package/dist/cli.d.ts +3 -25
- package/dist/cli.js +12 -41
- package/dist/cli.js.map +1 -1
- package/dist/fatal-handlers.js +13 -17
- package/dist/fatal-handlers.js.map +1 -1
- package/dist/installer-help.d.ts +31 -49
- package/dist/installer-help.js +31 -54
- package/dist/installer-help.js.map +1 -1
- package/dist/installer.mjs +63 -120
- package/dist/mcp-server.mjs +16 -30
- package/dist/preview-window/main.cjs +9 -13
- package/dist/tool-server.cjs +426 -682
- package/package.json +1 -1
package/dist/tool-server.cjs
CHANGED
|
@@ -709,15 +709,12 @@ var init_failure_codes = __esm({
|
|
|
709
709
|
NATIVE_PROFILER_SESSION_TORN_DOWN: "NATIVE_PROFILER_SESSION_TORN_DOWN",
|
|
710
710
|
NATIVE_PROFILER_APP_PROCESS_NOT_FOUND: "NATIVE_PROFILER_APP_PROCESS_NOT_FOUND",
|
|
711
711
|
NATIVE_PROFILER_NO_EXPORTED_TRACE: "NATIVE_PROFILER_NO_EXPORTED_TRACE",
|
|
712
|
-
// Android perfetto start
|
|
713
|
-
// failed recording start is classified rather than falling through to the
|
|
714
|
-
// generic tool-execution bucket.
|
|
712
|
+
// Android perfetto start failures, mirroring the iOS xctrace set above.
|
|
715
713
|
NATIVE_PROFILER_PERFETTO_PROCESS_ERROR: "NATIVE_PROFILER_PERFETTO_PROCESS_ERROR",
|
|
716
714
|
NATIVE_PROFILER_PERFETTO_READY_TIMEOUT: "NATIVE_PROFILER_PERFETTO_READY_TIMEOUT",
|
|
717
715
|
NATIVE_PROFILER_PERFETTO_READY_EXITED: "NATIVE_PROFILER_PERFETTO_READY_EXITED",
|
|
718
|
-
//
|
|
719
|
-
//
|
|
720
|
-
// the step that failed rather than the device family.
|
|
716
|
+
// iOS and Android share one capture path (simulator-server frames into
|
|
717
|
+
// ffmpeg), so these name the failing stage, not the device family.
|
|
721
718
|
SCREEN_RECORDING_FACTORY_OPTIONS_MISSING: "SCREEN_RECORDING_FACTORY_OPTIONS_MISSING",
|
|
722
719
|
SCREEN_RECORDING_WRONG_PLATFORM: "SCREEN_RECORDING_WRONG_PLATFORM",
|
|
723
720
|
SCREEN_RECORDING_ALREADY_ACTIVE: "SCREEN_RECORDING_ALREADY_ACTIVE",
|
|
@@ -16086,22 +16083,19 @@ var init_registry = __esm({
|
|
|
16086
16083
|
init_zod_to_json_schema();
|
|
16087
16084
|
import_node_crypto2 = require("node:crypto");
|
|
16088
16085
|
Registry = class {
|
|
16089
|
-
/** Single map: URN -> ServiceNode (all instances). */
|
|
16090
16086
|
services = /* @__PURE__ */ new Map();
|
|
16091
16087
|
blueprints = /* @__PURE__ */ new Map();
|
|
16092
16088
|
tools = /* @__PURE__ */ new Map();
|
|
16093
16089
|
/**
|
|
16094
|
-
*
|
|
16095
|
-
*
|
|
16096
|
-
*
|
|
16097
|
-
* existing `new Registry()` call sites (tests, non-flag deployments) keep
|
|
16098
|
-
* their previous behavior. The tool-server wires the real `isFlagEnabled`.
|
|
16090
|
+
* Injected so the registry needs no dependency on the flag store; the
|
|
16091
|
+
* tool-server wires the real check. The default enables every flag, so a
|
|
16092
|
+
* plain `new Registry()` (tests, non-flag deployments) gates nothing.
|
|
16099
16093
|
*/
|
|
16100
16094
|
isFlagEnabled;
|
|
16101
16095
|
/**
|
|
16102
|
-
* Host files produced by tools,
|
|
16103
|
-
*
|
|
16104
|
-
* path and the HTTP route
|
|
16096
|
+
* Host files produced by tools, served by the tool-server's `/artifacts/:id`
|
|
16097
|
+
* route. Owned per registry rather than as a module singleton, so the tool
|
|
16098
|
+
* path and the HTTP route see the same store.
|
|
16105
16099
|
*/
|
|
16106
16100
|
artifacts = new ArtifactStore();
|
|
16107
16101
|
events = new TypedEventEmitter();
|
|
@@ -16122,8 +16116,8 @@ var init_registry = __esm({
|
|
|
16122
16116
|
return this.tools.get(id)?.definition;
|
|
16123
16117
|
}
|
|
16124
16118
|
/**
|
|
16125
|
-
* Resolve a service by URN
|
|
16126
|
-
*
|
|
16119
|
+
* Resolve a service by URN, JIT-instantiating from its blueprint on first use.
|
|
16120
|
+
* `options` reach the blueprint factory only on that first instantiation.
|
|
16127
16121
|
*/
|
|
16128
16122
|
resolveService(urn, options) {
|
|
16129
16123
|
return this._resolve(urn, [], options);
|
|
@@ -16240,14 +16234,10 @@ var init_registry = __esm({
|
|
|
16240
16234
|
};
|
|
16241
16235
|
}
|
|
16242
16236
|
/**
|
|
16243
|
-
*
|
|
16244
|
-
*
|
|
16245
|
-
*
|
|
16246
|
-
*
|
|
16247
|
-
*
|
|
16248
|
-
* Only currently-RUNNING nodes are considered: a service that already
|
|
16249
|
-
* errored/torn down during resolution needs no recovery here, and a URN this
|
|
16250
|
-
* tool never resolved must not be touched.
|
|
16237
|
+
* Dispose every service in `refs` whose blueprint calls `error` recoverable, so
|
|
16238
|
+
* the next `resolveService` re-creates it; returns whether anything was
|
|
16239
|
+
* disposed, i.e. whether retrying the tool is worthwhile. Only RUNNING nodes
|
|
16240
|
+
* qualify — one that already errored or tore down needs no recovery.
|
|
16251
16241
|
*/
|
|
16252
16242
|
async _recoverFailedServices(refs, error52) {
|
|
16253
16243
|
let recoveredAny = false;
|
|
@@ -16263,10 +16253,7 @@ var init_registry = __esm({
|
|
|
16263
16253
|
}
|
|
16264
16254
|
return recoveredAny;
|
|
16265
16255
|
}
|
|
16266
|
-
/**
|
|
16267
|
-
* Tear down a single service by URN (and cascade to its dependents).
|
|
16268
|
-
* After disposal the service returns to IDLE and can be re-resolved.
|
|
16269
|
-
*/
|
|
16256
|
+
/** Tear down a service and its dependents; it returns to IDLE and can be re-resolved. */
|
|
16270
16257
|
async disposeService(urn) {
|
|
16271
16258
|
const node = this.services.get(urn);
|
|
16272
16259
|
if (!node) throw new ServiceNotFoundError(urn);
|
|
@@ -16279,7 +16266,6 @@ var init_registry = __esm({
|
|
|
16279
16266
|
}
|
|
16280
16267
|
}
|
|
16281
16268
|
}
|
|
16282
|
-
// ── Private: Resolution ──
|
|
16283
16269
|
_resolve(urn, resolutionPath, options) {
|
|
16284
16270
|
let node = this.services.get(urn);
|
|
16285
16271
|
if (!node) {
|
|
@@ -69928,16 +69914,12 @@ function androidRoots() {
|
|
|
69928
69914
|
function defaultAndroidRoots() {
|
|
69929
69915
|
const home = (0, import_node_os2.homedir)();
|
|
69930
69916
|
const roots = [
|
|
69931
|
-
// Android Studio defaults (the big ones — cover the majority of user
|
|
69932
|
-
// installs that arrive without any env-var setup).
|
|
69933
69917
|
(0, import_node_path3.join)(home, "Library", "Android", "sdk"),
|
|
69934
69918
|
// macOS Android Studio default
|
|
69935
69919
|
(0, import_node_path3.join)(home, "Android", "Sdk"),
|
|
69936
69920
|
// Linux Android Studio default
|
|
69937
|
-
// Common manual install convention. Not picked by any installer but used
|
|
69938
|
-
// often enough in tutorials and Dockerfiles that probing it costs little.
|
|
69939
69921
|
(0, import_node_path3.join)(home, "android-sdk"),
|
|
69940
|
-
//
|
|
69922
|
+
// manual-install convention; no installer picks it
|
|
69941
69923
|
"/opt/android-sdk",
|
|
69942
69924
|
"/usr/lib/android-sdk",
|
|
69943
69925
|
// Debian/Ubuntu `android-sdk` apt package
|
|
@@ -72072,9 +72054,7 @@ var require_min_release_age = __commonJS({
|
|
|
72072
72054
|
var PROBE_TIMEOUT_MS = 3e3;
|
|
72073
72055
|
var OVERRIDE_ENV = "ARGENT_MIN_RELEASE_AGE_DAYS";
|
|
72074
72056
|
var PM_PROBES = {
|
|
72075
|
-
//
|
|
72076
|
-
// npm 11.x builds report `min-release-age=null` even while the policy is
|
|
72077
|
-
// active. Probe `before`, which is what the resolver actually uses.
|
|
72057
|
+
// Probe `before`: that is the effective cutoff npm's resolver applies.
|
|
72078
72058
|
npm: { command: "npm config get before", parse: config_parse_1.parseBeforeAgeMs },
|
|
72079
72059
|
pnpm: {
|
|
72080
72060
|
command: "pnpm config get minimumReleaseAge",
|
|
@@ -92085,14 +92065,12 @@ var CONFIG_SCHEMA = [
|
|
|
92085
92065
|
description: "Whether anonymous opt-out telemetry is enabled (on by default; environment opt-outs like DO_NOT_TRACK are not reflected here \u2014 `argent telemetry status` shows effective consent).",
|
|
92086
92066
|
scopes: ["global"],
|
|
92087
92067
|
parse: asBoolean,
|
|
92088
|
-
// A committed project file must never re-enable telemetry a user disabled
|
|
92089
|
-
// globally, so the more-restrictive (opt-out) value always wins.
|
|
92090
92068
|
merge: "prioritize-restrictive",
|
|
92091
|
-
//
|
|
92092
|
-
//
|
|
92069
|
+
// Opt-out: consent.ts reads an unstored value as enabled, so the config
|
|
92070
|
+
// surface must show the same rather than "(unset)".
|
|
92093
92071
|
default: true,
|
|
92094
|
-
//
|
|
92095
|
-
//
|
|
92072
|
+
// Opt-in/out goes through the dedicated command so the live client is
|
|
92073
|
+
// drained/reset, not just the file rewritten.
|
|
92096
92074
|
manageCommand: "argent telemetry"
|
|
92097
92075
|
},
|
|
92098
92076
|
{
|
|
@@ -92100,8 +92078,6 @@ var CONFIG_SCHEMA = [
|
|
|
92100
92078
|
description: "Coding-agent id remembered by `argent lens` to skip the picker.",
|
|
92101
92079
|
scopes: ["project", "global"],
|
|
92102
92080
|
parse: asString,
|
|
92103
|
-
// A repo can pin the agent its screenshots should use; falls back to the
|
|
92104
|
-
// user's global remembered choice.
|
|
92105
92081
|
merge: "prioritize-local",
|
|
92106
92082
|
example: "claude"
|
|
92107
92083
|
},
|
|
@@ -92110,11 +92086,9 @@ var CONFIG_SCHEMA = [
|
|
|
92110
92086
|
description: "Additional CoreSimulator device-set directories whose simulators argent should see alongside the default set. Absolute paths (or ~/\u2026); relative entries resolve against the project root (project scope) or home (global scope).",
|
|
92111
92087
|
scopes: ["project", "global"],
|
|
92112
92088
|
parse: asStringArray,
|
|
92113
|
-
// Additive
|
|
92114
|
-
//
|
|
92115
|
-
//
|
|
92116
|
-
// `getAdditionalIosDeviceSets` re-implements this union (path resolution
|
|
92117
|
-
// must precede dedup) and guards on the preset staying "union".
|
|
92089
|
+
// Additive rather than shadowing: global baseline first, project extras
|
|
92090
|
+
// after, deduplicated. `getAdditionalIosDeviceSets` re-implements this union
|
|
92091
|
+
// (path resolution must precede dedup) and guards on the preset staying "union".
|
|
92118
92092
|
merge: "union",
|
|
92119
92093
|
example: '["~/DeviceSets/ci"]'
|
|
92120
92094
|
},
|
|
@@ -92123,10 +92097,8 @@ var CONFIG_SCHEMA = [
|
|
|
92123
92097
|
description: "Directory where finished screen recordings (mp4) are saved on the client host. Absolute, `~`-prefixed, or relative to the project root (home dir when not in a project). Unset \u21D2 `.argent/recordings` under the project root.",
|
|
92124
92098
|
scopes: ["project", "global"],
|
|
92125
92099
|
parse: asString,
|
|
92126
|
-
//
|
|
92127
|
-
//
|
|
92128
|
-
// persisted to), so with a remote `argent link` tool-server it is the
|
|
92129
|
-
// *client's* config that decides.
|
|
92100
|
+
// Resolved on the client (the machine the mp4 is persisted to), so with a
|
|
92101
|
+
// remote `argent link` tool-server it is the *client's* config that decides.
|
|
92130
92102
|
merge: "prioritize-local",
|
|
92131
92103
|
example: "~/Movies/argent"
|
|
92132
92104
|
}
|
|
@@ -94853,17 +94825,16 @@ function createExporter(config2) {
|
|
|
94853
94825
|
// The exporter bounds a request with `req.setTimeout()`, which Node only
|
|
94854
94826
|
// arms once the socket is CONNECTED — so a collector whose address drops
|
|
94855
94827
|
// packets (corporate egress filter, dead host behind a firewall) leaves a
|
|
94856
|
-
// socket stuck
|
|
94857
|
-
//
|
|
94858
|
-
//
|
|
94859
|
-
//
|
|
94860
|
-
//
|
|
94828
|
+
// socket stuck connecting that no export deadline can reach, holding the
|
|
94829
|
+
// process open for the OS connect timeout after shutdown() has resolved.
|
|
94830
|
+
// The agent's socket timeout is armed when the socket is CREATED, so it
|
|
94831
|
+
// covers connect too: it fires, the request emits 'timeout', and the
|
|
94832
|
+
// exporter's handler destroys it.
|
|
94861
94833
|
//
|
|
94862
94834
|
// keepAlive is restated because supplying httpAgentOptions at all
|
|
94863
|
-
// replaces the agent the SDK would otherwise build,
|
|
94864
|
-
// keepAlive: true
|
|
94865
|
-
// TCP+TLS handshake for every
|
|
94866
|
-
// request against a loopback collector, versus one socket shared.
|
|
94835
|
+
// replaces the agent the SDK would otherwise build, whose default is
|
|
94836
|
+
// keepAlive: true; without it the long-lived tool-server pays a fresh
|
|
94837
|
+
// TCP+TLS handshake for every batch.
|
|
94867
94838
|
httpAgentOptions: { timeout: EXPORT_TIMEOUT_MS, keepAlive: true }
|
|
94868
94839
|
});
|
|
94869
94840
|
} finally {
|
|
@@ -95082,7 +95053,6 @@ var ALLOWED = {
|
|
|
95082
95053
|
install_mode: INSTALL_MODE
|
|
95083
95054
|
},
|
|
95084
95055
|
"installation:global_install_decision": {
|
|
95085
|
-
// `from_tar` is intentionally absent; the installer skips that dev path.
|
|
95086
95056
|
decision: oneOf(["install", "cancel", "already_installed"])
|
|
95087
95057
|
},
|
|
95088
95058
|
"installation:update_decision": {
|
|
@@ -95161,9 +95131,8 @@ var ALLOWED = {
|
|
|
95161
95131
|
tool_invocation_id: UUID,
|
|
95162
95132
|
platform: PLATFORM,
|
|
95163
95133
|
duration_ms: DURATION_MS,
|
|
95164
|
-
//
|
|
95165
|
-
//
|
|
95166
|
-
// voids anything longer or with a non-identifier element.
|
|
95134
|
+
// Emit side sends only names declared in the tool's zod shape, capped at 16
|
|
95135
|
+
// because arrayOf voids the whole array once it is longer.
|
|
95167
95136
|
invalid_params: arrayOf(matches(/^[a-z][a-z0-9_]{0,63}$/i, 64), 16),
|
|
95168
95137
|
...FAILURE_SIGNAL2,
|
|
95169
95138
|
...AI_TELEMETRY
|
|
@@ -95695,7 +95664,7 @@ var _CI_VENDOR_COUNT_FOR_TEST = vendors_default.length;
|
|
|
95695
95664
|
var SESSION_ID = (0, import_node_crypto3.randomUUID)();
|
|
95696
95665
|
function readCliVersion() {
|
|
95697
95666
|
if (true) {
|
|
95698
|
-
return "0.22.1-next.
|
|
95667
|
+
return "0.22.1-next.4";
|
|
95699
95668
|
}
|
|
95700
95669
|
return "0.0.0";
|
|
95701
95670
|
}
|
|
@@ -96097,15 +96066,11 @@ function resolveHostFingerprint() {
|
|
|
96097
96066
|
const out = (0, import_node_child_process.execFileSync)(simulatorServerBinaryPath(), ["fingerprint"], {
|
|
96098
96067
|
encoding: "utf8",
|
|
96099
96068
|
timeout: FINGERPRINT_TIMEOUT_MS,
|
|
96100
|
-
//
|
|
96101
|
-
//
|
|
96102
|
-
// SIGKILL can't be trapped, so the timeout is a genuine bound here.
|
|
96069
|
+
// SIGKILL, not the default SIGTERM: a binary that ignores SIGTERM would
|
|
96070
|
+
// otherwise block the (synchronous) event loop past the cap forever.
|
|
96103
96071
|
killSignal: "SIGKILL",
|
|
96104
|
-
// Cap captured stdout (same limit as the async variant): a binary streaming
|
|
96105
|
-
// output is SIGKILL'd at this cap rather than filling Node's 1 MiB default.
|
|
96106
96072
|
maxBuffer: FINGERPRINT_MAX_BUFFER,
|
|
96107
|
-
// Ignore stderr so
|
|
96108
|
-
// caller's stderr; stdout (index 1) is captured as the return value.
|
|
96073
|
+
// Ignore stderr so the binary's diagnostics don't pollute the caller's.
|
|
96109
96074
|
stdio: ["ignore", "pipe", "ignore"]
|
|
96110
96075
|
}).trim();
|
|
96111
96076
|
return out.length > 0 ? out : null;
|
|
@@ -96754,11 +96719,10 @@ function describeVegaFailure(args, err, kindOverride) {
|
|
|
96754
96719
|
error_code: FAILURE_CODES.VEGA_CLI_COMMAND_FAILED,
|
|
96755
96720
|
failure_stage: "vega_cli_command",
|
|
96756
96721
|
failure_area: "tool_server",
|
|
96757
|
-
// A
|
|
96758
|
-
//
|
|
96759
|
-
//
|
|
96760
|
-
//
|
|
96761
|
-
// timeout. Those callers pass an explicit kind; everything else uses the heuristic.
|
|
96722
|
+
// A forced reap shapes the error with killed=true so the message reads correctly, but
|
|
96723
|
+
// only a genuine *timeout* may classify as `error_kind: "timeout"` — listVegaDevices
|
|
96724
|
+
// keys its skip-the-recovery-call decision off that, so an overflow must not
|
|
96725
|
+
// masquerade as a wedged agent. Those callers pass an explicit kind.
|
|
96762
96726
|
error_kind: kindOverride ?? (e.killed || e.signal ? "timeout" : "subprocess"),
|
|
96763
96727
|
...subprocessFailureMetadata(err, "vega")
|
|
96764
96728
|
};
|
|
@@ -96803,7 +96767,7 @@ async function runVega(args, options = {}) {
|
|
|
96803
96767
|
};
|
|
96804
96768
|
const rejectTimeout = () => (
|
|
96805
96769
|
// Shape like an execFile timeout rejection (killed=true) so it classifies as a
|
|
96806
|
-
// timeout downstream
|
|
96770
|
+
// timeout downstream.
|
|
96807
96771
|
settle(
|
|
96808
96772
|
() => reject(
|
|
96809
96773
|
describeVegaFailure(
|
|
@@ -96826,9 +96790,9 @@ async function runVega(args, options = {}) {
|
|
|
96826
96790
|
new Error(`vega ${args.join(" ")} output exceeded ${maxOutputBytes} bytes`),
|
|
96827
96791
|
{ killed: true, signal: VEGA_KILL_SIGNAL, stdout, stderr }
|
|
96828
96792
|
),
|
|
96829
|
-
// Force "subprocess": an overflow is a misbehaving child, not a wedged
|
|
96830
|
-
//
|
|
96831
|
-
//
|
|
96793
|
+
// Force "subprocess": an overflow is a misbehaving child, not a wedged agent.
|
|
96794
|
+
// The killed=true shape would otherwise classify as "timeout" and wrongly
|
|
96795
|
+
// suppress the listVegaDevices recovery call.
|
|
96832
96796
|
"subprocess"
|
|
96833
96797
|
)
|
|
96834
96798
|
)
|
|
@@ -97455,7 +97419,6 @@ async function run(args, options) {
|
|
|
97455
97419
|
timeout: options?.timeoutMs ?? DEFAULT_TIMEOUT_MS,
|
|
97456
97420
|
maxBuffer: 16 * 1024 * 1024,
|
|
97457
97421
|
encoding: "utf8",
|
|
97458
|
-
// sim-remote pipes stdin through to pbcopy etc.
|
|
97459
97422
|
input: options?.stdin
|
|
97460
97423
|
});
|
|
97461
97424
|
return { stdout: typeof stdout === "string" ? stdout : stdout.toString("utf8") };
|
|
@@ -97747,9 +97710,9 @@ async function readProcessLaunchState(pid) {
|
|
|
97747
97710
|
({ stdout } = await execFileAsync8(PS_BIN, ["eww", "-p", String(pid), "-o", "etime=,command="], {
|
|
97748
97711
|
encoding: "utf8",
|
|
97749
97712
|
timeout: PS_PROBE_TIMEOUT_MS,
|
|
97750
|
-
// Matches the other `ps` probes (vega-process.ts)
|
|
97713
|
+
// Matches the other `ps` probes (vega-process.ts): an environment can run
|
|
97751
97714
|
// to `kern.argmax` (1 MiB), exactly Node's default cap, so the default
|
|
97752
|
-
// would ENOBUFS on a maximal one
|
|
97715
|
+
// would ENOBUFS on a maximal one.
|
|
97753
97716
|
maxBuffer: 16 * 1024 * 1024
|
|
97754
97717
|
}));
|
|
97755
97718
|
} catch (err) {
|
|
@@ -97845,17 +97808,16 @@ var remoteIosHost = {
|
|
|
97845
97808
|
const { stdout } = await simctlSpawn(udid, { args: ["launchctl", "list"] });
|
|
97846
97809
|
return parseUIKitApplicationBundleIds(stdout);
|
|
97847
97810
|
},
|
|
97848
|
-
// App processes live on the orchestrator,
|
|
97849
|
-
//
|
|
97850
|
-
//
|
|
97811
|
+
// App processes live on the orchestrator, out of reach of the local process
|
|
97812
|
+
// table, so only running-ness is answerable; the null process keeps callers on
|
|
97813
|
+
// their no-evidence path.
|
|
97851
97814
|
async inspectRunningApp(udid, bundleId) {
|
|
97852
97815
|
const { stdout } = await simctlSpawn(udid, { args: ["launchctl", "list"] });
|
|
97853
97816
|
return { running: parseUIKitApplicationJobs(stdout).has(bundleId), process: null };
|
|
97854
97817
|
},
|
|
97855
|
-
//
|
|
97856
|
-
//
|
|
97857
|
-
//
|
|
97858
|
-
// sims; if it isn't, describe will still surface a useful error.
|
|
97818
|
+
// The same accessibility `defaults write`s the local host performs, routed
|
|
97819
|
+
// through the remote generic spawn. The entitlement-bypass plist is assumed
|
|
97820
|
+
// active on cloud sims.
|
|
97859
97821
|
async bootstrapAx(udid) {
|
|
97860
97822
|
for (const flag of ACCESSIBILITY_DEFAULT_FLAGS) {
|
|
97861
97823
|
await simctlSpawn(udid, {
|
|
@@ -98266,13 +98228,11 @@ var NotImplementedOnPlatformError = class extends Error {
|
|
|
98266
98228
|
};
|
|
98267
98229
|
var InvalidToolInputError = class extends Error {
|
|
98268
98230
|
/**
|
|
98269
|
-
* @param signal
|
|
98270
|
-
*
|
|
98271
|
-
*
|
|
98272
|
-
*
|
|
98273
|
-
*
|
|
98274
|
-
* (from #420) — and keep both the granular telemetry bucket AND the 400
|
|
98275
|
-
* status. Defaults to the generic `TOOL_INPUT_INVALID` / validation signal.
|
|
98231
|
+
* @param signal Telemetry-signal overrides. The HTTP 400 mapping keys off the
|
|
98232
|
+
* error *class* (see http.ts), not the `error_code`, so a caller can pass a
|
|
98233
|
+
* more granular code (e.g. the keyboard backends'
|
|
98234
|
+
* `KEYBOARD_CHARACTER_UNSUPPORTED`) and keep both the granular telemetry
|
|
98235
|
+
* bucket and the 400 status.
|
|
98276
98236
|
*/
|
|
98277
98237
|
constructor(message, signal) {
|
|
98278
98238
|
super(message);
|
|
@@ -108489,21 +108449,13 @@ var simulatorServerBlueprint = {
|
|
|
108489
108449
|
return `${SIMULATOR_SERVER_NAMESPACE}:${device.id}`;
|
|
108490
108450
|
},
|
|
108491
108451
|
/**
|
|
108492
|
-
* A
|
|
108493
|
-
*
|
|
108494
|
-
*
|
|
108495
|
-
*
|
|
108496
|
-
*
|
|
108497
|
-
*
|
|
108498
|
-
*
|
|
108499
|
-
*
|
|
108500
|
-
* Treat a connection-refused failure as proof the instance is dead so the
|
|
108501
|
-
* registry disposes it (killing the wedged process) and re-spawns a fresh
|
|
108502
|
-
* simulator-server on the next call. Scoped to connection-refused only:
|
|
108503
|
-
* ECONNREFUSED means the request never reached the server, so retrying can't
|
|
108504
|
-
* double-apply a gesture. Timeouts and resets are deliberately excluded — the
|
|
108505
|
-
* request there may have taken effect, and a hung-but-listening server is a
|
|
108506
|
-
* different failure that respawning wouldn't fix.
|
|
108452
|
+
* A wedged simulator-server (sim un-booted, native server crashed) can keep its
|
|
108453
|
+
* process alive while no longer listening, so it never emits `exit`, the
|
|
108454
|
+
* registry's teardown never fires, and every later call gets `ECONNREFUSED`
|
|
108455
|
+
* until a human runs `stop-simulator-server`. Calling that recoverable makes
|
|
108456
|
+
* the registry dispose the instance and re-spawn. Scoped to connection-refused
|
|
108457
|
+
* only: the request provably never reached the server, so a retry can't
|
|
108458
|
+
* double-apply a gesture, whereas a timeout or reset may have taken effect.
|
|
108507
108459
|
*/
|
|
108508
108460
|
recoverable(error52) {
|
|
108509
108461
|
return getFailureSignal(error52)?.network_failure === "connection_refused";
|
|
@@ -108782,17 +108734,10 @@ var CDPClient = class {
|
|
|
108782
108734
|
});
|
|
108783
108735
|
}
|
|
108784
108736
|
/**
|
|
108785
|
-
* Re-point this client at
|
|
108786
|
-
*
|
|
108787
|
-
*
|
|
108788
|
-
*
|
|
108789
|
-
* (`server.cdp`, `api.cdp`, and every closure that captured it) automatically
|
|
108790
|
-
* target the new tab after the swap — no rewiring needed. Callers that wire
|
|
108791
|
-
* `disconnected` to teardown/termination therefore do not see a tab switch as
|
|
108792
|
-
* a device loss.
|
|
108793
|
-
*
|
|
108794
|
-
* In-flight requests are rejected and per-connection state (enabled domains,
|
|
108795
|
-
* parsed scripts) is reset — the new target starts fresh, so the caller must
|
|
108737
|
+
* Re-point this client at another CDP target (e.g. a new browser tab) without
|
|
108738
|
+
* emitting `disconnected`, which callers treat as a device loss. Object
|
|
108739
|
+
* identity is preserved, so existing references need no rewiring. In-flight
|
|
108740
|
+
* requests are rejected and per-connection state is reset, so the caller must
|
|
108796
108741
|
* re-enable any domains it needs.
|
|
108797
108742
|
*/
|
|
108798
108743
|
async reconnect(newWsUrl) {
|
|
@@ -108828,10 +108773,9 @@ var CDPClient = class {
|
|
|
108828
108773
|
const timer = setTimeout(() => {
|
|
108829
108774
|
this.pending.delete(id);
|
|
108830
108775
|
reject(
|
|
108831
|
-
// The message carries its own recovery guidance
|
|
108832
|
-
//
|
|
108833
|
-
//
|
|
108834
|
-
// retry-looping (each loop iteration waits out this full timeout).
|
|
108776
|
+
// The message carries its own recovery guidance: agents otherwise read
|
|
108777
|
+
// this state as transient and retry-loop, each pass waiting out the
|
|
108778
|
+
// full timeout.
|
|
108835
108779
|
new FailureError(
|
|
108836
108780
|
`CDP request ${method} (id=${id}) timed out \u2014 the runtime accepted the connection but did not answer; it may be frozen, or paused at a breakpoint. debugger-status can still report "connected" in this state (the socket is open). Do not retry in a loop \u2014 restart the app, then reconnect and retry once.`,
|
|
108837
108781
|
{
|
|
@@ -108878,8 +108822,8 @@ var CDPClient = class {
|
|
|
108878
108822
|
this.bindingUnavailable = probe3 === "undefined";
|
|
108879
108823
|
}
|
|
108880
108824
|
/**
|
|
108881
|
-
* Inject a script that
|
|
108882
|
-
*
|
|
108825
|
+
* Inject a script that pushes its result over the binding tagged with a
|
|
108826
|
+
* requestId; resolves with the payload of the matching binding call.
|
|
108883
108827
|
*/
|
|
108884
108828
|
evaluateWithBinding(expression, requestId, options) {
|
|
108885
108829
|
const id = requestId ?? crypto3.randomUUID();
|
|
@@ -109077,9 +109021,8 @@ async function browserWebSocketUrl(port, signal) {
|
|
|
109077
109021
|
throw new FailureError(
|
|
109078
109022
|
`Chromium CDP on port ${port} did not report a browser webSocketDebuggerUrl in /json/version.`,
|
|
109079
109023
|
{
|
|
109080
|
-
//
|
|
109081
|
-
//
|
|
109082
|
-
// conflate "reached but malformed" with a genuinely down debug port.
|
|
109024
|
+
// Reached but malformed — telemetry must not conflate this with a
|
|
109025
|
+
// genuinely down debug port.
|
|
109083
109026
|
error_code: FAILURE_CODES.CHROMIUM_CDP_INVALID_RESPONSE,
|
|
109084
109027
|
failure_stage: "chromium_cdp_browser_ws",
|
|
109085
109028
|
failure_area: "tool_server",
|
|
@@ -109434,19 +109377,14 @@ var ScreencastManager = class {
|
|
|
109434
109377
|
fps;
|
|
109435
109378
|
activeCount = 0;
|
|
109436
109379
|
currentOpts = null;
|
|
109437
|
-
// The in-flight Page.startScreencast
|
|
109438
|
-
//
|
|
109439
|
-
//
|
|
109440
|
-
// when no start is in flight (idle, or a live session already running).
|
|
109380
|
+
// The first subscriber's in-flight Page.startScreencast, published so joiners
|
|
109381
|
+
// await the SAME start instead of assuming a live session and stranding
|
|
109382
|
+
// themselves on a frame-less stream if it fails.
|
|
109441
109383
|
startInFlight = null;
|
|
109442
109384
|
lastFrame = null;
|
|
109443
109385
|
cdpListenerInstalled = false;
|
|
109444
|
-
/**
|
|
109445
|
-
*
|
|
109446
|
-
* Chromium hasn't pushed a frame yet. Exposed so single-shot consumers
|
|
109447
|
-
* (preview overlay, snapshot debug tool) can grab the last frame without
|
|
109448
|
-
* starting their own session.
|
|
109449
|
-
*/
|
|
109386
|
+
/** Never cleared on stop, so single-shot consumers can read a frame without
|
|
109387
|
+
* starting their own session. */
|
|
109450
109388
|
getLastFrame() {
|
|
109451
109389
|
return this.lastFrame;
|
|
109452
109390
|
}
|
|
@@ -109574,7 +109512,7 @@ function warnSharpMissingOnce(reason) {
|
|
|
109574
109512
|
var DOWNSCALER_TO_KERNEL = {
|
|
109575
109513
|
lanczos3: "lanczos3",
|
|
109576
109514
|
box: "mitchell",
|
|
109577
|
-
// sharp
|
|
109515
|
+
// sharp has no box kernel
|
|
109578
109516
|
bilinear: "lanczos2",
|
|
109579
109517
|
nearest: "nearest"
|
|
109580
109518
|
};
|
|
@@ -109789,12 +109727,8 @@ function createTabsManager(deps) {
|
|
|
109789
109727
|
error_code: FAILURE_CODES.CHROMIUM_TAB_OPEN_FAILED,
|
|
109790
109728
|
failure_stage: "chromium_tab_open",
|
|
109791
109729
|
failure_area: "tool_server",
|
|
109792
|
-
//
|
|
109793
|
-
//
|
|
109794
|
-
// classified `unknown` like the other CDP-command failures in this
|
|
109795
|
-
// server (CHROMIUM_SCREENSHOT_FAILED, the viewport/storage evals).
|
|
109796
|
-
// `network`/`invalid_response` is reserved for the HTTP /json
|
|
109797
|
-
// discovery layer, which has a genuine fetch transport.
|
|
109730
|
+
// A malformed CDP response, not a transport failure:
|
|
109731
|
+
// `network`/`invalid_response` is reserved for the HTTP /json layer.
|
|
109798
109732
|
error_kind: "unknown"
|
|
109799
109733
|
});
|
|
109800
109734
|
return out.targetId;
|
|
@@ -109888,9 +109822,8 @@ function createNetworkManager(deps) {
|
|
|
109888
109822
|
rec.resourceType = params.type ?? rec.resourceType;
|
|
109889
109823
|
break;
|
|
109890
109824
|
}
|
|
109891
|
-
// The *ExtraInfo events carry
|
|
109892
|
-
//
|
|
109893
|
-
// before the base event, so `record()` creates the entry if needed.
|
|
109825
|
+
// The *ExtraInfo events carry on-the-wire headers (Authorization, Set-Cookie, …)
|
|
109826
|
+
// the base events omit, and may arrive before them — hence `record()`, not `get()`.
|
|
109894
109827
|
case "Network.requestWillBeSentExtraInfo": {
|
|
109895
109828
|
const h = params.headers;
|
|
109896
109829
|
if (h) {
|
|
@@ -110557,11 +110490,9 @@ Booted/ready devices are listed first. Platforms whose CLI is unavailable are si
|
|
|
110557
110490
|
withDeadline(listIosSimulators(), [], "ios"),
|
|
110558
110491
|
withDeadline(listRemoteIosSimulators(), [], "ios-remote"),
|
|
110559
110492
|
withDeadline(
|
|
110560
|
-
//
|
|
110561
|
-
//
|
|
110562
|
-
//
|
|
110563
|
-
// bound (NOT boot-device's 30s default) so the Android branch self-bounds
|
|
110564
|
-
// under BRANCH_DEADLINE_MS — see ADB_DEVICES_TIMEOUT_MS.
|
|
110493
|
+
// list-devices is the one caller that surfaces TV vs mobile, so it pays for
|
|
110494
|
+
// runtimeKind's extra per-device probe. The explicit `adb devices` bound
|
|
110495
|
+
// (not runAdb's 30s default) keeps this branch under BRANCH_DEADLINE_MS.
|
|
110565
110496
|
listAndroidDevices({ runtimeKind: true, devicesTimeoutMs: ADB_DEVICES_TIMEOUT_MS }).catch(
|
|
110566
110497
|
() => []
|
|
110567
110498
|
),
|
|
@@ -110620,39 +110551,33 @@ var VariantProposalStore = class {
|
|
|
110620
110551
|
consumed = false;
|
|
110621
110552
|
globalComment = "";
|
|
110622
110553
|
/**
|
|
110623
|
-
*
|
|
110624
|
-
*
|
|
110625
|
-
* — so it is intentionally NOT cleared by `reset()`.
|
|
110554
|
+
* Last non-empty udid an agent passed to `propose_variant`. One device spans
|
|
110555
|
+
* many rounds, so `reset()` intentionally does NOT clear it.
|
|
110626
110556
|
*/
|
|
110627
110557
|
device = null;
|
|
110628
110558
|
/**
|
|
110629
|
-
* True while an `argent lens` CLI session owns the window.
|
|
110630
|
-
*
|
|
110631
|
-
* many propose→submit rounds, like `device`.
|
|
110559
|
+
* True while an `argent lens` CLI session owns the window. A session spans many
|
|
110560
|
+
* propose→submit rounds, so `reset()` deliberately does NOT clear it.
|
|
110632
110561
|
*/
|
|
110633
110562
|
cliSession = false;
|
|
110634
110563
|
/**
|
|
110635
110564
|
* The agent choices a CLI Lens session offers (when more than one is
|
|
110636
|
-
* installed) and the one the human picked
|
|
110637
|
-
*
|
|
110638
|
-
*
|
|
110639
|
-
* `cliSession`, deliberately NOT cleared by `reset()`.
|
|
110565
|
+
* installed) and the one the human picked. `argent lens` passes the choices in
|
|
110566
|
+
* on begin and learns the pick over `/preview/lens-stream`. Like `cliSession`,
|
|
110567
|
+
* deliberately NOT cleared by `reset()`.
|
|
110640
110568
|
*/
|
|
110641
110569
|
lensAgents = [];
|
|
110642
110570
|
lensAgentChoice = null;
|
|
110643
110571
|
/**
|
|
110644
|
-
* Whether the human
|
|
110645
|
-
*
|
|
110646
|
-
*
|
|
110647
|
-
* picker. Tied to `lensAgentChoice`; reset with it.
|
|
110572
|
+
* Whether the human ticked the picker's "Remember this choice". `argent lens`
|
|
110573
|
+
* reads it alongside the pick and persists it to `~/.argent/config.json` so
|
|
110574
|
+
* later runs skip the picker. Tied to `lensAgentChoice`; reset with it.
|
|
110648
110575
|
*/
|
|
110649
110576
|
lensAgentRemember = false;
|
|
110650
110577
|
/**
|
|
110651
|
-
* Devices
|
|
110652
|
-
*
|
|
110653
|
-
*
|
|
110654
|
-
* session ends (`takeOwnedDevices`), without ever touching a device the user
|
|
110655
|
-
* had already booted. Like `cliSession`, NOT cleared by `reset()`.
|
|
110578
|
+
* Devices `POST /preview/boot` started because they were not already running,
|
|
110579
|
+
* so session-end teardown (`takeOwnedDevices`) shuts down only those and never
|
|
110580
|
+
* one the user had booted. Like `cliSession`, NOT cleared by `reset()`.
|
|
110656
110581
|
*/
|
|
110657
110582
|
ownedDevices = /* @__PURE__ */ new Set();
|
|
110658
110583
|
submitted = [];
|
|
@@ -110663,15 +110588,12 @@ var VariantProposalStore = class {
|
|
|
110663
110588
|
/** Frozen result of the current round once the user submits. */
|
|
110664
110589
|
lastOutcome = null;
|
|
110665
110590
|
/**
|
|
110666
|
-
* Completed outcomes that finished with no
|
|
110667
|
-
*
|
|
110668
|
-
*
|
|
110669
|
-
*
|
|
110670
|
-
*
|
|
110671
|
-
*
|
|
110672
|
-
* drained first by `awaitSelection`, oldest first. Without it, a human's
|
|
110673
|
-
* already-submitted selection is destroyed the moment the next
|
|
110674
|
-
* `propose_variant` call rolls the round out from under it.
|
|
110591
|
+
* Completed outcomes that finished with no await parked to receive them, in
|
|
110592
|
+
* completion order. `autoRollIfCompleted` rolls on the next `propose_variant`
|
|
110593
|
+
* whether or not the outcome was retrieved, so this queue — unlike
|
|
110594
|
+
* `lastOutcome`/`completed`/`consumed`, which describe only the CURRENT round —
|
|
110595
|
+
* survives `reset()` and is drained first by `awaitSelection`. Without it a
|
|
110596
|
+
* roll destroys a human's already-submitted selection.
|
|
110675
110597
|
*/
|
|
110676
110598
|
pendingOutcomes = [];
|
|
110677
110599
|
/** Begin a fresh round, discarding the previous one's proposals/selections. */
|
|
@@ -110707,15 +110629,12 @@ var VariantProposalStore = class {
|
|
|
110707
110629
|
this.events.emit("changed");
|
|
110708
110630
|
}
|
|
110709
110631
|
/**
|
|
110710
|
-
* Emit the drop-off signal for a round still staged
|
|
110711
|
-
*
|
|
110712
|
-
* tool-server calls this
|
|
110713
|
-
*
|
|
110714
|
-
*
|
|
110715
|
-
*
|
|
110716
|
-
* so a completed or empty round is a no-op — which also settles any await still
|
|
110717
|
-
* parked on the dying round rather than letting it hang. Returns whether an
|
|
110718
|
-
* abandonment was emitted (for the caller's logging / tests).
|
|
110632
|
+
* Emit the drop-off signal for a round still staged at process shutdown — "the
|
|
110633
|
+
* server died mid-review" — so it is counted instead of vanishing into the
|
|
110634
|
+
* unattributable opens-minus-completions residue. The tool-server calls this
|
|
110635
|
+
* before its final telemetry drain. Routes through reset(), the single
|
|
110636
|
+
* abandonment choke point, which also settles any await parked on the dying
|
|
110637
|
+
* round. Returns whether an abandonment was emitted.
|
|
110719
110638
|
*/
|
|
110720
110639
|
flushAbandonedRound() {
|
|
110721
110640
|
if (this.completed || this.proposals.length === 0) return false;
|
|
@@ -110728,13 +110647,12 @@ var VariantProposalStore = class {
|
|
|
110728
110647
|
return p?.variants.find((v) => v.id === variantId) ?? null;
|
|
110729
110648
|
}
|
|
110730
110649
|
/**
|
|
110731
|
-
*
|
|
110732
|
-
*
|
|
110733
|
-
*
|
|
110734
|
-
*
|
|
110735
|
-
*
|
|
110736
|
-
*
|
|
110737
|
-
* when nothing is parked.
|
|
110650
|
+
* Settle every parked waiter with a `pending` outcome pointing at the browser
|
|
110651
|
+
* fallback URL when the native preview window could not launch (e.g. the
|
|
110652
|
+
* optional `electron` dependency is absent on a headless/CI host), rather than
|
|
110653
|
+
* letting the await run its full timeout with no window and no feedback. The
|
|
110654
|
+
* proposals stay live, so the agent can relay the URL and re-await. No-ops when
|
|
110655
|
+
* nothing is parked.
|
|
110738
110656
|
*/
|
|
110739
110657
|
notifyWindowUnavailable(reason, url2) {
|
|
110740
110658
|
const toSettle = this.waitersList.filter((w) => !w.settled);
|
|
@@ -110815,10 +110733,10 @@ var VariantProposalStore = class {
|
|
|
110815
110733
|
}
|
|
110816
110734
|
/**
|
|
110817
110735
|
* Begin or end a CLI-driven Lens session (`argent lens`), optionally offering
|
|
110818
|
-
*
|
|
110819
|
-
*
|
|
110820
|
-
*
|
|
110821
|
-
*
|
|
110736
|
+
* agent choices for the window's picker. `cliSessionChanged` fires only on an
|
|
110737
|
+
* actual begin/end transition (so the window opens/closes once), but the
|
|
110738
|
+
* choices are refreshed on every begin — a re-begin from a fresh `argent lens`
|
|
110739
|
+
* must replace stale ones.
|
|
110822
110740
|
*/
|
|
110823
110741
|
setCliSession(active, agents = []) {
|
|
110824
110742
|
const transitioned = this.cliSession !== active;
|
|
@@ -110836,8 +110754,7 @@ var VariantProposalStore = class {
|
|
|
110836
110754
|
}
|
|
110837
110755
|
this.events.emit("changed");
|
|
110838
110756
|
}
|
|
110839
|
-
/** Record the agent the human picked
|
|
110840
|
-
* asked to remember it. */
|
|
110757
|
+
/** Record the agent the human picked, and whether they asked to remember it. */
|
|
110841
110758
|
setLensAgentChoice(id, remember = false) {
|
|
110842
110759
|
this.lensAgentChoice = id;
|
|
110843
110760
|
this.lensAgentRemember = remember;
|
|
@@ -110860,18 +110777,16 @@ var VariantProposalStore = class {
|
|
|
110860
110777
|
if (id.trim()) this.ownedDevices.add(id.trim());
|
|
110861
110778
|
}
|
|
110862
110779
|
/**
|
|
110863
|
-
* Whether Lens booted this device itself
|
|
110864
|
-
*
|
|
110865
|
-
*
|
|
110866
|
-
* read a single device's ownership. Kept as a non-mutating way for tests to
|
|
110867
|
-
* assert ownership without draining it via `takeOwnedDevices`.
|
|
110780
|
+
* Whether Lens booted this device itself. Test-only: production manages
|
|
110781
|
+
* ownership through `markDeviceOwned` / `releaseDevice` / `takeOwnedDevices`,
|
|
110782
|
+
* so this exists as a non-mutating way to assert it without draining the set.
|
|
110868
110783
|
*/
|
|
110869
110784
|
isDeviceOwned(id) {
|
|
110870
110785
|
return this.ownedDevices.has(id.trim());
|
|
110871
110786
|
}
|
|
110872
110787
|
/**
|
|
110873
|
-
* Drop a single owned device — e.g. the user shut it down
|
|
110874
|
-
*
|
|
110788
|
+
* Drop a single owned device — e.g. the user shut it down from the preview
|
|
110789
|
+
* window, so session-end teardown must not try to kill it again.
|
|
110875
110790
|
*/
|
|
110876
110791
|
releaseDevice(id) {
|
|
110877
110792
|
this.ownedDevices.delete(id.trim());
|
|
@@ -110884,22 +110799,21 @@ var VariantProposalStore = class {
|
|
|
110884
110799
|
}
|
|
110885
110800
|
/**
|
|
110886
110801
|
* The frozen outcome of the last submitted round, or null if nothing has been
|
|
110887
|
-
* submitted since the last reset.
|
|
110888
|
-
* `argent lens` watcher can format the user's
|
|
110889
|
-
*
|
|
110802
|
+
* submitted since the last reset. Served over `/preview/outcome` and
|
|
110803
|
+
* `/preview/lens-stream` so the `argent lens` watcher can format the user's
|
|
110804
|
+
* feedback and type it into the spawned agent terminal.
|
|
110890
110805
|
*/
|
|
110891
110806
|
getLastOutcome() {
|
|
110892
110807
|
return this.lastOutcome;
|
|
110893
110808
|
}
|
|
110894
|
-
/** Called by the preview UI when the human
|
|
110809
|
+
/** Called by the preview UI when the human submits their picks. */
|
|
110895
110810
|
submitSelection(input) {
|
|
110896
110811
|
if (typeof input.round === "number" && input.round !== this.round) {
|
|
110897
110812
|
return { ok: true, round: this.round, resolved: 0, stale: true };
|
|
110898
110813
|
}
|
|
110899
110814
|
const cleanAnnotations = (input.annotations ?? []).filter((a) => a && typeof a.comment === "string" && a.comment.trim()).slice(0, MAX_ANNOTATIONS).map((a) => ({
|
|
110900
110815
|
target: String(a.target ?? "").slice(0, 200) || "(element)",
|
|
110901
|
-
//
|
|
110902
|
-
// comment, was previously ingested uncapped.
|
|
110816
|
+
// Caller-supplied and, unlike the comment, otherwise ingested uncapped.
|
|
110903
110817
|
match: {
|
|
110904
110818
|
by: a.match?.by ?? "text",
|
|
110905
110819
|
value: String(a.match?.value ?? "").slice(0, MAX_MATCH_VALUE_LENGTH)
|
|
@@ -111015,14 +110929,12 @@ var VariantProposalStore = class {
|
|
|
111015
110929
|
};
|
|
111016
110930
|
}
|
|
111017
110931
|
/**
|
|
111018
|
-
* Block until the user submits a selection for the current round
|
|
111019
|
-
*
|
|
111020
|
-
*
|
|
111021
|
-
*
|
|
111022
|
-
*
|
|
111023
|
-
*
|
|
111024
|
-
* await parked on a round is resolved when that round is submitted (or the
|
|
111025
|
-
* round is superseded), so concurrent / re-entrant awaits never strand.
|
|
110932
|
+
* Block until the user submits a selection for the current round, resolving
|
|
110933
|
+
* immediately if one is already waiting to be consumed. On `timeoutMs` returns
|
|
110934
|
+
* a `pending` outcome so the caller can re-await without losing the live
|
|
110935
|
+
* proposals; a `signal` abort rejects with an AbortError. Every await parked on
|
|
110936
|
+
* a round is resolved when that round is submitted or superseded, so concurrent
|
|
110937
|
+
* / re-entrant awaits never strand.
|
|
111026
110938
|
*/
|
|
111027
110939
|
awaitSelection(opts) {
|
|
111028
110940
|
if (opts.signal?.aborted) {
|
|
@@ -112074,9 +111986,8 @@ function deriveUiAutomatorRole(className) {
|
|
|
112074
111986
|
return short || "View";
|
|
112075
111987
|
}
|
|
112076
111988
|
var NOISY_CLASSES = /* @__PURE__ */ new Set([
|
|
112077
|
-
//
|
|
112078
|
-
// carries the icon's content-desc
|
|
112079
|
-
// 40+ leaf nodes. Drop the entire subtree.
|
|
111989
|
+
// react-native-svg icon internals: never tappable, and the parent already
|
|
111990
|
+
// carries the icon's content-desc.
|
|
112080
111991
|
"com.horcrux.svg.PathView",
|
|
112081
111992
|
"com.horcrux.svg.GroupView",
|
|
112082
111993
|
"com.horcrux.svg.SvgView"
|
|
@@ -112085,10 +111996,8 @@ function isNoisyUiAutomatorClass(className) {
|
|
|
112085
111996
|
return NOISY_CLASSES.has(className);
|
|
112086
111997
|
}
|
|
112087
111998
|
var SYSTEM_PACKAGES = /* @__PURE__ */ new Set([
|
|
112088
|
-
// Status bar / nav bar / quick settings
|
|
112089
|
-
//
|
|
112090
|
-
// the foreground-app's own package even when the foreground IS a system app
|
|
112091
|
-
// (settings, permission dialog), so permission prompts still surface.
|
|
111999
|
+
// Status bar / nav bar / quick settings. Only systemui is listed on purpose:
|
|
112000
|
+
// a foreground system app (settings, permission dialog) must still surface.
|
|
112092
112001
|
"com.android.systemui"
|
|
112093
112002
|
]);
|
|
112094
112003
|
var SYSTEM_RID_PREFIXES = [
|
|
@@ -112103,8 +112012,8 @@ var LAYOUT_CONTAINERS = /* @__PURE__ */ new Set([
|
|
|
112103
112012
|
"androidx.constraintlayout.widget.ConstraintLayout",
|
|
112104
112013
|
"androidx.coordinatorlayout.widget.CoordinatorLayout",
|
|
112105
112014
|
"android.view.ViewGroup",
|
|
112106
|
-
//
|
|
112107
|
-
//
|
|
112015
|
+
// Compose emits bare android.view.View for semantics nodes with no widget
|
|
112016
|
+
// mapping.
|
|
112108
112017
|
"android.view.View"
|
|
112109
112018
|
]);
|
|
112110
112019
|
function isUiAutomatorLayoutContainer(className) {
|
|
@@ -112442,8 +112351,7 @@ function resolveTraceProcessorAssets() {
|
|
|
112442
112351
|
}
|
|
112443
112352
|
function patchGlueForNode(src) {
|
|
112444
112353
|
const edits = [
|
|
112445
|
-
// Force memory32: skip the memory64
|
|
112446
|
-
// memory64 __syscall_mprotect path; no global WebAssembly wrapper).
|
|
112354
|
+
// Force memory32: skip the memory64 probe and its __syscall_mprotect path.
|
|
112447
112355
|
["this.useMemory64 = hasMemory64Support();", "this.useMemory64 = false;"],
|
|
112448
112356
|
// Hand the wasm bytes straight to emscripten -> it never calls readBinary/XHR.
|
|
112449
112357
|
["locateFile: (s) => s,", "locateFile: (s) => s, wasmBinary: globalThis.__TP_WASM_BYTES,"],
|
|
@@ -113222,10 +113130,8 @@ async function describeAndroid(registry2, serial, _bundleId, isTv) {
|
|
|
113222
113130
|
throw new FailureError(
|
|
113223
113131
|
`uiautomator could not capture the screen: ${trimmed}. Common causes: device locked / keyguard, DRM or secure overlay, Play Integrity screen. Unlock the device or take a screenshot as a fallback.`,
|
|
113224
113132
|
{
|
|
113225
|
-
//
|
|
113226
|
-
//
|
|
113227
|
-
// subprocess. Classified `subprocess` to match the sibling
|
|
113228
|
-
// ANDROID_UIAUTOMATOR_PARSE_FAILED (also adb-exit-0, unusable output).
|
|
113133
|
+
// adb exits 0, but uiautomator reported an in-band `ERROR:` line — same
|
|
113134
|
+
// adb-exit-0/unusable-output shape as ANDROID_UIAUTOMATOR_PARSE_FAILED.
|
|
113229
113135
|
error_code: FAILURE_CODES.ANDROID_UIAUTOMATOR_CAPTURE_FAILED,
|
|
113230
113136
|
failure_stage: "android_uiautomator_capture",
|
|
113231
113137
|
failure_area: "tool_server",
|
|
@@ -113270,10 +113176,9 @@ function createPreviewRouter(registry2) {
|
|
|
113270
113176
|
element_count: snap.proposals.length,
|
|
113271
113177
|
variant_count: snap.proposals.reduce((n, p) => n + p.variants.length, 0),
|
|
113272
113178
|
is_cli_session: snap.cliSession,
|
|
113273
|
-
//
|
|
113274
|
-
//
|
|
113275
|
-
//
|
|
113276
|
-
// prior flow's platform — a stale value next to a zero-count open.
|
|
113179
|
+
// `device` deliberately survives the store's reset(), so a CLI up-front
|
|
113180
|
+
// open (no proposals staged yet) would otherwise report a prior flow's
|
|
113181
|
+
// platform.
|
|
113277
113182
|
platform: snap.proposals.length > 0 && snap.device ? classifyDeviceForTelemetry(snap.device) : void 0
|
|
113278
113183
|
});
|
|
113279
113184
|
};
|
|
@@ -113539,16 +113444,16 @@ data: ${JSON.stringify(data)}
|
|
|
113539
113444
|
}
|
|
113540
113445
|
try {
|
|
113541
113446
|
const result = variantProposalStore.submitSelection({
|
|
113542
|
-
// The round the UI built this submit against
|
|
113543
|
-
// rejects it
|
|
113544
|
-
//
|
|
113447
|
+
// The round the UI built this submit against, if it sent one. The store
|
|
113448
|
+
// rejects it once the round has rolled, so a click from a stale tab can't
|
|
113449
|
+
// mint a phantom completion.
|
|
113545
113450
|
round: typeof body.round === "number" ? body.round : void 0,
|
|
113546
113451
|
selections,
|
|
113547
113452
|
annotations,
|
|
113548
113453
|
globalComment: typeof body.globalComment === "string" ? body.globalComment : void 0,
|
|
113549
|
-
//
|
|
113550
|
-
//
|
|
113551
|
-
//
|
|
113454
|
+
// UI usage signals for `lens:round_completed`. Coerced to strict booleans
|
|
113455
|
+
// so a malformed field from this unauthenticated route can't carry
|
|
113456
|
+
// anything else into telemetry.
|
|
113552
113457
|
inspectorUsed: body.inspectorUsed === true,
|
|
113553
113458
|
offscreenRevealed: body.offscreenRevealed === true
|
|
113554
113459
|
});
|
|
@@ -115065,7 +114970,7 @@ var SourceMapsRegistry = class {
|
|
|
115065
114970
|
}
|
|
115066
114971
|
/**
|
|
115067
114972
|
* Begin fetching and registering a source map from a Debugger.scriptParsed event.
|
|
115068
|
-
* Returns immediately;
|
|
114973
|
+
* Returns immediately; `waitForPending()` blocks until all maps are loaded.
|
|
115069
114974
|
*/
|
|
115070
114975
|
registerFromScriptParsed(scriptUrl, scriptId, sourceMapURL) {
|
|
115071
114976
|
if (!sourceMapURL) return;
|
|
@@ -115079,10 +114984,8 @@ var SourceMapsRegistry = class {
|
|
|
115079
114984
|
/**
|
|
115080
114985
|
* Resolve an original source file + line to its generated position in the bundle.
|
|
115081
114986
|
*
|
|
115082
|
-
* `filePath`
|
|
115083
|
-
*
|
|
115084
|
-
* - absolute, e.g. "/Users/.../App.tsx"
|
|
115085
|
-
* - aliased, e.g. "/[metro-project]/App.tsx"
|
|
114987
|
+
* `filePath` may be project-relative ("src/Foo.tsx"), absolute, or aliased
|
|
114988
|
+
* ("/[metro-project]/App.tsx").
|
|
115086
114989
|
*/
|
|
115087
114990
|
toGeneratedPosition(filePath, line1Based, column0Based = 0) {
|
|
115088
114991
|
const candidates = this.buildSourceCandidates(filePath);
|
|
@@ -115110,10 +115013,7 @@ var SourceMapsRegistry = class {
|
|
|
115110
115013
|
}
|
|
115111
115014
|
return null;
|
|
115112
115015
|
}
|
|
115113
|
-
/**
|
|
115114
|
-
* Find which source map source path matches the given file path.
|
|
115115
|
-
* Returns the matched source string or null.
|
|
115116
|
-
*/
|
|
115016
|
+
/** Matching entry in a registered map's `sources`, or null. */
|
|
115117
115017
|
findMatchingSource(filePath) {
|
|
115118
115018
|
const candidates = this.buildSourceCandidates(filePath);
|
|
115119
115019
|
for (const map2 of this.maps) {
|
|
@@ -115456,22 +115356,12 @@ var chromiumJsRuntimeDebuggerBlueprint = {
|
|
|
115456
115356
|
getDependencies(_payload) {
|
|
115457
115357
|
return { chromium: `${CHROMIUM_CDP_NAMESPACE}:${_payload}` };
|
|
115458
115358
|
},
|
|
115459
|
-
// Deliberately NO recoverable()
|
|
115460
|
-
//
|
|
115461
|
-
//
|
|
115462
|
-
//
|
|
115463
|
-
//
|
|
115464
|
-
//
|
|
115465
|
-
// RUNNING is a tab switch, where CDPClient.reconnect() rejects in-flight
|
|
115466
|
-
// requests with CONNECTION_CLOSED (late sends with NOT_CONNECTED) but
|
|
115467
|
-
// re-points the SAME client object at the new tab — the cached node heals
|
|
115468
|
-
// itself for the next call without any dispose. The failing call surfaces a
|
|
115469
|
-
// classified error that debugger-status maps to a structured "reconnecting"
|
|
115470
|
-
// result with retry-once guidance. A genuinely dead Chromium socket instead
|
|
115471
|
-
// fires ChromiumCdp's own terminated event, whose teardown cascades into this
|
|
115472
|
-
// dependent — the node leaves RUNNING and the next call re-resolves fresh.
|
|
115473
|
-
// (Same log-preservation reasoning as debugger-log-registry's missing socket
|
|
115474
|
-
// gate — see that tool's comment.)
|
|
115359
|
+
// Deliberately NO recoverable(): the registry's self-heal disposes the node
|
|
115360
|
+
// before retrying, and dispose unlinks the captured console log. It would
|
|
115361
|
+
// also buy nothing — the only failure window while this node and ChromiumCdp
|
|
115362
|
+
// both stay RUNNING is a tab switch, where CDPClient.reconnect() re-points
|
|
115363
|
+
// the same client object and the cached node heals itself; a genuinely dead
|
|
115364
|
+
// socket arrives instead as ChromiumCdp's terminated cascade.
|
|
115475
115365
|
async factory(deps, payload, options) {
|
|
115476
115366
|
const opts = options;
|
|
115477
115367
|
const device = opts?.device;
|
|
@@ -115527,14 +115417,13 @@ var chromiumJsRuntimeDebuggerBlueprint = {
|
|
|
115527
115417
|
const sourceResolver = makeStubSourceResolver();
|
|
115528
115418
|
const api = {
|
|
115529
115419
|
port,
|
|
115530
|
-
//
|
|
115531
|
-
//
|
|
115532
|
-
// source resolver) are gated out before they ever touch this field.
|
|
115420
|
+
// No Metro project root on Chromium; debugger-connect and debugger-status
|
|
115421
|
+
// document the field as empty here.
|
|
115533
115422
|
projectRoot: "",
|
|
115534
115423
|
deviceName: device.name ?? "Chromium",
|
|
115535
115424
|
appName: "Chromium",
|
|
115536
115425
|
logicalDeviceId: device.id,
|
|
115537
|
-
//
|
|
115426
|
+
// No legacy RN inspector on Chromium.
|
|
115538
115427
|
isNewDebugger: true,
|
|
115539
115428
|
cdp,
|
|
115540
115429
|
sourceResolver,
|
|
@@ -115913,14 +115802,11 @@ var ANDROID_NAMED_KEYCODES = {
|
|
|
115913
115802
|
"esc": 111,
|
|
115914
115803
|
// alias of escape
|
|
115915
115804
|
"backspace": 67,
|
|
115916
|
-
// KEYCODE_DEL
|
|
115917
|
-
//
|
|
115918
|
-
// key-codes.ts
|
|
115919
|
-
//
|
|
115920
|
-
// key must mean the same thing on every platform, so map it to KEYCODE_DEL (67)
|
|
115921
|
-
// here too rather than KEYCODE_FORWARD_DEL (112).
|
|
115805
|
+
// KEYCODE_DEL
|
|
115806
|
+
// KEYCODE_DEL, not KEYCODE_FORWARD_DEL (112): the shared HID vocabulary in
|
|
115807
|
+
// key-codes.ts maps both `backspace` and `delete` to usage 42, and a named key
|
|
115808
|
+
// must mean the same thing on every platform.
|
|
115922
115809
|
"delete": 67,
|
|
115923
|
-
// KEYCODE_DEL (alias of backspace — see note above)
|
|
115924
115810
|
"tab": 61,
|
|
115925
115811
|
// KEYCODE_TAB
|
|
115926
115812
|
"space": 62,
|
|
@@ -115933,7 +115819,7 @@ var ANDROID_NAMED_KEYCODES = {
|
|
|
115933
115819
|
// KEYCODE_DPAD_LEFT
|
|
115934
115820
|
"arrow-right": 22,
|
|
115935
115821
|
// KEYCODE_DPAD_RIGHT
|
|
115936
|
-
//
|
|
115822
|
+
// KEYCODE_F1 (131) .. KEYCODE_F12 (142) are contiguous.
|
|
115937
115823
|
...Object.fromEntries(Array.from({ length: 12 }, (_, i) => [`f${i + 1}`, 131 + i]))
|
|
115938
115824
|
};
|
|
115939
115825
|
var ANDROID_BUTTON_KEYCODES = {
|
|
@@ -115953,9 +115839,8 @@ var ANDROID_BUTTON_KEYCODES = {
|
|
|
115953
115839
|
function assertTypeableAndroidText(text) {
|
|
115954
115840
|
if (/[\n\r]/.test(text)) {
|
|
115955
115841
|
throw new InvalidToolInputError(
|
|
115956
|
-
//
|
|
115957
|
-
//
|
|
115958
|
-
// equivalent is the tv-remote select press.
|
|
115842
|
+
// The advice must also hold on the TV path (typeTv), which rejects named
|
|
115843
|
+
// keys in favour of tv-remote select.
|
|
115959
115844
|
'keyboard text must not contain a newline on Android; press enter separately instead (key: "enter" on a phone or tablet, tv-remote select on a TV)',
|
|
115960
115845
|
{
|
|
115961
115846
|
error_code: FAILURE_CODES.KEYBOARD_CHARACTER_UNSUPPORTED,
|
|
@@ -116181,15 +116066,13 @@ var androidTvControlBlueprint = {
|
|
|
116181
116066
|
await injectAndroidText(serial, words[i]);
|
|
116182
116067
|
}
|
|
116183
116068
|
},
|
|
116184
|
-
// Android TV reads the live hierarchy on every describe
|
|
116185
|
-
// daemon), so there is no stale-cache class of bug to recover from.
|
|
116069
|
+
// Android TV reads the live hierarchy on every describe — no cache to drop.
|
|
116186
116070
|
async recycleAx() {
|
|
116187
116071
|
}
|
|
116188
116072
|
};
|
|
116189
116073
|
const instance = {
|
|
116190
116074
|
api,
|
|
116191
|
-
// Stateless: every
|
|
116192
|
-
// tear down. Present to satisfy the ServiceInstance contract.
|
|
116075
|
+
// Stateless: every call is a fresh adb shell-out, so nothing to tear down.
|
|
116193
116076
|
dispose: async () => {
|
|
116194
116077
|
},
|
|
116195
116078
|
events
|
|
@@ -116216,9 +116099,8 @@ var nativeDevtoolsStatusTool = {
|
|
|
116216
116099
|
},
|
|
116217
116100
|
capability: { apple: { simulator: true, device: true }, appleRemote: { simulator: true } },
|
|
116218
116101
|
// The "injectable is false" recovery sentence inlines NON_INJECTABLE_RECOVERY
|
|
116219
|
-
// verbatim: the description must stay
|
|
116220
|
-
//
|
|
116221
|
-
// by native-devtools-status.test.ts.
|
|
116102
|
+
// verbatim (pinned by native-devtools-status.test.ts): the description must stay
|
|
116103
|
+
// a plain literal for scripts/extract-tools.mjs to read statically.
|
|
116222
116104
|
description: `Check whether native devtools are connected to a specific app and whether the next launch is prepared for injection.
|
|
116223
116105
|
Use when you need to verify native devtools readiness before calling native-full-hierarchy, native-describe-screen, or native-network-logs.
|
|
116224
116106
|
|
|
@@ -116297,13 +116179,13 @@ Fails if the simulator server is not running for the given UDID.`,
|
|
|
116297
116179
|
// fresh process fixes — `indeterminate` among them, since an uninspectable
|
|
116298
116180
|
// host (ios-remote) supports no finer reading. Both already carry a live
|
|
116299
116181
|
// process (the settling above rewrote an empty `indeterminate` to
|
|
116300
|
-
// `not_running`), so an `appRunning` conjunct would
|
|
116182
|
+
// `not_running`), so an `appRunning` conjunct would restate the state.
|
|
116301
116183
|
requiresRestart: state3 === "stale_process" || state3 === "indeterminate",
|
|
116302
116184
|
state: state3,
|
|
116303
116185
|
// The booleans cannot express "one restart, then stop" — the shape
|
|
116304
116186
|
// `indeterminate` needs, and the only one ios-remote can report for a
|
|
116305
|
-
// running app.
|
|
116306
|
-
//
|
|
116187
|
+
// running app. The shared prose puts that escape in front of an agent who
|
|
116188
|
+
// never read this tool's description.
|
|
116307
116189
|
...state3 === "connected" ? {} : { message: buildAppStateMessage(params.bundleId, state3) },
|
|
116308
116190
|
nextLaunchWillBeInjected: envSetup,
|
|
116309
116191
|
injectable: true
|
|
@@ -117181,22 +117063,11 @@ var jsRuntimeDebuggerBlueprint = {
|
|
|
117181
117063
|
getURN(payload) {
|
|
117182
117064
|
return `${JS_RUNTIME_DEBUGGER_NAMESPACE}:${payload}`;
|
|
117183
117065
|
},
|
|
117184
|
-
//
|
|
117185
|
-
//
|
|
117186
|
-
//
|
|
117187
|
-
//
|
|
117188
|
-
//
|
|
117189
|
-
// there the request provably never left the host, making a retry safe.
|
|
117190
|
-
// Deliberately NOT recoverable:
|
|
117191
|
-
// - DEBUGGER_CDP_CONNECTION_CLOSED: the request was delivered and may have
|
|
117192
|
-
// taken effect (double-execution risk); on this path the node has also
|
|
117193
|
-
// already left RUNNING when it fires.
|
|
117194
|
-
// - DEBUGGER_CDP_REQUEST_TIMEOUT: the request may have taken effect, and a
|
|
117195
|
-
// hung-but-open runtime (e.g. paused at a breakpoint) is not fixed by
|
|
117196
|
-
// reconnecting.
|
|
117197
|
-
// - Metro discovery / target-selection codes: init-path failures — the node
|
|
117198
|
-
// never reaches RUNNING, so recovery is never consulted, and a retry would
|
|
117199
|
-
// be hopeless anyway.
|
|
117066
|
+
// Only the send() guard's DEBUGGER_CDP_NOT_CONNECTED proves the request never
|
|
117067
|
+
// left the host, so only it is safe to retry. CONNECTION_CLOSED and
|
|
117068
|
+
// REQUEST_TIMEOUT reject requests that were delivered and may have taken
|
|
117069
|
+
// effect; Metro discovery and target-selection codes throw before the node is
|
|
117070
|
+
// RUNNING, where the registry never consults this.
|
|
117200
117071
|
recoverable(error52) {
|
|
117201
117072
|
return getFailureSignal(error52)?.error_code === FAILURE_CODES.DEBUGGER_CDP_NOT_CONNECTED;
|
|
117202
117073
|
},
|
|
@@ -118367,11 +118238,8 @@ async function waitForAdbDevice(serial, timeoutMs) {
|
|
|
118367
118238
|
error_code: FAILURE_CODES.VEGA_DEVICE_NOT_REGISTERED,
|
|
118368
118239
|
failure_stage: "vega_adb_register",
|
|
118369
118240
|
failure_area: "tool_server",
|
|
118370
|
-
//
|
|
118371
|
-
//
|
|
118372
|
-
// (vs VEGA_BOOT_TIMEOUT, the VVD never starting) already carries the
|
|
118373
|
-
// "registered vs started" distinction — error_kind reflects the true
|
|
118374
|
-
// nature (deadline expiry) rather than double-encoding that.
|
|
118241
|
+
// Deadline expiry, hence `timeout`; the error_code already separates this
|
|
118242
|
+
// from VEGA_BOOT_TIMEOUT (the VVD never starting).
|
|
118375
118243
|
error_kind: "timeout"
|
|
118376
118244
|
}
|
|
118377
118245
|
);
|
|
@@ -118671,11 +118539,9 @@ async function bootElectronApp(options) {
|
|
|
118671
118539
|
child = (0, import_node_child_process17.spawn)(launcher.command, args, {
|
|
118672
118540
|
detached: true,
|
|
118673
118541
|
stdio: ["ignore", "pipe", "pipe"],
|
|
118674
|
-
// Strip ELECTRON_RUN_AS_NODE (see electronGuiChildEnv):
|
|
118675
|
-
//
|
|
118676
|
-
//
|
|
118677
|
-
// child exits early, or the readiness probe times out) instead of the app
|
|
118678
|
-
// coming up.
|
|
118542
|
+
// Strip ELECTRON_RUN_AS_NODE (see electronGuiChildEnv): inherited from an
|
|
118543
|
+
// Electron-based MCP host it would boot the binary in Node mode with no
|
|
118544
|
+
// CDP endpoint, failing boot-device instead of bringing the app up.
|
|
118679
118545
|
env: electronGuiChildEnv({ ELECTRON_ENABLE_LOGGING: "1" })
|
|
118680
118546
|
});
|
|
118681
118547
|
} catch (err) {
|
|
@@ -118838,11 +118704,9 @@ var STAGE_BUDGET = {
|
|
|
118838
118704
|
pmReady: 45e3,
|
|
118839
118705
|
// pm path android answers (retried; non-fatal on the final attempt)
|
|
118840
118706
|
firstRealFrame: 9e4,
|
|
118841
|
-
// screencap returns ≥1 non-zero pixel after cold boot
|
|
118842
118707
|
firstRealFrameHot: 8e3
|
|
118843
|
-
//
|
|
118844
|
-
//
|
|
118845
|
-
// few seconds is enough to discriminate transient blanks from genuine wedge.
|
|
118708
|
+
// the sticky-blank state never clears on its own, so a
|
|
118709
|
+
// few seconds is enough to tell it from a transient blank.
|
|
118846
118710
|
};
|
|
118847
118711
|
var VALID_GPU_MODES = /* @__PURE__ */ new Set([
|
|
118848
118712
|
"auto",
|
|
@@ -119361,14 +119225,13 @@ async function bootAndroidImpl(params) {
|
|
|
119361
119225
|
emulatorArgs: hotArgs,
|
|
119362
119226
|
attemptDeadline: hotAttemptDeadline,
|
|
119363
119227
|
serialsBefore,
|
|
119364
|
-
// Snapshot restores register with adb within a
|
|
119365
|
-
//
|
|
119366
|
-
// scenario where load fails and the child silently cold-boots.
|
|
119228
|
+
// Snapshot restores register with adb within seconds; a minute-long
|
|
119229
|
+
// wait here would mask a failed load that silently cold-boots.
|
|
119367
119230
|
adbRegisterBudgetMs: 3e4,
|
|
119368
119231
|
deviceReadyBudgetMs: 3e4,
|
|
119369
119232
|
bootCompletedBudgetMs: 3e4,
|
|
119370
|
-
// Keep the hot path tight:
|
|
119371
|
-
//
|
|
119233
|
+
// Keep the hot path tight: one ~10 s PM window, tear down on failure so
|
|
119234
|
+
// we fall through to the cold boot below.
|
|
119372
119235
|
pmProbeBudgetMs: 1e4,
|
|
119373
119236
|
tearDownIfUnready: true
|
|
119374
119237
|
});
|
|
@@ -119409,9 +119272,9 @@ async function bootAndroidImpl(params) {
|
|
|
119409
119272
|
adbRegisterBudgetMs: STAGE_BUDGET.adbRegister,
|
|
119410
119273
|
deviceReadyBudgetMs: STAGE_BUDGET.deviceReady,
|
|
119411
119274
|
bootCompletedBudgetMs: STAGE_BUDGET.bootCompleted,
|
|
119412
|
-
// Final attempt: retry PM for longer
|
|
119413
|
-
//
|
|
119414
|
-
//
|
|
119275
|
+
// Final attempt: retry PM for longer and don't tear the emulator down if
|
|
119276
|
+
// it stays slow — a guest that reached boot_completed is usable, and there
|
|
119277
|
+
// is no further fallback to justify destroying it.
|
|
119415
119278
|
pmProbeBudgetMs: STAGE_BUDGET.pmReady,
|
|
119416
119279
|
tearDownIfUnready: false
|
|
119417
119280
|
});
|
|
@@ -119899,11 +119762,8 @@ Common Android packages: com.android.settings, com.android.chrome, com.google.an
|
|
|
119899
119762
|
searchHint: "open start app bundle id package simulator emulator chromium vega launch tvos apple tv fire tv",
|
|
119900
119763
|
zodSchema: zodSchema10,
|
|
119901
119764
|
capability: capability2,
|
|
119902
|
-
//
|
|
119903
|
-
//
|
|
119904
|
-
// which reads `services.nativeDevtools`). Local iOS resolves native-devtools
|
|
119905
|
-
// lazily in its handler so a tvOS udid never spins up the iOS-only injection
|
|
119906
|
-
// (see header comment); Android and Vega need no service.
|
|
119765
|
+
// ios-remote's handler reads `services.nativeDevtools`; local iOS resolves
|
|
119766
|
+
// it lazily instead (see header comment).
|
|
119907
119767
|
services: (params) => {
|
|
119908
119768
|
const device = resolveDevice(params.udid);
|
|
119909
119769
|
if (device.platform === "ios-remote") return { nativeDevtools: nativeDevtoolsRef(device) };
|
|
@@ -120084,11 +119944,8 @@ Returns { restarted, bundleId }. Fails if the app is not installed.`,
|
|
|
120084
119944
|
searchHint: "terminate relaunch restart reset app bundle id package simulator emulator vega tvos fire tv",
|
|
120085
119945
|
zodSchema: zodSchema11,
|
|
120086
119946
|
capability: capability3,
|
|
120087
|
-
// ios-remote
|
|
120088
|
-
//
|
|
120089
|
-
// iOS resolves native-devtools lazily in its handler so a tvOS udid never
|
|
120090
|
-
// spins up the iOS-only injection (see header comment); Android and Vega
|
|
120091
|
-
// need no service.
|
|
119947
|
+
// Only ios-remote's handler reads `services.nativeDevtools`, so only it
|
|
119948
|
+
// needs an eager declaration.
|
|
120092
119949
|
services: (params) => {
|
|
120093
119950
|
const device = resolveDevice(params.udid);
|
|
120094
119951
|
if (device.platform === "ios-remote") return { nativeDevtools: nativeDevtoolsRef(device) };
|
|
@@ -120381,8 +120238,8 @@ function buildIosHandler(backend) {
|
|
|
120381
120238
|
failure_stage: "ios_settings_permission_simctl_privacy",
|
|
120382
120239
|
failure_area: "tool_server",
|
|
120383
120240
|
error_kind: "subprocess",
|
|
120384
|
-
// Both backends run the `simctl privacy` verb
|
|
120385
|
-
//
|
|
120241
|
+
// Both backends run the same `simctl privacy` verb, so telemetry
|
|
120242
|
+
// uses one subprocess name.
|
|
120386
120243
|
...subprocessFailureMetadata(err, "xcrun_simctl")
|
|
120387
120244
|
},
|
|
120388
120245
|
{ cause: err instanceof Error ? err : new Error(String(err)) }
|
|
@@ -120562,12 +120419,11 @@ var permissionAction = {
|
|
|
120562
120419
|
reset: { started: "Resetting", completed: "Reset" }
|
|
120563
120420
|
};
|
|
120564
120421
|
var capability5 = {
|
|
120565
|
-
// `simctl privacy` edits the simulator's TCC store
|
|
120566
|
-
// equivalent host-side switch,
|
|
120422
|
+
// `simctl privacy` edits the simulator's TCC store; physical iPhones have no
|
|
120423
|
+
// equivalent host-side switch, hence no `device: true`.
|
|
120567
120424
|
apple: { simulator: true },
|
|
120568
|
-
// sim-remote
|
|
120569
|
-
//
|
|
120570
|
-
// launch-app / restart-app / reinstall-app / open-url family.
|
|
120425
|
+
// sim-remote exposes the same `simctl privacy` verb, so remote sims can
|
|
120426
|
+
// pre-set permissions too.
|
|
120571
120427
|
appleRemote: { simulator: true },
|
|
120572
120428
|
android: { emulator: true, device: true, unknown: true }
|
|
120573
120429
|
};
|
|
@@ -121218,9 +121074,9 @@ Fails if the simulator-server / emulator backend / Chromium CDP is not reachable
|
|
|
121218
121074
|
zodSchema: zodSchema15,
|
|
121219
121075
|
outputHint: "image",
|
|
121220
121076
|
capability: capability7,
|
|
121221
|
-
// No eager service: a tvOS udid classifies as iOS by shape,
|
|
121222
|
-
// simulator-server here would spawn it for
|
|
121223
|
-
//
|
|
121077
|
+
// No eager service: a tvOS udid classifies as iOS by shape, so declaring
|
|
121078
|
+
// simulator-server here would spawn it for a device it cannot drive and hang
|
|
121079
|
+
// on the ready timeout. Resolve the backend lazily instead.
|
|
121224
121080
|
services: () => ({}),
|
|
121225
121081
|
async execute(_services, params, ctx) {
|
|
121226
121082
|
const signal = ctx?.signal ?? AbortSignal.timeout(16e3);
|
|
@@ -121908,15 +121764,12 @@ var zodSchema23 = external_exports.object({
|
|
|
121908
121764
|
});
|
|
121909
121765
|
var BUTTONS_BY_PLATFORM = {
|
|
121910
121766
|
"ios": /* @__PURE__ */ new Set(["home", "power", "volumeUp", "volumeDown", "appSwitch", "actionButton"]),
|
|
121911
|
-
// Remote iOS sims expose the same hardware buttons as local iOS.
|
|
121912
121767
|
"ios-remote": /* @__PURE__ */ new Set(["home", "power", "volumeUp", "volumeDown", "appSwitch", "actionButton"]),
|
|
121913
121768
|
"android": /* @__PURE__ */ new Set(["home", "back", "power", "volumeUp", "volumeDown", "appSwitch"]),
|
|
121914
|
-
//
|
|
121915
|
-
// excludes them, the empty set keeps the lookup total if one slips through.
|
|
121769
|
+
// The capability gate excludes chromium; the empty set keeps the lookup total.
|
|
121916
121770
|
"chromium": /* @__PURE__ */ new Set([]),
|
|
121917
|
-
// Vega
|
|
121918
|
-
// `
|
|
121919
|
-
// rejected before this map is consulted. Empty set keeps the record total.
|
|
121771
|
+
// Vega buttons / D-pad go through the `tv-remote` tool; the capability omits
|
|
121772
|
+
// `vega`, so this entry only keeps the record total.
|
|
121920
121773
|
"vega": /* @__PURE__ */ new Set([])
|
|
121921
121774
|
};
|
|
121922
121775
|
var capability15 = {
|
|
@@ -121938,12 +121791,9 @@ Returns { pressed: buttonName }.
|
|
|
121938
121791
|
Fails if the device backend is not reachable \u2014 the simulator-server for iOS, or \`adb\` for Android (Android presses are injected with \`adb shell input keyevent\`).`,
|
|
121939
121792
|
zodSchema: zodSchema23,
|
|
121940
121793
|
capability: capability15,
|
|
121941
|
-
// Android
|
|
121942
|
-
//
|
|
121943
|
-
//
|
|
121944
|
-
// to a 30s ready-wait) and could throw ServiceInitializationError before the
|
|
121945
|
-
// adb path even runs. Declare it only for the iOS / ios-remote path that
|
|
121946
|
-
// actually consumes it (mirrors the sibling `keyboard` tool's lazy services).
|
|
121794
|
+
// The Android path uses `adb`, so declaring the service for an Android target
|
|
121795
|
+
// would spawn a sim-server the tool never uses (up to a 30s ready-wait) and
|
|
121796
|
+
// could throw ServiceInitializationError before the adb path even runs.
|
|
121947
121797
|
services: (params) => {
|
|
121948
121798
|
const device = resolveDevice(params.udid);
|
|
121949
121799
|
return device.platform === "android" ? {} : { simulatorServer: simulatorServerRef(device) };
|
|
@@ -122223,12 +122073,9 @@ async function typeAndroidPhone(device, params) {
|
|
|
122223
122073
|
}
|
|
122224
122074
|
function makeAndroidImpl(registry2) {
|
|
122225
122075
|
return {
|
|
122226
|
-
// Both sub-paths shell out to `adb
|
|
122227
|
-
//
|
|
122228
|
-
// `
|
|
122229
|
-
// missing binary fails with the clean 424 install hint rather than surfacing
|
|
122230
|
-
// from deeper in the probe. Matches the android branch of `describe` and
|
|
122231
|
-
// `tv-remote`.
|
|
122076
|
+
// Both sub-paths shell out to `adb` (the `isAndroidTv` probe, then `input`
|
|
122077
|
+
// either way), so declaring it makes a missing binary fail with
|
|
122078
|
+
// `dispatchByPlatform`'s 424 install hint instead of from inside the probe.
|
|
122232
122079
|
requires: ["adb"],
|
|
122233
122080
|
handler: async (_services, params, device) => await isAndroidTv(device.id) ? typeTv(registry2, device, params) : typeAndroidPhone(device, params)
|
|
122234
122081
|
};
|
|
@@ -122399,11 +122246,9 @@ var REMOTE_BUTTONS = Object.keys(REMOTE_KEYCODES);
|
|
|
122399
122246
|
var NAMED_KEYCODES = {
|
|
122400
122247
|
"enter": "KEY_ENTER",
|
|
122401
122248
|
"return": "KEY_ENTER",
|
|
122402
|
-
// alias of enter (matches iOS/Android/Chromium)
|
|
122403
122249
|
// Back is the TV analog of Escape; KEY_ESC is inert for the focus engine.
|
|
122404
122250
|
"escape": "KEY_BACK",
|
|
122405
122251
|
"esc": "KEY_BACK",
|
|
122406
|
-
// alias of escape
|
|
122407
122252
|
"backspace": "KEY_BACKSPACE",
|
|
122408
122253
|
"delete": "KEY_DELETE",
|
|
122409
122254
|
"tab": "KEY_TAB",
|
|
@@ -122412,8 +122257,7 @@ var NAMED_KEYCODES = {
|
|
|
122412
122257
|
"arrow-down": "KEY_DOWN",
|
|
122413
122258
|
"arrow-left": "KEY_LEFT",
|
|
122414
122259
|
"arrow-right": "KEY_RIGHT",
|
|
122415
|
-
// Vega names function keys KEY_FN_F<n
|
|
122416
|
-
// in the device key-name table (verified against system.ext4, SDK 0.22.6759).
|
|
122260
|
+
// Vega names function keys KEY_FN_F<n>, not KEY_F<n> (SDK 0.22.6759 key table).
|
|
122417
122261
|
...Object.fromEntries(Array.from({ length: 12 }, (_, i) => [`f${i + 1}`, `KEY_FN_F${i + 1}`]))
|
|
122418
122262
|
};
|
|
122419
122263
|
var SETTLE_BETWEEN_PRESSES_S = 0.3;
|
|
@@ -122524,16 +122368,13 @@ function createKeyboardTool(registry2) {
|
|
|
122524
122368
|
return {
|
|
122525
122369
|
id: "keyboard",
|
|
122526
122370
|
interaction: {
|
|
122527
|
-
//
|
|
122528
|
-
//
|
|
122529
|
-
//
|
|
122371
|
+
// Never quote the parameters: `text` may hold a plaintext credential and
|
|
122372
|
+
// `key` is an unvalidated free string here, yet these messages reach the
|
|
122373
|
+
// event log before `execute` runs.
|
|
122530
122374
|
//
|
|
122531
|
-
//
|
|
122532
|
-
//
|
|
122533
|
-
// a
|
|
122534
|
-
// after a call that succeeded, so it sees neither. Each formatter
|
|
122535
|
-
// therefore has to word a different set of shapes, and the empty
|
|
122536
|
-
// request — neither parameter, a documented no-op — reaches both.
|
|
122375
|
+
// That ordering also makes `startedMsg` word requests `execute` then
|
|
122376
|
+
// rejects (text+key, `{ key: "" }`), while `completedMsg` runs only after
|
|
122377
|
+
// a success and sees neither. Both see the empty request, a no-op.
|
|
122537
122378
|
startedMsg: ({ params }) => {
|
|
122538
122379
|
if (params.text === void 0) return "Pressing a key";
|
|
122539
122380
|
if (params.key === void 0) return "Entering text";
|
|
@@ -122553,29 +122394,21 @@ One call does one action: pass text OR key, never both. To type and then press a
|
|
|
122553
122394
|
zodSchema: zodSchema24,
|
|
122554
122395
|
capability: capability16,
|
|
122555
122396
|
searchHint: "type text keyboard input named key enter escape arrow tv vega fire tv search field hid leanback",
|
|
122556
|
-
// No eager service: each branch resolves its backend lazily (TV control,
|
|
122557
|
-
// simulator-server, CDP, or Vega adb), since distinguishing a TV target is
|
|
122558
|
-
// async and a tvOS udid must never resolve simulator-server.
|
|
122559
122397
|
services: () => ({}),
|
|
122560
122398
|
execute: async (services, params, options) => {
|
|
122561
122399
|
if (params.text !== void 0 && params.key !== void 0) {
|
|
122562
122400
|
throw new InvalidToolInputError(
|
|
122563
122401
|
// Says what did NOT happen, so the caller retries instead of first
|
|
122564
|
-
// inspecting the field
|
|
122565
|
-
//
|
|
122402
|
+
// inspecting the field. The example is literal because an ellipsis is
|
|
122403
|
+
// non-ASCII and the Android backend rejects it.
|
|
122566
122404
|
//
|
|
122567
|
-
// The TV caveat is
|
|
122568
|
-
// target
|
|
122569
|
-
//
|
|
122570
|
-
//
|
|
122571
|
-
|
|
122572
|
-
//
|
|
122573
|
-
//
|
|
122574
|
-
'keyboard takes `text` or `key`, not both \u2014 nothing was typed. To type and then press a key, send two `keyboard` steps in one `run-sequence`: { text: "hello" } followed by { key: "enter" }. On a TV target (Apple TV / Android TV) `key` is not supported at all \u2014 type with `text` and move focus with `tv-remote` (up/down/left/right/select).' + // The one-`run-sequence` form and two bare calls are NOT equivalent
|
|
122575
|
-
// once the text carries a placeholder, and this message is where an
|
|
122576
|
-
// agent converts a combined secret call — the tool description's
|
|
122577
|
-
// caveat is read long before that moment, if at all. The check is
|
|
122578
|
-
// syntactic (the same `.includes` flow-utils.ts uses), so the guard
|
|
122405
|
+
// The TV caveat is static, not probed: this guard runs above the
|
|
122406
|
+
// dispatch, so the target kind is unknown here — yet without it the
|
|
122407
|
+
// prescribed `{ key: "enter" }` is a retry that cannot succeed on a
|
|
122408
|
+
// TV, where `key` is rejected outright (platforms/tv.ts).
|
|
122409
|
+
'keyboard takes `text` or `key`, not both \u2014 nothing was typed. To type and then press a key, send two `keyboard` steps in one `run-sequence`: { text: "hello" } followed by { key: "enter" }. On a TV target (Apple TV / Android TV) `key` is not supported at all \u2014 type with `text` and move focus with `tv-remote` (up/down/left/right/select).' + // One `run-sequence` and two bare calls are NOT equivalent once the
|
|
122410
|
+
// text carries a placeholder, and this message is where an agent
|
|
122411
|
+
// converts a combined secret call. Syntactic check, so the guard
|
|
122579
122412
|
// still resolves nothing.
|
|
122580
122413
|
(params.text.includes(SECRET_PLACEHOLDER_MARKER) ? " This `text` carries a `" + SECRET_PLACEHOLDER_MARKER + '...}}` placeholder, so keep both steps in that ONE `run-sequence` rather than splitting them into two bare calls: the auto-screenshot skip is decided per tool call from the whole request, and a separate { key: "enter" } call carries no placeholder \u2014 its screenshot is taken after the key lands and can capture the still-visible secret.' : ""),
|
|
122581
122414
|
{
|
|
@@ -122586,12 +122419,12 @@ One call does one action: pass text OR key, never both. To type and then press a
|
|
|
122586
122419
|
}
|
|
122587
122420
|
if (params.key === "") {
|
|
122588
122421
|
throw new InvalidToolInputError(
|
|
122589
|
-
// Names the omission as the alternative
|
|
122590
|
-
//
|
|
122422
|
+
// Names the omission as the alternative: a caller that sent an empty
|
|
122423
|
+
// string usually built the value from something absent.
|
|
122591
122424
|
"`key` is an empty string, which names no key \u2014 nothing was pressed. Pass a named key (enter, escape, backspace, tab, space, arrow-up, arrow-down, arrow-left, arrow-right, f1\u2013f12), or omit `key` if there is nothing to press.",
|
|
122592
122425
|
{
|
|
122593
|
-
// The same code an unknown name gets
|
|
122594
|
-
//
|
|
122426
|
+
// The same code an unknown name gets: one telemetry bucket for
|
|
122427
|
+
// every unusable `key` value.
|
|
122595
122428
|
error_code: FAILURE_CODES.KEYBOARD_KEY_UNSUPPORTED,
|
|
122596
122429
|
failure_stage: "keyboard_named_key_empty",
|
|
122597
122430
|
error_kind: "unsupported"
|
|
@@ -122648,8 +122481,8 @@ async function pasteSimulator(api, text) {
|
|
|
122648
122481
|
}
|
|
122649
122482
|
function makeIosImpl4(registry2) {
|
|
122650
122483
|
return {
|
|
122651
|
-
// `
|
|
122652
|
-
//
|
|
122484
|
+
// `xcrun` is for the `isTvOsSimulator` probe; simulator-server comes from
|
|
122485
|
+
// the blueprint.
|
|
122653
122486
|
requires: ["xcrun"],
|
|
122654
122487
|
async handler(_services, params, device) {
|
|
122655
122488
|
if (await isTvOsSimulator(device.id)) rejectTv(device);
|
|
@@ -122702,21 +122535,16 @@ function makeAndroidImpl2(registry2) {
|
|
|
122702
122535
|
|
|
122703
122536
|
// ../tool-server/src/tools/paste/index.ts
|
|
122704
122537
|
var capability17 = {
|
|
122705
|
-
// Simulators only. A physical iPhone's pasteboard is reachable through the
|
|
122706
|
-
// same simulator-server endpoint, but the paste keystroke is not verified
|
|
122707
|
-
// over the CoreDevice HID path, so `device` stays off until it is.
|
|
122708
122538
|
apple: { simulator: true },
|
|
122709
|
-
// A remote
|
|
122710
|
-
//
|
|
122539
|
+
// A remote sim pastes over the MoQ transport (`simctl pbcopy` + ⌘V); the HTTP
|
|
122540
|
+
// clipboard route does not exist there.
|
|
122711
122541
|
appleRemote: { simulator: true },
|
|
122712
|
-
// Emulators only: the clipboard is set through the emulator's gRPC
|
|
122713
|
-
//
|
|
122714
|
-
//
|
|
122715
|
-
// simulator-server refuses a phone either way.
|
|
122542
|
+
// Emulators only: the clipboard is set through the emulator's gRPC endpoint,
|
|
122543
|
+
// which a physical phone does not have. `unknown` is admitted because an
|
|
122544
|
+
// unresolved serial may still be an emulator.
|
|
122716
122545
|
android: { emulator: true, unknown: true }
|
|
122717
|
-
// No `chromium`:
|
|
122718
|
-
//
|
|
122719
|
-
// clipboard API is exposed by the VVD tooling.
|
|
122546
|
+
// No `chromium`: its only clipboard is the HOST one, so a paste would
|
|
122547
|
+
// overwrite what the user copied. No `vega`: VVD exposes no clipboard API.
|
|
122720
122548
|
//
|
|
122721
122549
|
// TV targets are not separate platforms (an Apple TV simulator is
|
|
122722
122550
|
// `ios`/`simulator`, an Android TV emulator `android`/`emulator`), so each
|
|
@@ -123045,9 +122873,8 @@ function shakeFailure(udid, detail, cause) {
|
|
|
123045
122873
|
failure_stage: "ios_shake_notifyutil",
|
|
123046
122874
|
failure_area: "tool_server",
|
|
123047
122875
|
error_kind: "subprocess",
|
|
123048
|
-
// Only a thrown subprocess error carries the syscall/exit metadata
|
|
123049
|
-
// remote backend reports a
|
|
123050
|
-
// throwing, so there is no error object to mine there.
|
|
122876
|
+
// Only a thrown subprocess error carries the syscall/exit metadata; the
|
|
122877
|
+
// remote backend reports a failed child in its JSON payload instead.
|
|
123051
122878
|
...cause ? subprocessFailureMetadata(cause, "xcrun_simctl") : {}
|
|
123052
122879
|
},
|
|
123053
122880
|
cause ? { cause } : void 0
|
|
@@ -123229,26 +123056,22 @@ var androidImpl6 = {
|
|
|
123229
123056
|
|
|
123230
123057
|
// ../tool-server/src/tools/shake/index.ts
|
|
123231
123058
|
var capability19 = {
|
|
123232
|
-
// Simulator only
|
|
123233
|
-
//
|
|
123234
|
-
// gets a clean 400 instead of a silent no-op.
|
|
123059
|
+
// Simulator only: a physical iPhone's motion is real hardware, with no
|
|
123060
|
+
// host-side hook to fake it.
|
|
123235
123061
|
apple: { simulator: true },
|
|
123236
|
-
//
|
|
123237
|
-
//
|
|
123062
|
+
// `sim-remote spawn` runs the same in-simulator `notifyutil` argv the local
|
|
123063
|
+
// path does.
|
|
123238
123064
|
appleRemote: { simulator: true },
|
|
123239
|
-
//
|
|
123240
|
-
//
|
|
123241
|
-
// because a serial that didn't resolve may still be an emulator; the handler
|
|
123242
|
-
// re-checks and rejects a non-emulator serial explicitly.
|
|
123065
|
+
// Emulators only, for the same reason as iOS. `unknown` is let through and
|
|
123066
|
+
// the handler rejects a serial with no emulator console.
|
|
123243
123067
|
android: { emulator: true, unknown: true }
|
|
123244
|
-
// No `vega
|
|
123068
|
+
// No `vega` block, so a Fire TV is rejected by the capability gate.
|
|
123245
123069
|
//
|
|
123246
|
-
// TV
|
|
123247
|
-
//
|
|
123248
|
-
// `android`/`emulator
|
|
123249
|
-
//
|
|
123250
|
-
//
|
|
123251
|
-
// kind is an async `simctl list` / `adb` probe.
|
|
123070
|
+
// A TV that is not a separate platform can't be excluded here: an Apple TV
|
|
123071
|
+
// simulator is `ios`/`simulator` and an Android TV emulator is
|
|
123072
|
+
// `android`/`emulator`. Each platform handler probes the runtime and rejects
|
|
123073
|
+
// a TV instead; `supports` can't, being synchronous while the probe is an
|
|
123074
|
+
// async `simctl list` / `adb` call.
|
|
123252
123075
|
};
|
|
123253
123076
|
var shakeTool = {
|
|
123254
123077
|
id: "shake",
|
|
@@ -123267,8 +123090,8 @@ Only phone/tablet simulators and emulators are supported.`,
|
|
|
123267
123090
|
searchHint: "shake motion accelerometer undo typing dev menu gesture",
|
|
123268
123091
|
zodSchema: shakeZodSchema,
|
|
123269
123092
|
capability: capability19,
|
|
123270
|
-
//
|
|
123271
|
-
//
|
|
123093
|
+
// No simulator-server is resolved: `simctl`/`adb` are called directly, so a
|
|
123094
|
+
// tool that never uses one doesn't spawn it or wait for it to be ready.
|
|
123272
123095
|
services: () => ({}),
|
|
123273
123096
|
execute: dispatchByPlatform({
|
|
123274
123097
|
toolId: "shake",
|
|
@@ -123395,10 +123218,8 @@ Multi-step navigation: pass a path as { button: ["up","right","right","select"]
|
|
|
123395
123218
|
Read the screen with \`describe\` before and after to see where focus landed.
|
|
123396
123219
|
Returns { pressed, count }.`,
|
|
123397
123220
|
alwaysLoad: true,
|
|
123398
|
-
// A path (≤64 buttons) × repeat (≤50) flattens to thousands of presses
|
|
123399
|
-
//
|
|
123400
|
-
// long-running so the MCP adapter doesn't abort it at its per-request fetch
|
|
123401
|
-
// timeout and the idle-shutdown timer is kept warm for the call's duration.
|
|
123221
|
+
// A path (≤64 buttons) × repeat (≤50) flattens to thousands of presses, sent
|
|
123222
|
+
// one round-trip at a time on the Apple/Android path — minutes of wall-clock.
|
|
123402
123223
|
longRunning: true,
|
|
123403
123224
|
searchHint: "tv remote dpad d-pad navigate focus up down left right select ok back home menu play pause rewind fast forward sequence path apple tv tvos android tv leanback vega fire tv",
|
|
123404
123225
|
zodSchema: zodSchema26,
|
|
@@ -129777,16 +129598,13 @@ var ALLOWED_TOOLS = /* @__PURE__ */ new Set([
|
|
|
129777
129598
|
"gesture-rotate",
|
|
129778
129599
|
"button",
|
|
129779
129600
|
"keyboard",
|
|
129780
|
-
//
|
|
129781
|
-
//
|
|
129601
|
+
// Sequenceable for the same reason `keyboard` is: the focus tap, the paste
|
|
129602
|
+
// and the submit are one user action.
|
|
129782
129603
|
"paste",
|
|
129783
129604
|
"rotate",
|
|
129784
|
-
//
|
|
129785
|
-
//
|
|
129786
|
-
// dispatched back-to-back rather than across separate round-trips.
|
|
129605
|
+
// Shake's interesting cases are races (shake while a sheet is dismissing,
|
|
129606
|
+
// shake right after typing), which need back-to-back dispatch.
|
|
129787
129607
|
"shake",
|
|
129788
|
-
// `tv-remote` drives the D-pad on a TV target (Apple TV / Android TV / Vega);
|
|
129789
|
-
// `keyboard` types into the focused field there.
|
|
129790
129608
|
"tv-remote",
|
|
129791
129609
|
AWAIT_UI_ELEMENT_TOOL_ID
|
|
129792
129610
|
]);
|
|
@@ -129812,9 +129630,8 @@ var capability22 = {
|
|
|
129812
129630
|
android: { emulator: true, device: true, unknown: true },
|
|
129813
129631
|
chromium: { app: true },
|
|
129814
129632
|
// Vega (Fire TV) is a valid target: its `tv-remote` / `keyboard` steps are
|
|
129815
|
-
// supported
|
|
129816
|
-
//
|
|
129817
|
-
// before any step runs — each step's own capability is still enforced below.
|
|
129633
|
+
// supported. Without this key the HTTP layer's `assertSupported` would reject
|
|
129634
|
+
// a Vega udid before any step runs.
|
|
129818
129635
|
vega: { vvd: true }
|
|
129819
129636
|
};
|
|
129820
129637
|
function createRunSequenceTool(registry2) {
|
|
@@ -129888,15 +129705,10 @@ Stops on the first error (or unmet await-ui-element condition) and returns parti
|
|
|
129888
129705
|
searchHint: "batch sequence multiple gesture steps sequentially",
|
|
129889
129706
|
zodSchema: zodSchema28,
|
|
129890
129707
|
capability: capability22,
|
|
129891
|
-
//
|
|
129892
|
-
// `
|
|
129893
|
-
//
|
|
129894
|
-
//
|
|
129895
|
-
// `tvos` platform) — declaring simulator-server for it would spawn a
|
|
129896
|
-
// controller it can't drive and hang on the ready timeout before any tv-*
|
|
129897
|
-
// step could run. The sub-tool invocations still pay only their own
|
|
129898
|
-
// first-step spawn cost, and `ctx` is threaded through so nested steps keep
|
|
129899
|
-
// the outer request's telemetry attribution.
|
|
129708
|
+
// Each step resolves its own services. An eager resolver can't be used
|
|
129709
|
+
// because a tvOS udid shape-classifies as `ios` (there is no `tvos`
|
|
129710
|
+
// platform), so declaring simulator-server would spawn a controller it
|
|
129711
|
+
// can't drive and hang on the ready timeout before any tv-remote step runs.
|
|
129900
129712
|
services: () => ({}),
|
|
129901
129713
|
async execute(_services, params, ctx) {
|
|
129902
129714
|
const { udid, steps } = params;
|
|
@@ -130044,16 +129856,15 @@ var NOT_CONNECTED_CODE_MAP = {
|
|
|
130044
129856
|
[FAILURE_CODES.DEBUGGER_CDP_SOCKET_CLOSED_BEFORE_OPEN]: "cdp_unreachable",
|
|
130045
129857
|
[FAILURE_CODES.DEBUGGER_CDP_NOT_CONNECTED]: "cdp_unreachable",
|
|
130046
129858
|
[FAILURE_CODES.DEBUGGER_CDP_CONNECTION_CLOSED]: "cdp_unreachable",
|
|
130047
|
-
//
|
|
130048
|
-
// accepts the socket but its JS runtime never answers
|
|
130049
|
-
//
|
|
130050
|
-
//
|
|
129859
|
+
// Raised by the connect pipeline's enable/binding sends when the target
|
|
129860
|
+
// accepts the socket but its JS runtime never answers. A post-connect hang
|
|
129861
|
+
// differs: the OPEN socket still reports status "connected" (see the
|
|
129862
|
+
// socket-state gate in debugger-status).
|
|
130051
129863
|
[FAILURE_CODES.DEBUGGER_CDP_REQUEST_TIMEOUT]: "runtime_unresponsive",
|
|
130052
129864
|
[FAILURE_CODES.CHROMIUM_CDP_UNREACHABLE]: "cdp_unreachable",
|
|
130053
|
-
//
|
|
130054
|
-
//
|
|
130055
|
-
//
|
|
130056
|
-
// actually answered), so it must not escape as a thrown tool failure.
|
|
129865
|
+
// Reached but not CDP: a squatter on the debug port, an HTTP error status, or
|
|
129866
|
+
// a non-JSON body — the same precondition class as the Metro arm's non-Metro
|
|
129867
|
+
// occupant, so it must not escape as a thrown tool failure.
|
|
130057
129868
|
[FAILURE_CODES.CHROMIUM_CDP_INVALID_RESPONSE]: "cdp_unreachable",
|
|
130058
129869
|
[FAILURE_CODES.CHROMIUM_CDP_NO_PAGE_TARGET]: "cdp_unreachable",
|
|
130059
129870
|
[FAILURE_CODES.REGISTRY_SERVICE_TERMINATING]: "reconnecting"
|
|
@@ -130122,7 +129933,7 @@ Use when you need to verify connectivity before using other debugger tools. Neve
|
|
|
130122
129933
|
zodSchema: zodSchema30,
|
|
130123
129934
|
capability: DEBUGGER_TOOL_CAPABILITY,
|
|
130124
129935
|
// Resolved manually in execute so a not-connected precondition becomes a
|
|
130125
|
-
// structured result instead of a
|
|
129936
|
+
// structured result instead of a tool failure.
|
|
130126
129937
|
services: () => ({}),
|
|
130127
129938
|
async execute(_services, params, ctx) {
|
|
130128
129939
|
try {
|
|
@@ -130245,11 +130056,8 @@ var debuggerReloadMetroTool = {
|
|
|
130245
130056
|
description: `Restart the Metro JS bundle in the connected React Native app without restarting the native process.
|
|
130246
130057
|
Use when you want to apply code changes or reset JS state. Returns { reloaded, port, method, deviceName, appName, logicalDeviceId } indicating which reload path was used and which device/app was targeted. Fails if Metro is not running on the given port.`,
|
|
130247
130058
|
zodSchema: zodSchema32,
|
|
130248
|
-
//
|
|
130249
|
-
//
|
|
130250
|
-
// — preserving the URL but re-fetching index.html, blowing away in-memory
|
|
130251
|
-
// app state — that calling it under the same tool name would mislead. If we
|
|
130252
|
-
// want that on Chromium later, it deserves its own tool.
|
|
130059
|
+
// RN-only: reloading a Chromium page is a different operation from restarting
|
|
130060
|
+
// the Metro bundle, so it would need its own tool.
|
|
130253
130061
|
capability: RN_ONLY_TOOL_CAPABILITY,
|
|
130254
130062
|
services: (params) => ({
|
|
130255
130063
|
debugger: `JsRuntimeDebugger:${params.port}:${canonicalDeviceId(params.device_id)}`
|
|
@@ -131094,9 +130902,8 @@ Use when you need tap coordinates for a React Native UI element. Returns a compa
|
|
|
131094
130902
|
alwaysLoad: true,
|
|
131095
130903
|
searchHint: "react native component tree discovery tap coordinates",
|
|
131096
130904
|
zodSchema: zodSchema33,
|
|
131097
|
-
// RN-only:
|
|
131098
|
-
//
|
|
131099
|
-
// for DOM-tree discovery on Chromium.
|
|
130905
|
+
// RN-only: needs the React DevTools backend from the dev JS bundle. Chromium has
|
|
130906
|
+
// no equivalent — use `describe` there.
|
|
131100
130907
|
capability: RN_ONLY_TOOL_CAPABILITY,
|
|
131101
130908
|
services: (params) => ({
|
|
131102
130909
|
debugger: `JsRuntimeDebugger:${params.port}:${canonicalDeviceId(params.device_id)}`
|
|
@@ -131464,7 +131271,6 @@ var SKIP_SET = /* @__PURE__ */ new Set([
|
|
|
131464
131271
|
"TextInputLabel",
|
|
131465
131272
|
"ThemeContext",
|
|
131466
131273
|
"BaseHTMLEngineProvider",
|
|
131467
|
-
// Fabric / cross-app entries
|
|
131468
131274
|
"VScrollViewNativeComponent",
|
|
131469
131275
|
"InnerScreen",
|
|
131470
131276
|
"ScreenStackItem",
|
|
@@ -131603,10 +131409,8 @@ Set resolveSourceMaps to false to skip symbolication and get raw bundled locatio
|
|
|
131603
131409
|
Set includeSkipped=true to see filtered items annotated with skip reasons.
|
|
131604
131410
|
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.`,
|
|
131605
131411
|
zodSchema: zodSchema34,
|
|
131606
|
-
// RN-only:
|
|
131607
|
-
// Metro's /symbolicate
|
|
131608
|
-
// for "what's here?" but the source-map flow would need a complete rewrite —
|
|
131609
|
-
// out of scope for this port.
|
|
131412
|
+
// RN-only: needs React Native's internal getInspectorDataForViewAtPoint and
|
|
131413
|
+
// Metro's /symbolicate; the Chromium session has no source resolver.
|
|
131610
131414
|
capability: RN_ONLY_TOOL_CAPABILITY,
|
|
131611
131415
|
services: (params) => ({
|
|
131612
131416
|
debugger: `JsRuntimeDebugger:${params.port}:${canonicalDeviceId(params.device_id)}`
|
|
@@ -131846,8 +131650,6 @@ On React Native (iOS / Android / Vega) interception is injected into the JS runt
|
|
|
131846
131650
|
Use when inspecting outbound HTTP traffic or debugging API calls in the running app.
|
|
131847
131651
|
Fails if the app is not connected (RN) or the device is not reachable (Chromium).`,
|
|
131848
131652
|
zodSchema: zodSchema36,
|
|
131849
|
-
// Works on RN (Metro-injected interceptor) and Chromium (native CDP Network
|
|
131850
|
-
// domain), dispatched on the device id in `services` / `execute`.
|
|
131851
131653
|
capability: DEBUGGER_TOOL_CAPABILITY,
|
|
131852
131654
|
services: (params) => {
|
|
131853
131655
|
const device = resolveDevice(params.device_id);
|
|
@@ -131936,8 +131738,6 @@ Returns request/response headers (sensitive headers redacted), status, timing, a
|
|
|
131936
131738
|
Large response bodies are truncated. Use when you need headers, body, or timing for a specific request after listing logs.
|
|
131937
131739
|
Returns an error message string if the requestId is not found \u2014 use view-network-logs to get valid requestId values.`,
|
|
131938
131740
|
zodSchema: zodSchema37,
|
|
131939
|
-
// Companion to view-network-logs: RN via the injected interceptor, Chromium
|
|
131940
|
-
// via the native CDP Network recording. Dispatched on the device id.
|
|
131941
131741
|
capability: DEBUGGER_TOOL_CAPABILITY,
|
|
131942
131742
|
services: (params) => {
|
|
131943
131743
|
const device = resolveDevice(params.device_id);
|
|
@@ -132048,10 +131848,9 @@ init_zod();
|
|
|
132048
131848
|
|
|
132049
131849
|
// ../tool-server/src/tools/describe/format-tree.ts
|
|
132050
131850
|
var CONTENT_ROLES = /* @__PURE__ */ new Set([
|
|
132051
|
-
//
|
|
132052
|
-
//
|
|
132053
|
-
//
|
|
132054
|
-
// groupings out of the output.
|
|
131851
|
+
// The roles mapNativeTraitsToDescribeRole can return. AXGroup is excluded on
|
|
131852
|
+
// purpose: as its catch-all fallback, requiring it to carry its own
|
|
131853
|
+
// label/value before we emit a line keeps decorative groupings out.
|
|
132055
131854
|
"AXButton",
|
|
132056
131855
|
"AXStaticText",
|
|
132057
131856
|
"AXImage",
|
|
@@ -132280,10 +132079,9 @@ function makeDescribeExecute(registry2) {
|
|
|
132280
132079
|
)
|
|
132281
132080
|
},
|
|
132282
132081
|
iosRemote: {
|
|
132283
|
-
//
|
|
132284
|
-
//
|
|
132285
|
-
//
|
|
132286
|
-
// (never tvOS), so the isTvOs verdict is always false.
|
|
132082
|
+
// Both the ax-service and native-devtools blueprints route through
|
|
132083
|
+
// sim-remote for an ios-remote device, so only the preflight dep differs
|
|
132084
|
+
// from the ios branch.
|
|
132287
132085
|
requires: ["sim-remote"],
|
|
132288
132086
|
handler: async (_services, params, device) => withDescription(
|
|
132289
132087
|
withBootCaveatOncePerDevice(
|
|
@@ -132295,9 +132093,8 @@ function makeDescribeExecute(registry2) {
|
|
|
132295
132093
|
android: {
|
|
132296
132094
|
requires: androidRequires,
|
|
132297
132095
|
handler: async (_services, params, device) => (
|
|
132298
|
-
// Resolve the form factor once and
|
|
132299
|
-
//
|
|
132300
|
-
// known `isTv: false` through so describeAndroid doesn't re-probe.
|
|
132096
|
+
// Resolve the form factor once and thread the known `isTv: false`
|
|
132097
|
+
// through so describeAndroid doesn't re-probe.
|
|
132301
132098
|
await isAndroidTv(device.id) ? describeTv(registry2, device) : withDescription(await describeAndroid(registry2, params.udid, params.bundleId, false))
|
|
132302
132099
|
)
|
|
132303
132100
|
},
|
|
@@ -132553,9 +132350,6 @@ After starting, ask the user to perform the interaction to profile, then call re
|
|
|
132553
132350
|
Returns { started_at, startedAtEpochMs, hermes_version, detected_architecture } on success, or the already_running payload described above.
|
|
132554
132351
|
Fails if the Hermes runtime is not reachable or the Metro CDP connection cannot be established.`,
|
|
132555
132352
|
zodSchema: zodSchema40,
|
|
132556
|
-
// RN-only: bootstraps the React DevTools backend and uses Hermes'
|
|
132557
|
-
// Profiler.start. A CDP-direct CPU profile for Chromium is tracked as a
|
|
132558
|
-
// follow-up; the React commit recording has no Chromium analog.
|
|
132559
132353
|
capability: RN_ONLY_TOOL_CAPABILITY,
|
|
132560
132354
|
services: () => ({}),
|
|
132561
132355
|
async execute(_services, params) {
|
|
@@ -132700,8 +132494,8 @@ Fails if the Hermes runtime is not reachable or the Metro CDP connection cannot
|
|
|
132700
132494
|
const sessionId = crypto6.randomUUID();
|
|
132701
132495
|
const ownerPayload = {
|
|
132702
132496
|
sessionId,
|
|
132703
|
-
//
|
|
132704
|
-
//
|
|
132497
|
+
// Set inside the start script from the wrapper-captured clock, to
|
|
132498
|
+
// eliminate skew.
|
|
132705
132499
|
startedAtEpochMs: 0,
|
|
132706
132500
|
lastHeartbeatEpochMs: 0
|
|
132707
132501
|
};
|
|
@@ -132915,7 +132709,6 @@ Returns { duration_ms, sample_count, fiber_renders_captured, total_react_commits
|
|
|
132915
132709
|
When any commit had fibers whose display name could not be resolved at stop time (typically transient components like modals/tooltips/animations that unmounted before stop), the response also includes { unattributed_ms, unattributed_fiber_count, unattributed_commit_count } \u2014 these quantify how much work is not accounted for in the per-component breakdown (the per-commit duration itself remains correct).
|
|
132916
132710
|
Fails if no active profiling session exists or the CDP connection was lost during recording.`,
|
|
132917
132711
|
zodSchema: zodSchema41,
|
|
132918
|
-
// RN-only: companion to react-profiler-start.
|
|
132919
132712
|
capability: RN_ONLY_TOOL_CAPABILITY,
|
|
132920
132713
|
services: () => ({}),
|
|
132921
132714
|
async execute(_services, params) {
|
|
@@ -132954,10 +132747,8 @@ Fails if no active profiling session exists or the CDP connection was lost durin
|
|
|
132954
132747
|
error_code: FAILURE_CODES.REACT_PROFILER_NO_ACTIVE_SESSION,
|
|
132955
132748
|
failure_stage: "react_profiler_stop_inactive",
|
|
132956
132749
|
failure_area: "tool_server",
|
|
132957
|
-
// Internal session-state
|
|
132958
|
-
//
|
|
132959
|
-
// native NATIVE_PROFILER_NO_ACTIVE_SESSION so this code carries one
|
|
132960
|
-
// consistent kind rather than splitting by which guard tripped.
|
|
132750
|
+
// Internal session-state, not caller input — matches the session-lookup
|
|
132751
|
+
// site above and the native NATIVE_PROFILER_NO_ACTIVE_SESSION twin.
|
|
132961
132752
|
error_kind: "not_found"
|
|
132962
132753
|
}
|
|
132963
132754
|
);
|
|
@@ -134066,7 +133857,7 @@ async function runPipeline(input, options) {
|
|
|
134066
133857
|
allClear: input.sessionMeta.allClear ?? false,
|
|
134067
133858
|
maxCommitMs: input.sessionMeta.maxCommitMs,
|
|
134068
133859
|
anyRuntimeCompilerDetected: tagOutput.anyRuntimeCompilerDetected,
|
|
134069
|
-
//
|
|
133860
|
+
// The all-clear path keeps no commits, so tagOutput.reactCommits is 0
|
|
134070
133861
|
reactCommits: input.sessionMeta.totalReactCommits ?? tagOutput.reactCommits,
|
|
134071
133862
|
fiberRenders: tagOutput.fiberRenders,
|
|
134072
133863
|
totalFirstMounts: tagOutput.totalFirstMounts,
|
|
@@ -134805,8 +134596,8 @@ is returned by react-profiler-start.
|
|
|
134805
134596
|
Use when the profiling session is complete and you need to interpret the collected data.
|
|
134806
134597
|
Fails if react-profiler-stop has not been called or no profiling data is stored.`,
|
|
134807
134598
|
zodSchema: zodSchema43,
|
|
134808
|
-
// RN-only:
|
|
134809
|
-
//
|
|
134599
|
+
// RN-only: reads commit data captured via the React DevTools backend, which
|
|
134600
|
+
// Chromium does not have.
|
|
134810
134601
|
capability: RN_ONLY_TOOL_CAPABILITY,
|
|
134811
134602
|
services: () => ({}),
|
|
134812
134603
|
async execute(_services, params, ctx) {
|
|
@@ -134960,12 +134751,9 @@ Call this per-finding after react-profiler-analyze to inspect source before prop
|
|
|
134960
134751
|
Returns found: false if the component is not found in user-owned code (e.g. lives in node_modules).
|
|
134961
134752
|
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) \u2014 check it before assuming the returned file is the one you meant.`,
|
|
134962
134753
|
zodSchema: zodSchema44,
|
|
134963
|
-
//
|
|
134964
|
-
//
|
|
134965
|
-
//
|
|
134966
|
-
// there's nothing for the gate to inspect). An LLM agent reading the tool
|
|
134967
|
-
// catalogue should see this is paired with the other react-profiler tools
|
|
134968
|
-
// and not reach for it on a Chromium app.
|
|
134754
|
+
// Declared so the tool catalogue groups this with the other react-profiler-*
|
|
134755
|
+
// tools; the HTTP gate itself is a no-op here, as there is no device arg to
|
|
134756
|
+
// inspect.
|
|
134969
134757
|
capability: RN_ONLY_TOOL_CAPABILITY,
|
|
134970
134758
|
fileInputs,
|
|
134971
134759
|
services: () => ({}),
|
|
@@ -134999,8 +134787,8 @@ When several files define a component with the same name (e.g. platform variants
|
|
|
134999
134787
|
}
|
|
135000
134788
|
return {
|
|
135001
134789
|
found: true,
|
|
135002
|
-
// The key that
|
|
135003
|
-
//
|
|
134790
|
+
// The key that matched, so the caller sees when a wrapped name resolved
|
|
134791
|
+
// through to a bare source identifier.
|
|
135004
134792
|
component: matchedKey ?? params.component_name,
|
|
135005
134793
|
requested: params.component_name,
|
|
135006
134794
|
file: entry.file,
|
|
@@ -135101,9 +134889,7 @@ Call react-profiler-stop first. Reads directly from the stored cpuProfile.
|
|
|
135101
134889
|
Returns a markdown table of the top hotspot functions with self-time, total-time, and location.
|
|
135102
134890
|
Fails if react-profiler-stop has not been called or no CPU profile is stored.`,
|
|
135103
134891
|
zodSchema: zodSchema45,
|
|
135104
|
-
// RN-only: reads a Hermes CPU profile
|
|
135105
|
-
// session. Chromium's V8 Profiler emits a different sample format — see the
|
|
135106
|
-
// PR description for the follow-up scope.
|
|
134892
|
+
// RN-only: reads a Hermes CPU profile; Chromium's V8 sample format differs.
|
|
135107
134893
|
capability: RN_ONLY_TOOL_CAPABILITY,
|
|
135108
134894
|
services: () => ({}),
|
|
135109
134895
|
async execute(_services, params) {
|
|
@@ -135812,11 +135598,8 @@ async function execFileAsyncWithTimeout(file2, args, options = {}) {
|
|
|
135812
135598
|
const { stdout, stderr } = await execFileAsync25(file2, args, {
|
|
135813
135599
|
encoding: "utf-8",
|
|
135814
135600
|
...options,
|
|
135815
|
-
//
|
|
135816
|
-
//
|
|
135817
|
-
// applied AFTER ...options — a caller can never silently weaken them by
|
|
135818
|
-
// passing its own. maxBuffer stays a floor: a caller may raise it for an
|
|
135819
|
-
// even larger capture, but never drop below the 256 MiB guard.
|
|
135601
|
+
// Applied after ...options so a caller cannot weaken the guards; maxBuffer
|
|
135602
|
+
// is a floor, so a caller may still raise it for a larger capture.
|
|
135820
135603
|
timeout: DEFAULT_EXEC_TIMEOUT_MS,
|
|
135821
135604
|
maxBuffer: Math.max(options.maxBuffer ?? 0, DEFAULT_EXEC_MAX_BUFFER)
|
|
135822
135605
|
});
|
|
@@ -136369,8 +136152,7 @@ function aggregateCpuHotspots(rows, options) {
|
|
|
136369
136152
|
duringHang,
|
|
136370
136153
|
timeRangeMs: { first: firstMs, last: lastMs },
|
|
136371
136154
|
burstWindows,
|
|
136372
|
-
//
|
|
136373
|
-
// hotspot object shape byte-identical to before this change.
|
|
136155
|
+
// Omit the key on iOS rather than emitting `dominantMapping: undefined`.
|
|
136374
136156
|
...acc.dominantMapping !== void 0 ? { dominantMapping: acc.dominantMapping } : {}
|
|
136375
136157
|
});
|
|
136376
136158
|
}
|
|
@@ -136784,17 +136566,16 @@ var SYSTEM_FRAME_PATTERNS = [
|
|
|
136784
136566
|
/gfxstream/i,
|
|
136785
136567
|
/rcCreateSync/,
|
|
136786
136568
|
/_enc\b/,
|
|
136787
|
-
//
|
|
136569
|
+
// emulator GL/Vulkan encoder trampolines
|
|
136788
136570
|
// Linux kernel syscall entry + mm/vfs internals (no app symbol to act on).
|
|
136789
136571
|
// x86-64 entry path:
|
|
136790
136572
|
/\bdo_syscall_64\b/,
|
|
136791
136573
|
/\bentry_SYSCALL/,
|
|
136792
136574
|
/\b__x64_sys_/,
|
|
136793
136575
|
/\bx64_sys_call\b/,
|
|
136794
|
-
// arm64
|
|
136795
|
-
//
|
|
136796
|
-
//
|
|
136797
|
-
// SVC (syscall) handler, which calls invoke_syscall → __arm64_sys_<name>.
|
|
136576
|
+
// arm64 entry path, named nothing like the x86 one: the EL0
|
|
136577
|
+
// synchronous-exception vector dispatches to the SVC (syscall) handler, which
|
|
136578
|
+
// calls invoke_syscall → __arm64_sys_<name>.
|
|
136798
136579
|
// arch/arm64/kernel/{entry.S,entry-common.c,syscall.c}.
|
|
136799
136580
|
/\b__arm64_sys_/,
|
|
136800
136581
|
/\bel0t_64_sync(_handler)?\b/,
|
|
@@ -136804,9 +136585,9 @@ var SYSTEM_FRAME_PATTERNS = [
|
|
|
136804
136585
|
/\bdo_el0_svc\b/,
|
|
136805
136586
|
/\binvoke_syscall\b/,
|
|
136806
136587
|
/\bel0_(da|ia)\b/,
|
|
136807
|
-
// data / instruction abort
|
|
136588
|
+
// data / instruction abort (page-fault) handlers
|
|
136808
136589
|
/\b__arch_copy_(from|to)_user\b/,
|
|
136809
|
-
// arm64 uaccess copy helpers
|
|
136590
|
+
// arm64 uaccess copy helpers
|
|
136810
136591
|
/\bksys_/,
|
|
136811
136592
|
/\bvfs_(read|write|fsync)\b/,
|
|
136812
136593
|
/\bgup_/,
|
|
@@ -137331,8 +137112,8 @@ function resolveDefaultTemplatePath() {
|
|
|
137331
137112
|
${candidates.map((c) => ` - ${c}`).join("\n")}
|
|
137332
137113
|
Pass template_path explicitly, or rebuild so the template is copied into place.`,
|
|
137333
137114
|
{
|
|
137334
|
-
// A
|
|
137335
|
-
//
|
|
137115
|
+
// A missing bundled asset is a packaging/build problem, not a device or
|
|
137116
|
+
// subprocess failure.
|
|
137336
137117
|
error_code: FAILURE_CODES.NATIVE_PROFILER_TRACE_TEMPLATE_MISSING,
|
|
137337
137118
|
failure_stage: "ios_native_profiler_template_resolve",
|
|
137338
137119
|
failure_area: "tool_server",
|
|
@@ -137869,8 +137650,7 @@ async function stopNativeProfilerIos(api) {
|
|
|
137869
137650
|
failure_stage: "native_profiler_stop_session_state",
|
|
137870
137651
|
failure_area: "tool_server",
|
|
137871
137652
|
// Internal session-state, not caller input — matches the react twin
|
|
137872
|
-
// REACT_PROFILER_NO_ACTIVE_SESSION
|
|
137873
|
-
// "no active session" family carries one consistent kind.
|
|
137653
|
+
// REACT_PROFILER_NO_ACTIVE_SESSION and the Android site.
|
|
137874
137654
|
error_kind: "not_found"
|
|
137875
137655
|
}
|
|
137876
137656
|
);
|
|
@@ -137946,13 +137726,12 @@ async function analyzeNativeProfilerIos(api) {
|
|
|
137946
137726
|
uiHangs,
|
|
137947
137727
|
cpuHotspots,
|
|
137948
137728
|
memoryLeaks,
|
|
137949
|
-
// Freeze the
|
|
137950
|
-
//
|
|
137951
|
-
//
|
|
137729
|
+
// Freeze the capture mode with the parsed data so drill-down consumers
|
|
137730
|
+
// (leak_stacks, combined report) stay paired with it after a newer capture
|
|
137731
|
+
// re-stamps the session fields.
|
|
137952
137732
|
mallocStackLogging: api.mallocStackLogging,
|
|
137953
|
-
// Freeze the
|
|
137954
|
-
//
|
|
137955
|
-
// a later native-profiler-start re-stamps onto the live session field.
|
|
137733
|
+
// Freeze the start time too — the combined report anchors these hangs to
|
|
137734
|
+
// wall-clock time and must use THIS capture's start, not a later one's.
|
|
137956
137735
|
wallClockStartMs: api.wallClockStartMs
|
|
137957
137736
|
};
|
|
137958
137737
|
const exportErrors = {};
|
|
@@ -137981,21 +137760,17 @@ async function analyzeNativeProfilerIos(api) {
|
|
|
137981
137760
|
payload,
|
|
137982
137761
|
traceFile: api.traceFile,
|
|
137983
137762
|
exportErrors,
|
|
137984
|
-
//
|
|
137985
|
-
//
|
|
137986
|
-
// trace from an earlier capture in this same process run, not a fresh one.
|
|
137763
|
+
// A large gap between the in-memory start time and "now" means analyze is reusing
|
|
137764
|
+
// a trace from an earlier capture in this same process run, not a fresh one.
|
|
137987
137765
|
//
|
|
137988
|
-
//
|
|
137989
|
-
//
|
|
137990
|
-
//
|
|
137991
|
-
//
|
|
137992
|
-
// for one restored from disk. Restoring iOS start-time across loads needs an
|
|
137993
|
-
// iOS sidecar this Android-scoped change does not add; formatTraceFreshness
|
|
137994
|
-
// degrades cleanly to null in that case. See test/ios-instruments/load-freshness.test.ts.
|
|
137766
|
+
// iOS, unlike Android, has no on-disk metadata sidecar, so profiler-load (raw_*.xml
|
|
137767
|
+
// only) cannot recover the start time: wallClockStartMs is null for a loaded
|
|
137768
|
+
// session, formatTraceFreshness returns null, and the note stays off. See
|
|
137769
|
+
// test/ios-instruments/load-freshness.test.ts.
|
|
137995
137770
|
freshnessNote: formatTraceFreshness(api.wallClockStartMs, Date.now()) ?? void 0,
|
|
137996
137771
|
// Same live-session-only caveat as wallClockStartMs: profiler-load has no
|
|
137997
137772
|
// capture-mode sidecar, so a restored session renders with null (the
|
|
137998
|
-
// unattributed-leaks note then
|
|
137773
|
+
// unattributed-leaks note then goes by the attributed-leak count instead).
|
|
137999
137774
|
mallocStackLogging: api.mallocStackLogging
|
|
138000
137775
|
});
|
|
138001
137776
|
}
|
|
@@ -138843,20 +138618,18 @@ function cpuRowsToAggregatorRows(rows, traceStartNs) {
|
|
|
138843
138618
|
const thread = normaliseAndroidThread(row.thread_name, row.is_main_thread === 1);
|
|
138844
138619
|
out.push({
|
|
138845
138620
|
dominantFunction: dominant,
|
|
138846
|
-
//
|
|
138847
|
-
// threaded through so classifyNativeFrame can recognise `/kernel` leaves.
|
|
138621
|
+
// Threaded through so classifyNativeFrame can recognise `/kernel` leaves.
|
|
138848
138622
|
...row.leaf_mapping != null ? { dominantMapping: row.leaf_mapping } : {},
|
|
138849
138623
|
thread,
|
|
138850
138624
|
weightNs: row.sample_count * SAMPLE_PERIOD_NS,
|
|
138851
|
-
//
|
|
138852
|
-
//
|
|
138625
|
+
// Bursts are precomputed in SQL, so no raw timestamps ship; the aggregator's
|
|
138626
|
+
// duringHang stays false (Android never passes hangSampleTimestamps).
|
|
138853
138627
|
timestampsNs: [],
|
|
138854
138628
|
callChains: [{ chain: [dominant], count: row.sample_count }],
|
|
138855
138629
|
precomputedBursts: parseBurstWindows(row.burst_windows, traceStartMs),
|
|
138856
|
-
//
|
|
138857
|
-
//
|
|
138858
|
-
//
|
|
138859
|
-
// avoid "Cannot mix BigInt and other types" — values stay integral.
|
|
138630
|
+
// Absolute CLOCK_MONOTONIC ns passes 2^53 after ~104 days of uptime and
|
|
138631
|
+
// readCell hands those back as bigint — coerce before mixing with the
|
|
138632
|
+
// plain-Number traceStartNs.
|
|
138860
138633
|
firstMs: Math.round((Number(row.first_ts_ns) - traceStartNs) / 1e6),
|
|
138861
138634
|
lastMs: Math.round((Number(row.last_ts_ns) - traceStartNs) / 1e6),
|
|
138862
138635
|
sampleCount: row.sample_count
|
|
@@ -139078,8 +138851,8 @@ async function stopNativeProfilerAndroid(api) {
|
|
|
139078
138851
|
failure_stage: "android_native_profiler_stop",
|
|
139079
138852
|
failure_area: "tool_server",
|
|
139080
138853
|
// Internal session-state, not caller input — matches the react twin
|
|
139081
|
-
// REACT_PROFILER_NO_ACTIVE_SESSION
|
|
139082
|
-
//
|
|
138854
|
+
// REACT_PROFILER_NO_ACTIVE_SESSION so the "no active session" family
|
|
138855
|
+
// carries one consistent kind.
|
|
139083
138856
|
error_kind: "not_found"
|
|
139084
138857
|
}
|
|
139085
138858
|
);
|
|
@@ -139173,9 +138946,8 @@ async function analyzeNativeProfilerAndroid(api) {
|
|
|
139173
138946
|
payload,
|
|
139174
138947
|
traceFile: hostTracePath,
|
|
139175
138948
|
exportErrors: pipelineResult.exportErrors,
|
|
139176
|
-
//
|
|
139177
|
-
//
|
|
139178
|
-
// means we're analyzing a trace from an earlier session, not a fresh capture.
|
|
138949
|
+
// Recording start time, persisted in the metadata sidecar and restored by
|
|
138950
|
+
// profiler-load, so a large gap to "now" means an earlier session's trace.
|
|
139179
138951
|
freshnessNote: formatTraceFreshness(api.wallClockStartMs, Date.now()) ?? void 0,
|
|
139180
138952
|
// Explains an absent CPU section when samples exist but carry no stacks.
|
|
139181
138953
|
cpuDiagnostic: pipelineResult.cpuDiagnostic
|
|
@@ -139274,7 +139046,7 @@ var nativeProfilerStopTool = {
|
|
|
139274
139046
|
failedMsg: ({ failureSignal: failureSignal2 }) => `Failed to stop native profiler: ${failureSignal2.error_code}`
|
|
139275
139047
|
},
|
|
139276
139048
|
capability: capability26,
|
|
139277
|
-
// Packaging plus the export passes routinely exceed the 30s fetch timeout.
|
|
139049
|
+
// Packaging plus the export passes routinely exceed the 30s MCP fetch timeout.
|
|
139278
139050
|
longRunning: true,
|
|
139279
139051
|
description: `Stop native profiling and export trace data.
|
|
139280
139052
|
iOS: sends SIGINT to xctrace, waits for packaging, then exports CPU, hangs, and leaks XML.
|
|
@@ -139777,8 +139549,7 @@ function assertStoppableSession(api, stage) {
|
|
|
139777
139549
|
error_code: reaped2 ? FAILURE_CODES.SCREEN_RECORDING_SERVER_SHUTTING_DOWN : FAILURE_CODES.SCREEN_RECORDING_NO_ACTIVE_SESSION,
|
|
139778
139550
|
failure_stage: stage,
|
|
139779
139551
|
failure_area: "tool_server",
|
|
139780
|
-
// Session-state, not caller input — matches the profiler family's
|
|
139781
|
-
// "no active session" kind.
|
|
139552
|
+
// Session-state, not caller input — matches the profiler family's kind.
|
|
139782
139553
|
error_kind: "not_found"
|
|
139783
139554
|
}
|
|
139784
139555
|
);
|
|
@@ -139926,7 +139697,7 @@ function ffmpegArgs(opts) {
|
|
|
139926
139697
|
"-loglevel",
|
|
139927
139698
|
"warning",
|
|
139928
139699
|
// The pump feeds whole JPEGs at a fixed cadence, so the input timeline is
|
|
139929
|
-
// exactly OUTPUT_FPS — no timestamp guessing
|
|
139700
|
+
// exactly OUTPUT_FPS — no timestamp guessing.
|
|
139930
139701
|
"-f",
|
|
139931
139702
|
"image2pipe",
|
|
139932
139703
|
"-framerate",
|
|
@@ -140354,10 +140125,9 @@ Returns { status: "recording", timeLimitSeconds, outputFile } \u2014 the video i
|
|
|
140354
140125
|
Fails if a recording is already running on the device, the device is not booted, ffmpeg is not installed, or the platform cannot be recorded (tvOS, Chromium, Vega and remote simulators are unsupported).`,
|
|
140355
140126
|
searchHint: "record video screen capture movie mp4 start filming screencast",
|
|
140356
140127
|
zodSchema: zodSchema51,
|
|
140357
|
-
//
|
|
140358
|
-
//
|
|
140359
|
-
//
|
|
140360
|
-
// timeout (same reasoning as `screenshot`).
|
|
140128
|
+
// Resolved inside execute, not declared eagerly: a tvOS udid classifies as
|
|
140129
|
+
// iOS by shape, so an eager service would spawn simulator-server for a
|
|
140130
|
+
// device it cannot drive and hang on its ready timeout (as in `screenshot`).
|
|
140361
140131
|
services: (params) => ({
|
|
140362
140132
|
session: screenRecordingSessionRef(resolveDevice(params.udid))
|
|
140363
140133
|
}),
|
|
@@ -140471,8 +140241,7 @@ Fails if no recording (running or finished-but-unretrieved) exists for the given
|
|
|
140471
140241
|
hostPath: stopped.outputFile,
|
|
140472
140242
|
kind: "screen-recording",
|
|
140473
140243
|
mimeType: "video/mp4",
|
|
140474
|
-
// Drop the internal `argent-` temp prefix
|
|
140475
|
-
// as `.argent/recordings/screen-recording-<device>-<ts>.mp4`.
|
|
140244
|
+
// Drop the internal `argent-` temp-file prefix from the saved name.
|
|
140476
140245
|
filename: (0, import_node_path20.basename)(stopped.outputFile).replace(/^argent-/, ""),
|
|
140477
140246
|
saveDir: RECORDINGS_DIR
|
|
140478
140247
|
});
|
|
@@ -140786,8 +140555,7 @@ Use when investigating JS CPU hotspots or correlating CPU cost with specific com
|
|
|
140786
140555
|
Returns a markdown table of CPU hotspots, call tree, or per-component CPU breakdown.
|
|
140787
140556
|
Fails if no CPU profile is stored \u2014 run react-profiler-stop first.`,
|
|
140788
140557
|
zodSchema: zodSchema53,
|
|
140789
|
-
// RN-only: reads Hermes-format CPU profiles
|
|
140790
|
-
// different — see the PR description for the follow-up scope.
|
|
140558
|
+
// RN-only: reads Hermes-format CPU profiles; Chromium's V8 sample format differs.
|
|
140791
140559
|
capability: RN_ONLY_TOOL_CAPABILITY,
|
|
140792
140560
|
services: () => ({}),
|
|
140793
140561
|
async execute(_services, params) {
|
|
@@ -141146,7 +140914,7 @@ Use when drilling into specific components or time windows after react-profiler-
|
|
|
141146
140914
|
Returns a markdown table or tree of commit data matching the requested mode.
|
|
141147
140915
|
Fails if react-profiler-stop has not been called or no commit data is stored.`,
|
|
141148
140916
|
zodSchema: zodSchema54,
|
|
141149
|
-
//
|
|
140917
|
+
// Reads React commit data captured via the React DevTools backend.
|
|
141150
140918
|
capability: RN_ONLY_TOOL_CAPABILITY,
|
|
141151
140919
|
services: () => ({}),
|
|
141152
140920
|
async execute(_services, params) {
|
|
@@ -141534,9 +141302,7 @@ Use when drilling into native hang stacks, thread CPU breakdown, or memory leaks
|
|
|
141534
141302
|
Returns a markdown report with native call stacks, thread weights, or leak details for the selected mode.
|
|
141535
141303
|
Fails if native-profiler-analyze has not been run or no parsed trace data is in memory.`,
|
|
141536
141304
|
zodSchema: zodSchema55,
|
|
141537
|
-
//
|
|
141538
|
-
// in-process trace-processor engine (see executeAndroid). Chromium has no
|
|
141539
|
-
// native trace capture.
|
|
141305
|
+
// No chromium entry: it has no native trace capture.
|
|
141540
141306
|
capability: {
|
|
141541
141307
|
apple: { simulator: true, device: true },
|
|
141542
141308
|
android: { emulator: true, device: true, unknown: true }
|
|
@@ -141618,9 +141384,8 @@ Call this tool when both profilers were run in parallel on the same session.
|
|
|
141618
141384
|
Returns a markdown report correlating hangs with React commits, memory leaks, and investigation hints.
|
|
141619
141385
|
Fails if either react-profiler-analyze or native-profiler-analyze has not been called first.`,
|
|
141620
141386
|
zodSchema: zodSchema56,
|
|
141621
|
-
//
|
|
141622
|
-
//
|
|
141623
|
-
// capture half exists on neither platform's Chromium.
|
|
141387
|
+
// iOS reads xctrace output; Android re-queries the Perfetto .pftrace via
|
|
141388
|
+
// loadAndroidCombinedData. Chromium has no native trace capture.
|
|
141624
141389
|
capability: {
|
|
141625
141390
|
apple: { simulator: true, device: true },
|
|
141626
141391
|
android: { emulator: true, device: true, unknown: true }
|
|
@@ -141867,7 +141632,7 @@ Fails if either react-profiler-analyze or native-profiler-analyze has not been c
|
|
|
141867
141632
|
memoryLeaks,
|
|
141868
141633
|
mountComponents,
|
|
141869
141634
|
// From parsedData, not the live session field: a recording started
|
|
141870
|
-
// after
|
|
141635
|
+
// after analyze must not re-label the data rendered here.
|
|
141871
141636
|
nativeApi.parsedData?.mallocStackLogging ?? null
|
|
141872
141637
|
)
|
|
141873
141638
|
);
|
|
@@ -142234,10 +141999,8 @@ async function loadNativeSession(debugDir, sessionId, api, appProcessOverride) {
|
|
|
142234
141999
|
error_code: FAILURE_CODES.PROFILER_NATIVE_TRACE_MISSING,
|
|
142235
142000
|
failure_stage: "profiler_load_native_session",
|
|
142236
142001
|
failure_area: "tool_server",
|
|
142237
|
-
// A trace
|
|
142238
|
-
//
|
|
142239
|
-
// split into two kinds by platform (validation stays for the
|
|
142240
|
-
// analyze-before-stop guard, NATIVE_PROFILER_NO_EXPORTED_TRACE).
|
|
142002
|
+
// A trace missing on disk is not_found; validation stays for the
|
|
142003
|
+
// analyze-before-stop guard (NATIVE_PROFILER_NO_EXPORTED_TRACE).
|
|
142241
142004
|
error_kind: "not_found"
|
|
142242
142005
|
}
|
|
142243
142006
|
);
|
|
@@ -142303,9 +142066,8 @@ Modes:
|
|
|
142303
142066
|
Returns a summary of the loaded session or a session list for the list mode.
|
|
142304
142067
|
Fails if the session_id is not found or required XML files are missing from disk.`,
|
|
142305
142068
|
zodSchema: zodSchema57,
|
|
142306
|
-
//
|
|
142307
|
-
//
|
|
142308
|
-
// letting it surface from inside the trace parser.
|
|
142069
|
+
// The Hermes, xctrace and perfetto formats this loads have no Chromium
|
|
142070
|
+
// equivalent; the gate fails at the call site, not inside the trace parser.
|
|
142309
142071
|
capability: RN_ONLY_TOOL_CAPABILITY,
|
|
142310
142072
|
services: (params) => {
|
|
142311
142073
|
const svcs = {};
|
|
@@ -142367,12 +142129,9 @@ init_src();
|
|
|
142367
142129
|
var URN_SUFFIXES = ["", ":tcp"];
|
|
142368
142130
|
var PORT_KEYED_NAMESPACES = [
|
|
142369
142131
|
JS_RUNTIME_DEBUGGER_NAMESPACE,
|
|
142370
|
-
// Both
|
|
142371
|
-
//
|
|
142372
|
-
//
|
|
142373
|
-
// reports: a session that had a network inspector or a React profiler open is
|
|
142374
|
-
// told those went away by name, rather than inferring it from the debugger
|
|
142375
|
-
// line.
|
|
142132
|
+
// Both depend on `JsRuntimeDebugger:<payload>`, so a cascade already reaps
|
|
142133
|
+
// them; listed so `stopped` names them instead of leaving the caller to infer
|
|
142134
|
+
// them from the debugger line.
|
|
142376
142135
|
NETWORK_INSPECTOR_NAMESPACE,
|
|
142377
142136
|
REACT_PROFILER_SESSION_NAMESPACE
|
|
142378
142137
|
];
|
|
@@ -142478,8 +142237,7 @@ function createStopAllSimulatorServersTool(registry2) {
|
|
|
142478
142237
|
id: "stop-all-simulator-servers",
|
|
142479
142238
|
interaction: {
|
|
142480
142239
|
// "all" only holds for the unscoped sweep; a scoped call touches just the
|
|
142481
|
-
// ids it was given
|
|
142482
|
-
// deliberately left another agent's devices running.
|
|
142240
|
+
// ids it was given.
|
|
142483
142241
|
startedMsg: ({ params }) => {
|
|
142484
142242
|
const devices = params?.devices;
|
|
142485
142243
|
return devices ? `Stopping simulator servers for ${devices.length} ${devices.length === 1 ? "device" : "devices"}` : "Stopping all simulator servers";
|
|
@@ -142575,9 +142333,8 @@ function listeningPids(port) {
|
|
|
142575
142333
|
const output2 = (0, import_node_child_process28.execFileSync)("netstat", ["-ano"], {
|
|
142576
142334
|
encoding: "utf-8",
|
|
142577
142335
|
timeout: 5e3,
|
|
142578
|
-
// `netstat -ano` dumps every socket on the host;
|
|
142579
|
-
//
|
|
142580
|
-
// throw would misread as "port is free" (stopped:false).
|
|
142336
|
+
// `netstat -ano` dumps every socket on the host; overflowing Node's
|
|
142337
|
+
// default 1 MiB throws, which this tool would misread as "port is free".
|
|
142581
142338
|
maxBuffer: 16 * 1024 * 1024
|
|
142582
142339
|
});
|
|
142583
142340
|
return parseNetstatListeningPids(output2, port);
|
|
@@ -144346,8 +144103,8 @@ var fileInputs2 = [
|
|
|
144346
144103
|
var flowStartRecordingTool = {
|
|
144347
144104
|
id: "flow-start-recording",
|
|
144348
144105
|
interaction: {
|
|
144349
|
-
// Name the flow: recordings
|
|
144350
|
-
//
|
|
144106
|
+
// Name the flow: concurrent recordings interleave in one log, and "flow
|
|
144107
|
+
// recording" would not say which.
|
|
144351
144108
|
startedMsg: ({ params }) => `Starting recording of flow ${params.name}`,
|
|
144352
144109
|
completedMsg: ({ params, result }) => {
|
|
144353
144110
|
if (!result.restarted) return `Started recording flow ${params.name}`;
|
|
@@ -144710,7 +144467,7 @@ function projectIosNode(node, screenW, screenH) {
|
|
|
144710
144467
|
children: node.children ?? [],
|
|
144711
144468
|
// Text hoists only from on-screen nodes (frame is null when the view is
|
|
144712
144469
|
// scrolled off or zero-area) — otherwise a text assert against an ancestor
|
|
144713
|
-
// would pass on content the screen doesn't show.
|
|
144470
|
+
// would pass on content the screen doesn't show. A label makes a node
|
|
144714
144471
|
// leaf-eligible, so `frame` was computed for any node with text.
|
|
144715
144472
|
ownText: frame ? node.label ?? "" : "",
|
|
144716
144473
|
leaf,
|
|
@@ -144751,8 +144508,8 @@ var FULL_HIERARCHY_FIELDS = [
|
|
|
144751
144508
|
"windowFrame",
|
|
144752
144509
|
"hidden",
|
|
144753
144510
|
"alpha",
|
|
144754
|
-
//
|
|
144755
|
-
//
|
|
144511
|
+
// Read by the type directive's focus wait; an injected framework that omits
|
|
144512
|
+
// it just leaves that wait's poll unconfirmed.
|
|
144756
144513
|
"firstResponder"
|
|
144757
144514
|
];
|
|
144758
144515
|
async function unreadableHierarchyReason(nativeApi, bundleId) {
|
|
@@ -144880,18 +144637,17 @@ function projectAndroidNode(node, screenW, screenH) {
|
|
|
144880
144637
|
return {
|
|
144881
144638
|
skip: skip2,
|
|
144882
144639
|
children: childNodes(node),
|
|
144883
|
-
//
|
|
144884
|
-
//
|
|
144885
|
-
//
|
|
144886
|
-
// leaf-eligible (its label is non-empty), so `frame` was computed for it.
|
|
144640
|
+
// Off-screen text must not hoist, or an ancestor text assert would pass on
|
|
144641
|
+
// content the screen doesn't show. Any node with text is leaf-eligible (its
|
|
144642
|
+
// label is non-empty), so `frame` was computed for it.
|
|
144887
144643
|
ownText: frame ? ownText2 : "",
|
|
144888
144644
|
leaf,
|
|
144889
|
-
// A password
|
|
144890
|
-
//
|
|
144645
|
+
// A password field shields even when it carries no id, so nothing from it
|
|
144646
|
+
// bubbles into an ancestor's hoisted text.
|
|
144891
144647
|
shield: Boolean(identifier) || isPassword,
|
|
144892
|
-
// Scroll-clip inputs (see `flattenHoisting`): a
|
|
144893
|
-
//
|
|
144894
|
-
//
|
|
144648
|
+
// Scroll-clip inputs (see `flattenHoisting`): a scroller's raw bounds clip
|
|
144649
|
+
// its subtree, so a row scrolled out of view — but still on the device
|
|
144650
|
+
// screen — is dropped, matching the describe path's prune.
|
|
144895
144651
|
rect,
|
|
144896
144652
|
scrolls: isUiAutomatorScrollable(attrs)
|
|
144897
144653
|
};
|
|
@@ -144954,9 +144710,9 @@ function projectChromiumNode(node) {
|
|
|
144954
144710
|
return {
|
|
144955
144711
|
skip: false,
|
|
144956
144712
|
children: node.children,
|
|
144957
|
-
//
|
|
144958
|
-
//
|
|
144959
|
-
//
|
|
144713
|
+
// Off-screen text must not hoist, or a text assert against an ancestor
|
|
144714
|
+
// would pass on content the screen doesn't show. A password's text never
|
|
144715
|
+
// bubbles up.
|
|
144960
144716
|
ownText: onScreen && !node.password ? nodeText(node) : "",
|
|
144961
144717
|
leaf,
|
|
144962
144718
|
shield: Boolean(node.identifier) || node.password === true
|
|
@@ -144987,8 +144743,8 @@ function projectVegaNode(node) {
|
|
|
144987
144743
|
return {
|
|
144988
144744
|
skip: false,
|
|
144989
144745
|
children: node.children,
|
|
144990
|
-
//
|
|
144991
|
-
//
|
|
144746
|
+
// Off-screen text must not hoist, or a text assert against an ancestor
|
|
144747
|
+
// would pass on content the screen doesn't show.
|
|
144992
144748
|
ownText: onScreen ? nodeText(node) : "",
|
|
144993
144749
|
leaf: { ...node, children: [] },
|
|
144994
144750
|
shield: isAuthoredVegaTestId(node.identifier)
|
|
@@ -145826,10 +145582,9 @@ async function waitForIdle(env, step) {
|
|
|
145826
145582
|
ok: false,
|
|
145827
145583
|
indeterminate: true,
|
|
145828
145584
|
// The underlying reader reports an instrumentation failure, whose remedy
|
|
145829
|
-
// (relaunch the app) is the wrong repair for the commonest cause
|
|
145830
|
-
//
|
|
145831
|
-
//
|
|
145832
|
-
// before relaunching anything.
|
|
145585
|
+
// (relaunch the app) is the wrong repair for the commonest cause here: the
|
|
145586
|
+
// app is simply not in the foreground, which reads exactly the same from the
|
|
145587
|
+
// tree source. Name that first.
|
|
145833
145588
|
reason: `could not read the UI tree while waiting for the screen to settle \u2014 check the app is still in the foreground (a backgrounded app reads the same as an uninstrumented one). Underlying error: ${underlying}`
|
|
145834
145589
|
});
|
|
145835
145590
|
const degraded = () => ({
|
|
@@ -145976,13 +145731,12 @@ function anchoredWarnings(session, steps) {
|
|
|
145976
145731
|
var flowFinishRecordingTool = {
|
|
145977
145732
|
id: "flow-finish-recording",
|
|
145978
145733
|
interaction: {
|
|
145979
|
-
// Name the flow: other recordings stay live
|
|
145980
|
-
//
|
|
145734
|
+
// Name the flow: other recordings stay live, so an unqualified message would
|
|
145735
|
+
// not identify which one.
|
|
145981
145736
|
startedMsg: ({ params }) => `Finishing recording of flow ${params.name}`,
|
|
145982
|
-
// `params.name`
|
|
145983
|
-
//
|
|
145984
|
-
//
|
|
145985
|
-
// and this spelling matches the two formatters either side of it.
|
|
145737
|
+
// `params.name` equals the basename of `result.path` on every branch
|
|
145738
|
+
// (`assertSafeFlowName` admits no dots or separators), and matches the two
|
|
145739
|
+
// formatters either side.
|
|
145986
145740
|
completedMsg: ({ params }) => `Saved recorded flow ${params.name}`,
|
|
145987
145741
|
failedMsg: ({ params, failureSignal: failureSignal2 }) => `Failed to finish recording of flow ${params.name}: ${failureSignal2.error_code}`
|
|
145988
145742
|
},
|
|
@@ -146417,7 +146171,7 @@ function createFlowAddStepTool(registry2) {
|
|
|
146417
146171
|
id: "flow-add-step",
|
|
146418
146172
|
interaction: {
|
|
146419
146173
|
// Name the flow: recordings are concurrent, so several of these lines can
|
|
146420
|
-
// interleave in one log and "the recorded flow" would not
|
|
146174
|
+
// interleave in one log and "the recorded flow" would not say which.
|
|
146421
146175
|
startedMsg: ({ params }) => `Adding ${params.command} step to flow ${params.name}`,
|
|
146422
146176
|
completedMsg: ({ params }) => `Added ${params.command} step to flow ${params.name}`,
|
|
146423
146177
|
failedMsg: ({ params, failureSignal: failureSignal2 }) => `Failed to add ${params.command} step to flow ${params.name}: ${failureSignal2.error_code}`
|
|
@@ -146497,9 +146251,6 @@ If a step was recorded by mistake, remove it from the .yaml after \`flow-finish-
|
|
|
146497
146251
|
toolResult,
|
|
146498
146252
|
stepCount,
|
|
146499
146253
|
recorded: summarizeStep(step, stepCount),
|
|
146500
|
-
// Host mode: a path. Client mode: the directive that carries the YAML
|
|
146501
|
-
// to the client, which IS the persistence mechanism there — the one
|
|
146502
|
-
// place the full file still has to travel per step.
|
|
146503
146254
|
savedTo
|
|
146504
146255
|
};
|
|
146505
146256
|
}
|
|
@@ -146518,8 +146269,7 @@ var zodSchema64 = external_exports.object({
|
|
|
146518
146269
|
var flowInsertEchoTool = {
|
|
146519
146270
|
id: "flow-add-echo",
|
|
146520
146271
|
interaction: {
|
|
146521
|
-
// Name the flow: recordings are concurrent, so
|
|
146522
|
-
// interleave in one log and "the recorded flow" would not identify which.
|
|
146272
|
+
// Name the flow: recordings are concurrent, so an unqualified message is ambiguous.
|
|
146523
146273
|
startedMsg: ({ params }) => `Adding note to flow ${params.name}`,
|
|
146524
146274
|
completedMsg: ({ params }) => `Added note to flow ${params.name}`,
|
|
146525
146275
|
failedMsg: ({ params, failureSignal: failureSignal2 }) => `Failed to add note to flow ${params.name}: ${failureSignal2.error_code}`
|
|
@@ -148834,12 +148584,11 @@ async function runSnapshot(env, opts) {
|
|
|
148834
148584
|
baselinePath,
|
|
148835
148585
|
currentPath,
|
|
148836
148586
|
outputDir,
|
|
148837
|
-
// A crop compares EVERY pixel of the element's region
|
|
148838
|
-
//
|
|
148839
|
-
//
|
|
148840
|
-
//
|
|
148841
|
-
//
|
|
148842
|
-
// asserts the element clears it.
|
|
148587
|
+
// A crop compares EVERY pixel of the element's region, wherever it
|
|
148588
|
+
// sits. Masking a crop's overlap with the screen's top status-bar band
|
|
148589
|
+
// would degenerate into comparing nothing for an element inside the
|
|
148590
|
+
// band (a vacuous pass); a crop overlapping the band leans on the run's
|
|
148591
|
+
// best-effort pinStatusBar instead.
|
|
148843
148592
|
topMask: cropFrame === void 0 ? "status-bar" : "none",
|
|
148844
148593
|
// Crop dimensions track the element — size drift must hard-fail below
|
|
148845
148594
|
// instead of being resampled away like a full-screen scale difference.
|
|
@@ -149434,8 +149183,8 @@ Pass exactly one flow source: name for a saved flow under project_root, or flow_
|
|
|
149434
149183
|
// One holder per ExecState, shared by nested `run:` flows: `deviceEnv`
|
|
149435
149184
|
// spreads the reference, so what one step's settle learns about the
|
|
149436
149185
|
// tree source the next one already has. A `tool: flow-execute` builds
|
|
149437
|
-
// its own
|
|
149438
|
-
//
|
|
149186
|
+
// its own, which is why that step spends this verdict rather than
|
|
149187
|
+
// inheriting whatever the sub-run proved.
|
|
149439
149188
|
treeOutage: {},
|
|
149440
149189
|
flowsDir,
|
|
149441
149190
|
viaUpload,
|
|
@@ -149626,8 +149375,7 @@ function summarize(flowName, deviceId, executionPrerequisite, steps, aborted2) {
|
|
|
149626
149375
|
// A cancelled run must never read as PASS — it may contain skips alone
|
|
149627
149376
|
// (no fail/error report), so the verdict folds the abort in directly. A
|
|
149628
149377
|
// skip by itself is NOT a failure: an unmet `when:` guard skips its block
|
|
149629
|
-
// as a successful omission
|
|
149630
|
-
// fail/error report.
|
|
149378
|
+
// as a successful omission.
|
|
149631
149379
|
ok: failed === 0 && errored === 0 && !aborted2,
|
|
149632
149380
|
...aborted2 ? { aborted: true } : {},
|
|
149633
149381
|
passed,
|
|
@@ -151222,11 +150970,10 @@ var awaitUserSelectionTool = {
|
|
|
151222
150970
|
failedMsg: ({ failureSignal: failureSignal2 }) => `Failed while waiting for variant selection: ${failureSignal2.error_code}`
|
|
151223
150971
|
},
|
|
151224
150972
|
featureFlag: "argent-lens",
|
|
151225
|
-
// Hidden
|
|
151226
|
-
//
|
|
151227
|
-
//
|
|
151228
|
-
//
|
|
151229
|
-
// CLI-relay surface honest — propose_variant then end the turn.
|
|
150973
|
+
// Hidden while an `argent lens` CLI session owns the preview window: there the
|
|
150974
|
+
// user's picks are relayed into the agent's terminal as a normal message (see
|
|
150975
|
+
// `argent-cli/src/lens.ts`), so the agent ends its turn after propose_variant
|
|
150976
|
+
// instead of blocking.
|
|
151230
150977
|
hideWhen: () => variantProposalStore.isCliSession(),
|
|
151231
150978
|
description: `Block until the human finishes picking among the variants you proposed (the ONE blocking call).
|
|
151232
150979
|
|
|
@@ -151901,10 +151648,8 @@ function createPreviewWindowManager(opts = {}) {
|
|
|
151901
151648
|
const launchBin = wrapperBin ?? electronBin;
|
|
151902
151649
|
const launchArgs = wrapperBin ? ["--no-sandbox", mainScript] : [mainScript];
|
|
151903
151650
|
const next = (0, import_node_child_process33.spawn)(launchBin, launchArgs, {
|
|
151904
|
-
//
|
|
151905
|
-
//
|
|
151906
|
-
// host puts it in our env, and inheriting it makes main.cjs crash at
|
|
151907
|
-
// app.setName() with `app` undefined — the window never opens.
|
|
151651
|
+
// Strips ELECTRON_RUN_AS_NODE, which an Electron-based MCP host leaves in
|
|
151652
|
+
// our env, so the child boots as a GUI app instead of bare Node.
|
|
151908
151653
|
env: electronGuiChildEnv({ ARGENT_PREVIEW_URL: url2 }),
|
|
151909
151654
|
stdio: ["pipe", "ignore", "pipe"]
|
|
151910
151655
|
});
|
|
@@ -152053,11 +151798,10 @@ function start() {
|
|
|
152053
151798
|
const { stop: stopWatcher, ready: watcherReady } = startSimulatorWatcher(registry2);
|
|
152054
151799
|
let server = null;
|
|
152055
151800
|
const previewWindow = createPreviewWindowManager({
|
|
152056
|
-
//
|
|
152057
|
-
//
|
|
152058
|
-
//
|
|
152059
|
-
//
|
|
152060
|
-
// this fires at runtime, long after module init.
|
|
151801
|
+
// Electron is an optionalDependency (absent on headless/CI hosts); on a launch
|
|
151802
|
+
// failure unblock any parked await with the browser fallback URL rather than
|
|
151803
|
+
// stranding it for the full timeout. `previewWindowBaseUrl` is declared below
|
|
151804
|
+
// but only called at runtime.
|
|
152061
151805
|
onLaunchFailure: (err) => variantProposalStore.notifyWindowUnavailable(err.message, previewWindowBaseUrl())
|
|
152062
151806
|
});
|
|
152063
151807
|
const previewWindowBaseUrl = () => {
|