@swmansion/argent 0.19.1-next.2 → 0.19.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/dist/cli-cmds.mjs +29 -1
- package/dist/installer.mjs +28 -0
- package/dist/mcp-server.mjs +28 -0
- package/dist/tool-server.cjs +1031 -280
- package/package.json +1 -1
- package/skills/argent-create-flow/SKILL.md +16 -1
- package/skills/argent-metro-debugger/SKILL.md +14 -14
- package/skills/argent-metro-debugger/references/failure-scenarios.md +11 -7
- package/skills/argent-react-native-app-workflow/SKILL.md +4 -4
- package/skills/argent-react-native-optimization/SKILL.md +1 -1
- package/skills/argent-react-native-profiler/references/diagnostic-tools.md +1 -1
- package/skills/argent-test-ui-flow/SKILL.md +1 -1
- package/skills/argent-tv-interact/SKILL.md +1 -1
package/dist/tool-server.cjs
CHANGED
|
@@ -45,7 +45,7 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
45
45
|
// ../../node_modules/dotenv/lib/main.js
|
|
46
46
|
var require_main = __commonJS({
|
|
47
47
|
"../../node_modules/dotenv/lib/main.js"(exports2, module2) {
|
|
48
|
-
var
|
|
48
|
+
var fs55 = require("fs");
|
|
49
49
|
var path40 = require("path");
|
|
50
50
|
var os15 = require("os");
|
|
51
51
|
var crypto8 = require("crypto");
|
|
@@ -177,7 +177,7 @@ var require_main = __commonJS({
|
|
|
177
177
|
if (options && options.path && options.path.length > 0) {
|
|
178
178
|
if (Array.isArray(options.path)) {
|
|
179
179
|
for (const filepath of options.path) {
|
|
180
|
-
if (
|
|
180
|
+
if (fs55.existsSync(filepath)) {
|
|
181
181
|
possibleVaultPath = filepath.endsWith(".vault") ? filepath : `${filepath}.vault`;
|
|
182
182
|
}
|
|
183
183
|
}
|
|
@@ -187,7 +187,7 @@ var require_main = __commonJS({
|
|
|
187
187
|
} else {
|
|
188
188
|
possibleVaultPath = path40.resolve(process.cwd(), ".env.vault");
|
|
189
189
|
}
|
|
190
|
-
if (
|
|
190
|
+
if (fs55.existsSync(possibleVaultPath)) {
|
|
191
191
|
return possibleVaultPath;
|
|
192
192
|
}
|
|
193
193
|
return null;
|
|
@@ -240,7 +240,7 @@ var require_main = __commonJS({
|
|
|
240
240
|
const parsedAll = {};
|
|
241
241
|
for (const path41 of optionPaths) {
|
|
242
242
|
try {
|
|
243
|
-
const parsed = DotenvModule.parse(
|
|
243
|
+
const parsed = DotenvModule.parse(fs55.readFileSync(path41, { encoding }));
|
|
244
244
|
DotenvModule.populate(parsedAll, parsed, options);
|
|
245
245
|
} catch (e) {
|
|
246
246
|
if (debug) {
|
|
@@ -523,6 +523,7 @@ var init_failure_codes = __esm({
|
|
|
523
523
|
REGISTRY_TOOL_NOT_FOUND: "REGISTRY_TOOL_NOT_FOUND",
|
|
524
524
|
REGISTRY_TOOL_EXECUTION_FAILED: "REGISTRY_TOOL_EXECUTION_FAILED",
|
|
525
525
|
REGISTRY_TOOL_FAILURE_UNCLASSIFIED: "REGISTRY_TOOL_FAILURE_UNCLASSIFIED",
|
|
526
|
+
REGISTRY_SERVICE_TERMINATING: "REGISTRY_SERVICE_TERMINATING",
|
|
526
527
|
HTTP_TOOL_NOT_FOUND: "HTTP_TOOL_NOT_FOUND",
|
|
527
528
|
HTTP_ZOD_VALIDATION_FAILED: "HTTP_ZOD_VALIDATION_FAILED",
|
|
528
529
|
HTTP_CAPABILITY_UNSUPPORTED_OPERATION: "HTTP_CAPABILITY_UNSUPPORTED_OPERATION",
|
|
@@ -646,6 +647,13 @@ var init_failure_codes = __esm({
|
|
|
646
647
|
DEBUGGER_CDP_BINDING_TIMEOUT: "DEBUGGER_CDP_BINDING_TIMEOUT",
|
|
647
648
|
DEBUGGER_CDP_BINDING_UNAVAILABLE: "DEBUGGER_CDP_BINDING_UNAVAILABLE",
|
|
648
649
|
DEBUGGER_CDP_PROTOCOL_ERROR: "DEBUGGER_CDP_PROTOCOL_ERROR",
|
|
650
|
+
DEBUGGER_CDP_CONNECT_FAILED: "DEBUGGER_CDP_CONNECT_FAILED",
|
|
651
|
+
DEBUGGER_CDP_SOCKET_CLOSED_BEFORE_OPEN: "DEBUGGER_CDP_SOCKET_CLOSED_BEFORE_OPEN",
|
|
652
|
+
DEBUGGER_CDP_NOT_CONNECTED: "DEBUGGER_CDP_NOT_CONNECTED",
|
|
653
|
+
DEBUGGER_CDP_REQUEST_TIMEOUT: "DEBUGGER_CDP_REQUEST_TIMEOUT",
|
|
654
|
+
DEBUGGER_CDP_CONNECTION_CLOSED: "DEBUGGER_CDP_CONNECTION_CLOSED",
|
|
655
|
+
DEBUGGER_TARGET_DEVICE_MISMATCH: "DEBUGGER_TARGET_DEVICE_MISMATCH",
|
|
656
|
+
DEBUGGER_EVALUATE_EXPRESSION_THREW: "DEBUGGER_EVALUATE_EXPRESSION_THREW",
|
|
649
657
|
DEBUGGER_RELOAD_FAILED: "DEBUGGER_RELOAD_FAILED",
|
|
650
658
|
JS_RUNTIME_CONSOLE_SERVER_BIND_FAILED: "JS_RUNTIME_CONSOLE_SERVER_BIND_FAILED",
|
|
651
659
|
JS_RUNTIME_PAYLOAD_INVALID: "JS_RUNTIME_PAYLOAD_INVALID",
|
|
@@ -16042,6 +16050,14 @@ var init_zod_to_json_schema = __esm({
|
|
|
16042
16050
|
});
|
|
16043
16051
|
|
|
16044
16052
|
// ../registry/src/registry.ts
|
|
16053
|
+
function terminatingSignalCause(message) {
|
|
16054
|
+
return new FailureError(message, {
|
|
16055
|
+
error_code: FAILURE_CODES.REGISTRY_SERVICE_TERMINATING,
|
|
16056
|
+
failure_stage: "registry_service_terminating",
|
|
16057
|
+
failure_area: "registry",
|
|
16058
|
+
error_kind: "unknown"
|
|
16059
|
+
});
|
|
16060
|
+
}
|
|
16045
16061
|
function formatInteractionMessage(format, fallback) {
|
|
16046
16062
|
try {
|
|
16047
16063
|
return format() ?? fallback;
|
|
@@ -16057,6 +16073,7 @@ var init_registry = __esm({
|
|
|
16057
16073
|
init_types();
|
|
16058
16074
|
init_artifacts();
|
|
16059
16075
|
init_errors();
|
|
16076
|
+
init_failure_codes();
|
|
16060
16077
|
init_urn();
|
|
16061
16078
|
init_zod_to_json_schema();
|
|
16062
16079
|
import_node_crypto2 = require("node:crypto");
|
|
@@ -16142,7 +16159,7 @@ var init_registry = __esm({
|
|
|
16142
16159
|
urn: typeof ref === "string" ? ref : ref.urn,
|
|
16143
16160
|
options: typeof ref === "string" ? void 0 : ref.options
|
|
16144
16161
|
}));
|
|
16145
|
-
const ctx = { ...options, artifacts: this.artifacts };
|
|
16162
|
+
const ctx = { ...options, toolInvocationId, artifacts: this.artifacts };
|
|
16146
16163
|
const runOnce = async () => {
|
|
16147
16164
|
const resolvedServices = {};
|
|
16148
16165
|
for (const { alias, urn, options: resolveOptions } of refs) {
|
|
@@ -16288,7 +16305,9 @@ var init_registry = __esm({
|
|
|
16288
16305
|
}
|
|
16289
16306
|
if (node.state === "TERMINATING" /* TERMINATING */) {
|
|
16290
16307
|
return Promise.reject(
|
|
16291
|
-
new ServiceInitializationError(urn, "Service is currently terminating"
|
|
16308
|
+
new ServiceInitializationError(urn, "Service is currently terminating", {
|
|
16309
|
+
cause: terminatingSignalCause("Service is currently terminating")
|
|
16310
|
+
})
|
|
16292
16311
|
);
|
|
16293
16312
|
}
|
|
16294
16313
|
if (node.state === "RUNNING" /* RUNNING */ && node.instance) {
|
|
@@ -16320,7 +16339,9 @@ var init_registry = __esm({
|
|
|
16320
16339
|
} catch {
|
|
16321
16340
|
}
|
|
16322
16341
|
node.initPromise = null;
|
|
16323
|
-
throw new ServiceInitializationError(urn, "Service was terminated during initialization"
|
|
16342
|
+
throw new ServiceInitializationError(urn, "Service was terminated during initialization", {
|
|
16343
|
+
cause: terminatingSignalCause("Service was terminated during initialization")
|
|
16344
|
+
});
|
|
16324
16345
|
}
|
|
16325
16346
|
this._transition(node, "RUNNING" /* RUNNING */);
|
|
16326
16347
|
node.instance = instance;
|
|
@@ -35264,7 +35285,7 @@ var require_view = __commonJS({
|
|
|
35264
35285
|
"use strict";
|
|
35265
35286
|
var debug = require_src()("express:view");
|
|
35266
35287
|
var path40 = require("node:path");
|
|
35267
|
-
var
|
|
35288
|
+
var fs55 = require("node:fs");
|
|
35268
35289
|
var dirname15 = path40.dirname;
|
|
35269
35290
|
var basename13 = path40.basename;
|
|
35270
35291
|
var extname6 = path40.extname;
|
|
@@ -35344,7 +35365,7 @@ var require_view = __commonJS({
|
|
|
35344
35365
|
function tryStat(path41) {
|
|
35345
35366
|
debug('stat "%s"', path41);
|
|
35346
35367
|
try {
|
|
35347
|
-
return
|
|
35368
|
+
return fs55.statSync(path41);
|
|
35348
35369
|
} catch (e) {
|
|
35349
35370
|
return void 0;
|
|
35350
35371
|
}
|
|
@@ -67649,7 +67670,7 @@ var require_send = __commonJS({
|
|
|
67649
67670
|
var escapeHtml = require_escape_html();
|
|
67650
67671
|
var etag = require_etag();
|
|
67651
67672
|
var fresh = require_fresh();
|
|
67652
|
-
var
|
|
67673
|
+
var fs55 = require("fs");
|
|
67653
67674
|
var mime = require_mime_types4();
|
|
67654
67675
|
var ms = require_ms();
|
|
67655
67676
|
var onFinished = require_on_finished();
|
|
@@ -67931,7 +67952,7 @@ var require_send = __commonJS({
|
|
|
67931
67952
|
var i = 0;
|
|
67932
67953
|
var self = this;
|
|
67933
67954
|
debug('stat "%s"', path41);
|
|
67934
|
-
|
|
67955
|
+
fs55.stat(path41, function onstat(err, stat5) {
|
|
67935
67956
|
var pathEndsWithSep = path41[path41.length - 1] === sep7;
|
|
67936
67957
|
if (err && err.code === "ENOENT" && !extname6(path41) && !pathEndsWithSep) {
|
|
67937
67958
|
return next(err);
|
|
@@ -67948,7 +67969,7 @@ var require_send = __commonJS({
|
|
|
67948
67969
|
}
|
|
67949
67970
|
var p = path41 + "." + self._extensions[i++];
|
|
67950
67971
|
debug('stat "%s"', p);
|
|
67951
|
-
|
|
67972
|
+
fs55.stat(p, function(err2, stat5) {
|
|
67952
67973
|
if (err2) return next(err2);
|
|
67953
67974
|
if (stat5.isDirectory()) return next();
|
|
67954
67975
|
self.emit("file", p, stat5);
|
|
@@ -67966,7 +67987,7 @@ var require_send = __commonJS({
|
|
|
67966
67987
|
}
|
|
67967
67988
|
var p = join47(path41, self._index[i]);
|
|
67968
67989
|
debug('stat "%s"', p);
|
|
67969
|
-
|
|
67990
|
+
fs55.stat(p, function(err2, stat5) {
|
|
67970
67991
|
if (err2) return next(err2);
|
|
67971
67992
|
if (stat5.isDirectory()) return next();
|
|
67972
67993
|
self.emit("file", p, stat5);
|
|
@@ -67978,7 +67999,7 @@ var require_send = __commonJS({
|
|
|
67978
67999
|
SendStream.prototype.stream = function stream(path41, options) {
|
|
67979
68000
|
var self = this;
|
|
67980
68001
|
var res = this.res;
|
|
67981
|
-
var stream2 =
|
|
68002
|
+
var stream2 = fs55.createReadStream(path41, options);
|
|
67982
68003
|
this.emit("stream", stream2);
|
|
67983
68004
|
stream2.pipe(res);
|
|
67984
68005
|
function cleanup() {
|
|
@@ -75469,10 +75490,10 @@ function avdRootCandidates() {
|
|
|
75469
75490
|
return candidates.filter((p) => Boolean(p && (0, import_node_path6.isAbsolute)(p)));
|
|
75470
75491
|
}
|
|
75471
75492
|
async function resolveAvdPath(avdName) {
|
|
75472
|
-
const { readFile:
|
|
75493
|
+
const { readFile: readFile13 } = await import("node:fs/promises");
|
|
75473
75494
|
for (const root of avdRootCandidates()) {
|
|
75474
75495
|
try {
|
|
75475
|
-
const content = await
|
|
75496
|
+
const content = await readFile13(`${root}/${avdName}.ini`, "utf-8");
|
|
75476
75497
|
const raw = (0, import_ini.parse)(content).path;
|
|
75477
75498
|
if (typeof raw !== "string") continue;
|
|
75478
75499
|
const trimmed = raw.trim();
|
|
@@ -75602,7 +75623,7 @@ var require_safe_json_stringify = __commonJS({
|
|
|
75602
75623
|
// ../../node_modules/ncp/lib/ncp.js
|
|
75603
75624
|
var require_ncp = __commonJS({
|
|
75604
75625
|
"../../node_modules/ncp/lib/ncp.js"(exports2, module2) {
|
|
75605
|
-
var
|
|
75626
|
+
var fs55 = require("fs");
|
|
75606
75627
|
var path40 = require("path");
|
|
75607
75628
|
module2.exports = ncp;
|
|
75608
75629
|
ncp.ncp = ncp;
|
|
@@ -75631,7 +75652,7 @@ var require_ncp = __commonJS({
|
|
|
75631
75652
|
return getStats(source2);
|
|
75632
75653
|
}
|
|
75633
75654
|
function getStats(source2) {
|
|
75634
|
-
var stat5 = dereference ?
|
|
75655
|
+
var stat5 = dereference ? fs55.stat : fs55.lstat;
|
|
75635
75656
|
if (running >= limit) {
|
|
75636
75657
|
return setImmediate(function() {
|
|
75637
75658
|
getStats(source2);
|
|
@@ -75671,7 +75692,7 @@ var require_ncp = __commonJS({
|
|
|
75671
75692
|
});
|
|
75672
75693
|
}
|
|
75673
75694
|
if (modified) {
|
|
75674
|
-
var stat5 = dereference ?
|
|
75695
|
+
var stat5 = dereference ? fs55.stat : fs55.lstat;
|
|
75675
75696
|
stat5(target, function(err, stats) {
|
|
75676
75697
|
if (file2.mtime.getTime() > stats.mtime.getTime())
|
|
75677
75698
|
copyFile2(file2, target);
|
|
@@ -75683,7 +75704,7 @@ var require_ncp = __commonJS({
|
|
|
75683
75704
|
});
|
|
75684
75705
|
}
|
|
75685
75706
|
function copyFile2(file2, target) {
|
|
75686
|
-
var readStream =
|
|
75707
|
+
var readStream = fs55.createReadStream(file2.name), writeStream = fs55.createWriteStream(target, { mode: file2.mode });
|
|
75687
75708
|
readStream.on("error", onError);
|
|
75688
75709
|
writeStream.on("error", onError);
|
|
75689
75710
|
if (transform2) {
|
|
@@ -75695,13 +75716,13 @@ var require_ncp = __commonJS({
|
|
|
75695
75716
|
}
|
|
75696
75717
|
writeStream.once("finish", function() {
|
|
75697
75718
|
if (modified) {
|
|
75698
|
-
|
|
75719
|
+
fs55.utimesSync(target, file2.atime, file2.mtime);
|
|
75699
75720
|
cb();
|
|
75700
75721
|
} else cb();
|
|
75701
75722
|
});
|
|
75702
75723
|
}
|
|
75703
75724
|
function rmFile(file2, done) {
|
|
75704
|
-
|
|
75725
|
+
fs55.unlink(file2, function(err) {
|
|
75705
75726
|
if (err) {
|
|
75706
75727
|
return onError(err);
|
|
75707
75728
|
}
|
|
@@ -75718,7 +75739,7 @@ var require_ncp = __commonJS({
|
|
|
75718
75739
|
});
|
|
75719
75740
|
}
|
|
75720
75741
|
function mkDir(dir, target) {
|
|
75721
|
-
|
|
75742
|
+
fs55.mkdir(target, dir.mode, function(err) {
|
|
75722
75743
|
if (err) {
|
|
75723
75744
|
return onError(err);
|
|
75724
75745
|
}
|
|
@@ -75726,7 +75747,7 @@ var require_ncp = __commonJS({
|
|
|
75726
75747
|
});
|
|
75727
75748
|
}
|
|
75728
75749
|
function copyDir(dir) {
|
|
75729
|
-
|
|
75750
|
+
fs55.readdir(dir, function(err, items) {
|
|
75730
75751
|
if (err) {
|
|
75731
75752
|
return onError(err);
|
|
75732
75753
|
}
|
|
@@ -75738,7 +75759,7 @@ var require_ncp = __commonJS({
|
|
|
75738
75759
|
}
|
|
75739
75760
|
function onLink(link) {
|
|
75740
75761
|
var target = link.replace(currentPath, targetPath);
|
|
75741
|
-
|
|
75762
|
+
fs55.readlink(link, function(err, resolvedPath) {
|
|
75742
75763
|
if (err) {
|
|
75743
75764
|
return onError(err);
|
|
75744
75765
|
}
|
|
@@ -75753,7 +75774,7 @@ var require_ncp = __commonJS({
|
|
|
75753
75774
|
if (writable) {
|
|
75754
75775
|
return makeLink(resolvedPath, target);
|
|
75755
75776
|
}
|
|
75756
|
-
|
|
75777
|
+
fs55.readlink(target, function(err, targetDest) {
|
|
75757
75778
|
if (err) {
|
|
75758
75779
|
return onError(err);
|
|
75759
75780
|
}
|
|
@@ -75770,7 +75791,7 @@ var require_ncp = __commonJS({
|
|
|
75770
75791
|
});
|
|
75771
75792
|
}
|
|
75772
75793
|
function makeLink(linkPath, target) {
|
|
75773
|
-
|
|
75794
|
+
fs55.symlink(linkPath, target, function(err) {
|
|
75774
75795
|
if (err) {
|
|
75775
75796
|
return onError(err);
|
|
75776
75797
|
}
|
|
@@ -75778,7 +75799,7 @@ var require_ncp = __commonJS({
|
|
|
75778
75799
|
});
|
|
75779
75800
|
}
|
|
75780
75801
|
function isWritable2(path41, done) {
|
|
75781
|
-
|
|
75802
|
+
fs55.lstat(path41, function(err) {
|
|
75782
75803
|
if (err) {
|
|
75783
75804
|
if (err.code === "ENOENT") return done(true);
|
|
75784
75805
|
return done(false);
|
|
@@ -75790,7 +75811,7 @@ var require_ncp = __commonJS({
|
|
|
75790
75811
|
if (options.stopOnError) {
|
|
75791
75812
|
return cback(err);
|
|
75792
75813
|
} else if (!errs && options.errs) {
|
|
75793
|
-
errs =
|
|
75814
|
+
errs = fs55.createWriteStream(options.errs);
|
|
75794
75815
|
} else if (!errs) {
|
|
75795
75816
|
errs = [];
|
|
75796
75817
|
}
|
|
@@ -76919,7 +76940,7 @@ var require_sync = __commonJS({
|
|
|
76919
76940
|
"../../node_modules/glob/sync.js"(exports2, module2) {
|
|
76920
76941
|
module2.exports = globSync;
|
|
76921
76942
|
globSync.GlobSync = GlobSync;
|
|
76922
|
-
var
|
|
76943
|
+
var fs55 = require("fs");
|
|
76923
76944
|
var minimatch = require_minimatch();
|
|
76924
76945
|
var Minimatch = minimatch.Minimatch;
|
|
76925
76946
|
var Glob = require_glob().Glob;
|
|
@@ -76964,7 +76985,7 @@ var require_sync = __commonJS({
|
|
|
76964
76985
|
for (var p in matchset) {
|
|
76965
76986
|
try {
|
|
76966
76987
|
p = self._makeAbs(p);
|
|
76967
|
-
var real =
|
|
76988
|
+
var real = fs55.realpathSync(p, self.realpathCache);
|
|
76968
76989
|
set2[real] = true;
|
|
76969
76990
|
} catch (er) {
|
|
76970
76991
|
if (er.syscall === "stat")
|
|
@@ -77091,7 +77112,7 @@ var require_sync = __commonJS({
|
|
|
77091
77112
|
var lstat;
|
|
77092
77113
|
var stat5;
|
|
77093
77114
|
try {
|
|
77094
|
-
lstat =
|
|
77115
|
+
lstat = fs55.lstatSync(abs);
|
|
77095
77116
|
} catch (er) {
|
|
77096
77117
|
return null;
|
|
77097
77118
|
}
|
|
@@ -77115,7 +77136,7 @@ var require_sync = __commonJS({
|
|
|
77115
77136
|
return c;
|
|
77116
77137
|
}
|
|
77117
77138
|
try {
|
|
77118
|
-
return this._readdirEntries(abs,
|
|
77139
|
+
return this._readdirEntries(abs, fs55.readdirSync(abs));
|
|
77119
77140
|
} catch (er) {
|
|
77120
77141
|
this._readdirError(abs, er);
|
|
77121
77142
|
return null;
|
|
@@ -77219,13 +77240,13 @@ var require_sync = __commonJS({
|
|
|
77219
77240
|
if (!stat5) {
|
|
77220
77241
|
var lstat;
|
|
77221
77242
|
try {
|
|
77222
|
-
lstat =
|
|
77243
|
+
lstat = fs55.lstatSync(abs);
|
|
77223
77244
|
} catch (er) {
|
|
77224
77245
|
return false;
|
|
77225
77246
|
}
|
|
77226
77247
|
if (lstat.isSymbolicLink()) {
|
|
77227
77248
|
try {
|
|
77228
|
-
stat5 =
|
|
77249
|
+
stat5 = fs55.statSync(abs);
|
|
77229
77250
|
} catch (er) {
|
|
77230
77251
|
stat5 = lstat;
|
|
77231
77252
|
}
|
|
@@ -77299,7 +77320,7 @@ var require_inflight = __commonJS({
|
|
|
77299
77320
|
var require_glob = __commonJS({
|
|
77300
77321
|
"../../node_modules/glob/glob.js"(exports2, module2) {
|
|
77301
77322
|
module2.exports = glob;
|
|
77302
|
-
var
|
|
77323
|
+
var fs55 = require("fs");
|
|
77303
77324
|
var minimatch = require_minimatch();
|
|
77304
77325
|
var Minimatch = minimatch.Minimatch;
|
|
77305
77326
|
var inherits = require_inherits();
|
|
@@ -77436,7 +77457,7 @@ var require_glob = __commonJS({
|
|
|
77436
77457
|
var set2 = this.matches[index] = /* @__PURE__ */ Object.create(null);
|
|
77437
77458
|
found.forEach(function(p, i) {
|
|
77438
77459
|
p = self._makeAbs(p);
|
|
77439
|
-
|
|
77460
|
+
fs55.realpath(p, self.realpathCache, function(er, real) {
|
|
77440
77461
|
if (!er)
|
|
77441
77462
|
set2[real] = true;
|
|
77442
77463
|
else if (er.syscall === "stat")
|
|
@@ -77631,7 +77652,7 @@ var require_glob = __commonJS({
|
|
|
77631
77652
|
var self = this;
|
|
77632
77653
|
var lstatcb = inflight(lstatkey, lstatcb_);
|
|
77633
77654
|
if (lstatcb)
|
|
77634
|
-
|
|
77655
|
+
fs55.lstat(abs, lstatcb);
|
|
77635
77656
|
function lstatcb_(er, lstat) {
|
|
77636
77657
|
if (er)
|
|
77637
77658
|
return cb();
|
|
@@ -77660,7 +77681,7 @@ var require_glob = __commonJS({
|
|
|
77660
77681
|
return cb(null, c);
|
|
77661
77682
|
}
|
|
77662
77683
|
var self = this;
|
|
77663
|
-
|
|
77684
|
+
fs55.readdir(abs, readdirCb(this, abs, cb));
|
|
77664
77685
|
};
|
|
77665
77686
|
function readdirCb(self, abs, cb) {
|
|
77666
77687
|
return function(er, entries) {
|
|
@@ -77798,10 +77819,10 @@ var require_glob = __commonJS({
|
|
|
77798
77819
|
var self = this;
|
|
77799
77820
|
var statcb = inflight("stat\0" + abs, lstatcb_);
|
|
77800
77821
|
if (statcb)
|
|
77801
|
-
|
|
77822
|
+
fs55.lstat(abs, statcb);
|
|
77802
77823
|
function lstatcb_(er, lstat) {
|
|
77803
77824
|
if (lstat && lstat.isSymbolicLink()) {
|
|
77804
|
-
return
|
|
77825
|
+
return fs55.stat(abs, function(er2, stat6) {
|
|
77805
77826
|
if (er2)
|
|
77806
77827
|
self._stat2(f, abs, null, lstat, cb);
|
|
77807
77828
|
else
|
|
@@ -77837,7 +77858,7 @@ var require_rimraf = __commonJS({
|
|
|
77837
77858
|
rimraf.sync = rimrafSync;
|
|
77838
77859
|
var assert2 = require("assert");
|
|
77839
77860
|
var path40 = require("path");
|
|
77840
|
-
var
|
|
77861
|
+
var fs55 = require("fs");
|
|
77841
77862
|
var glob = require_glob();
|
|
77842
77863
|
var globOpts = {
|
|
77843
77864
|
nosort: true,
|
|
@@ -77857,9 +77878,9 @@ var require_rimraf = __commonJS({
|
|
|
77857
77878
|
"readdir"
|
|
77858
77879
|
];
|
|
77859
77880
|
methods.forEach(function(m) {
|
|
77860
|
-
options[m] = options[m] ||
|
|
77881
|
+
options[m] = options[m] || fs55[m];
|
|
77861
77882
|
m = m + "Sync";
|
|
77862
|
-
options[m] = options[m] ||
|
|
77883
|
+
options[m] = options[m] || fs55[m];
|
|
77863
77884
|
});
|
|
77864
77885
|
options.maxBusyTries = options.maxBusyTries || 3;
|
|
77865
77886
|
options.emfileWait = options.emfileWait || 1e3;
|
|
@@ -77881,7 +77902,7 @@ var require_rimraf = __commonJS({
|
|
|
77881
77902
|
var n = 0;
|
|
77882
77903
|
if (options.disableGlob || !glob.hasMagic(p))
|
|
77883
77904
|
return afterGlob(null, [p]);
|
|
77884
|
-
|
|
77905
|
+
fs55.lstat(p, function(er, stat5) {
|
|
77885
77906
|
if (!er)
|
|
77886
77907
|
return afterGlob(null, [p]);
|
|
77887
77908
|
glob(p, globOpts, afterGlob);
|
|
@@ -78038,7 +78059,7 @@ var require_rimraf = __commonJS({
|
|
|
78038
78059
|
results = [p];
|
|
78039
78060
|
} else {
|
|
78040
78061
|
try {
|
|
78041
|
-
|
|
78062
|
+
fs55.lstatSync(p);
|
|
78042
78063
|
results = [p];
|
|
78043
78064
|
} catch (er) {
|
|
78044
78065
|
results = glob.sync(p, globOpts);
|
|
@@ -78101,7 +78122,7 @@ var require_rimraf = __commonJS({
|
|
|
78101
78122
|
var require_mkdirp = __commonJS({
|
|
78102
78123
|
"../../node_modules/mkdirp/index.js"(exports2, module2) {
|
|
78103
78124
|
var path40 = require("path");
|
|
78104
|
-
var
|
|
78125
|
+
var fs55 = require("fs");
|
|
78105
78126
|
var _0777 = parseInt("0777", 8);
|
|
78106
78127
|
module2.exports = mkdirP.mkdirp = mkdirP.mkdirP = mkdirP;
|
|
78107
78128
|
function mkdirP(p, opts, f, made) {
|
|
@@ -78112,7 +78133,7 @@ var require_mkdirp = __commonJS({
|
|
|
78112
78133
|
opts = { mode: opts };
|
|
78113
78134
|
}
|
|
78114
78135
|
var mode = opts.mode;
|
|
78115
|
-
var xfs = opts.fs ||
|
|
78136
|
+
var xfs = opts.fs || fs55;
|
|
78116
78137
|
if (mode === void 0) {
|
|
78117
78138
|
mode = _0777;
|
|
78118
78139
|
}
|
|
@@ -78151,7 +78172,7 @@ var require_mkdirp = __commonJS({
|
|
|
78151
78172
|
opts = { mode: opts };
|
|
78152
78173
|
}
|
|
78153
78174
|
var mode = opts.mode;
|
|
78154
|
-
var xfs = opts.fs ||
|
|
78175
|
+
var xfs = opts.fs || fs55;
|
|
78155
78176
|
if (mode === void 0) {
|
|
78156
78177
|
mode = _0777;
|
|
78157
78178
|
}
|
|
@@ -78188,7 +78209,7 @@ var require_mkdirp = __commonJS({
|
|
|
78188
78209
|
// ../../node_modules/mv/index.js
|
|
78189
78210
|
var require_mv = __commonJS({
|
|
78190
78211
|
"../../node_modules/mv/index.js"(exports2, module2) {
|
|
78191
|
-
var
|
|
78212
|
+
var fs55 = require("fs");
|
|
78192
78213
|
var ncp = require_ncp().ncp;
|
|
78193
78214
|
var path40 = require("path");
|
|
78194
78215
|
var rimraf = require_rimraf();
|
|
@@ -78215,13 +78236,13 @@ var require_mv = __commonJS({
|
|
|
78215
78236
|
}
|
|
78216
78237
|
function doRename() {
|
|
78217
78238
|
if (clobber) {
|
|
78218
|
-
|
|
78239
|
+
fs55.rename(source, dest, function(err) {
|
|
78219
78240
|
if (!err) return cb();
|
|
78220
78241
|
if (err.code !== "EXDEV") return cb(err);
|
|
78221
78242
|
moveFileAcrossDevice(source, dest, clobber, limit, cb);
|
|
78222
78243
|
});
|
|
78223
78244
|
} else {
|
|
78224
|
-
|
|
78245
|
+
fs55.link(source, dest, function(err) {
|
|
78225
78246
|
if (err) {
|
|
78226
78247
|
if (err.code === "EXDEV") {
|
|
78227
78248
|
moveFileAcrossDevice(source, dest, clobber, limit, cb);
|
|
@@ -78234,15 +78255,15 @@ var require_mv = __commonJS({
|
|
|
78234
78255
|
cb(err);
|
|
78235
78256
|
return;
|
|
78236
78257
|
}
|
|
78237
|
-
|
|
78258
|
+
fs55.unlink(source, cb);
|
|
78238
78259
|
});
|
|
78239
78260
|
}
|
|
78240
78261
|
}
|
|
78241
78262
|
}
|
|
78242
78263
|
function moveFileAcrossDevice(source, dest, clobber, limit, cb) {
|
|
78243
78264
|
var outFlags = clobber ? "w" : "wx";
|
|
78244
|
-
var ins =
|
|
78245
|
-
var outs =
|
|
78265
|
+
var ins = fs55.createReadStream(source);
|
|
78266
|
+
var outs = fs55.createWriteStream(dest, { flags: outFlags });
|
|
78246
78267
|
ins.on("error", function(err) {
|
|
78247
78268
|
ins.destroy();
|
|
78248
78269
|
outs.destroy();
|
|
@@ -78262,7 +78283,7 @@ var require_mv = __commonJS({
|
|
|
78262
78283
|
outs.once("close", onClose);
|
|
78263
78284
|
ins.pipe(outs);
|
|
78264
78285
|
function onClose() {
|
|
78265
|
-
|
|
78286
|
+
fs55.unlink(source, cb);
|
|
78266
78287
|
}
|
|
78267
78288
|
}
|
|
78268
78289
|
function moveDirAcrossDevice(source, dest, clobber, limit, cb) {
|
|
@@ -78317,7 +78338,7 @@ var require_bunyan = __commonJS({
|
|
|
78317
78338
|
throw new Error("unknown runtime environment");
|
|
78318
78339
|
}
|
|
78319
78340
|
var os15;
|
|
78320
|
-
var
|
|
78341
|
+
var fs55;
|
|
78321
78342
|
var dtrace;
|
|
78322
78343
|
if (runtimeEnv === "browser") {
|
|
78323
78344
|
os15 = {
|
|
@@ -78325,11 +78346,11 @@ var require_bunyan = __commonJS({
|
|
|
78325
78346
|
return window.location.host;
|
|
78326
78347
|
}
|
|
78327
78348
|
};
|
|
78328
|
-
|
|
78349
|
+
fs55 = {};
|
|
78329
78350
|
dtrace = null;
|
|
78330
78351
|
} else {
|
|
78331
78352
|
os15 = require("os");
|
|
78332
|
-
|
|
78353
|
+
fs55 = require("fs");
|
|
78333
78354
|
try {
|
|
78334
78355
|
dtrace = require("dtrace-provider");
|
|
78335
78356
|
} catch (e) {
|
|
@@ -78709,7 +78730,7 @@ var require_bunyan = __commonJS({
|
|
|
78709
78730
|
s.reemitErrorEvents = true;
|
|
78710
78731
|
}
|
|
78711
78732
|
if (!s.stream) {
|
|
78712
|
-
s.stream =
|
|
78733
|
+
s.stream = fs55.createWriteStream(
|
|
78713
78734
|
s.path,
|
|
78714
78735
|
{ flags: "a", encoding: "utf8" }
|
|
78715
78736
|
);
|
|
@@ -78779,7 +78800,7 @@ var require_bunyan = __commonJS({
|
|
|
78779
78800
|
s.stream.destroySoon();
|
|
78780
78801
|
delete s.stream;
|
|
78781
78802
|
}
|
|
78782
|
-
s.stream =
|
|
78803
|
+
s.stream = fs55.createWriteStream(
|
|
78783
78804
|
s.path,
|
|
78784
78805
|
{ flags: "a", encoding: "utf8" }
|
|
78785
78806
|
);
|
|
@@ -79121,7 +79142,7 @@ var require_bunyan = __commonJS({
|
|
|
79121
79142
|
}
|
|
79122
79143
|
var lastModified = null;
|
|
79123
79144
|
try {
|
|
79124
|
-
var fileInfo =
|
|
79145
|
+
var fileInfo = fs55.statSync(this.path);
|
|
79125
79146
|
lastModified = fileInfo.mtime.getTime();
|
|
79126
79147
|
} catch (err) {
|
|
79127
79148
|
}
|
|
@@ -79132,7 +79153,7 @@ var require_bunyan = __commonJS({
|
|
|
79132
79153
|
rotateAfterOpen = true;
|
|
79133
79154
|
}
|
|
79134
79155
|
}
|
|
79135
|
-
this.stream =
|
|
79156
|
+
this.stream = fs55.createWriteStream(
|
|
79136
79157
|
this.path,
|
|
79137
79158
|
{ flags: "a", encoding: "utf8" }
|
|
79138
79159
|
);
|
|
@@ -79299,7 +79320,7 @@ var require_bunyan = __commonJS({
|
|
|
79299
79320
|
}
|
|
79300
79321
|
n -= 1;
|
|
79301
79322
|
self._debug(" rm %s", toDel);
|
|
79302
|
-
|
|
79323
|
+
fs55.unlink(toDel, function(delErr) {
|
|
79303
79324
|
moves();
|
|
79304
79325
|
});
|
|
79305
79326
|
}
|
|
@@ -79313,7 +79334,7 @@ var require_bunyan = __commonJS({
|
|
|
79313
79334
|
before += "." + String(n - 1);
|
|
79314
79335
|
}
|
|
79315
79336
|
n -= 1;
|
|
79316
|
-
|
|
79337
|
+
fs55.exists(before, function(exists2) {
|
|
79317
79338
|
if (!exists2) {
|
|
79318
79339
|
moves();
|
|
79319
79340
|
} else {
|
|
@@ -79331,7 +79352,7 @@ var require_bunyan = __commonJS({
|
|
|
79331
79352
|
}
|
|
79332
79353
|
function finish() {
|
|
79333
79354
|
self._debug(" open %s", self.path);
|
|
79334
|
-
self.stream =
|
|
79355
|
+
self.stream = fs55.createWriteStream(
|
|
79335
79356
|
self.path,
|
|
79336
79357
|
{ flags: "a", encoding: "utf8" }
|
|
79337
79358
|
);
|
|
@@ -83276,7 +83297,7 @@ var require_png = __commonJS({
|
|
|
83276
83297
|
var Parser = require_parser_async();
|
|
83277
83298
|
var Packer = require_packer_async();
|
|
83278
83299
|
var PNGSync = require_png_sync();
|
|
83279
|
-
var
|
|
83300
|
+
var PNG5 = exports2.PNG = function(options) {
|
|
83280
83301
|
Stream2.call(this);
|
|
83281
83302
|
options = options || {};
|
|
83282
83303
|
this.width = options.width | 0;
|
|
@@ -83305,9 +83326,9 @@ var require_png = __commonJS({
|
|
|
83305
83326
|
this._parser.on("close", this._handleClose.bind(this));
|
|
83306
83327
|
this._packer.on("error", this.emit.bind(this, "error"));
|
|
83307
83328
|
};
|
|
83308
|
-
util.inherits(
|
|
83309
|
-
|
|
83310
|
-
|
|
83329
|
+
util.inherits(PNG5, Stream2);
|
|
83330
|
+
PNG5.sync = PNGSync;
|
|
83331
|
+
PNG5.prototype.pack = function() {
|
|
83311
83332
|
if (!this.data || !this.data.length) {
|
|
83312
83333
|
this.emit("error", "No data provided");
|
|
83313
83334
|
return this;
|
|
@@ -83319,7 +83340,7 @@ var require_png = __commonJS({
|
|
|
83319
83340
|
);
|
|
83320
83341
|
return this;
|
|
83321
83342
|
};
|
|
83322
|
-
|
|
83343
|
+
PNG5.prototype.parse = function(data, callback) {
|
|
83323
83344
|
if (callback) {
|
|
83324
83345
|
let onParsed, onError;
|
|
83325
83346
|
onParsed = function(parsedData) {
|
|
@@ -83337,27 +83358,27 @@ var require_png = __commonJS({
|
|
|
83337
83358
|
this.end(data);
|
|
83338
83359
|
return this;
|
|
83339
83360
|
};
|
|
83340
|
-
|
|
83361
|
+
PNG5.prototype.write = function(data) {
|
|
83341
83362
|
this._parser.write(data);
|
|
83342
83363
|
return true;
|
|
83343
83364
|
};
|
|
83344
|
-
|
|
83365
|
+
PNG5.prototype.end = function(data) {
|
|
83345
83366
|
this._parser.end(data);
|
|
83346
83367
|
};
|
|
83347
|
-
|
|
83368
|
+
PNG5.prototype._metadata = function(metadata) {
|
|
83348
83369
|
this.width = metadata.width;
|
|
83349
83370
|
this.height = metadata.height;
|
|
83350
83371
|
this.emit("metadata", metadata);
|
|
83351
83372
|
};
|
|
83352
|
-
|
|
83373
|
+
PNG5.prototype._gamma = function(gamma) {
|
|
83353
83374
|
this.gamma = gamma;
|
|
83354
83375
|
};
|
|
83355
|
-
|
|
83376
|
+
PNG5.prototype._handleClose = function() {
|
|
83356
83377
|
if (!this._parser.writable && !this._packer.readable) {
|
|
83357
83378
|
this.emit("close");
|
|
83358
83379
|
}
|
|
83359
83380
|
};
|
|
83360
|
-
|
|
83381
|
+
PNG5.bitblt = function(src, dst, srcX, srcY, width, height, deltaX, deltaY) {
|
|
83361
83382
|
srcX |= 0;
|
|
83362
83383
|
srcY |= 0;
|
|
83363
83384
|
width |= 0;
|
|
@@ -83379,11 +83400,11 @@ var require_png = __commonJS({
|
|
|
83379
83400
|
);
|
|
83380
83401
|
}
|
|
83381
83402
|
};
|
|
83382
|
-
|
|
83383
|
-
|
|
83403
|
+
PNG5.prototype.bitblt = function(dst, srcX, srcY, width, height, deltaX, deltaY) {
|
|
83404
|
+
PNG5.bitblt(this, dst, srcX, srcY, width, height, deltaX, deltaY);
|
|
83384
83405
|
return this;
|
|
83385
83406
|
};
|
|
83386
|
-
|
|
83407
|
+
PNG5.adjustGamma = function(src) {
|
|
83387
83408
|
if (src.gamma) {
|
|
83388
83409
|
for (let y = 0; y < src.height; y++) {
|
|
83389
83410
|
for (let x = 0; x < src.width; x++) {
|
|
@@ -83398,8 +83419,8 @@ var require_png = __commonJS({
|
|
|
83398
83419
|
src.gamma = 0;
|
|
83399
83420
|
}
|
|
83400
83421
|
};
|
|
83401
|
-
|
|
83402
|
-
|
|
83422
|
+
PNG5.prototype.adjustGamma = function() {
|
|
83423
|
+
PNG5.adjustGamma(this);
|
|
83403
83424
|
};
|
|
83404
83425
|
}
|
|
83405
83426
|
});
|
|
@@ -90282,14 +90303,14 @@ var require_parser2 = __commonJS({
|
|
|
90282
90303
|
case "scalar":
|
|
90283
90304
|
case "single-quoted-scalar":
|
|
90284
90305
|
case "double-quoted-scalar": {
|
|
90285
|
-
const
|
|
90306
|
+
const fs55 = this.flowScalar(this.type);
|
|
90286
90307
|
if (atNextItem || it.value) {
|
|
90287
|
-
map2.items.push({ start: start2, key:
|
|
90308
|
+
map2.items.push({ start: start2, key: fs55, sep: [] });
|
|
90288
90309
|
this.onKeyLine = true;
|
|
90289
90310
|
} else if (it.sep) {
|
|
90290
|
-
this.stack.push(
|
|
90311
|
+
this.stack.push(fs55);
|
|
90291
90312
|
} else {
|
|
90292
|
-
Object.assign(it, { key:
|
|
90313
|
+
Object.assign(it, { key: fs55, sep: [] });
|
|
90293
90314
|
this.onKeyLine = true;
|
|
90294
90315
|
}
|
|
90295
90316
|
return;
|
|
@@ -90417,13 +90438,13 @@ var require_parser2 = __commonJS({
|
|
|
90417
90438
|
case "scalar":
|
|
90418
90439
|
case "single-quoted-scalar":
|
|
90419
90440
|
case "double-quoted-scalar": {
|
|
90420
|
-
const
|
|
90441
|
+
const fs55 = this.flowScalar(this.type);
|
|
90421
90442
|
if (!it || it.value)
|
|
90422
|
-
fc.items.push({ start: [], key:
|
|
90443
|
+
fc.items.push({ start: [], key: fs55, sep: [] });
|
|
90423
90444
|
else if (it.sep)
|
|
90424
|
-
this.stack.push(
|
|
90445
|
+
this.stack.push(fs55);
|
|
90425
90446
|
else
|
|
90426
|
-
Object.assign(it, { key:
|
|
90447
|
+
Object.assign(it, { key: fs55, sep: [] });
|
|
90427
90448
|
return;
|
|
90428
90449
|
}
|
|
90429
90450
|
case "flow-map-end":
|
|
@@ -96039,6 +96060,16 @@ var PLATFORMS = [
|
|
|
96039
96060
|
"tvos",
|
|
96040
96061
|
"android-tv"
|
|
96041
96062
|
];
|
|
96063
|
+
var DEBUGGER_NOT_CONNECTED_REASONS = [
|
|
96064
|
+
"metro_not_running",
|
|
96065
|
+
"no_app_connected",
|
|
96066
|
+
"device_mismatch",
|
|
96067
|
+
"cdp_unreachable",
|
|
96068
|
+
"runtime_unresponsive",
|
|
96069
|
+
"stale_connection",
|
|
96070
|
+
"reconnecting"
|
|
96071
|
+
];
|
|
96072
|
+
var DEBUGGER_TOOL_OUTCOMES = ["connected", ...DEBUGGER_NOT_CONNECTED_REASONS];
|
|
96042
96073
|
|
|
96043
96074
|
// ../telemetry/src/ai-identity.ts
|
|
96044
96075
|
var AI_CLIENTS = [
|
|
@@ -96233,9 +96264,19 @@ var ALLOWED = {
|
|
|
96233
96264
|
tool_invocation_id: UUID2,
|
|
96234
96265
|
platform: PLATFORM,
|
|
96235
96266
|
duration_ms: DURATION_MS,
|
|
96267
|
+
// Schema-declared parameter names only (emit side filters against the tool's
|
|
96268
|
+
// own zod shape and caps at 16 before this gate); the array validator also
|
|
96269
|
+
// voids anything longer or with a non-identifier element.
|
|
96270
|
+
invalid_params: arrayOf(matches(/^[a-z][a-z0-9_]{0,63}$/i, 64), 16),
|
|
96236
96271
|
...FAILURE_SIGNAL2,
|
|
96237
96272
|
...AI_TELEMETRY
|
|
96238
96273
|
},
|
|
96274
|
+
"debugger:tool_outcome": {
|
|
96275
|
+
tool: oneOf(["debugger-status", "debugger-log-registry"]),
|
|
96276
|
+
outcome: oneOf(DEBUGGER_TOOL_OUTCOMES),
|
|
96277
|
+
platform: PLATFORM,
|
|
96278
|
+
tool_invocation_id: UUID2
|
|
96279
|
+
},
|
|
96239
96280
|
"cli:run_fail": {
|
|
96240
96281
|
tool: TOOL_NAME,
|
|
96241
96282
|
duration_ms: DURATION_MS,
|
|
@@ -109729,11 +109770,29 @@ var CDPClient = class {
|
|
|
109729
109770
|
};
|
|
109730
109771
|
const onError = (err) => {
|
|
109731
109772
|
cleanup();
|
|
109732
|
-
reject(
|
|
109773
|
+
reject(
|
|
109774
|
+
new FailureError(
|
|
109775
|
+
err.message,
|
|
109776
|
+
{
|
|
109777
|
+
error_code: FAILURE_CODES.DEBUGGER_CDP_CONNECT_FAILED,
|
|
109778
|
+
failure_stage: "debugger_cdp_connect",
|
|
109779
|
+
failure_area: "tool_server",
|
|
109780
|
+
error_kind: "network"
|
|
109781
|
+
},
|
|
109782
|
+
{ cause: err }
|
|
109783
|
+
)
|
|
109784
|
+
);
|
|
109733
109785
|
};
|
|
109734
109786
|
const onClose = () => {
|
|
109735
109787
|
cleanup();
|
|
109736
|
-
reject(
|
|
109788
|
+
reject(
|
|
109789
|
+
new FailureError("WebSocket closed before open", {
|
|
109790
|
+
error_code: FAILURE_CODES.DEBUGGER_CDP_SOCKET_CLOSED_BEFORE_OPEN,
|
|
109791
|
+
failure_stage: "debugger_cdp_connect",
|
|
109792
|
+
failure_area: "tool_server",
|
|
109793
|
+
error_kind: "network"
|
|
109794
|
+
})
|
|
109795
|
+
);
|
|
109737
109796
|
};
|
|
109738
109797
|
const cleanup = () => {
|
|
109739
109798
|
ws.removeListener("open", onOpen);
|
|
@@ -109798,12 +109857,33 @@ var CDPClient = class {
|
|
|
109798
109857
|
send(method, params, timeout = DEFAULT_TIMEOUT_MS2) {
|
|
109799
109858
|
return new Promise((resolve11, reject) => {
|
|
109800
109859
|
if (!this.ws || this.ws.readyState !== wrapper_default.OPEN) {
|
|
109801
|
-
return reject(
|
|
109860
|
+
return reject(
|
|
109861
|
+
new FailureError("CDP not connected", {
|
|
109862
|
+
error_code: FAILURE_CODES.DEBUGGER_CDP_NOT_CONNECTED,
|
|
109863
|
+
failure_stage: "debugger_cdp_send",
|
|
109864
|
+
failure_area: "tool_server",
|
|
109865
|
+
error_kind: "network"
|
|
109866
|
+
})
|
|
109867
|
+
);
|
|
109802
109868
|
}
|
|
109803
109869
|
const id = this.nextId++;
|
|
109804
109870
|
const timer = setTimeout(() => {
|
|
109805
109871
|
this.pending.delete(id);
|
|
109806
|
-
reject(
|
|
109872
|
+
reject(
|
|
109873
|
+
// The message carries its own recovery guidance so skills don't have
|
|
109874
|
+
// to re-explain this state: the runtime is reachable but not
|
|
109875
|
+
// answering, which agents otherwise read as a transient worth
|
|
109876
|
+
// retry-looping (each loop iteration waits out this full timeout).
|
|
109877
|
+
new FailureError(
|
|
109878
|
+
`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.`,
|
|
109879
|
+
{
|
|
109880
|
+
error_code: FAILURE_CODES.DEBUGGER_CDP_REQUEST_TIMEOUT,
|
|
109881
|
+
failure_stage: "debugger_cdp_send",
|
|
109882
|
+
failure_area: "tool_server",
|
|
109883
|
+
error_kind: "timeout"
|
|
109884
|
+
}
|
|
109885
|
+
)
|
|
109886
|
+
);
|
|
109807
109887
|
}, timeout);
|
|
109808
109888
|
this.pending.set(id, {
|
|
109809
109889
|
resolve: (result) => {
|
|
@@ -109971,14 +110051,20 @@ var CDPClient = class {
|
|
|
109971
110051
|
else if (action === "disable") this.enabledDomains.delete(domain2);
|
|
109972
110052
|
}
|
|
109973
110053
|
cleanup() {
|
|
110054
|
+
const connectionClosed = () => new FailureError("CDP connection closed", {
|
|
110055
|
+
error_code: FAILURE_CODES.DEBUGGER_CDP_CONNECTION_CLOSED,
|
|
110056
|
+
failure_stage: "debugger_cdp_lifecycle",
|
|
110057
|
+
failure_area: "tool_server",
|
|
110058
|
+
error_kind: "network"
|
|
110059
|
+
});
|
|
109974
110060
|
for (const [, req] of this.pending) {
|
|
109975
110061
|
clearTimeout(req.timer);
|
|
109976
|
-
req.reject(
|
|
110062
|
+
req.reject(connectionClosed());
|
|
109977
110063
|
}
|
|
109978
110064
|
this.pending.clear();
|
|
109979
110065
|
for (const [, binding] of this.pendingBindings) {
|
|
109980
110066
|
clearTimeout(binding.timer);
|
|
109981
|
-
binding.reject(
|
|
110067
|
+
binding.reject(connectionClosed());
|
|
109982
110068
|
}
|
|
109983
110069
|
this.pendingBindings.clear();
|
|
109984
110070
|
this.scripts.clear();
|
|
@@ -114838,6 +114924,45 @@ async function resolveFileInputs(def, body, lookupUpload) {
|
|
|
114838
114924
|
return { args, fileInputs: resolved, cleanup };
|
|
114839
114925
|
}
|
|
114840
114926
|
|
|
114927
|
+
// ../tool-server/src/utils/debugger/device-alias.ts
|
|
114928
|
+
var logicalIdToConnectId = /* @__PURE__ */ new Map();
|
|
114929
|
+
function rememberDeviceAlias(logicalDeviceId, connectDeviceId) {
|
|
114930
|
+
if (!logicalDeviceId || logicalDeviceId === connectDeviceId) return;
|
|
114931
|
+
logicalIdToConnectId.set(logicalDeviceId, connectDeviceId);
|
|
114932
|
+
}
|
|
114933
|
+
function canonicalDeviceId(deviceId) {
|
|
114934
|
+
if (!deviceId) return deviceId;
|
|
114935
|
+
return logicalIdToConnectId.get(deviceId) ?? deviceId;
|
|
114936
|
+
}
|
|
114937
|
+
function forgetDeviceAlias(logicalDeviceId) {
|
|
114938
|
+
if (logicalDeviceId) logicalIdToConnectId.delete(logicalDeviceId);
|
|
114939
|
+
}
|
|
114940
|
+
var logicalKeyedConnectIds = /* @__PURE__ */ new Set();
|
|
114941
|
+
function rememberLogicalKeyedDevice(logicalDeviceId, connectDeviceId) {
|
|
114942
|
+
if (logicalDeviceId && logicalDeviceId === connectDeviceId) {
|
|
114943
|
+
logicalKeyedConnectIds.add(connectDeviceId.toLowerCase());
|
|
114944
|
+
}
|
|
114945
|
+
}
|
|
114946
|
+
function isLogicalKeyedDevice(deviceId) {
|
|
114947
|
+
return deviceId !== void 0 && logicalKeyedConnectIds.has(deviceId.toLowerCase());
|
|
114948
|
+
}
|
|
114949
|
+
function forgetLogicalKeyedDevice(connectDeviceId) {
|
|
114950
|
+
logicalKeyedConnectIds.delete(connectDeviceId.toLowerCase());
|
|
114951
|
+
}
|
|
114952
|
+
|
|
114953
|
+
// ../tool-server/src/utils/invalid-params.ts
|
|
114954
|
+
function deriveInvalidParams(error52, declared) {
|
|
114955
|
+
const out = [];
|
|
114956
|
+
for (const issue2 of error52.issues) {
|
|
114957
|
+
const name = issue2.code === "unrecognized_keys" ? "unrecognized_keys" : String(issue2.path[0] ?? "");
|
|
114958
|
+
if (!name) continue;
|
|
114959
|
+
if (name !== "unrecognized_keys" && !declared.has(name)) continue;
|
|
114960
|
+
if (!out.includes(name)) out.push(name);
|
|
114961
|
+
if (out.length >= 16) break;
|
|
114962
|
+
}
|
|
114963
|
+
return out;
|
|
114964
|
+
}
|
|
114965
|
+
|
|
114841
114966
|
// ../tool-server/src/chromium-server/http-api.ts
|
|
114842
114967
|
var import_express2 = __toESM(require_express2());
|
|
114843
114968
|
init_wrapper();
|
|
@@ -115122,7 +115247,8 @@ function extractDeviceArg(data) {
|
|
|
115122
115247
|
function inferPlatform(deviceId) {
|
|
115123
115248
|
if (!deviceId) return null;
|
|
115124
115249
|
try {
|
|
115125
|
-
|
|
115250
|
+
const canonical = canonicalDeviceId(deviceId) ?? deviceId;
|
|
115251
|
+
return refineTvPlatform(resolveDevice(canonical).platform, canonical);
|
|
115126
115252
|
} catch {
|
|
115127
115253
|
return null;
|
|
115128
115254
|
}
|
|
@@ -115393,7 +115519,7 @@ function createHttpApp(registry2, options) {
|
|
|
115393
115519
|
const name = req.params.name;
|
|
115394
115520
|
const requestStartedAt = performance.now();
|
|
115395
115521
|
const aiMeta = extractAiTelemetryMeta(req);
|
|
115396
|
-
const emitHttpFailure = (signal, parsedDataForMeta = req.body) => {
|
|
115522
|
+
const emitHttpFailure = (signal, parsedDataForMeta = req.body, extraMeta) => {
|
|
115397
115523
|
if (!options?.recordFailure) return;
|
|
115398
115524
|
const failedDeviceArg = extractDeviceArg(parsedDataForMeta);
|
|
115399
115525
|
const platform = inferPlatform(failedDeviceArg);
|
|
@@ -115401,6 +115527,7 @@ function createHttpApp(registry2, options) {
|
|
|
115401
115527
|
name,
|
|
115402
115528
|
{
|
|
115403
115529
|
...platform ? { platform } : {},
|
|
115530
|
+
...extraMeta?.invalid_params?.length ? { invalid_params: extraMeta.invalid_params } : {},
|
|
115404
115531
|
...aiMeta
|
|
115405
115532
|
},
|
|
115406
115533
|
signal,
|
|
@@ -115444,6 +115571,7 @@ function createHttpApp(registry2, options) {
|
|
|
115444
115571
|
if (def.zodSchema) {
|
|
115445
115572
|
const parseResult = def.zodSchema.safeParse(bodyArgs);
|
|
115446
115573
|
if (!parseResult.success) {
|
|
115574
|
+
const declared = new Set(Object.keys(def.zodSchema.shape ?? {}));
|
|
115447
115575
|
emitHttpFailure(
|
|
115448
115576
|
{
|
|
115449
115577
|
error_code: FAILURE_CODES.HTTP_ZOD_VALIDATION_FAILED,
|
|
@@ -115451,7 +115579,8 @@ function createHttpApp(registry2, options) {
|
|
|
115451
115579
|
failure_area: "http",
|
|
115452
115580
|
error_kind: "validation"
|
|
115453
115581
|
},
|
|
115454
|
-
req.body
|
|
115582
|
+
req.body,
|
|
115583
|
+
{ invalid_params: deriveInvalidParams(parseResult.error, declared) }
|
|
115455
115584
|
);
|
|
115456
115585
|
res.status(400).json({ error: parseResult.error.message });
|
|
115457
115586
|
return;
|
|
@@ -116258,6 +116387,22 @@ var chromiumJsRuntimeDebuggerBlueprint = {
|
|
|
116258
116387
|
getDependencies(_payload) {
|
|
116259
116388
|
return { chromium: `${CHROMIUM_CDP_NAMESPACE}:${_payload}` };
|
|
116260
116389
|
},
|
|
116390
|
+
// Deliberately NO recoverable() here. The registry's self-heal disposes the
|
|
116391
|
+
// recovering node before it retries, and this blueprint's dispose closes the
|
|
116392
|
+
// LogFileWriter — which UNLINKS the session's captured console log from disk
|
|
116393
|
+
// (log-file-writer.ts) — so a recovery pass would destroy the logs whether or
|
|
116394
|
+
// not the retry then succeeds. It would also buy nothing: the one window
|
|
116395
|
+
// where a call fails while this node and its ChromiumCdp dependency stay
|
|
116396
|
+
// RUNNING is a tab switch, where CDPClient.reconnect() rejects in-flight
|
|
116397
|
+
// requests with CONNECTION_CLOSED (late sends with NOT_CONNECTED) but
|
|
116398
|
+
// re-points the SAME client object at the new tab — the cached node heals
|
|
116399
|
+
// itself for the next call without any dispose. The failing call surfaces a
|
|
116400
|
+
// classified error that debugger-status maps to a structured "reconnecting"
|
|
116401
|
+
// result with retry-once guidance. A genuinely dead Chromium socket instead
|
|
116402
|
+
// fires ChromiumCdp's own terminated event, whose teardown cascades into this
|
|
116403
|
+
// dependent — the node leaves RUNNING and the next call re-resolves fresh.
|
|
116404
|
+
// (Same log-preservation reasoning as debugger-log-registry's missing socket
|
|
116405
|
+
// gate — see that tool's comment.)
|
|
116261
116406
|
async factory(deps, payload, options) {
|
|
116262
116407
|
const opts = options;
|
|
116263
116408
|
const device = opts?.device;
|
|
@@ -117460,7 +117605,7 @@ async function discoverMetro(port) {
|
|
|
117460
117605
|
statusRes = await fetch(`http://localhost:${port}/status`);
|
|
117461
117606
|
} catch (err) {
|
|
117462
117607
|
throw new FailureError(
|
|
117463
|
-
`Metro at port ${port} is not running (got: ${err instanceof Error ? err.message : String(err)})
|
|
117608
|
+
`Metro at port ${port} is not running (got: ${err instanceof Error ? err.message : String(err)}). Do not retry in a loop \u2014 the result will not change until Metro is started. Start Metro (e.g. \`npx react-native start\` or \`npx expo start\`) or ask the user, wait for it to report ready, then retry once.`,
|
|
117464
117609
|
{
|
|
117465
117610
|
error_code: FAILURE_CODES.DEBUGGER_METRO_NOT_RUNNING,
|
|
117466
117611
|
failure_stage: "debugger_discover_metro_status",
|
|
@@ -117469,10 +117614,24 @@ async function discoverMetro(port) {
|
|
|
117469
117614
|
}
|
|
117470
117615
|
);
|
|
117471
117616
|
}
|
|
117472
|
-
const
|
|
117617
|
+
const notRunning = (stage, err) => new FailureError(
|
|
117618
|
+
`Metro at port ${port} is not running (got: ${err instanceof Error ? err.message : String(err)}). Do not retry in a loop \u2014 the result will not change until Metro is started. Start Metro (e.g. \`npx react-native start\` or \`npx expo start\`) or ask the user, wait for it to report ready, then retry once.`,
|
|
117619
|
+
{
|
|
117620
|
+
error_code: FAILURE_CODES.DEBUGGER_METRO_NOT_RUNNING,
|
|
117621
|
+
failure_stage: stage,
|
|
117622
|
+
failure_area: "tool_server",
|
|
117623
|
+
error_kind: "network"
|
|
117624
|
+
}
|
|
117625
|
+
);
|
|
117626
|
+
let statusText;
|
|
117627
|
+
try {
|
|
117628
|
+
statusText = await statusRes.text();
|
|
117629
|
+
} catch (err) {
|
|
117630
|
+
throw notRunning("debugger_discover_metro_status_body", err);
|
|
117631
|
+
}
|
|
117473
117632
|
if (!statusText.includes("packager-status:running")) {
|
|
117474
117633
|
throw new FailureError(
|
|
117475
|
-
`Metro at port ${port} is not running (got: ${statusText.slice(0, 100)})
|
|
117634
|
+
`Metro at port ${port} is not running (got: ${statusText.slice(0, 100)}). Something else is listening on this port \u2014 it did not answer like Metro. Do not retry in a loop; find the port Metro actually runs on (or start it), then retry once.`,
|
|
117476
117635
|
{
|
|
117477
117636
|
error_code: FAILURE_CODES.DEBUGGER_METRO_NOT_RUNNING,
|
|
117478
117637
|
failure_stage: "debugger_discover_metro_status",
|
|
@@ -117482,14 +117641,19 @@ async function discoverMetro(port) {
|
|
|
117482
117641
|
);
|
|
117483
117642
|
}
|
|
117484
117643
|
const projectRoot = statusRes.headers.get("X-React-Native-Project-Root") ?? "";
|
|
117485
|
-
|
|
117644
|
+
let listRes;
|
|
117645
|
+
try {
|
|
117646
|
+
listRes = await fetch(`http://localhost:${port}/json/list`);
|
|
117647
|
+
} catch (err) {
|
|
117648
|
+
throw notRunning("debugger_discover_metro_list", err);
|
|
117649
|
+
}
|
|
117486
117650
|
const parsed = await listRes.json().catch(() => null);
|
|
117487
117651
|
const targets = (Array.isArray(parsed) ? parsed : []).filter(
|
|
117488
117652
|
(t) => t?.vm !== DECOY_VM
|
|
117489
117653
|
);
|
|
117490
117654
|
if (!targets.length) {
|
|
117491
117655
|
throw new FailureError(
|
|
117492
|
-
`Metro at port ${port} has no CDP targets \u2014 is a React Native app connected
|
|
117656
|
+
`Metro at port ${port} has no CDP targets \u2014 is a React Native app connected? Do not retry immediately \u2014 this will not change until an app attaches. Launch or restart the RN app on the target device (launch-app / restart-app), wait a few seconds for the bundle to load, then retry once. On Android, a missing port reverse-proxy is the most common cause (see the metro-debugger skill's Android prerequisites).`,
|
|
117493
117657
|
{
|
|
117494
117658
|
error_code: FAILURE_CODES.DEBUGGER_METRO_NO_TARGETS,
|
|
117495
117659
|
failure_stage: "debugger_discover_metro_targets",
|
|
@@ -117502,6 +117666,7 @@ async function discoverMetro(port) {
|
|
|
117502
117666
|
}
|
|
117503
117667
|
|
|
117504
117668
|
// ../tool-server/src/utils/debugger/target-selection.ts
|
|
117669
|
+
init_src();
|
|
117505
117670
|
function deviceKey(target) {
|
|
117506
117671
|
const logicalId = target.reactNative?.logicalDeviceId;
|
|
117507
117672
|
if (logicalId) return logicalId;
|
|
@@ -117535,8 +117700,14 @@ function selectTarget(targets, port, options) {
|
|
|
117535
117700
|
const listed = [...distinctDevices.values()].map(
|
|
117536
117701
|
(d) => d.logicalId ? `${d.name ?? "unknown"} (${d.logicalId})` : `${d.name ?? "unknown"} (legacy inspector \u2014 no logicalDeviceId)`
|
|
117537
117702
|
).join(", ");
|
|
117538
|
-
throw new
|
|
117539
|
-
`No debugger target matches device_id "${deviceId}". ${distinctDevices.size} devices are connected to Metro on port ${port}: ${listed}. Re-target with the logicalDeviceId in parentheses \u2014 that is what debugger-connect returns and what subsequent debugger-* calls must pass. A legacy-inspector device (RN 0.72 / Vega) reports none and cannot be singled out of a shared Metro: give it its own Metro port
|
|
117703
|
+
throw new FailureError(
|
|
117704
|
+
`No debugger target matches device_id "${deviceId}". ${distinctDevices.size} devices are connected to Metro on port ${port}: ${listed}. Re-target with the logicalDeviceId in parentheses \u2014 that is what debugger-connect returns and what subsequent debugger-* calls must pass. A legacy-inspector device (RN 0.72 / Vega) reports none and cannot be singled out of a shared Metro: give it its own Metro port.`,
|
|
117705
|
+
{
|
|
117706
|
+
error_code: FAILURE_CODES.DEBUGGER_TARGET_DEVICE_MISMATCH,
|
|
117707
|
+
failure_stage: "debugger_select_target",
|
|
117708
|
+
failure_area: "tool_server",
|
|
117709
|
+
error_kind: "not_found"
|
|
117710
|
+
}
|
|
117540
117711
|
);
|
|
117541
117712
|
}
|
|
117542
117713
|
}
|
|
@@ -117570,32 +117741,6 @@ function normalizeWsUrl(wsUrl, port) {
|
|
|
117570
117741
|
return url2.toString();
|
|
117571
117742
|
}
|
|
117572
117743
|
|
|
117573
|
-
// ../tool-server/src/utils/debugger/device-alias.ts
|
|
117574
|
-
var logicalIdToConnectId = /* @__PURE__ */ new Map();
|
|
117575
|
-
function rememberDeviceAlias(logicalDeviceId, connectDeviceId) {
|
|
117576
|
-
if (!logicalDeviceId || logicalDeviceId === connectDeviceId) return;
|
|
117577
|
-
logicalIdToConnectId.set(logicalDeviceId, connectDeviceId);
|
|
117578
|
-
}
|
|
117579
|
-
function canonicalDeviceId(deviceId) {
|
|
117580
|
-
if (!deviceId) return deviceId;
|
|
117581
|
-
return logicalIdToConnectId.get(deviceId) ?? deviceId;
|
|
117582
|
-
}
|
|
117583
|
-
function forgetDeviceAlias(logicalDeviceId) {
|
|
117584
|
-
if (logicalDeviceId) logicalIdToConnectId.delete(logicalDeviceId);
|
|
117585
|
-
}
|
|
117586
|
-
var logicalKeyedConnectIds = /* @__PURE__ */ new Set();
|
|
117587
|
-
function rememberLogicalKeyedDevice(logicalDeviceId, connectDeviceId) {
|
|
117588
|
-
if (logicalDeviceId && logicalDeviceId === connectDeviceId) {
|
|
117589
|
-
logicalKeyedConnectIds.add(connectDeviceId.toLowerCase());
|
|
117590
|
-
}
|
|
117591
|
-
}
|
|
117592
|
-
function isLogicalKeyedDevice(deviceId) {
|
|
117593
|
-
return deviceId !== void 0 && logicalKeyedConnectIds.has(deviceId.toLowerCase());
|
|
117594
|
-
}
|
|
117595
|
-
function forgetLogicalKeyedDevice(connectDeviceId) {
|
|
117596
|
-
logicalKeyedConnectIds.delete(connectDeviceId.toLowerCase());
|
|
117597
|
-
}
|
|
117598
|
-
|
|
117599
117744
|
// ../tool-server/src/utils/debugger/source-resolver.ts
|
|
117600
117745
|
var fs22 = __toESM(require("node:fs/promises"));
|
|
117601
117746
|
var path19 = __toESM(require("node:path"));
|
|
@@ -117911,6 +118056,25 @@ var jsRuntimeDebuggerBlueprint = {
|
|
|
117911
118056
|
getURN(payload) {
|
|
117912
118057
|
return `${JS_RUNTIME_DEBUGGER_NAMESPACE}:${payload}`;
|
|
117913
118058
|
},
|
|
118059
|
+
// Consulted by the registry's dispose-and-retry-once self-heal, and only for
|
|
118060
|
+
// a node still in RUNNING state. On this blueprint a detected socket death
|
|
118061
|
+
// tears the node down via the terminated cascade before the failing call's
|
|
118062
|
+
// catch runs, so the only recoverable window is the send() guard rejecting
|
|
118063
|
+
// while the WebSocket is CLOSING but the close event has not dispatched yet —
|
|
118064
|
+
// there the request provably never left the host, making a retry safe.
|
|
118065
|
+
// Deliberately NOT recoverable:
|
|
118066
|
+
// - DEBUGGER_CDP_CONNECTION_CLOSED: the request was delivered and may have
|
|
118067
|
+
// taken effect (double-execution risk); on this path the node has also
|
|
118068
|
+
// already left RUNNING when it fires.
|
|
118069
|
+
// - DEBUGGER_CDP_REQUEST_TIMEOUT: the request may have taken effect, and a
|
|
118070
|
+
// hung-but-open runtime (e.g. paused at a breakpoint) is not fixed by
|
|
118071
|
+
// reconnecting.
|
|
118072
|
+
// - Metro discovery / target-selection codes: init-path failures — the node
|
|
118073
|
+
// never reaches RUNNING, so recovery is never consulted, and a retry would
|
|
118074
|
+
// be hopeless anyway.
|
|
118075
|
+
recoverable(error52) {
|
|
118076
|
+
return getFailureSignal(error52)?.error_code === FAILURE_CODES.DEBUGGER_CDP_NOT_CONNECTED;
|
|
118077
|
+
},
|
|
117914
118078
|
async factory(_deps, payload, options) {
|
|
117915
118079
|
const colonIdx = payload.indexOf(":");
|
|
117916
118080
|
if (colonIdx < 0) {
|
|
@@ -129807,46 +129971,158 @@ Use when starting a debug session or before calling other debugger-* tools. Fail
|
|
|
129807
129971
|
|
|
129808
129972
|
// ../tool-server/src/tools/debugger/debugger-status.ts
|
|
129809
129973
|
init_zod();
|
|
129974
|
+
|
|
129975
|
+
// ../tool-server/src/tools/debugger/not-connected.ts
|
|
129976
|
+
init_src();
|
|
129977
|
+
var GUIDANCE = {
|
|
129978
|
+
metro_not_running: "Metro is not running on this port. Do not retry in a loop \u2014 the result will not change until Metro is started. Start Metro (e.g. `npx react-native start` or `npx expo start`) or ask the user, wait for it to report ready, then retry once.",
|
|
129979
|
+
no_app_connected: "Metro is running but no app is attached. Do not retry immediately \u2014 launch or restart the RN app on the target device (launch-app / restart-app), wait a few seconds for the bundle to load, then retry once.",
|
|
129980
|
+
device_mismatch: "The device_id does not match any debugger target on this Metro. Re-target with the logicalDeviceId listed in the detail message, or give the device its own Metro port.",
|
|
129981
|
+
cdp_unreachable: "The runtime's CDP endpoint could not be reached. Verify the app is running (launch-app), then call debugger-connect and retry once.",
|
|
129982
|
+
runtime_unresponsive: "The runtime accepted the debugger connection but did not answer within the timeout \u2014 it is likely frozen, or paused at a breakpoint. Do not retry in a loop (each attempt waits out the full timeout). Check the app; if it is hung, restart it (restart-app), then retry once.",
|
|
129983
|
+
stale_connection: "The cached debugger connection went stale; it has been discarded. Restart the app (restart-app) if it is not running, then call debugger-connect \u2014 the next call reconnects fresh.",
|
|
129984
|
+
reconnecting: "The debugger connection is being re-established (the previous one was torn down or a tab switch is in progress). Wait a moment and retry once."
|
|
129985
|
+
};
|
|
129986
|
+
var NOT_CONNECTED_CODE_MAP = {
|
|
129987
|
+
[FAILURE_CODES.DEBUGGER_METRO_NOT_RUNNING]: "metro_not_running",
|
|
129988
|
+
[FAILURE_CODES.DEBUGGER_METRO_NO_TARGETS]: "no_app_connected",
|
|
129989
|
+
[FAILURE_CODES.DEBUGGER_TARGET_DEVICE_MISMATCH]: "device_mismatch",
|
|
129990
|
+
[FAILURE_CODES.DEBUGGER_CDP_CONNECT_FAILED]: "cdp_unreachable",
|
|
129991
|
+
[FAILURE_CODES.DEBUGGER_CDP_SOCKET_CLOSED_BEFORE_OPEN]: "cdp_unreachable",
|
|
129992
|
+
[FAILURE_CODES.DEBUGGER_CDP_NOT_CONNECTED]: "cdp_unreachable",
|
|
129993
|
+
[FAILURE_CODES.DEBUGGER_CDP_CONNECTION_CLOSED]: "cdp_unreachable",
|
|
129994
|
+
// Reachable from the connect pipeline's enable/binding sends when the target
|
|
129995
|
+
// accepts the socket but its JS runtime never answers (frozen, or paused at a
|
|
129996
|
+
// breakpoint). Post-connect hangs are different: an OPEN socket still reports
|
|
129997
|
+
// status "connected" (see the socket-state gate comment in debugger-status).
|
|
129998
|
+
[FAILURE_CODES.DEBUGGER_CDP_REQUEST_TIMEOUT]: "runtime_unresponsive",
|
|
129999
|
+
[FAILURE_CODES.CHROMIUM_CDP_UNREACHABLE]: "cdp_unreachable",
|
|
130000
|
+
// "Reached but not CDP / malformed answer" — a non-CDP server squatting the
|
|
130001
|
+
// debug port, an HTTP error status, or a non-JSON body. Same precondition
|
|
130002
|
+
// class as the Metro arm's non-Metro-port-occupant (detail names what
|
|
130003
|
+
// actually answered), so it must not escape as a thrown tool failure.
|
|
130004
|
+
[FAILURE_CODES.CHROMIUM_CDP_INVALID_RESPONSE]: "cdp_unreachable",
|
|
130005
|
+
[FAILURE_CODES.CHROMIUM_CDP_NO_PAGE_TARGET]: "cdp_unreachable",
|
|
130006
|
+
[FAILURE_CODES.REGISTRY_SERVICE_TERMINATING]: "reconnecting"
|
|
130007
|
+
};
|
|
130008
|
+
function classifyNotConnected(err) {
|
|
130009
|
+
const code = getFailureSignal(err)?.error_code;
|
|
130010
|
+
return code ? NOT_CONNECTED_CODE_MAP[code] : void 0;
|
|
130011
|
+
}
|
|
130012
|
+
var CHROMIUM_GUIDANCE = {
|
|
130013
|
+
cdp_unreachable: "The app's CDP endpoint could not be reached (or did not answer like CDP \u2014 see detail). launch-app cannot start a Chromium app; make sure the app is running with --remote-debugging-port (for an Electron app, boot-device with electronAppPath relaunches it), then retry once.",
|
|
130014
|
+
runtime_unresponsive: "The app accepted the debugger connection but did not answer within the timeout \u2014 it is likely frozen. Do not retry in a loop (each attempt waits out the full timeout). Restart the app (for an Electron app, boot-device with electronAppPath and force: true), then retry once."
|
|
130015
|
+
};
|
|
130016
|
+
function buildNotConnected(reason, err, params) {
|
|
130017
|
+
const isChromium = params.device_id?.startsWith(CHROMIUM_ID_PREFIX) ?? false;
|
|
130018
|
+
return {
|
|
130019
|
+
status: "not_connected",
|
|
130020
|
+
connected: false,
|
|
130021
|
+
...isChromium ? {} : { port: params.port },
|
|
130022
|
+
reason,
|
|
130023
|
+
detail: err instanceof Error ? err.message : String(err),
|
|
130024
|
+
guidance: (isChromium ? CHROMIUM_GUIDANCE[reason] : void 0) ?? GUIDANCE[reason]
|
|
130025
|
+
};
|
|
130026
|
+
}
|
|
130027
|
+
function trackDebuggerOutcome(tool, outcome, params, ctx) {
|
|
130028
|
+
let platform;
|
|
130029
|
+
try {
|
|
130030
|
+
const deviceId = canonicalDeviceId(params.device_id);
|
|
130031
|
+
platform = deviceId ? classifyDeviceForTelemetry(deviceId) : void 0;
|
|
130032
|
+
} catch {
|
|
130033
|
+
platform = void 0;
|
|
130034
|
+
}
|
|
130035
|
+
track("debugger:tool_outcome", {
|
|
130036
|
+
tool,
|
|
130037
|
+
outcome,
|
|
130038
|
+
...platform ? { platform } : {},
|
|
130039
|
+
...ctx?.toolInvocationId ? { tool_invocation_id: ctx.toolInvocationId } : {}
|
|
130040
|
+
});
|
|
130041
|
+
}
|
|
130042
|
+
async function resolveDebuggerService(registry2, params) {
|
|
130043
|
+
const ref = debuggerServiceRef(params);
|
|
130044
|
+
return typeof ref === "string" ? registry2.resolveService(ref) : registry2.resolveService(ref.urn, ref.options);
|
|
130045
|
+
}
|
|
130046
|
+
function isDebuggerNotConnectedResult(toolId, result) {
|
|
130047
|
+
return (toolId === "debugger-status" || toolId === "debugger-log-registry") && typeof result === "object" && result !== null && result.status === "not_connected";
|
|
130048
|
+
}
|
|
130049
|
+
|
|
130050
|
+
// ../tool-server/src/tools/debugger/debugger-status.ts
|
|
129810
130051
|
var zodSchema30 = external_exports.object({
|
|
129811
130052
|
port: external_exports.coerce.number().default(8081).describe("Metro server port (ignored for Chromium)"),
|
|
129812
130053
|
device_id: external_exports.string().describe(
|
|
129813
130054
|
"Device id from list-devices \u2014 the SAME id you passed to debugger-connect (iOS simulator UDID, Android serial, Vega serial, or Chromium device id). The logicalDeviceId debugger-connect returns also resolves here, but prefer the stable list-devices id."
|
|
129814
130055
|
)
|
|
129815
130056
|
});
|
|
129816
|
-
|
|
129817
|
-
|
|
129818
|
-
|
|
129819
|
-
|
|
129820
|
-
|
|
129821
|
-
|
|
129822
|
-
|
|
129823
|
-
|
|
129824
|
-
|
|
129825
|
-
|
|
129826
|
-
|
|
129827
|
-
|
|
129828
|
-
|
|
129829
|
-
|
|
129830
|
-
|
|
129831
|
-
|
|
129832
|
-
|
|
129833
|
-
|
|
129834
|
-
|
|
129835
|
-
|
|
129836
|
-
|
|
129837
|
-
|
|
129838
|
-
|
|
129839
|
-
|
|
129840
|
-
|
|
129841
|
-
|
|
129842
|
-
|
|
129843
|
-
|
|
129844
|
-
|
|
129845
|
-
|
|
129846
|
-
|
|
130057
|
+
function createDebuggerStatusTool(registry2) {
|
|
130058
|
+
return {
|
|
130059
|
+
id: "debugger-status",
|
|
130060
|
+
interaction: {
|
|
130061
|
+
startedMsg: () => "Checking JavaScript debugger",
|
|
130062
|
+
completedMsg: ({ result }) => result.status === "connected" ? "Checked JavaScript debugger" : "JavaScript debugger is not connected",
|
|
130063
|
+
failedMsg: ({ failureSignal: failureSignal2 }) => `Failed to check JavaScript debugger: ${failureSignal2.error_code}`
|
|
130064
|
+
},
|
|
130065
|
+
description: `Get JS runtime debugger connection status and diagnostic info.
|
|
130066
|
+
Use when you need to verify connectivity before using other debugger tools. Never fails when the runtime is simply unreachable \u2014 it returns a discriminated result instead:
|
|
130067
|
+
- { status: "connected", ... } with port, projectRoot (empty on Chromium and on legacy Metro, e.g. Vega), deviceName, appName, logicalDeviceId (absent on Vega), isNewDebugger (false on the legacy inspector), connected flag, loadedScripts count, and sourceMapReady (always true \u2014 waits for pending source maps before returning; no-op on Chromium).
|
|
130068
|
+
- { status: "not_connected", connected: false, reason, detail, guidance } (port omitted on Chromium) when Metro is not running (reason "metro_not_running"), no app is attached ("no_app_connected"), the device_id matches no target ("device_mismatch"), the CDP endpoint is unreachable or answered malformed ("cdp_unreachable"), the runtime accepted the connection but never answered ("runtime_unresponsive"), the cached connection went stale ("stale_connection"), or a reconnect is in flight ("reconnecting"). Follow the guidance field \u2014 do not retry in a loop.`,
|
|
130069
|
+
zodSchema: zodSchema30,
|
|
130070
|
+
capability: DEBUGGER_TOOL_CAPABILITY,
|
|
130071
|
+
// Resolved manually in execute so a not-connected precondition becomes a
|
|
130072
|
+
// structured result instead of a service-resolution tool failure.
|
|
130073
|
+
services: () => ({}),
|
|
130074
|
+
async execute(_services, params, ctx) {
|
|
130075
|
+
try {
|
|
130076
|
+
const api = await resolveDebuggerService(registry2, params);
|
|
130077
|
+
await api.sourceMaps.waitForPending();
|
|
130078
|
+
if (!api.cdp.isConnected()) {
|
|
130079
|
+
const isChromium = params.device_id?.startsWith(CHROMIUM_ID_PREFIX) ?? false;
|
|
130080
|
+
if (isChromium) {
|
|
130081
|
+
const result = buildNotConnected(
|
|
130082
|
+
"reconnecting",
|
|
130083
|
+
new Error("CDP socket is reconnecting (tab switch in progress)"),
|
|
130084
|
+
params
|
|
130085
|
+
);
|
|
130086
|
+
trackDebuggerOutcome("debugger-status", "reconnecting", params, ctx);
|
|
130087
|
+
return result;
|
|
130088
|
+
}
|
|
130089
|
+
trackDebuggerOutcome("debugger-status", "stale_connection", params, ctx);
|
|
130090
|
+
const ref = debuggerServiceRef(params);
|
|
130091
|
+
await registry2.disposeService(typeof ref === "string" ? ref : ref.urn).catch(() => {
|
|
130092
|
+
});
|
|
130093
|
+
return buildNotConnected(
|
|
130094
|
+
"stale_connection",
|
|
130095
|
+
new Error("Cached debugger connection is no longer open"),
|
|
130096
|
+
params
|
|
130097
|
+
);
|
|
130098
|
+
}
|
|
130099
|
+
trackDebuggerOutcome("debugger-status", "connected", params, ctx);
|
|
130100
|
+
return {
|
|
130101
|
+
status: "connected",
|
|
130102
|
+
port: api.port,
|
|
130103
|
+
projectRoot: api.projectRoot,
|
|
130104
|
+
deviceName: api.deviceName,
|
|
130105
|
+
appName: api.appName,
|
|
130106
|
+
logicalDeviceId: api.logicalDeviceId,
|
|
130107
|
+
isNewDebugger: api.isNewDebugger,
|
|
130108
|
+
connected: true,
|
|
130109
|
+
loadedScripts: api.cdp.getLoadedScripts().size,
|
|
130110
|
+
enabledDomains: [...api.cdp.getEnabledDomains()],
|
|
130111
|
+
sourceMapReady: true
|
|
130112
|
+
};
|
|
130113
|
+
} catch (err) {
|
|
130114
|
+
const reason = classifyNotConnected(err);
|
|
130115
|
+
if (!reason) throw err;
|
|
130116
|
+
trackDebuggerOutcome("debugger-status", reason, params, ctx);
|
|
130117
|
+
return buildNotConnected(reason, err, params);
|
|
130118
|
+
}
|
|
130119
|
+
}
|
|
130120
|
+
};
|
|
130121
|
+
}
|
|
129847
130122
|
|
|
129848
130123
|
// ../tool-server/src/tools/debugger/debugger-evaluate.ts
|
|
129849
130124
|
init_zod();
|
|
130125
|
+
init_src();
|
|
129850
130126
|
var zodSchema31 = external_exports.object({
|
|
129851
130127
|
port: external_exports.coerce.number().default(8081).describe("Metro server port (ignored for Chromium)"),
|
|
129852
130128
|
device_id: external_exports.string().describe(
|
|
@@ -129870,7 +130146,24 @@ Returns the evaluation result as a JSON-serializable value, along with deviceNam
|
|
|
129870
130146
|
}),
|
|
129871
130147
|
async execute(services, params) {
|
|
129872
130148
|
const api = services.debugger;
|
|
129873
|
-
|
|
130149
|
+
let result;
|
|
130150
|
+
try {
|
|
130151
|
+
result = await api.cdp.evaluate(params.expression);
|
|
130152
|
+
} catch (err) {
|
|
130153
|
+
if (err instanceof Error && getFailureSignal(err)?.error_code === FAILURE_CODES.DEBUGGER_CDP_RUNTIME_EXCEPTION) {
|
|
130154
|
+
throw new FailureError(
|
|
130155
|
+
err.message,
|
|
130156
|
+
{
|
|
130157
|
+
error_code: FAILURE_CODES.DEBUGGER_EVALUATE_EXPRESSION_THREW,
|
|
130158
|
+
failure_stage: "debugger_evaluate_expression",
|
|
130159
|
+
failure_area: "tool_server",
|
|
130160
|
+
error_kind: "unknown"
|
|
130161
|
+
},
|
|
130162
|
+
{ cause: err }
|
|
130163
|
+
);
|
|
130164
|
+
}
|
|
130165
|
+
throw err;
|
|
130166
|
+
}
|
|
129874
130167
|
return {
|
|
129875
130168
|
result,
|
|
129876
130169
|
deviceName: api.deviceName,
|
|
@@ -131363,48 +131656,60 @@ var zodSchema35 = external_exports.object({
|
|
|
131363
131656
|
"Device id from list-devices \u2014 the SAME id you passed to debugger-connect (iOS simulator UDID, Android serial, Vega serial, or Chromium device id). The logicalDeviceId debugger-connect returns also resolves here, but prefer the stable list-devices id."
|
|
131364
131657
|
)
|
|
131365
131658
|
});
|
|
131366
|
-
|
|
131367
|
-
|
|
131368
|
-
|
|
131369
|
-
|
|
131370
|
-
|
|
131371
|
-
|
|
131372
|
-
|
|
131373
|
-
|
|
131659
|
+
function createDebuggerLogRegistryTool(registry2) {
|
|
131660
|
+
return {
|
|
131661
|
+
id: "debugger-log-registry",
|
|
131662
|
+
interaction: {
|
|
131663
|
+
startedMsg: () => "Reading app logs",
|
|
131664
|
+
completedMsg: ({ result }) => result.status === "connected" ? "Read app logs" : "JavaScript debugger is not connected \u2014 no logs captured",
|
|
131665
|
+
failedMsg: ({ failureSignal: failureSignal2 }) => `Failed to read app logs: ${failureSignal2.error_code}`
|
|
131666
|
+
},
|
|
131667
|
+
description: `Get a summary of all console logs captured from the app's JS runtime.
|
|
131374
131668
|
Returns the log file path, entry counts by level, and message clusters (grouped by similarity). Works against Hermes (iOS / Android / Vega) and V8 (Chromium).
|
|
131375
|
-
Use when investigating warnings, errors, or unexpected output \u2014 call this first for an overview, then read the returned file for details. Returns empty stats if no log data has been captured yet \u2014 but check { note }, which is present only when the stats are empty BECAUSE a stop-all-simulator-servers tore the previous debugger session down and deleted its log file. Absent that note, empty really does mean the app has logged nothing
|
|
131376
|
-
|
|
131377
|
-
|
|
131378
|
-
|
|
131379
|
-
|
|
131380
|
-
|
|
131381
|
-
|
|
131382
|
-
|
|
131383
|
-
|
|
131384
|
-
|
|
131385
|
-
|
|
131386
|
-
|
|
131387
|
-
|
|
131388
|
-
|
|
131389
|
-
|
|
131390
|
-
|
|
131391
|
-
|
|
131392
|
-
|
|
131393
|
-
|
|
131394
|
-
|
|
131395
|
-
|
|
131396
|
-
|
|
131397
|
-
|
|
131398
|
-
|
|
131399
|
-
|
|
131400
|
-
|
|
131401
|
-
|
|
131669
|
+
Use when investigating warnings, errors, or unexpected output \u2014 call this first for an overview, then read the returned file for details. Returns empty stats if no log data has been captured yet \u2014 but check { note }, which is present only when the stats are empty BECAUSE a stop-all-simulator-servers tore the previous debugger session down and deleted its log file. Absent that note, empty really does mean the app has logged nothing.
|
|
131670
|
+
When the debugger cannot be reached, this tool does not fail: it returns { status: "not_connected", reason, detail, guidance } with NO log file \u2014 follow the guidance (do not retry in a loop, and do not try to read a log file from this state). A "connected" result's stats may come from a session whose socket has since died \u2014 use debugger-status, not this tool, to judge debugger health.`,
|
|
131671
|
+
zodSchema: zodSchema35,
|
|
131672
|
+
capability: DEBUGGER_TOOL_CAPABILITY,
|
|
131673
|
+
// Resolved manually in execute so a not-connected precondition becomes a
|
|
131674
|
+
// structured result instead of a service-resolution tool failure.
|
|
131675
|
+
services: () => ({}),
|
|
131676
|
+
async execute(_services, params, ctx) {
|
|
131677
|
+
try {
|
|
131678
|
+
const api = await resolveDebuggerService(registry2, params);
|
|
131679
|
+
const stats = api.logWriter.getStats();
|
|
131680
|
+
const clusters = api.logWriter.getClusters(20);
|
|
131681
|
+
trackDebuggerOutcome("debugger-log-registry", "connected", params, ctx);
|
|
131682
|
+
const response = {
|
|
131683
|
+
status: "connected",
|
|
131684
|
+
...stats,
|
|
131685
|
+
clusters,
|
|
131686
|
+
deviceName: api.deviceName,
|
|
131687
|
+
appName: api.appName,
|
|
131688
|
+
logicalDeviceId: api.logicalDeviceId
|
|
131689
|
+
};
|
|
131690
|
+
if (stats.totalEntries === 0) {
|
|
131691
|
+
const aliases = [
|
|
131692
|
+
canonicalDeviceId(params.device_id),
|
|
131693
|
+
params.device_id,
|
|
131694
|
+
api.logicalDeviceId
|
|
131695
|
+
].filter((id) => id !== void 0);
|
|
131696
|
+
let reaped2;
|
|
131697
|
+
for (const id of new Set(aliases)) {
|
|
131698
|
+
const entry = takeReapedSession("js-runtime-debugger", id);
|
|
131699
|
+
reaped2 ??= entry;
|
|
131700
|
+
}
|
|
131701
|
+
if (reaped2) response.note = describeReapedSession(reaped2, "JS-runtime debugger session");
|
|
131702
|
+
}
|
|
131703
|
+
return response;
|
|
131704
|
+
} catch (err) {
|
|
131705
|
+
const reason = classifyNotConnected(err);
|
|
131706
|
+
if (!reason) throw err;
|
|
131707
|
+
trackDebuggerOutcome("debugger-log-registry", reason, params, ctx);
|
|
131708
|
+
return buildNotConnected(reason, err, params);
|
|
131402
131709
|
}
|
|
131403
|
-
if (reaped2) response.note = describeReapedSession(reaped2, "JS-runtime debugger session");
|
|
131404
131710
|
}
|
|
131405
|
-
|
|
131406
|
-
|
|
131407
|
-
};
|
|
131711
|
+
};
|
|
131712
|
+
}
|
|
131408
131713
|
|
|
131409
131714
|
// ../tool-server/src/tools/network/network-logs.ts
|
|
131410
131715
|
init_zod();
|
|
@@ -135709,14 +136014,14 @@ function parseHangsXml(xml) {
|
|
|
135709
136014
|
function parseLeaksXml(xml) {
|
|
135710
136015
|
const leaks = [];
|
|
135711
136016
|
const rowRe = /<row\s+([^>]*?)\/>/g;
|
|
135712
|
-
let
|
|
135713
|
-
while ((
|
|
135714
|
-
const objectType = attr(
|
|
135715
|
-
const sizeStr = attr(
|
|
136017
|
+
let rm8;
|
|
136018
|
+
while ((rm8 = rowRe.exec(xml)) !== null) {
|
|
136019
|
+
const objectType = attr(rm8[0], "leaked-object") ?? "Unknown";
|
|
136020
|
+
const sizeStr = attr(rm8[0], "size");
|
|
135716
136021
|
const sizeBytes = sizeStr ? parseInt(sizeStr, 10) : 0;
|
|
135717
|
-
const responsibleFrame = attr(
|
|
135718
|
-
const responsibleLibrary = attr(
|
|
135719
|
-
const countStr = attr(
|
|
136022
|
+
const responsibleFrame = attr(rm8[0], "responsible-frame") ?? "Unknown";
|
|
136023
|
+
const responsibleLibrary = attr(rm8[0], "responsible-library") ?? "";
|
|
136024
|
+
const countStr = attr(rm8[0], "count");
|
|
135720
136025
|
const count2 = countStr ? parseInt(countStr, 10) : 1;
|
|
135721
136026
|
leaks.push({
|
|
135722
136027
|
objectType,
|
|
@@ -142440,10 +142745,18 @@ function waitToYaml(condition, selector, expectedText, textMatch, timeoutMs) {
|
|
|
142440
142745
|
if (timeoutMs !== void 0) body.timeout = timeoutMs;
|
|
142441
142746
|
return body;
|
|
142442
142747
|
}
|
|
142748
|
+
function idleToYaml(step) {
|
|
142749
|
+
const body = { idle: true };
|
|
142750
|
+
if (step.stableFor !== void 0) body.stableFor = step.stableFor;
|
|
142751
|
+
if (step.timeout !== void 0) body.timeout = step.timeout;
|
|
142752
|
+
return { await: body };
|
|
142753
|
+
}
|
|
142443
142754
|
function toYamlStep(step) {
|
|
142444
142755
|
switch (step.kind) {
|
|
142445
142756
|
case "echo":
|
|
142446
142757
|
return { echo: step.message };
|
|
142758
|
+
case "idle":
|
|
142759
|
+
return idleToYaml(step);
|
|
142447
142760
|
case "launch":
|
|
142448
142761
|
return { launch: step.app };
|
|
142449
142762
|
case "run":
|
|
@@ -142735,16 +143048,14 @@ var TEXT_MATCH_MODES = Object.keys({
|
|
|
142735
143048
|
});
|
|
142736
143049
|
var SCROLL_DIRECTIONS = ["up", "down", "left", "right"];
|
|
142737
143050
|
function parseWaitFields(raw, kind) {
|
|
143051
|
+
const legalKeys = kind === "await" ? [...WAIT_CONDITIONS, IDLE_CONDITION] : WAIT_CONDITIONS;
|
|
142738
143052
|
if (raw === null || typeof raw !== "object") {
|
|
142739
|
-
badEntry({ [kind]: raw }, `${kind} needs a condition (${
|
|
143053
|
+
badEntry({ [kind]: raw }, `${kind} needs a condition (${legalKeys.join(", ")})`);
|
|
142740
143054
|
}
|
|
142741
143055
|
const b = raw;
|
|
142742
143056
|
const present = WAIT_CONDITIONS.filter((c) => c in b);
|
|
142743
143057
|
if (present.length !== 1) {
|
|
142744
|
-
badEntry(
|
|
142745
|
-
{ [kind]: b },
|
|
142746
|
-
`${kind} needs exactly one condition key (${WAIT_CONDITIONS.join(", ")})`
|
|
142747
|
-
);
|
|
143058
|
+
badEntry({ [kind]: b }, `${kind} needs exactly one condition key (${legalKeys.join(", ")})`);
|
|
142748
143059
|
}
|
|
142749
143060
|
const condition = present[0];
|
|
142750
143061
|
let timeout;
|
|
@@ -142755,13 +143066,7 @@ function parseWaitFields(raw, kind) {
|
|
|
142755
143066
|
"assert has no timeout \u2014 it is an immediate check; use `await` for a timed wait"
|
|
142756
143067
|
);
|
|
142757
143068
|
}
|
|
142758
|
-
|
|
142759
|
-
badEntry(
|
|
142760
|
-
{ [kind]: b },
|
|
142761
|
-
"await.timeout needs a positive number of milliseconds (e.g. `timeout: 10000`)"
|
|
142762
|
-
);
|
|
142763
|
-
}
|
|
142764
|
-
timeout = b.timeout;
|
|
143069
|
+
timeout = parseAwaitTimeout({ [kind]: b }, b.timeout);
|
|
142765
143070
|
}
|
|
142766
143071
|
rejectUnknownKeys(
|
|
142767
143072
|
{ [kind]: b },
|
|
@@ -142806,6 +143111,76 @@ function parseWaitFields(raw, kind) {
|
|
|
142806
143111
|
}
|
|
142807
143112
|
return { condition, selector: parseSelector(b[condition], `${kind}.${condition}`), timeout };
|
|
142808
143113
|
}
|
|
143114
|
+
var IDLE_CONDITION = "idle";
|
|
143115
|
+
var IDLE_DEFAULT_TIMEOUT_MS = 7500;
|
|
143116
|
+
var IDLE_DEFAULT_STABLE_FOR_MS = 250;
|
|
143117
|
+
var IDLE_POLL_MS = 200;
|
|
143118
|
+
var IDLE_MIN_STILL_INTERVALS = 2;
|
|
143119
|
+
var IDLE_SETTLE_SPAN_MS = IDLE_MIN_STILL_INTERVALS * IDLE_POLL_MS;
|
|
143120
|
+
function idleMinimumTimeoutMs(stableFor) {
|
|
143121
|
+
return Math.max(IDLE_SETTLE_SPAN_MS, stableFor) + IDLE_POLL_MS;
|
|
143122
|
+
}
|
|
143123
|
+
var IDLE_MAX_STABLE_FOR_MS = 6e5;
|
|
143124
|
+
function parseAwaitTimeout(entry, value) {
|
|
143125
|
+
if (typeof value !== "number" || !Number.isFinite(value) || value <= 0) {
|
|
143126
|
+
badEntry(
|
|
143127
|
+
entry,
|
|
143128
|
+
"await.timeout needs a positive number of milliseconds (e.g. `timeout: 10000`)"
|
|
143129
|
+
);
|
|
143130
|
+
}
|
|
143131
|
+
return value;
|
|
143132
|
+
}
|
|
143133
|
+
function parseBoundedMs(entry, value, where, max) {
|
|
143134
|
+
if (typeof value !== "number" || !Number.isInteger(value) || value < 0 || value > max) {
|
|
143135
|
+
badEntry(entry, `${where} needs an integer between 0 and ${max} (milliseconds)`);
|
|
143136
|
+
}
|
|
143137
|
+
return value;
|
|
143138
|
+
}
|
|
143139
|
+
function parseIdleFields(raw, kind) {
|
|
143140
|
+
const entry = { [kind]: raw };
|
|
143141
|
+
if (kind !== "await") {
|
|
143142
|
+
const mixed = WAIT_CONDITIONS.filter((c) => c in raw);
|
|
143143
|
+
badEntry(
|
|
143144
|
+
entry,
|
|
143145
|
+
"idle has no assert form \u2014 it waits for the screen to stop changing, which is an `await`" + (mixed.length > 0 ? `. Give it its own step as \`await: { idle: true }\` and leave \`${mixed.join(
|
|
143146
|
+
"`, `"
|
|
143147
|
+
)}\` in the assert \u2014 a step checks exactly one condition` : "")
|
|
143148
|
+
);
|
|
143149
|
+
}
|
|
143150
|
+
rejectUnknownKeys(entry, raw, ["idle", "stableFor", "timeout"], kind);
|
|
143151
|
+
if (raw.idle !== true) {
|
|
143152
|
+
badEntry(entry, "idle takes only `true` (`await: { idle: true }`)");
|
|
143153
|
+
}
|
|
143154
|
+
const step = { kind: "idle" };
|
|
143155
|
+
if ("timeout" in raw) step.timeout = parseAwaitTimeout(entry, raw.timeout);
|
|
143156
|
+
if (raw.stableFor !== void 0) {
|
|
143157
|
+
step.stableFor = parseBoundedMs(entry, raw.stableFor, "idle.stableFor", IDLE_MAX_STABLE_FOR_MS);
|
|
143158
|
+
}
|
|
143159
|
+
const timeoutMs = step.timeout ?? IDLE_DEFAULT_TIMEOUT_MS;
|
|
143160
|
+
const stableFor = step.stableFor ?? IDLE_DEFAULT_STABLE_FOR_MS;
|
|
143161
|
+
const needed = idleMinimumTimeoutMs(stableFor);
|
|
143162
|
+
if (timeoutMs < needed) {
|
|
143163
|
+
badEntry(
|
|
143164
|
+
entry,
|
|
143165
|
+
`idle needs a timeout of at least ${needed}ms to hold still for ${step.stableFor === void 0 ? `the default ` : ``}${stableFor}ms: a settle is ${IDLE_MIN_STILL_INTERVALS + 1} reads spanning ${IDLE_MIN_STILL_INTERVALS} ${IDLE_POLL_MS}ms polls, and the hold is counted across those polls rather than after them \u2014 so the wait has to contain whichever of the two is longer, plus the ${IDLE_POLL_MS}ms of budget the closing round has to have left to be allowed to start. Raise \`timeout\`${step.stableFor === void 0 ? "" : " or lower `stableFor`"}`
|
|
143166
|
+
);
|
|
143167
|
+
}
|
|
143168
|
+
return step;
|
|
143169
|
+
}
|
|
143170
|
+
function isIdleCondition(raw, kind) {
|
|
143171
|
+
if (raw === null || typeof raw !== "object" || Array.isArray(raw)) return false;
|
|
143172
|
+
const body = raw;
|
|
143173
|
+
if (!(IDLE_CONDITION in body)) return false;
|
|
143174
|
+
if (kind === "assert") return true;
|
|
143175
|
+
const selectorConditions = WAIT_CONDITIONS.filter((c) => c in body);
|
|
143176
|
+
if (selectorConditions.length > 0) {
|
|
143177
|
+
badEntry(
|
|
143178
|
+
{ [kind]: body },
|
|
143179
|
+
`${kind} mixes \`${IDLE_CONDITION}\` with \`${selectorConditions.join("`, `")}\` \u2014 a step checks exactly one condition`
|
|
143180
|
+
);
|
|
143181
|
+
}
|
|
143182
|
+
return true;
|
|
143183
|
+
}
|
|
142809
143184
|
var LAUNCH_PLATFORMS = ["ios", "android", "chromium", "vega"];
|
|
142810
143185
|
var LAUNCH_MAP_KEYS = ["native", ...LAUNCH_PLATFORMS];
|
|
142811
143186
|
function parseChromiumLaunch(raw) {
|
|
@@ -143019,6 +143394,12 @@ function parseWhenCondition(raw) {
|
|
|
143019
143394
|
badEntry({ when: raw }, `when needs exactly one condition key (${conditionKeys})`);
|
|
143020
143395
|
}
|
|
143021
143396
|
const b = raw;
|
|
143397
|
+
if (IDLE_CONDITION in b) {
|
|
143398
|
+
badEntry(
|
|
143399
|
+
{ when: raw },
|
|
143400
|
+
"when has no idle form \u2014 stillness is a wait, and a guard asks what is on the screen now. Put `await: { idle: true }` before the block instead"
|
|
143401
|
+
);
|
|
143402
|
+
}
|
|
143022
143403
|
const present = [...WAIT_CONDITIONS, "platform"].filter((c) => c in b);
|
|
143023
143404
|
if (present.length !== 1) {
|
|
143024
143405
|
badEntry({ when: raw }, `when needs exactly one condition key (${conditionKeys})`);
|
|
@@ -143128,6 +143509,9 @@ function fromYamlStep(raw, whenDepth = 0) {
|
|
|
143128
143509
|
}
|
|
143129
143510
|
const kinds = STEP_DIRECTIVE_KEYS.filter((k) => k in entry);
|
|
143130
143511
|
if (kinds.length === 0) {
|
|
143512
|
+
if (IDLE_CONDITION in entry) {
|
|
143513
|
+
badEntry(raw, `idle is a condition, not a step kind \u2014 write it as \`await: { idle: true }\``);
|
|
143514
|
+
}
|
|
143131
143515
|
const hint = Object.keys(entry).map((k) => closestKey(k, STEP_DIRECTIVE_KEYS)).find((h) => h !== null);
|
|
143132
143516
|
badEntry(raw, `unrecognized step kind${hint ? ` (did you mean \`${hint}\`?)` : ""}`);
|
|
143133
143517
|
}
|
|
@@ -143175,10 +143559,18 @@ function fromYamlStep(raw, whenDepth = 0) {
|
|
|
143175
143559
|
return step;
|
|
143176
143560
|
}
|
|
143177
143561
|
if ("await" in raw) {
|
|
143178
|
-
|
|
143562
|
+
const body = raw.await;
|
|
143563
|
+
if (isIdleCondition(body, "await")) {
|
|
143564
|
+
return parseIdleFields(body, "await");
|
|
143565
|
+
}
|
|
143566
|
+
return { kind: "await", ...parseWaitFields(body, "await") };
|
|
143179
143567
|
}
|
|
143180
143568
|
if ("assert" in raw) {
|
|
143181
|
-
|
|
143569
|
+
const body = raw.assert;
|
|
143570
|
+
if (isIdleCondition(body, "assert")) {
|
|
143571
|
+
return parseIdleFields(body, "assert");
|
|
143572
|
+
}
|
|
143573
|
+
return { kind: "assert", ...parseWaitFields(body, "assert") };
|
|
143182
143574
|
}
|
|
143183
143575
|
if ("wait" in raw) {
|
|
143184
143576
|
const ms = Number(raw.wait);
|
|
@@ -143709,6 +144101,7 @@ function stepRequiresDevice(registry2, step) {
|
|
|
143709
144101
|
case "type":
|
|
143710
144102
|
case "await":
|
|
143711
144103
|
case "assert":
|
|
144104
|
+
case "idle":
|
|
143712
144105
|
case "scroll-to":
|
|
143713
144106
|
case "pinch":
|
|
143714
144107
|
case "rotate":
|
|
@@ -144563,6 +144956,8 @@ function summarizeSteps(flow) {
|
|
|
144563
144956
|
return `${n}. rotate: by ${step.by}\xB0${step.selector ? ` on ${selectorLabel(step.selector)}` : ""}`;
|
|
144564
144957
|
case "snapshot":
|
|
144565
144958
|
return `${n}. snapshot: ${step.name}`;
|
|
144959
|
+
case "idle":
|
|
144960
|
+
return `${n}. await: screen idle`;
|
|
144566
144961
|
case "tool":
|
|
144567
144962
|
default:
|
|
144568
144963
|
return `${n}. tool: ${step.name} ${renderToolArgs(step.args)}`;
|
|
@@ -144572,7 +144967,7 @@ function summarizeSteps(flow) {
|
|
|
144572
144967
|
|
|
144573
144968
|
// ../tool-server/src/tools/flows/flow-run.ts
|
|
144574
144969
|
init_zod();
|
|
144575
|
-
var
|
|
144970
|
+
var fs49 = __toESM(require("node:fs/promises"));
|
|
144576
144971
|
var path35 = __toESM(require("node:path"));
|
|
144577
144972
|
init_src();
|
|
144578
144973
|
|
|
@@ -144644,6 +145039,122 @@ function nestedOrchestratorOutcome(tool, result) {
|
|
|
144644
145039
|
return void 0;
|
|
144645
145040
|
}
|
|
144646
145041
|
|
|
145042
|
+
// ../tool-server/src/tools/flows/flow-pixels.ts
|
|
145043
|
+
var fs46 = __toESM(require("node:fs/promises"));
|
|
145044
|
+
var import_pngjs2 = __toESM(require_png());
|
|
145045
|
+
init_adb();
|
|
145046
|
+
var CAPTURE_SCALE = 0.25;
|
|
145047
|
+
var PIXEL_THRESHOLD = 0.03;
|
|
145048
|
+
var MAX_RGB_DISTANCE_SQUARED = 255 * 255 * 3;
|
|
145049
|
+
var PIXEL_THRESHOLD_SQUARED = PIXEL_THRESHOLD * PIXEL_THRESHOLD * MAX_RGB_DISTANCE_SQUARED;
|
|
145050
|
+
var MOTION_FRACTION = 2e-3;
|
|
145051
|
+
var MOTION_MIN_PIXELS = 100;
|
|
145052
|
+
var MOTION_MIN_PIXELS_FRAME_SHARE = 0.1;
|
|
145053
|
+
var LOCALIZED_MOTION_MIN_PIXELS = 10;
|
|
145054
|
+
var STATUS_BAR_MASK_FRACTION = 0.06;
|
|
145055
|
+
async function statusBarMaskFraction(device) {
|
|
145056
|
+
if (device.platform === "android") {
|
|
145057
|
+
return await isAndroidTv(device.id) ? 0 : STATUS_BAR_MASK_FRACTION;
|
|
145058
|
+
}
|
|
145059
|
+
if (device.platform === "ios-remote") return STATUS_BAR_MASK_FRACTION;
|
|
145060
|
+
if (device.platform !== "ios") return 0;
|
|
145061
|
+
return await isTvOsSimulator(device.id) ? 0 : STATUS_BAR_MASK_FRACTION;
|
|
145062
|
+
}
|
|
145063
|
+
var FIRST_CAPTURE_COMPLETION_MARGIN_MS = 500;
|
|
145064
|
+
var FIRST_PIXEL_CAPTURE_TIMEOUT_MS = FIRST_FRAME_WAIT_MS + FIRST_CAPTURE_COMPLETION_MARGIN_MS;
|
|
145065
|
+
var PIXEL_CAPTURE_TIMEOUT_MS = 2e3;
|
|
145066
|
+
function pixelCaptureTimeoutMs(device, firstCapture) {
|
|
145067
|
+
const warmFromTheStart = device.platform === "chromium" || device.platform === "vega";
|
|
145068
|
+
return firstCapture && !warmFromTheStart ? FIRST_PIXEL_CAPTURE_TIMEOUT_MS : PIXEL_CAPTURE_TIMEOUT_MS;
|
|
145069
|
+
}
|
|
145070
|
+
async function captureChromiumPng(env) {
|
|
145071
|
+
const ref = chromiumCdpRef(env.device);
|
|
145072
|
+
const api = await env.registry.resolveService(ref.urn, ref.options);
|
|
145073
|
+
const { width, height } = api.getViewport();
|
|
145074
|
+
const { x, y } = await chromiumScrollOffset(api);
|
|
145075
|
+
const shot = await api.cdp.send("Page.captureScreenshot", {
|
|
145076
|
+
format: "png",
|
|
145077
|
+
captureBeyondViewport: false,
|
|
145078
|
+
clip: { x, y, width, height, scale: CAPTURE_SCALE }
|
|
145079
|
+
});
|
|
145080
|
+
if (!shot.data) throw new Error("Page.captureScreenshot returned no data");
|
|
145081
|
+
return Buffer.from(shot.data, "base64");
|
|
145082
|
+
}
|
|
145083
|
+
async function chromiumScrollOffset(api) {
|
|
145084
|
+
try {
|
|
145085
|
+
const metrics = await api.cdp.send("Page.getLayoutMetrics");
|
|
145086
|
+
const vp = metrics.cssVisualViewport ?? metrics.cssLayoutViewport ?? metrics.layoutViewport;
|
|
145087
|
+
const x = vp?.pageX;
|
|
145088
|
+
const y = vp?.pageY;
|
|
145089
|
+
return {
|
|
145090
|
+
x: typeof x === "number" && Number.isFinite(x) ? x : 0,
|
|
145091
|
+
y: typeof y === "number" && Number.isFinite(y) ? y : 0
|
|
145092
|
+
};
|
|
145093
|
+
} catch {
|
|
145094
|
+
return { x: 0, y: 0 };
|
|
145095
|
+
}
|
|
145096
|
+
}
|
|
145097
|
+
async function captureFile(env, budgetMs) {
|
|
145098
|
+
if (env.device.platform === "vega") {
|
|
145099
|
+
return captureVegaScreenshotPng({ scale: CAPTURE_SCALE });
|
|
145100
|
+
}
|
|
145101
|
+
if (env.device.platform === "ios" && await isTvOsSimulator(env.device.id)) {
|
|
145102
|
+
return tvScreenshot(env.device.id, CAPTURE_SCALE, captureAbortSignal(env, budgetMs));
|
|
145103
|
+
}
|
|
145104
|
+
const ref = simulatorServerRef(env.device);
|
|
145105
|
+
const api = await env.registry.resolveService(ref.urn, ref.options);
|
|
145106
|
+
const { path: path40 } = await httpScreenshot(api, void 0, void 0, CAPTURE_SCALE);
|
|
145107
|
+
return path40;
|
|
145108
|
+
}
|
|
145109
|
+
async function capturePng(env, budgetMs) {
|
|
145110
|
+
if (env.device.platform === "chromium") return captureChromiumPng(env);
|
|
145111
|
+
const file2 = await captureFile(env, budgetMs);
|
|
145112
|
+
try {
|
|
145113
|
+
return await fs46.readFile(file2);
|
|
145114
|
+
} finally {
|
|
145115
|
+
await fs46.rm(file2, { force: true }).catch(() => {
|
|
145116
|
+
});
|
|
145117
|
+
}
|
|
145118
|
+
}
|
|
145119
|
+
async function capturePixels(env, budgetMs) {
|
|
145120
|
+
try {
|
|
145121
|
+
const png = import_pngjs2.PNG.sync.read(await capturePng(env, budgetMs));
|
|
145122
|
+
return { width: png.width, height: png.height, data: png.data };
|
|
145123
|
+
} catch {
|
|
145124
|
+
return void 0;
|
|
145125
|
+
}
|
|
145126
|
+
}
|
|
145127
|
+
async function capturePixelsWithin(env, deadline, firstCapture) {
|
|
145128
|
+
const budget = Math.min(deadline - Date.now(), pixelCaptureTimeoutMs(env.device, firstCapture));
|
|
145129
|
+
if (budget <= 0) return void 0;
|
|
145130
|
+
const result = await settleWithin(capturePixels(env, budget), budget, env.signal);
|
|
145131
|
+
return result.type === "value" ? result.value : void 0;
|
|
145132
|
+
}
|
|
145133
|
+
function captureAbortSignal(env, budgetMs) {
|
|
145134
|
+
const bound = AbortSignal.timeout(budgetMs);
|
|
145135
|
+
return env.signal ? AbortSignal.any([env.signal, bound]) : bound;
|
|
145136
|
+
}
|
|
145137
|
+
function comparePixels(a, b, maskTopFraction = 0) {
|
|
145138
|
+
if (a.width !== b.width || a.height !== b.height) return "moving";
|
|
145139
|
+
const maskedRows = Math.min(a.height, Math.floor(a.height * maskTopFraction));
|
|
145140
|
+
const total = a.width * (a.height - maskedRows);
|
|
145141
|
+
if (total <= 0) return "still";
|
|
145142
|
+
const limit = Math.min(a.data.length, b.data.length);
|
|
145143
|
+
let changed = 0;
|
|
145144
|
+
for (let o = maskedRows * a.width * 4; o + 2 < limit; o += 4) {
|
|
145145
|
+
const dr = a.data[o] - b.data[o];
|
|
145146
|
+
const dg = a.data[o + 1] - b.data[o + 1];
|
|
145147
|
+
const db = a.data[o + 2] - b.data[o + 2];
|
|
145148
|
+
if (dr * dr + dg * dg + db * db > PIXEL_THRESHOLD_SQUARED) changed++;
|
|
145149
|
+
}
|
|
145150
|
+
const motionThreshold = Math.max(
|
|
145151
|
+
total * MOTION_FRACTION,
|
|
145152
|
+
Math.min(MOTION_MIN_PIXELS, total * MOTION_MIN_PIXELS_FRAME_SHARE)
|
|
145153
|
+
);
|
|
145154
|
+
if (changed > motionThreshold) return "moving";
|
|
145155
|
+
return changed >= LOCALIZED_MOTION_MIN_PIXELS ? "localized" : "still";
|
|
145156
|
+
}
|
|
145157
|
+
|
|
144647
145158
|
// ../tool-server/src/tools/flows/flow-actions.ts
|
|
144648
145159
|
var ABORTED_OUTCOME = {
|
|
144649
145160
|
ok: false,
|
|
@@ -144889,6 +145400,8 @@ async function runDirective(env, step) {
|
|
|
144889
145400
|
return waitForCondition(env, step, step.timeout ?? DEFAULT_ACTION_TIMEOUT_MS);
|
|
144890
145401
|
case "assert":
|
|
144891
145402
|
return waitForCondition(env, step, DEFAULT_ASSERT_TIMEOUT_MS);
|
|
145403
|
+
case "idle":
|
|
145404
|
+
return waitForIdle(env, step);
|
|
144892
145405
|
case "scroll-to": {
|
|
144893
145406
|
const r = await scrollToVisible(env, step.target, step.direction, step.within);
|
|
144894
145407
|
if (r.aborted) return ABORTED_OUTCOME;
|
|
@@ -145131,6 +145644,215 @@ async function waitForCondition(env, step, timeoutMs) {
|
|
|
145131
145644
|
reason: assertReason(step.condition, step.selector, step.expectedText, step.textMatch, lastMatches) + blipNote
|
|
145132
145645
|
};
|
|
145133
145646
|
}
|
|
145647
|
+
var MIN_STILL_INTERVALS = IDLE_MIN_STILL_INTERVALS;
|
|
145648
|
+
var MIN_ROUND_BUDGET_MS = IDLE_POLL_MS;
|
|
145649
|
+
var LOCALIZED_MOTION_WARNING = `the screen settled, but a small part of it was still changing while it did \u2014 a spinner, a caret, a progress dot. If it is a loading spinner then the screen had not finished loading, and stillness cannot tell those apart: look at what is moving, and gate the next action on the element the loading produces rather than on this settle.`;
|
|
145650
|
+
var HUNG_TREE_READ_MS = 2e3;
|
|
145651
|
+
var IDLE_TOLERATED_DARK_READS = 1;
|
|
145652
|
+
function isBlindTreeRead(data) {
|
|
145653
|
+
return data.tree.children.length === 0 && Boolean(data.hint || data.should_restart);
|
|
145654
|
+
}
|
|
145655
|
+
async function waitForIdle(env, step) {
|
|
145656
|
+
const timeoutMs = step.timeout ?? IDLE_DEFAULT_TIMEOUT_MS;
|
|
145657
|
+
const stableFor = step.stableFor ?? IDLE_DEFAULT_STABLE_FOR_MS;
|
|
145658
|
+
const maskTopFraction = await statusBarMaskFraction(env.device);
|
|
145659
|
+
const deadline = Date.now() + timeoutMs;
|
|
145660
|
+
let treeSignature2;
|
|
145661
|
+
let treeSince = 0;
|
|
145662
|
+
let treeStillIntervals = 0;
|
|
145663
|
+
let treeSettledAtLastRead = false;
|
|
145664
|
+
let previousFrame;
|
|
145665
|
+
let bothSince = 0;
|
|
145666
|
+
let stillIntervals = 0;
|
|
145667
|
+
let heldForMs = 0;
|
|
145668
|
+
let localizedMotionDuringHold = false;
|
|
145669
|
+
let readsSucceeded = 0;
|
|
145670
|
+
let contentReads = 0;
|
|
145671
|
+
let lastRead;
|
|
145672
|
+
let treeErrorMessage;
|
|
145673
|
+
let treeReadBlind = false;
|
|
145674
|
+
let blindHint;
|
|
145675
|
+
let darkReads = 0;
|
|
145676
|
+
let treeReadHung = false;
|
|
145677
|
+
let slowestAnsweredReadMs = 0;
|
|
145678
|
+
let sawContent = false;
|
|
145679
|
+
let pixelsEverMoved = false;
|
|
145680
|
+
let comparedAPair = false;
|
|
145681
|
+
let firstCapture = true;
|
|
145682
|
+
for (; ; ) {
|
|
145683
|
+
if (env.signal?.aborted) return ABORTED_OUTCOME;
|
|
145684
|
+
const roundBudget = Math.max(1, deadline - Date.now());
|
|
145685
|
+
const roundStartedAt = Date.now();
|
|
145686
|
+
let answeredReadMs;
|
|
145687
|
+
const [read, frame] = await Promise.all([
|
|
145688
|
+
settleWithin(fetchFlowTree(env.registry, env.device), roundBudget, env.signal).then((r) => {
|
|
145689
|
+
answeredReadMs = Date.now() - roundStartedAt;
|
|
145690
|
+
return r;
|
|
145691
|
+
}),
|
|
145692
|
+
capturePixelsWithin(env, deadline, firstCapture)
|
|
145693
|
+
]);
|
|
145694
|
+
firstCapture = false;
|
|
145695
|
+
if (env.signal?.aborted || read.type === "aborted") return ABORTED_OUTCOME;
|
|
145696
|
+
if (read.type !== "timeout" && answeredReadMs !== void 0) {
|
|
145697
|
+
slowestAnsweredReadMs = Math.max(slowestAnsweredReadMs, answeredReadMs);
|
|
145698
|
+
}
|
|
145699
|
+
if (read.type === "timeout") {
|
|
145700
|
+
lastRead = "timeout";
|
|
145701
|
+
darkReads += 1;
|
|
145702
|
+
if (roundBudget >= HUNG_TREE_READ_MS && roundBudget > slowestAnsweredReadMs + HUNG_TREE_READ_MS) {
|
|
145703
|
+
treeReadHung = true;
|
|
145704
|
+
}
|
|
145705
|
+
} else if (read.type === "value" && isBlindTreeRead(read.value)) {
|
|
145706
|
+
lastRead = "blind";
|
|
145707
|
+
darkReads += 1;
|
|
145708
|
+
treeReadBlind = true;
|
|
145709
|
+
blindHint = read.value.hint;
|
|
145710
|
+
} else if (read.type === "error") {
|
|
145711
|
+
lastRead = "error";
|
|
145712
|
+
darkReads += 1;
|
|
145713
|
+
treeErrorMessage = read.error;
|
|
145714
|
+
treeSignature2 = void 0;
|
|
145715
|
+
previousFrame = void 0;
|
|
145716
|
+
treeSince = 0;
|
|
145717
|
+
treeStillIntervals = 0;
|
|
145718
|
+
treeSettledAtLastRead = false;
|
|
145719
|
+
bothSince = 0;
|
|
145720
|
+
stillIntervals = 0;
|
|
145721
|
+
} else {
|
|
145722
|
+
lastRead = "value";
|
|
145723
|
+
readsSucceeded += 1;
|
|
145724
|
+
darkReads = 0;
|
|
145725
|
+
treeErrorMessage = void 0;
|
|
145726
|
+
treeReadBlind = false;
|
|
145727
|
+
blindHint = void 0;
|
|
145728
|
+
treeReadHung = false;
|
|
145729
|
+
const tree = read.value.tree;
|
|
145730
|
+
if (tree.children.length === 0) {
|
|
145731
|
+
treeSignature2 = void 0;
|
|
145732
|
+
previousFrame = void 0;
|
|
145733
|
+
treeSince = 0;
|
|
145734
|
+
treeStillIntervals = 0;
|
|
145735
|
+
treeSettledAtLastRead = false;
|
|
145736
|
+
bothSince = 0;
|
|
145737
|
+
stillIntervals = 0;
|
|
145738
|
+
} else {
|
|
145739
|
+
sawContent = true;
|
|
145740
|
+
contentReads += 1;
|
|
145741
|
+
const signature = treeFingerprint(tree);
|
|
145742
|
+
const now = Date.now();
|
|
145743
|
+
const treeHeld = signature === treeSignature2;
|
|
145744
|
+
treeSignature2 = signature;
|
|
145745
|
+
if (!treeHeld) {
|
|
145746
|
+
treeSince = now;
|
|
145747
|
+
treeStillIntervals = 0;
|
|
145748
|
+
} else {
|
|
145749
|
+
treeStillIntervals += 1;
|
|
145750
|
+
}
|
|
145751
|
+
treeSettledAtLastRead = treeStillIntervals >= MIN_STILL_INTERVALS && now - treeSince >= stableFor;
|
|
145752
|
+
let pixelsHeld;
|
|
145753
|
+
let localizedThisInterval = false;
|
|
145754
|
+
if (frame !== void 0) {
|
|
145755
|
+
if (previousFrame !== void 0) {
|
|
145756
|
+
comparedAPair = true;
|
|
145757
|
+
const change = comparePixels(previousFrame, frame, maskTopFraction);
|
|
145758
|
+
if (change === "moving") {
|
|
145759
|
+
pixelsEverMoved = true;
|
|
145760
|
+
pixelsHeld = false;
|
|
145761
|
+
} else {
|
|
145762
|
+
pixelsHeld = true;
|
|
145763
|
+
localizedThisInterval = change === "localized";
|
|
145764
|
+
}
|
|
145765
|
+
}
|
|
145766
|
+
previousFrame = frame;
|
|
145767
|
+
}
|
|
145768
|
+
if (!treeHeld || pixelsHeld === false) {
|
|
145769
|
+
bothSince = now;
|
|
145770
|
+
stillIntervals = 0;
|
|
145771
|
+
heldForMs = 0;
|
|
145772
|
+
localizedMotionDuringHold = false;
|
|
145773
|
+
} else if (pixelsHeld === true) {
|
|
145774
|
+
stillIntervals += 1;
|
|
145775
|
+
heldForMs = now - bothSince;
|
|
145776
|
+
if (localizedThisInterval) localizedMotionDuringHold = true;
|
|
145777
|
+
if (stillIntervals >= MIN_STILL_INTERVALS && heldForMs >= stableFor) {
|
|
145778
|
+
return localizedMotionDuringHold ? { ok: true, warning: LOCALIZED_MOTION_WARNING } : { ok: true };
|
|
145779
|
+
}
|
|
145780
|
+
}
|
|
145781
|
+
}
|
|
145782
|
+
}
|
|
145783
|
+
if (env.signal?.aborted) return ABORTED_OUTCOME;
|
|
145784
|
+
const left = deadline - Date.now();
|
|
145785
|
+
if (left < MIN_ROUND_BUDGET_MS) break;
|
|
145786
|
+
if (!await sleepOrAbort(Math.min(IDLE_POLL_MS, left), env.signal)) return ABORTED_OUTCOME;
|
|
145787
|
+
}
|
|
145788
|
+
const unreadable = (underlying) => ({
|
|
145789
|
+
ok: false,
|
|
145790
|
+
indeterminate: true,
|
|
145791
|
+
// The underlying reader reports an instrumentation failure, whose remedy
|
|
145792
|
+
// (relaunch the app) is the wrong repair for the commonest cause of it
|
|
145793
|
+
// here: the app is simply not in the foreground, which reads exactly the
|
|
145794
|
+
// same from the tree source. Name that first so the author checks it
|
|
145795
|
+
// before relaunching anything.
|
|
145796
|
+
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}`
|
|
145797
|
+
});
|
|
145798
|
+
const degraded = () => ({
|
|
145799
|
+
ok: false,
|
|
145800
|
+
indeterminate: true,
|
|
145801
|
+
reason: `the UI tree read back empty and degraded while waiting for the screen to settle, so the screen was never observed \u2014 this is the reader reporting it could not see the app, not the app rendering nothing` + (blindHint === void 0 ? "" : `. ${blindHint}`)
|
|
145802
|
+
});
|
|
145803
|
+
if (readsSucceeded === 0) {
|
|
145804
|
+
if (treeErrorMessage !== void 0) return unreadable(treeErrorMessage);
|
|
145805
|
+
if (treeReadBlind) return degraded();
|
|
145806
|
+
return {
|
|
145807
|
+
ok: false,
|
|
145808
|
+
indeterminate: true,
|
|
145809
|
+
reason: `the tree source never answered within the step's ${timeoutMs}ms \u2014 raise this step's \`timeout:\` if it is merely slow (a tree read on a busy screen can take seconds), or repair it if it has stopped answering altogether`
|
|
145810
|
+
};
|
|
145811
|
+
}
|
|
145812
|
+
if (treeErrorMessage !== void 0 && darkReads > IDLE_TOLERATED_DARK_READS) {
|
|
145813
|
+
return unreadable(treeErrorMessage);
|
|
145814
|
+
}
|
|
145815
|
+
if (treeReadBlind && darkReads > IDLE_TOLERATED_DARK_READS) {
|
|
145816
|
+
return degraded();
|
|
145817
|
+
}
|
|
145818
|
+
if (lastRead === "timeout" && treeReadHung) {
|
|
145819
|
+
return {
|
|
145820
|
+
ok: false,
|
|
145821
|
+
indeterminate: true,
|
|
145822
|
+
reason: `the UI tree source answered and then stopped: a read given at least ${HUNG_TREE_READ_MS}ms never came back, so the screen could not be observed for the rest of the wait \u2014 check the app is still in the foreground and responding (a wedged app reads the same as a backgrounded one)`
|
|
145823
|
+
};
|
|
145824
|
+
}
|
|
145825
|
+
const blipNote = treeErrorMessage !== void 0 ? ` (the last read that came back failed: ${treeErrorMessage})` : "";
|
|
145826
|
+
if (!sawContent) {
|
|
145827
|
+
return {
|
|
145828
|
+
ok: true,
|
|
145829
|
+
warning: `the UI tree stayed empty for ${timeoutMs}ms \u2014 the screen never rendered content, so there was nothing to settle. If the screen is meant to render accessible content, this is where it did not; if it is a canvas or a video surface, it has none to read. Gate the next action on an element check either way.` + blipNote
|
|
145830
|
+
};
|
|
145831
|
+
}
|
|
145832
|
+
if (contentReads <= MIN_STILL_INTERVALS) {
|
|
145833
|
+
return {
|
|
145834
|
+
ok: true,
|
|
145835
|
+
warning: `the screen came back with content on ${contentReads} read${contentReads === 1 ? "" : "s"} in ${timeoutMs}ms, and a settle takes ${MIN_STILL_INTERVALS + 1} of them spanning ${MIN_STILL_INTERVALS} ${IDLE_POLL_MS}ms polls \u2014 so this step ended without ever being able to tell whether the screen was moving. Raise its \`timeout:\`, and gate the next action on a stable element rather than on stillness.` + blipNote
|
|
145836
|
+
};
|
|
145837
|
+
}
|
|
145838
|
+
if (treeSettledAtLastRead && !pixelsEverMoved && !comparedAPair) {
|
|
145839
|
+
return {
|
|
145840
|
+
ok: true,
|
|
145841
|
+
warning: `settled on the UI tree alone \u2014 this screen could not be screenshotted on enough polls to compare a pair of them, so animation that moves pixels without moving nodes (a push, a fade, a dismissing modal) was not waited out. Follow this with the element check the next step actually needs.`
|
|
145842
|
+
};
|
|
145843
|
+
}
|
|
145844
|
+
if (stillIntervals > 0) {
|
|
145845
|
+
const shortOf = stillIntervals < MIN_STILL_INTERVALS ? `a settle takes ${MIN_STILL_INTERVALS} consecutive ones \u2014 a single agreeing interval can be two samples either side of an animation's turning point` : `the hold asks for ${stableFor}ms of it`;
|
|
145846
|
+
return {
|
|
145847
|
+
ok: true,
|
|
145848
|
+
warning: `the screen was still for the last ${heldForMs}ms of the ${timeoutMs}ms wait, over ${stillIntervals} ${IDLE_POLL_MS}ms interval${stillIntervals === 1 ? "" : "s"} \u2014 but ${shortOf}, so the wait ran out before the settle could be confirmed rather than because the screen never stopped. Raise this step's \`timeout:\`, and gate the next action on a stable element rather than on stillness.` + blipNote
|
|
145849
|
+
};
|
|
145850
|
+
}
|
|
145851
|
+
return {
|
|
145852
|
+
ok: true,
|
|
145853
|
+
warning: `the screen never held still for ${MIN_STILL_INTERVALS} consecutive ${IDLE_POLL_MS}ms intervals${stableFor > 0 ? ` spanning ${stableFor}ms` : ""} within ${timeoutMs}ms, and was moving again on the last one, so this step went ahead without waiting it out. Either something on it never stops (a video, a looping animation, a carousel, live-updating text) or the screen never finished loading. Look at what is moving, and make sure the next action is gated on a stable element rather than on stillness.` + blipNote
|
|
145854
|
+
};
|
|
145855
|
+
}
|
|
145134
145856
|
function assertReason(condition, selector, expectedText, textMatch, matches2) {
|
|
145135
145857
|
const sel = describeSelector(selector);
|
|
145136
145858
|
switch (condition) {
|
|
@@ -145156,15 +145878,15 @@ function assertReason(condition, selector, expectedText, textMatch, matches2) {
|
|
|
145156
145878
|
|
|
145157
145879
|
// ../tool-server/src/tools/flows/flow-visual.ts
|
|
145158
145880
|
var import_node_crypto8 = require("node:crypto");
|
|
145159
|
-
var
|
|
145881
|
+
var fs48 = __toESM(require("node:fs/promises"));
|
|
145160
145882
|
var os12 = __toESM(require("node:os"));
|
|
145161
145883
|
var path34 = __toESM(require("node:path"));
|
|
145162
|
-
var
|
|
145884
|
+
var import_pngjs4 = __toESM(require_png());
|
|
145163
145885
|
|
|
145164
145886
|
// ../tool-server/src/tools/screenshot-diff/screenshot-diff.ts
|
|
145165
145887
|
var import_promises11 = __toESM(require("fs/promises"));
|
|
145166
145888
|
var import_path9 = __toESM(require("path"));
|
|
145167
|
-
var
|
|
145889
|
+
var import_pngjs3 = __toESM(require_png());
|
|
145168
145890
|
|
|
145169
145891
|
// ../tool-server/src/tools/screenshot-diff/screenshot-diff-ocr.ts
|
|
145170
145892
|
var import_child_process8 = require("child_process");
|
|
@@ -146709,7 +147431,7 @@ function formatPercentage(value) {
|
|
|
146709
147431
|
}
|
|
146710
147432
|
|
|
146711
147433
|
// ../tool-server/src/tools/screenshot-diff/screenshot-diff.ts
|
|
146712
|
-
var
|
|
147434
|
+
var MAX_RGB_DISTANCE_SQUARED2 = 255 * 255 * 3;
|
|
146713
147435
|
var DEFAULT_THRESHOLD = 0.1;
|
|
146714
147436
|
var DEFAULT_IGNORE_TOP_NORMALIZED_Y = 0.06;
|
|
146715
147437
|
var DEFAULT_REGION_MERGE_DISTANCE = 8;
|
|
@@ -146795,7 +147517,7 @@ async function diffPngFiles(options) {
|
|
|
146795
147517
|
}
|
|
146796
147518
|
function resolveDiffSettings(topMask) {
|
|
146797
147519
|
return {
|
|
146798
|
-
thresholdSquared: DEFAULT_THRESHOLD * DEFAULT_THRESHOLD *
|
|
147520
|
+
thresholdSquared: DEFAULT_THRESHOLD * DEFAULT_THRESHOLD * MAX_RGB_DISTANCE_SQUARED2,
|
|
146799
147521
|
ignoreTopNormalizedY: topMask === "none" ? 0 : DEFAULT_IGNORE_TOP_NORMALIZED_Y,
|
|
146800
147522
|
joinGapPixels: DEFAULT_REGION_MERGE_DISTANCE,
|
|
146801
147523
|
contextDiffScale: DEFAULT_CONTEXT_DIFF_SCALE
|
|
@@ -146900,7 +147622,7 @@ async function writeDiffArtifacts(params) {
|
|
|
146900
147622
|
}
|
|
146901
147623
|
async function decodePngFile(filePath) {
|
|
146902
147624
|
const buffer = await import_promises11.default.readFile(filePath);
|
|
146903
|
-
const png =
|
|
147625
|
+
const png = import_pngjs3.PNG.sync.read(buffer);
|
|
146904
147626
|
return {
|
|
146905
147627
|
width: png.width,
|
|
146906
147628
|
height: png.height,
|
|
@@ -146919,7 +147641,7 @@ async function analyzeScreenshotTextChangesSafely(options) {
|
|
|
146919
147641
|
}
|
|
146920
147642
|
}
|
|
146921
147643
|
function buildContextDiff(params) {
|
|
146922
|
-
const output = new
|
|
147644
|
+
const output = new import_pngjs3.PNG({ width: params.current.width, height: params.current.height });
|
|
146923
147645
|
for (let pixelIndex = 0; pixelIndex < params.mask.length; pixelIndex++) {
|
|
146924
147646
|
const offset = pixelIndex * 4;
|
|
146925
147647
|
if (params.mask[pixelIndex]) {
|
|
@@ -146944,7 +147666,7 @@ function luminanceFromOffset(data, offset) {
|
|
|
146944
147666
|
}
|
|
146945
147667
|
async function writePngFile(filePath, png) {
|
|
146946
147668
|
await import_promises11.default.mkdir(import_path9.default.dirname(filePath), { recursive: true });
|
|
146947
|
-
await import_promises11.default.writeFile(filePath,
|
|
147669
|
+
await import_promises11.default.writeFile(filePath, import_pngjs3.PNG.sync.write(png));
|
|
146948
147670
|
}
|
|
146949
147671
|
function downscalePng(source, scale) {
|
|
146950
147672
|
const resized = resizeDecodedPng(
|
|
@@ -146952,7 +147674,7 @@ function downscalePng(source, scale) {
|
|
|
146952
147674
|
source.width * scale,
|
|
146953
147675
|
source.height * scale
|
|
146954
147676
|
);
|
|
146955
|
-
const target = new
|
|
147677
|
+
const target = new import_pngjs3.PNG({ width: resized.width, height: resized.height });
|
|
146956
147678
|
resized.data.copy(target.data);
|
|
146957
147679
|
return target;
|
|
146958
147680
|
}
|
|
@@ -147217,7 +147939,7 @@ function roundToOne(value) {
|
|
|
147217
147939
|
// ../tool-server/src/tools/flows/flow-visual.ts
|
|
147218
147940
|
var DEFAULT_MAX_MISMATCH = 0.5;
|
|
147219
147941
|
async function pngDimensions(file2) {
|
|
147220
|
-
const fh = await
|
|
147942
|
+
const fh = await fs48.open(file2, "r");
|
|
147221
147943
|
try {
|
|
147222
147944
|
const buf = Buffer.alloc(24);
|
|
147223
147945
|
await fh.read(buf, 0, 24, 0);
|
|
@@ -147241,18 +147963,18 @@ function baselineDir(flowsDir, flowName) {
|
|
|
147241
147963
|
async function cleanupDiffDir(dir, keep) {
|
|
147242
147964
|
try {
|
|
147243
147965
|
if (!keep) {
|
|
147244
|
-
await
|
|
147966
|
+
await fs48.rm(dir, { recursive: true, force: true });
|
|
147245
147967
|
return;
|
|
147246
147968
|
}
|
|
147247
|
-
for (const entry of await
|
|
147969
|
+
for (const entry of await fs48.readdir(dir)) {
|
|
147248
147970
|
const entryPath = path34.join(dir, entry);
|
|
147249
|
-
if (entryPath !== keep) await
|
|
147971
|
+
if (entryPath !== keep) await fs48.rm(entryPath, { recursive: true, force: true });
|
|
147250
147972
|
}
|
|
147251
147973
|
} catch {
|
|
147252
147974
|
}
|
|
147253
147975
|
}
|
|
147254
147976
|
async function cropPngFile(src, dest, frame) {
|
|
147255
|
-
const png =
|
|
147977
|
+
const png = import_pngjs4.PNG.sync.read(await fs48.readFile(src));
|
|
147256
147978
|
const left = Math.max(0, Math.round(frame.x * png.width));
|
|
147257
147979
|
const top = Math.max(0, Math.round(frame.y * png.height));
|
|
147258
147980
|
const right = Math.min(png.width, Math.round((frame.x + frame.width) * png.width));
|
|
@@ -147260,9 +147982,9 @@ async function cropPngFile(src, dest, frame) {
|
|
|
147260
147982
|
const w = right - left;
|
|
147261
147983
|
const h = bottom - top;
|
|
147262
147984
|
if (w < 1 || h < 1) return null;
|
|
147263
|
-
const out = new
|
|
147264
|
-
|
|
147265
|
-
await
|
|
147985
|
+
const out = new import_pngjs4.PNG({ width: w, height: h });
|
|
147986
|
+
import_pngjs4.PNG.bitblt(png, out, left, top, w, h, 0, 0);
|
|
147987
|
+
await fs48.writeFile(dest, import_pngjs4.PNG.sync.write(out));
|
|
147266
147988
|
return { w, h };
|
|
147267
147989
|
}
|
|
147268
147990
|
async function runSnapshot(env, opts) {
|
|
@@ -147319,7 +148041,7 @@ async function runSnapshot(env, opts) {
|
|
|
147319
148041
|
};
|
|
147320
148042
|
try {
|
|
147321
148043
|
if (cropFrame !== void 0) {
|
|
147322
|
-
cropDir = await
|
|
148044
|
+
cropDir = await fs48.mkdtemp(path34.join(os12.tmpdir(), "argent-flow-crop-"));
|
|
147323
148045
|
const croppedPath = path34.join(cropDir, key2);
|
|
147324
148046
|
const cropped = await cropPngFile(shot.image.hostPath, croppedPath, cropFrame);
|
|
147325
148047
|
if (cropped === null) {
|
|
@@ -147333,10 +148055,10 @@ async function runSnapshot(env, opts) {
|
|
|
147333
148055
|
}
|
|
147334
148056
|
currentPath = croppedPath;
|
|
147335
148057
|
}
|
|
147336
|
-
const exists2 = await
|
|
148058
|
+
const exists2 = await fs48.access(baselinePath).then(() => true).catch(() => false);
|
|
147337
148059
|
if (opts.updateBaselines) {
|
|
147338
|
-
await
|
|
147339
|
-
await
|
|
148060
|
+
await fs48.mkdir(dir, { recursive: true });
|
|
148061
|
+
await fs48.copyFile(currentPath, baselinePath);
|
|
147340
148062
|
const baseline = await store.register(baselinePath, { mimeType: "image/png" });
|
|
147341
148063
|
return {
|
|
147342
148064
|
status: "pass",
|
|
@@ -147353,7 +148075,7 @@ async function runSnapshot(env, opts) {
|
|
|
147353
148075
|
artifacts: { current: await currentArtifact() }
|
|
147354
148076
|
};
|
|
147355
148077
|
}
|
|
147356
|
-
const outputDir = await
|
|
148078
|
+
const outputDir = await fs48.mkdtemp(path34.join(os12.tmpdir(), "argent-flow-diff-"));
|
|
147357
148079
|
let keepInOutputDir;
|
|
147358
148080
|
try {
|
|
147359
148081
|
const result = await diffPngFiles({
|
|
@@ -147819,7 +148541,13 @@ reads "inside card inside list", each container's frame inside the next);
|
|
|
147819
148541
|
(\`pinch: { on?, scale }\` \u2014 scale > 1 in, < 1 out; screen center when \`on\` is omitted); \`rotate\` is the
|
|
147820
148542
|
two-finger rotation gesture (\`rotate: { on?, by }\` \u2014 degrees, + clockwise, within \xB13000\xB0; screen center
|
|
147821
148543
|
when \`on\` is omitted; distinct from the \`rotate\` tool, which changes device orientation); \`await\` waits
|
|
147822
|
-
for a UI condition
|
|
148544
|
+
for a UI condition, and additionally takes the one condition that has no selector: \`idle: true\` waits
|
|
148545
|
+
until the screen has content and stops moving in BOTH the UI tree and the rendered pixels (it never
|
|
148546
|
+
fails a run \u2014 a screen that never settles passes carrying a \`warning\`, which is what makes it safe to
|
|
148547
|
+
persist; the one outcome that does stop the run is an \`error\` for a tree source that could not be read
|
|
148548
|
+
at all \u2014 a broken window rather than a verdict about the app, which leaves the run not-ok and skips
|
|
148549
|
+
every later step; it says nothing about WHICH screen settled \u2014 a dropped tap leaves the source screen
|
|
148550
|
+
perfectly idle \u2014 so pair it with the element check that names the destination); \`wait\` pauses for a fixed number of milliseconds; \`assert\` checks one now; \`snapshot\`
|
|
147823
148551
|
diffs a screenshot \u2014 or, with \`cropOn: <selector>\`, one element's cropped region \u2014 against a stored
|
|
147824
148552
|
baseline (a missing baseline fails the step \u2014 set updateBaselines to adopt the current screen; a
|
|
147825
148553
|
cropped element whose size drifted fails on dimensions); \`echo\` annotates; \`run\` executes another flow
|
|
@@ -147863,7 +148591,7 @@ returns a notice with the prerequisite instead of running.`,
|
|
|
147863
148591
|
);
|
|
147864
148592
|
const canonicalPath = await canonicalFlowPath2(filePath);
|
|
147865
148593
|
const flowsDir = path35.dirname(canonicalPath);
|
|
147866
|
-
const flow = parseFlow(await
|
|
148594
|
+
const flow = parseFlow(await fs49.readFile(canonicalPath, "utf8"));
|
|
147867
148595
|
if (viaUpload) assertUploadSelfContained(flow);
|
|
147868
148596
|
const rootEntry = { canonical: canonicalPath, display: flowName };
|
|
147869
148597
|
if (flow.executionPrerequisite && !pinnedToChromium(params.device)) {
|
|
@@ -148007,7 +148735,7 @@ async function scanLeadingLaunch(flow, stack) {
|
|
|
148007
148735
|
const supplied = path35.posix.basename(step.flow);
|
|
148008
148736
|
const spelling = await classifyOnDiskSpelling(path35.dirname(spelled), supplied);
|
|
148009
148737
|
if (spelling.state === "case_folded") return null;
|
|
148010
|
-
nested = parseFlow(await
|
|
148738
|
+
nested = parseFlow(await fs49.readFile(canonical, "utf8"));
|
|
148011
148739
|
} catch {
|
|
148012
148740
|
return null;
|
|
148013
148741
|
}
|
|
@@ -148034,7 +148762,7 @@ function launchTargetPlatform(launch, platform) {
|
|
|
148034
148762
|
async function resolveAppPath(specPath, flowDir) {
|
|
148035
148763
|
const lexical = path35.resolve(flowDir, specPath);
|
|
148036
148764
|
try {
|
|
148037
|
-
return await
|
|
148765
|
+
return await fs49.realpath(lexical);
|
|
148038
148766
|
} catch {
|
|
148039
148767
|
return lexical;
|
|
148040
148768
|
}
|
|
@@ -148142,6 +148870,8 @@ function stepTarget(step) {
|
|
|
148142
148870
|
case "await":
|
|
148143
148871
|
case "assert":
|
|
148144
148872
|
return conditionLabel(step, selectorLabel2);
|
|
148873
|
+
case "idle":
|
|
148874
|
+
return void 0;
|
|
148145
148875
|
case "when":
|
|
148146
148876
|
return step.condition.kind === "platform" ? `platform ${step.condition.platform}` : conditionLabel(step.condition, selectorLabel2);
|
|
148147
148877
|
case "scroll-to": {
|
|
@@ -148320,10 +149050,10 @@ async function execWhenStep(state3, step, scope) {
|
|
|
148320
149050
|
}
|
|
148321
149051
|
async function canonicalFlowPath2(p) {
|
|
148322
149052
|
try {
|
|
148323
|
-
return await
|
|
149053
|
+
return await fs49.realpath(p);
|
|
148324
149054
|
} catch {
|
|
148325
149055
|
try {
|
|
148326
|
-
return path35.join(await
|
|
149056
|
+
return path35.join(await fs49.realpath(path35.dirname(p)), path35.basename(p));
|
|
148327
149057
|
} catch {
|
|
148328
149058
|
return p;
|
|
148329
149059
|
}
|
|
@@ -148371,7 +149101,7 @@ async function execRunStep(state3, step, scope) {
|
|
|
148371
149101
|
}
|
|
148372
149102
|
let fragment;
|
|
148373
149103
|
try {
|
|
148374
|
-
fragment = parseFlow(await
|
|
149104
|
+
fragment = parseFlow(await fs49.readFile(canonical, "utf8"));
|
|
148375
149105
|
} catch (err) {
|
|
148376
149106
|
return fail(`could not load fragment "${target}": ${errMsg2(err)}`);
|
|
148377
149107
|
}
|
|
@@ -148411,13 +149141,22 @@ async function execLeafStep(state3, step, index, scope) {
|
|
|
148411
149141
|
case "type":
|
|
148412
149142
|
case "await":
|
|
148413
149143
|
case "assert":
|
|
149144
|
+
case "idle":
|
|
148414
149145
|
case "scroll-to":
|
|
148415
149146
|
case "pinch":
|
|
148416
149147
|
case "rotate": {
|
|
148417
149148
|
try {
|
|
148418
149149
|
const r = await runDirective(deviceEnv(state3), step);
|
|
148419
149150
|
if (r.aborted) return { ...base, status: "skip", reason: r.reason };
|
|
148420
|
-
|
|
149151
|
+
if (!r.ok && r.indeterminate && step.kind === "idle") {
|
|
149152
|
+
return { ...base, status: "error", reason: r.reason };
|
|
149153
|
+
}
|
|
149154
|
+
return {
|
|
149155
|
+
...base,
|
|
149156
|
+
status: r.ok ? "pass" : "fail",
|
|
149157
|
+
reason: r.reason,
|
|
149158
|
+
...r.warning !== void 0 ? { warning: r.warning } : {}
|
|
149159
|
+
};
|
|
148421
149160
|
} catch (err) {
|
|
148422
149161
|
return { ...base, status: "error", reason: errMsg2(err) };
|
|
148423
149162
|
}
|
|
@@ -148486,6 +149225,17 @@ async function execLeafStep(state3, step, index, scope) {
|
|
|
148486
149225
|
args
|
|
148487
149226
|
};
|
|
148488
149227
|
}
|
|
149228
|
+
if (isDebuggerNotConnectedResult(step.name, result)) {
|
|
149229
|
+
return {
|
|
149230
|
+
...base,
|
|
149231
|
+
status: "fail",
|
|
149232
|
+
tool: step.name,
|
|
149233
|
+
reason: `debugger not connected (${result.reason}): ${result.detail} \u2014 ${result.guidance}`,
|
|
149234
|
+
result,
|
|
149235
|
+
outputHint,
|
|
149236
|
+
args
|
|
149237
|
+
};
|
|
149238
|
+
}
|
|
148489
149239
|
return { ...base, status: "pass", tool: step.name, result, outputHint, args };
|
|
148490
149240
|
} catch (err) {
|
|
148491
149241
|
return { ...base, status: "error", tool: step.name, reason: errMsg2(err) };
|
|
@@ -148618,7 +149368,7 @@ async function resolveFlowSource(params, fileInput, flowPathInput) {
|
|
|
148618
149368
|
|
|
148619
149369
|
// ../tool-server/src/tools/flows/flow-read-prerequisite.ts
|
|
148620
149370
|
init_zod();
|
|
148621
|
-
var
|
|
149371
|
+
var fs50 = __toESM(require("node:fs/promises"));
|
|
148622
149372
|
init_src();
|
|
148623
149373
|
var zodSchema66 = external_exports.object({
|
|
148624
149374
|
name: external_exports.string().optional().describe(
|
|
@@ -148688,7 +149438,7 @@ Fails if the flow file does not exist.`,
|
|
|
148688
149438
|
ctx?.fileInputs?.flow_file,
|
|
148689
149439
|
ctx?.fileInputs?.flow_path
|
|
148690
149440
|
);
|
|
148691
|
-
const flow = parseFlow(await
|
|
149441
|
+
const flow = parseFlow(await fs50.readFile(filePath, "utf8"));
|
|
148692
149442
|
return {
|
|
148693
149443
|
flow: flowName,
|
|
148694
149444
|
executionPrerequisite: flow.executionPrerequisite
|
|
@@ -149036,13 +149786,13 @@ Fails if the workspacePath is not an absolute path or the directory cannot be ac
|
|
|
149036
149786
|
|
|
149037
149787
|
// ../tool-server/src/tools/system/update-argent.ts
|
|
149038
149788
|
var import_node_child_process29 = require("node:child_process");
|
|
149039
|
-
var
|
|
149789
|
+
var fs51 = __toESM(require("node:fs"));
|
|
149040
149790
|
var path36 = __toESM(require("node:path"));
|
|
149041
149791
|
init_zod();
|
|
149042
149792
|
function resolveCliEntry() {
|
|
149043
149793
|
try {
|
|
149044
149794
|
const entry = path36.join(__dirname, "cli.js");
|
|
149045
|
-
return
|
|
149795
|
+
return fs51.existsSync(entry) ? entry : null;
|
|
149046
149796
|
} catch {
|
|
149047
149797
|
return null;
|
|
149048
149798
|
}
|
|
@@ -149056,14 +149806,14 @@ function classifyRunningInstall() {
|
|
|
149056
149806
|
}
|
|
149057
149807
|
let runningRoot;
|
|
149058
149808
|
try {
|
|
149059
|
-
runningRoot =
|
|
149809
|
+
runningRoot = fs51.realpathSync(path36.dirname(__dirname));
|
|
149060
149810
|
} catch {
|
|
149061
149811
|
return { kind: "global", projectRoot: null };
|
|
149062
149812
|
}
|
|
149063
149813
|
let dir = process.cwd();
|
|
149064
149814
|
while (true) {
|
|
149065
149815
|
try {
|
|
149066
|
-
const nmReal =
|
|
149816
|
+
const nmReal = fs51.realpathSync(path36.join(dir, "node_modules"));
|
|
149067
149817
|
if (runningRoot === nmReal || runningRoot.startsWith(nmReal + path36.sep)) {
|
|
149068
149818
|
return { kind: "local", projectRoot: dir };
|
|
149069
149819
|
}
|
|
@@ -149078,14 +149828,14 @@ function classifyRunningInstall() {
|
|
|
149078
149828
|
function findDeclaringProjectRoot(startDir) {
|
|
149079
149829
|
let dir;
|
|
149080
149830
|
try {
|
|
149081
|
-
dir =
|
|
149831
|
+
dir = fs51.realpathSync(startDir);
|
|
149082
149832
|
} catch {
|
|
149083
149833
|
return null;
|
|
149084
149834
|
}
|
|
149085
149835
|
while (true) {
|
|
149086
|
-
if (
|
|
149836
|
+
if (fs51.existsSync(path36.join(dir, ".argent", "install.json"))) return dir;
|
|
149087
149837
|
try {
|
|
149088
|
-
const manifest = JSON.parse(
|
|
149838
|
+
const manifest = JSON.parse(fs51.readFileSync(path36.join(dir, "package.json"), "utf8"));
|
|
149089
149839
|
if (manifest.devDependencies?.[PACKAGE_NAME2] || manifest.dependencies?.[PACKAGE_NAME2] || manifest.optionalDependencies?.[PACKAGE_NAME2]) {
|
|
149090
149840
|
return dir;
|
|
149091
149841
|
}
|
|
@@ -149124,7 +149874,7 @@ var updateArgentTool = {
|
|
|
149124
149874
|
let projectRoot = null;
|
|
149125
149875
|
let effectiveTarget = resolved;
|
|
149126
149876
|
if (resolved === "local" || resolved === "both") {
|
|
149127
|
-
const recordedRoot = running.projectRoot &&
|
|
149877
|
+
const recordedRoot = running.projectRoot && fs51.existsSync(running.projectRoot) ? running.projectRoot : null;
|
|
149128
149878
|
projectRoot = recordedRoot ?? (running.kind === "local" ? findDeclaringProjectRoot(process.cwd()) : null);
|
|
149129
149879
|
if (!projectRoot) {
|
|
149130
149880
|
if (resolved === "local") {
|
|
@@ -149166,7 +149916,7 @@ var updateArgentTool = {
|
|
|
149166
149916
|
if (targetsOnlyRunningInstall && installableVersion) {
|
|
149167
149917
|
updateArgs.push("--version", installableVersion);
|
|
149168
149918
|
}
|
|
149169
|
-
const spawnRoot = projectRoot ?? (running.projectRoot &&
|
|
149919
|
+
const spawnRoot = projectRoot ?? (running.projectRoot && fs51.existsSync(running.projectRoot) ? running.projectRoot : null);
|
|
149170
149920
|
if (spawnRoot) updateArgs.push("--project-root", spawnRoot);
|
|
149171
149921
|
const cmd = cliEntry ? process.execPath : "argent";
|
|
149172
149922
|
const args = cliEntry ? [cliEntry, ...updateArgs] : updateArgs;
|
|
@@ -150011,12 +150761,12 @@ function createRegistry() {
|
|
|
150011
150761
|
registry2.registerTool(createTvRemoteTool(registry2));
|
|
150012
150762
|
registry2.registerTool(createRunSequenceTool(registry2));
|
|
150013
150763
|
registry2.registerTool(debuggerConnectTool);
|
|
150014
|
-
registry2.registerTool(
|
|
150764
|
+
registry2.registerTool(createDebuggerStatusTool(registry2));
|
|
150015
150765
|
registry2.registerTool(debuggerEvaluateTool);
|
|
150016
150766
|
registry2.registerTool(debuggerReloadMetroTool);
|
|
150017
150767
|
registry2.registerTool(debuggerComponentTreeTool);
|
|
150018
150768
|
registry2.registerTool(debuggerInspectElementTool);
|
|
150019
|
-
registry2.registerTool(
|
|
150769
|
+
registry2.registerTool(createDebuggerLogRegistryTool(registry2));
|
|
150020
150770
|
registry2.registerTool(networkLogsTool);
|
|
150021
150771
|
registry2.registerTool(networkRequestTool);
|
|
150022
150772
|
registry2.registerTool(createDescribeTool(registry2));
|
|
@@ -150086,7 +150836,7 @@ function probeArgentToolServer(host, port, timeoutMs = 500) {
|
|
|
150086
150836
|
}
|
|
150087
150837
|
|
|
150088
150838
|
// ../tool-server/src/utils/simulator-watcher.ts
|
|
150089
|
-
var
|
|
150839
|
+
var fs53 = __toESM(require("node:fs"));
|
|
150090
150840
|
var import_node_child_process30 = require("node:child_process");
|
|
150091
150841
|
var import_node_util21 = require("node:util");
|
|
150092
150842
|
var execFileAsync23 = (0, import_node_util21.promisify)(import_node_child_process30.execFile);
|
|
@@ -150113,7 +150863,7 @@ async function getBootedUdidsInSet(deviceSet) {
|
|
|
150113
150863
|
async function getBootedUdids() {
|
|
150114
150864
|
const sets = [
|
|
150115
150865
|
null,
|
|
150116
|
-
...configuredAdditionalDeviceSets().filter((p) =>
|
|
150866
|
+
...configuredAdditionalDeviceSets().filter((p) => fs53.existsSync(p))
|
|
150117
150867
|
];
|
|
150118
150868
|
const perSet = await Promise.all(sets.map(getBootedUdidsInSet));
|
|
150119
150869
|
return new Set(perSet.flatMap((s) => [...s]));
|
|
@@ -150166,7 +150916,7 @@ function startSimulatorWatcher(registry2) {
|
|
|
150166
150916
|
|
|
150167
150917
|
// ../tool-server/src/utils/preview-window.ts
|
|
150168
150918
|
var import_node_child_process31 = require("node:child_process");
|
|
150169
|
-
var
|
|
150919
|
+
var fs54 = __toESM(require("node:fs"));
|
|
150170
150920
|
var os14 = __toESM(require("node:os"));
|
|
150171
150921
|
var path38 = __toESM(require("node:path"));
|
|
150172
150922
|
function ensureLensAppBundle(electronBin) {
|
|
@@ -150183,18 +150933,18 @@ function ensureLensAppBundle(electronBin) {
|
|
|
150183
150933
|
);
|
|
150184
150934
|
const wrapperExec = path38.join(wrapperContents, "MacOS", "Electron");
|
|
150185
150935
|
try {
|
|
150186
|
-
if (
|
|
150936
|
+
if (fs54.realpathSync(wrapperExec) === fs54.realpathSync(electronBin)) return wrapperExec;
|
|
150187
150937
|
} catch {
|
|
150188
150938
|
}
|
|
150189
|
-
|
|
150190
|
-
|
|
150191
|
-
|
|
150192
|
-
|
|
150193
|
-
|
|
150939
|
+
fs54.rmSync(path38.dirname(wrapperContents), { recursive: true, force: true });
|
|
150940
|
+
fs54.mkdirSync(path38.join(wrapperContents, "MacOS"), { recursive: true });
|
|
150941
|
+
fs54.symlinkSync(path38.join(realContents, "Frameworks"), path38.join(wrapperContents, "Frameworks"));
|
|
150942
|
+
fs54.symlinkSync(path38.join(realContents, "Resources"), path38.join(wrapperContents, "Resources"));
|
|
150943
|
+
fs54.symlinkSync(electronBin, wrapperExec);
|
|
150194
150944
|
const pkgInfo = path38.join(realContents, "PkgInfo");
|
|
150195
|
-
if (
|
|
150945
|
+
if (fs54.existsSync(pkgInfo)) fs54.copyFileSync(pkgInfo, path38.join(wrapperContents, "PkgInfo"));
|
|
150196
150946
|
const plist = path38.join(wrapperContents, "Info.plist");
|
|
150197
|
-
|
|
150947
|
+
fs54.copyFileSync(path38.join(realContents, "Info.plist"), plist);
|
|
150198
150948
|
const setPlist = (entry, value) => {
|
|
150199
150949
|
try {
|
|
150200
150950
|
(0, import_node_child_process31.execFileSync)("/usr/libexec/PlistBuddy", ["-c", `Set :${entry} ${value}`, plist]);
|
|
@@ -150236,7 +150986,7 @@ function createPreviewWindowManager(opts = {}) {
|
|
|
150236
150986
|
const resolveMainScript = () => {
|
|
150237
150987
|
if (opts.mainScript) return opts.mainScript;
|
|
150238
150988
|
const bundled = path38.join(__dirname, "preview-window", "main.cjs");
|
|
150239
|
-
if (
|
|
150989
|
+
if (fs54.existsSync(bundled)) return bundled;
|
|
150240
150990
|
return require.resolve("@argent/preview-window/dist/main.js");
|
|
150241
150991
|
};
|
|
150242
150992
|
const isAlive = (c) => c !== null && c.exitCode === null && !c.killed;
|
|
@@ -150547,6 +151297,7 @@ function start() {
|
|
|
150547
151297
|
track("tool:fail", {
|
|
150548
151298
|
tool: toolId,
|
|
150549
151299
|
...meta3.platform ? { platform: meta3.platform } : {},
|
|
151300
|
+
...meta3.invalid_params?.length ? { invalid_params: meta3.invalid_params } : {},
|
|
150550
151301
|
duration_ms: durationMs,
|
|
150551
151302
|
...signal,
|
|
150552
151303
|
...aiTelemetryFromMeta(meta3)
|