@swmansion/argent 0.31.1-next.7 → 0.31.1-next.9
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 +9 -1
- package/dist/installer.mjs +1 -1
- package/dist/tool-server.cjs +119 -105
- package/package.json +1 -1
- package/skills/argent-android-emulator-setup/SKILL.md +1 -1
- package/skills/argent-device-interact/SKILL.md +1 -1
- package/skills/argent-metro-debugger/SKILL.md +1 -1
- package/skills/argent-react-native-app-workflow/SKILL.md +3 -1
- package/skills/argent-test-ui-flow/SKILL.md +1 -1
- package/skills/argent-tv-interact/SKILL.md +1 -1
package/dist/cli-cmds.mjs
CHANGED
|
@@ -35737,7 +35737,7 @@ var _CI_VENDOR_COUNT_FOR_TEST = vendors_default.length;
|
|
|
35737
35737
|
var SESSION_ID2 = randomUUID5();
|
|
35738
35738
|
function readCliVersion() {
|
|
35739
35739
|
if (true) {
|
|
35740
|
-
return "0.31.1-next.
|
|
35740
|
+
return "0.31.1-next.8";
|
|
35741
35741
|
}
|
|
35742
35742
|
return "0.0.0";
|
|
35743
35743
|
}
|
|
@@ -39893,6 +39893,8 @@ parsed (e.g. \`true\`, \`42\`, \`["a","b"]\`); anything else is stored as a stri
|
|
|
39893
39893
|
const stored = setConfigValue(key, coerceCliValue(rawValue), targetScope);
|
|
39894
39894
|
if (warning) console.error(import_picocolors3.default.yellow(warning));
|
|
39895
39895
|
console.log(`Set ${import_picocolors3.default.bold(key)} = ${formatValuePlain(stored)} (${scopeLabel(targetScope)}).`);
|
|
39896
|
+
const restart = restartHint(key);
|
|
39897
|
+
if (restart) console.error(import_picocolors3.default.yellow(restart));
|
|
39896
39898
|
} catch (err) {
|
|
39897
39899
|
reportError(err, () => suggestCorrectedSet(err, key, rawValue, scope));
|
|
39898
39900
|
}
|
|
@@ -39923,6 +39925,8 @@ other scope / the default on the next read.`);
|
|
|
39923
39925
|
console.log(
|
|
39924
39926
|
removed ? `Unset ${import_picocolors3.default.bold(key)} (${scopeLabel(targetScope)}).` : import_picocolors3.default.dim(`${key} was not set at ${targetScope} scope.`)
|
|
39925
39927
|
);
|
|
39928
|
+
const restart = removed ? restartHint(key) : null;
|
|
39929
|
+
if (restart) console.error(import_picocolors3.default.yellow(restart));
|
|
39926
39930
|
} catch (err) {
|
|
39927
39931
|
reportError(err);
|
|
39928
39932
|
}
|
|
@@ -39963,6 +39967,10 @@ function degenerateProjectScopeWarning(scope) {
|
|
|
39963
39967
|
}
|
|
39964
39968
|
return null;
|
|
39965
39969
|
}
|
|
39970
|
+
function restartHint(key) {
|
|
39971
|
+
if (key !== "android.adbServerPort") return null;
|
|
39972
|
+
return `The tool-server reads ${key} only when it starts. Apply the change with \`argent server stop\`: this stops it for every session, and the next tool call starts it again.`;
|
|
39973
|
+
}
|
|
39966
39974
|
function formatValuePlain(value) {
|
|
39967
39975
|
if (typeof value === "string") return value;
|
|
39968
39976
|
return JSON.stringify(value);
|
package/dist/installer.mjs
CHANGED
|
@@ -16912,7 +16912,7 @@ var _CI_VENDOR_COUNT_FOR_TEST = vendors_default.length;
|
|
|
16912
16912
|
var SESSION_ID = randomUUID4();
|
|
16913
16913
|
function readCliVersion() {
|
|
16914
16914
|
if (true) {
|
|
16915
|
-
return "0.31.1-next.
|
|
16915
|
+
return "0.31.1-next.8";
|
|
16916
16916
|
}
|
|
16917
16917
|
return "0.0.0";
|
|
16918
16918
|
}
|
package/dist/tool-server.cjs
CHANGED
|
@@ -101021,7 +101021,7 @@ var _CI_VENDOR_COUNT_FOR_TEST = vendors_default.length;
|
|
|
101021
101021
|
var SESSION_ID = (0, import_node_crypto3.randomUUID)();
|
|
101022
101022
|
function readCliVersion() {
|
|
101023
101023
|
if (true) {
|
|
101024
|
-
return "0.31.1-next.
|
|
101024
|
+
return "0.31.1-next.8";
|
|
101025
101025
|
}
|
|
101026
101026
|
return "0.0.0";
|
|
101027
101027
|
}
|
|
@@ -123566,6 +123566,100 @@ async function shutdownDevice(id) {
|
|
|
123566
123566
|
init_zod();
|
|
123567
123567
|
init_adb();
|
|
123568
123568
|
|
|
123569
|
+
// ../tool-server/src/utils/adb-server.ts
|
|
123570
|
+
var net2 = __toESM(require("node:net"));
|
|
123571
|
+
async function adbServerShell(serial, shellCommand, options = {}) {
|
|
123572
|
+
const { host, port } = adbServerAddress(process.env);
|
|
123573
|
+
const timeoutMs = options.timeoutMs ?? 5e3;
|
|
123574
|
+
return new Promise((resolve16, reject) => {
|
|
123575
|
+
const socket = net2.createConnection({ host, port });
|
|
123576
|
+
socket.setNoDelay(true);
|
|
123577
|
+
const chunks = [];
|
|
123578
|
+
let stage = "transport";
|
|
123579
|
+
let pending = Buffer.alloc(0);
|
|
123580
|
+
let settled = false;
|
|
123581
|
+
const finish = (err, value) => {
|
|
123582
|
+
if (settled) return;
|
|
123583
|
+
settled = true;
|
|
123584
|
+
clearTimeout(timer);
|
|
123585
|
+
socket.destroy();
|
|
123586
|
+
if (err) reject(err);
|
|
123587
|
+
else resolve16(value ?? "");
|
|
123588
|
+
};
|
|
123589
|
+
const timer = setTimeout(
|
|
123590
|
+
() => finish(new Error(`adb server shell timed out after ${timeoutMs}ms: ${shellCommand}`)),
|
|
123591
|
+
timeoutMs
|
|
123592
|
+
);
|
|
123593
|
+
const send = (message) => {
|
|
123594
|
+
const payload = Buffer.from(message, "utf8");
|
|
123595
|
+
socket.write(payload.length.toString(16).padStart(4, "0") + message);
|
|
123596
|
+
};
|
|
123597
|
+
const takeStatus = () => {
|
|
123598
|
+
if (pending.length < 4) return false;
|
|
123599
|
+
const status = pending.subarray(0, 4).toString("latin1");
|
|
123600
|
+
if (status === "OKAY") {
|
|
123601
|
+
pending = pending.subarray(4);
|
|
123602
|
+
return true;
|
|
123603
|
+
}
|
|
123604
|
+
if (status === "FAIL") {
|
|
123605
|
+
if (pending.length < 8) return false;
|
|
123606
|
+
const len = parseInt(pending.subarray(4, 8).toString("latin1"), 16);
|
|
123607
|
+
if (pending.length < 8 + len) return false;
|
|
123608
|
+
finish(new Error(`adb server: ${pending.subarray(8, 8 + len).toString("utf8")}`));
|
|
123609
|
+
return false;
|
|
123610
|
+
}
|
|
123611
|
+
finish(new Error(`adb server: unexpected status ${JSON.stringify(status)}`));
|
|
123612
|
+
return false;
|
|
123613
|
+
};
|
|
123614
|
+
socket.once("connect", () => send(`host:transport:${serial}`));
|
|
123615
|
+
socket.on("data", (data) => {
|
|
123616
|
+
if (stage === "output") {
|
|
123617
|
+
chunks.push(data);
|
|
123618
|
+
return;
|
|
123619
|
+
}
|
|
123620
|
+
pending = Buffer.concat([pending, data]);
|
|
123621
|
+
if (stage === "transport" && takeStatus()) {
|
|
123622
|
+
stage = "shell";
|
|
123623
|
+
send(`shell:${shellCommand}`);
|
|
123624
|
+
}
|
|
123625
|
+
if (stage === "shell" && takeStatus()) {
|
|
123626
|
+
stage = "output";
|
|
123627
|
+
if (pending.length) chunks.push(pending);
|
|
123628
|
+
pending = Buffer.alloc(0);
|
|
123629
|
+
}
|
|
123630
|
+
});
|
|
123631
|
+
socket.once("error", (err) => finish(err));
|
|
123632
|
+
socket.once("close", () => {
|
|
123633
|
+
if (stage === "output") finish(void 0, Buffer.concat(chunks).toString("utf8"));
|
|
123634
|
+
else finish(new Error("adb server closed the connection before answering"));
|
|
123635
|
+
});
|
|
123636
|
+
});
|
|
123637
|
+
}
|
|
123638
|
+
function configuredAdbServerPort(env, configured) {
|
|
123639
|
+
if (configured === null || env.ADB_SERVER_SOCKET || env.ANDROID_ADB_SERVER_PORT) return null;
|
|
123640
|
+
return String(configured);
|
|
123641
|
+
}
|
|
123642
|
+
function adbServerAddress(env) {
|
|
123643
|
+
const socketSpec = env.ADB_SERVER_SOCKET;
|
|
123644
|
+
if (socketSpec) {
|
|
123645
|
+
const m = /^tcp:(?:(.*):)?(\d+)$/.exec(socketSpec.trim());
|
|
123646
|
+
if (m) return { host: m[1] || "127.0.0.1", port: Number(m[2]) };
|
|
123647
|
+
}
|
|
123648
|
+
const port = Number(env.ANDROID_ADB_SERVER_PORT);
|
|
123649
|
+
return {
|
|
123650
|
+
host: env.ANDROID_ADB_SERVER_ADDRESS?.trim() || "127.0.0.1",
|
|
123651
|
+
port: Number.isInteger(port) && port > 0 && port < 65536 ? port : 5037
|
|
123652
|
+
};
|
|
123653
|
+
}
|
|
123654
|
+
function adbCommandPrefix(env) {
|
|
123655
|
+
const socketSpec = env.ADB_SERVER_SOCKET?.trim();
|
|
123656
|
+
if (socketSpec) return `ADB_SERVER_SOCKET=${socketSpec} `;
|
|
123657
|
+
const { host, port } = adbServerAddress(env);
|
|
123658
|
+
let prefix = port === 5037 ? "" : `ANDROID_ADB_SERVER_PORT=${port} `;
|
|
123659
|
+
if (host !== "127.0.0.1" && host !== "localhost") prefix += `ANDROID_ADB_SERVER_ADDRESS=${host} `;
|
|
123660
|
+
return prefix;
|
|
123661
|
+
}
|
|
123662
|
+
|
|
123569
123663
|
// ../tool-server/src/utils/ios-device/devicectl.ts
|
|
123570
123664
|
var import_node_child_process17 = require("node:child_process");
|
|
123571
123665
|
var import_node_util15 = require("node:util");
|
|
@@ -125996,6 +126090,9 @@ async function resolveRunningVvdSerial() {
|
|
|
125996
126090
|
// ../tool-server/src/tools/devices/list-devices.ts
|
|
125997
126091
|
init_external_devices();
|
|
125998
126092
|
var EXTERNAL_DEVICES_HINT = `Some entries are tagged 'external: true': another application is already driving that device, and its 'provider' field names it ('provider.workspace' names the project it opened, when it published one). Drive them with the usual tools, by the 'ext:'-prefixed id. Two rules differ: prefer the external device whose 'provider.workspace.path' matches the project you are working in, and do NOT call boot-device on them, since the provider owns their lifecycle. stop-simulator-server IS safe on them and never stops the provider's server \u2014 it drops argent's cached handles, which is the recovery when calls keep failing against an endpoint the provider has since moved. Each entry's 'capabilities' lists the mechanisms that provider granted; a tool relying on one it withheld fails with a clear message naming the provider.`;
|
|
126093
|
+
function adbServerHint(prefix) {
|
|
126094
|
+
return `Argent reaches Android and Vega devices through an adb server other than adb's default, so an adb command you run in your own shell does not see the serials listed here. Prefix every adb command you run yourself: \`${prefix}adb -s <serial> ...\`.`;
|
|
126095
|
+
}
|
|
125999
126096
|
function sortIos(a, b) {
|
|
126000
126097
|
const aBooted = a.state === "Booted" ? 0 : 1;
|
|
126001
126098
|
const bBooted = b.state === "Booted" ? 0 : 1;
|
|
@@ -126262,10 +126359,15 @@ Booted/ready devices are listed first. Platforms whose CLI is unavailable are si
|
|
|
126262
126359
|
const avdsTagged = avds.map(
|
|
126263
126360
|
(a) => foldableAvds.has(a.name) ? { ...a, foldable: true } : a
|
|
126264
126361
|
);
|
|
126362
|
+
const adbPrefix = adbCommandPrefix(process.env);
|
|
126363
|
+
const hints = [
|
|
126364
|
+
...external.length > 0 ? [EXTERNAL_DEVICES_HINT] : [],
|
|
126365
|
+
...adbPrefix ? [adbServerHint(adbPrefix)] : []
|
|
126366
|
+
];
|
|
126265
126367
|
return {
|
|
126266
126368
|
devices,
|
|
126267
126369
|
avds: avdsTagged,
|
|
126268
|
-
...
|
|
126370
|
+
...hints.length > 0 ? { hint: hints.join(" ") } : {}
|
|
126269
126371
|
};
|
|
126270
126372
|
}
|
|
126271
126373
|
};
|
|
@@ -126745,7 +126847,7 @@ var VariantProposalStore = class {
|
|
|
126745
126847
|
var variantProposalStore = new VariantProposalStore();
|
|
126746
126848
|
|
|
126747
126849
|
// ../tool-server/src/blueprints/native-devtools.ts
|
|
126748
|
-
var
|
|
126850
|
+
var net3 = __toESM(require("node:net"));
|
|
126749
126851
|
var fs23 = __toESM(require("node:fs"));
|
|
126750
126852
|
init_src2();
|
|
126751
126853
|
init_external_devices();
|
|
@@ -127099,12 +127201,12 @@ var nativeDevtoolsBlueprint = {
|
|
|
127099
127201
|
socket.on("error", () => {
|
|
127100
127202
|
});
|
|
127101
127203
|
};
|
|
127102
|
-
const server = lentSocketPath ? null :
|
|
127204
|
+
const server = lentSocketPath ? null : net3.createServer(serveAgentConnection);
|
|
127103
127205
|
let lentSocket = null;
|
|
127104
127206
|
let disposed = false;
|
|
127105
127207
|
if (lentSocketPath) {
|
|
127106
127208
|
lentSocket = await new Promise((resolve16, reject) => {
|
|
127107
|
-
const socket =
|
|
127209
|
+
const socket = net3.connect(lentSocketPath);
|
|
127108
127210
|
const onError = (err) => {
|
|
127109
127211
|
socket.destroy();
|
|
127110
127212
|
reject(
|
|
@@ -128590,14 +128692,14 @@ async function ensureAndroidDevtoolsInstalled(serial, options = {}) {
|
|
|
128590
128692
|
}
|
|
128591
128693
|
|
|
128592
128694
|
// ../tool-server/src/utils/android-devtools-client.ts
|
|
128593
|
-
var
|
|
128695
|
+
var net4 = __toESM(require("node:net"));
|
|
128594
128696
|
init_src2();
|
|
128595
128697
|
var DEFAULT_RPC_TIMEOUT_MS = 5e3;
|
|
128596
128698
|
var LONG_RPC_TIMEOUT_MS = 15e3;
|
|
128597
128699
|
var SET_TEXT_RPC_TIMEOUT_MS = 14e3;
|
|
128598
128700
|
function connectAndroidDevtoolsClient(localPort, onTerminated) {
|
|
128599
128701
|
return new Promise((resolve16, reject) => {
|
|
128600
|
-
const socket =
|
|
128702
|
+
const socket = net4.createConnection({ host: "127.0.0.1", port: localPort });
|
|
128601
128703
|
socket.setNoDelay(true);
|
|
128602
128704
|
const pending = /* @__PURE__ */ new Map();
|
|
128603
128705
|
let nextId = 1;
|
|
@@ -133287,7 +133389,7 @@ var chromiumJsRuntimeDebuggerBlueprint = {
|
|
|
133287
133389
|
};
|
|
133288
133390
|
|
|
133289
133391
|
// ../tool-server/src/blueprints/tv-control.ts
|
|
133290
|
-
var
|
|
133392
|
+
var net6 = __toESM(require("node:net"));
|
|
133291
133393
|
var fs31 = __toESM(require("node:fs"));
|
|
133292
133394
|
var import_node_child_process25 = require("node:child_process");
|
|
133293
133395
|
init_src2();
|
|
@@ -133307,7 +133409,7 @@ function hidSocketPath(udid) {
|
|
|
133307
133409
|
}
|
|
133308
133410
|
function sendLine(socketPath, line, timeoutMs = 1e4) {
|
|
133309
133411
|
return new Promise((resolve16, reject) => {
|
|
133310
|
-
const socket =
|
|
133412
|
+
const socket = net6.createConnection(socketPath);
|
|
133311
133413
|
const chunks = [];
|
|
133312
133414
|
let settled = false;
|
|
133313
133415
|
const timer = setTimeout(() => {
|
|
@@ -133395,7 +133497,7 @@ async function waitForSocket(socketPath, proc, timeoutMs) {
|
|
|
133395
133497
|
}
|
|
133396
133498
|
if (fs31.existsSync(socketPath)) {
|
|
133397
133499
|
const ok = await new Promise((resolve16) => {
|
|
133398
|
-
const s =
|
|
133500
|
+
const s = net6.createConnection(socketPath);
|
|
133399
133501
|
s.on("connect", () => {
|
|
133400
133502
|
s.destroy();
|
|
133401
133503
|
resolve16(true);
|
|
@@ -133886,7 +133988,7 @@ var androidTvControlBlueprint = {
|
|
|
133886
133988
|
const output2 = raw.trim().slice(0, 200);
|
|
133887
133989
|
if (/\bKilled\b/.test(output2)) {
|
|
133888
133990
|
throw new Error(
|
|
133889
|
-
`uiautomator could not capture the screen: ${output2}. Another UiAutomation client (the argent devtools helper, or a test runner such as Espresso or Appium) holds the accessibility connection. Stop it, for the helper with
|
|
133991
|
+
`uiautomator could not capture the screen: ${output2}. Another UiAutomation client (the argent devtools helper, or a test runner such as Espresso or Appium) holds the accessibility connection. Stop it, for the helper with \`${adbCommandPrefix(process.env)}adb shell am force-stop com.argent.androiddevtools\`, and try again.`
|
|
133890
133992
|
);
|
|
133891
133993
|
}
|
|
133892
133994
|
throw new Error(
|
|
@@ -137603,10 +137705,10 @@ function electronGuiChildEnv(overrides = {}) {
|
|
|
137603
137705
|
}
|
|
137604
137706
|
|
|
137605
137707
|
// ../tool-server/src/utils/free-port.ts
|
|
137606
|
-
var
|
|
137708
|
+
var net7 = __toESM(require("node:net"));
|
|
137607
137709
|
async function pickFreePort() {
|
|
137608
137710
|
return new Promise((resolve16, reject) => {
|
|
137609
|
-
const srv =
|
|
137711
|
+
const srv = net7.createServer();
|
|
137610
137712
|
srv.unref();
|
|
137611
137713
|
srv.on("error", reject);
|
|
137612
137714
|
srv.listen(0, "127.0.0.1", () => {
|
|
@@ -141111,94 +141213,6 @@ init_adb();
|
|
|
141111
141213
|
// ../tool-server/src/utils/device-orientation.ts
|
|
141112
141214
|
var import_node_fs13 = require("node:fs");
|
|
141113
141215
|
init_adb();
|
|
141114
|
-
|
|
141115
|
-
// ../tool-server/src/utils/adb-server.ts
|
|
141116
|
-
var net7 = __toESM(require("node:net"));
|
|
141117
|
-
async function adbServerShell(serial, shellCommand, options = {}) {
|
|
141118
|
-
const { host, port } = adbServerAddress(process.env);
|
|
141119
|
-
const timeoutMs = options.timeoutMs ?? 5e3;
|
|
141120
|
-
return new Promise((resolve16, reject) => {
|
|
141121
|
-
const socket = net7.createConnection({ host, port });
|
|
141122
|
-
socket.setNoDelay(true);
|
|
141123
|
-
const chunks = [];
|
|
141124
|
-
let stage = "transport";
|
|
141125
|
-
let pending = Buffer.alloc(0);
|
|
141126
|
-
let settled = false;
|
|
141127
|
-
const finish = (err, value) => {
|
|
141128
|
-
if (settled) return;
|
|
141129
|
-
settled = true;
|
|
141130
|
-
clearTimeout(timer);
|
|
141131
|
-
socket.destroy();
|
|
141132
|
-
if (err) reject(err);
|
|
141133
|
-
else resolve16(value ?? "");
|
|
141134
|
-
};
|
|
141135
|
-
const timer = setTimeout(
|
|
141136
|
-
() => finish(new Error(`adb server shell timed out after ${timeoutMs}ms: ${shellCommand}`)),
|
|
141137
|
-
timeoutMs
|
|
141138
|
-
);
|
|
141139
|
-
const send = (message) => {
|
|
141140
|
-
const payload = Buffer.from(message, "utf8");
|
|
141141
|
-
socket.write(payload.length.toString(16).padStart(4, "0") + message);
|
|
141142
|
-
};
|
|
141143
|
-
const takeStatus = () => {
|
|
141144
|
-
if (pending.length < 4) return false;
|
|
141145
|
-
const status = pending.subarray(0, 4).toString("latin1");
|
|
141146
|
-
if (status === "OKAY") {
|
|
141147
|
-
pending = pending.subarray(4);
|
|
141148
|
-
return true;
|
|
141149
|
-
}
|
|
141150
|
-
if (status === "FAIL") {
|
|
141151
|
-
if (pending.length < 8) return false;
|
|
141152
|
-
const len = parseInt(pending.subarray(4, 8).toString("latin1"), 16);
|
|
141153
|
-
if (pending.length < 8 + len) return false;
|
|
141154
|
-
finish(new Error(`adb server: ${pending.subarray(8, 8 + len).toString("utf8")}`));
|
|
141155
|
-
return false;
|
|
141156
|
-
}
|
|
141157
|
-
finish(new Error(`adb server: unexpected status ${JSON.stringify(status)}`));
|
|
141158
|
-
return false;
|
|
141159
|
-
};
|
|
141160
|
-
socket.once("connect", () => send(`host:transport:${serial}`));
|
|
141161
|
-
socket.on("data", (data) => {
|
|
141162
|
-
if (stage === "output") {
|
|
141163
|
-
chunks.push(data);
|
|
141164
|
-
return;
|
|
141165
|
-
}
|
|
141166
|
-
pending = Buffer.concat([pending, data]);
|
|
141167
|
-
if (stage === "transport" && takeStatus()) {
|
|
141168
|
-
stage = "shell";
|
|
141169
|
-
send(`shell:${shellCommand}`);
|
|
141170
|
-
}
|
|
141171
|
-
if (stage === "shell" && takeStatus()) {
|
|
141172
|
-
stage = "output";
|
|
141173
|
-
if (pending.length) chunks.push(pending);
|
|
141174
|
-
pending = Buffer.alloc(0);
|
|
141175
|
-
}
|
|
141176
|
-
});
|
|
141177
|
-
socket.once("error", (err) => finish(err));
|
|
141178
|
-
socket.once("close", () => {
|
|
141179
|
-
if (stage === "output") finish(void 0, Buffer.concat(chunks).toString("utf8"));
|
|
141180
|
-
else finish(new Error("adb server closed the connection before answering"));
|
|
141181
|
-
});
|
|
141182
|
-
});
|
|
141183
|
-
}
|
|
141184
|
-
function configuredAdbServerPort(env, configured) {
|
|
141185
|
-
if (configured === null || env.ADB_SERVER_SOCKET || env.ANDROID_ADB_SERVER_PORT) return null;
|
|
141186
|
-
return String(configured);
|
|
141187
|
-
}
|
|
141188
|
-
function adbServerAddress(env) {
|
|
141189
|
-
const socketSpec = env.ADB_SERVER_SOCKET;
|
|
141190
|
-
if (socketSpec) {
|
|
141191
|
-
const m = /^tcp:(?:(.*):)?(\d+)$/.exec(socketSpec.trim());
|
|
141192
|
-
if (m) return { host: m[1] || "127.0.0.1", port: Number(m[2]) };
|
|
141193
|
-
}
|
|
141194
|
-
const port = Number(env.ANDROID_ADB_SERVER_PORT);
|
|
141195
|
-
return {
|
|
141196
|
-
host: env.ANDROID_ADB_SERVER_ADDRESS?.trim() || "127.0.0.1",
|
|
141197
|
-
port: Number.isInteger(port) && port > 0 && port < 65536 ? port : 5037
|
|
141198
|
-
};
|
|
141199
|
-
}
|
|
141200
|
-
|
|
141201
|
-
// ../tool-server/src/utils/device-orientation.ts
|
|
141202
141216
|
var SURFACE_ROTATION_TO_NAME = {
|
|
141203
141217
|
0: "Portrait",
|
|
141204
141218
|
1: "LandscapeLeft",
|
|
@@ -158311,7 +158325,7 @@ function androidSalvage(midCapture, onDeviceTracePath) {
|
|
|
158311
158325
|
if (midCapture) {
|
|
158312
158326
|
return "The perfetto daemon was killed and its on-device trace removed, so no trace survived \u2014 re-profile to capture again.";
|
|
158313
158327
|
}
|
|
158314
|
-
return `The recording had already ended before this teardown (the 10-minute cap), so the on-device trace was left in place${onDeviceTracePath ? ` at ${onDeviceTracePath}` : ""} \u2014 but this session was the only thing that could pull it to the host. Re-profile, or
|
|
158328
|
+
return `The recording had already ended before this teardown (the 10-minute cap), so the on-device trace was left in place${onDeviceTracePath ? ` at ${onDeviceTracePath}` : ""} \u2014 but this session was the only thing that could pull it to the host. Re-profile, or \`${adbCommandPrefix(process.env)}adb pull\` it yourself.`;
|
|
158315
158329
|
}
|
|
158316
158330
|
function clearLiveState(state3) {
|
|
158317
158331
|
state3.profilingActive = false;
|
|
@@ -161067,7 +161081,7 @@ async function validateAndroidAppProcess(serial, appProcess) {
|
|
|
161067
161081
|
}
|
|
161068
161082
|
if (pidOut.trim().length > 0) return;
|
|
161069
161083
|
throw new FailureError(
|
|
161070
|
-
`app_process \`${appProcess}\` was not found on ${serial}: no installed package and no running process matches that name. Pass an installed package (see
|
|
161084
|
+
`app_process \`${appProcess}\` was not found on ${serial}: no installed package and no running process matches that name. Pass an installed package (see \`${adbCommandPrefix(process.env)}adb shell pm list packages\`), or omit app_process to auto-detect the foreground app.`,
|
|
161071
161085
|
{
|
|
161072
161086
|
error_code: FAILURE_CODES.NATIVE_PROFILER_APP_PROCESS_NOT_FOUND,
|
|
161073
161087
|
failure_stage: "android_app_process_validate",
|
|
@@ -161623,7 +161637,7 @@ async function renderThreadBreakdownAndroid(opts, target) {
|
|
|
161623
161637
|
function describeStacklessSamples(appPackage, cpuRows, stacklessSamples) {
|
|
161624
161638
|
const unwound = cpuRows.some((r) => r.leaf_mapping);
|
|
161625
161639
|
const head = `${stacklessSamples} CPU sample${stacklessSamples === 1 ? "" : "s"} were captured for \`${appPackage}\`, but none carry a usable call stack, so no CPU hotspots could be computed and \`profiler-stack-query\` mode=\`function_callers\` / mode=\`hang_stacks\` will find nothing. The app was running \u2014 this is a capture limitation, not an idle app. mode=\`thread_breakdown\` still works, since it counts samples and needs no stacks.`;
|
|
161626
|
-
return unwound ? `${head} The stacks were unwound but no frame resolved to a symbol, which points at stripped native libraries. Profile a build that keeps its symbols (a debug build, or a release build with unstripped \`.so\`s).` : `${head} No stack was unwound at all: Perfetto only unwinds a process it can read \`/proc/<pid>/mem\` for. Profile a debug build, or add \`<profileable android:shell="true"/>\` to \`<application>\` and rebuild \u2014 verify with
|
|
161640
|
+
return unwound ? `${head} The stacks were unwound but no frame resolved to a symbol, which points at stripped native libraries. Profile a build that keeps its symbols (a debug build, or a release build with unstripped \`.so\`s).` : `${head} No stack was unwound at all: Perfetto only unwinds a process it can read \`/proc/<pid>/mem\` for. Profile a debug build, or add \`<profileable android:shell="true"/>\` to \`<application>\` and rebuild \u2014 verify with \`${adbCommandPrefix(process.env)}adb shell dumpsys package ${appPackage}\`, which shows \`DEBUGGABLE\` for a profileable target. Platform packages such as \`com.android.settings\` are never profileable.`;
|
|
161627
161641
|
}
|
|
161628
161642
|
function cpuRowsToAggregatorRows(rows, traceStartNs) {
|
|
161629
161643
|
const traceStartMs = Math.round(traceStartNs / 1e6);
|
|
@@ -164417,7 +164431,7 @@ async function executeAndroid(api, params) {
|
|
|
164417
164431
|
);
|
|
164418
164432
|
}
|
|
164419
164433
|
if (params.mode === "leak_stacks") {
|
|
164420
|
-
return
|
|
164434
|
+
return `_Memory leak detection is not yet supported on Android. Use the RSS-growth weak signal in the analyze report as a hint, or capture a heap dump manually with \`${adbCommandPrefix(process.env)}adb shell am dumpheap\`._`;
|
|
164421
164435
|
}
|
|
164422
164436
|
return runAndroidStackQuery({
|
|
164423
164437
|
tracePath: api.traceFile,
|
package/package.json
CHANGED
|
@@ -13,7 +13,7 @@ Verify with `adb version` and `emulator -list-avds`.
|
|
|
13
13
|
|
|
14
14
|
## 2. Setup
|
|
15
15
|
|
|
16
|
-
1. **Find a ready device**: call `list-devices`. Filter for entries with `platform: "android"`. Ready devices (`state: "device"`) come first. Pick the first `serial` (e.g. `emulator-5554`) unless the user specified one.
|
|
16
|
+
1. **Find a ready device**: call `list-devices`. Filter for entries with `platform: "android"`. Ready devices (`state: "device"`) come first. Pick the first `serial` (e.g. `emulator-5554`) unless the user specified one. If the result has a `hint` about the adb server, prefix every `adb` command that you run yourself, as the hint shows.
|
|
17
17
|
2. **Boot if needed**: if nothing Android is ready, call `boot-device` with `avdName: <name>` from the same call's `avds` list. The tool transparently picks hot vs cold boot: it probes the AVD's `default_boot` snapshot, restores it under a tight deadline when usable, and falls back to a full cold boot otherwise. Hot path is typically ~30s; cold path takes 2–10 min. On any stage failure the tool kills the emulator process it started so your next call starts from a clean state.
|
|
18
18
|
3. **Metro (for React Native)**: once a device is up, run `adb -s <serial> reverse tcp:8081 tcp:8081` so the device can reach Metro on your host. Repeat if the device restarts.
|
|
19
19
|
|
|
@@ -387,7 +387,7 @@ Stops on the first error (or unmet `await-ui-element` condition) and returns par
|
|
|
387
387
|
|
|
388
388
|
### Android
|
|
389
389
|
|
|
390
|
-
- **Metro reachability**: run `adb reverse tcp:8081 tcp:8081` on the device before the RN app starts, or Metro won't be reachable from the device. See `argent-metro-debugger` for the full workflow. Re-run if the device restarts.
|
|
390
|
+
- **Metro reachability**: run `adb reverse tcp:8081 tcp:8081` on the device before the RN app starts, or Metro won't be reachable from the device. See `argent-metro-debugger` for the full workflow. Re-run if the device restarts. If `list-devices` returns a `hint` about the adb server, prefix the command as the hint shows.
|
|
391
391
|
- **First-launch permission prompts**: `reinstall-app` on Android always installs with `-g` so runtime permissions are pre-granted on first launch; no flag to pass.
|
|
392
392
|
- **Locked screen / secure surfaces**: `describe` throws a clear error if it can't capture (keyguard, DRM, Play Integrity). Unlock the device or fall back to `screenshot`.
|
|
393
393
|
- **APK vs .app in `reinstall-app`**: pass `.apk` absolute path on Android; `.app` directory on iOS.
|
|
@@ -21,7 +21,7 @@ Android emulators and physical devices do not resolve the host's `localhost` by
|
|
|
21
21
|
adb -s <serial> reverse tcp:8081 tcp:8081
|
|
22
22
|
```
|
|
23
23
|
|
|
24
|
-
`<serial>` is the Android `serial` from `list-devices`. If the device restarts or adb drops, re-run the command. A failing Metro connection on Android almost always means `adb reverse` has not been done or has been lost.
|
|
24
|
+
`<serial>` is the Android `serial` from `list-devices`. If `list-devices` returns a `hint` about the adb server, prefix the command as the hint shows. If the device restarts or adb drops, re-run the command. A failing Metro connection on Android almost always means `adb reverse` has not been done or has been lost.
|
|
25
25
|
|
|
26
26
|
## 2. Tool Overview
|
|
27
27
|
|
|
@@ -54,7 +54,7 @@ npx react-native run-ios --simulator="<name>" # iOS (or --udid <UDID>)
|
|
|
54
54
|
npx react-native run-android --deviceId=<adb-serial> # Android
|
|
55
55
|
```
|
|
56
56
|
|
|
57
|
-
**Android only**: after install, run `adb -s <serial> reverse tcp:8081 tcp:8081` so the emulator/device can reach Metro on your host. Repeat if the device restarts or adb drops.
|
|
57
|
+
**Android only**: after install, run `adb -s <serial> reverse tcp:8081 tcp:8081` so the emulator/device can reach Metro on your host. Repeat if the device restarts or adb drops. If `list-devices` returns a `hint` about the adb server, prefix this and every other `adb` command that you run yourself, as the hint shows.
|
|
58
58
|
|
|
59
59
|
**Agent checklist:**
|
|
60
60
|
|
|
@@ -233,6 +233,8 @@ If the user's intent is ambiguous (run existing tests, write new tests, or find
|
|
|
233
233
|
| Android native logs | `npx react-native log-android` or `adb -s <serial> logcat` |
|
|
234
234
|
| Clean + reinstall (nuclear) | See §3.1 step 3 |
|
|
235
235
|
|
|
236
|
+
If `list-devices` returns a `hint` about the adb server, prefix the `adb` commands above as the hint shows.
|
|
237
|
+
|
|
236
238
|
---
|
|
237
239
|
|
|
238
240
|
## Related Skills
|
|
@@ -26,7 +26,7 @@ For implementation tasks that modify visible UI, this workflow can also serve as
|
|
|
26
26
|
|
|
27
27
|
1. **Baseline screenshot**: Call `screenshot` to see the current UI state. For visual regression comparison or UI change verification, capture the baseline at `scale: 1.0` with `includeImageInContext: false` and keep the returned `path` before editing whenever feasible.
|
|
28
28
|
2. **Find target**: Before tapping, use a discovery tool to get element coordinates:
|
|
29
|
-
- **React Native apps**: use `debugger-component-tree`: it returns component names with (tap: x,y) coordinates. This is the preferred tool for RN apps on either platform. To use it, resolve the `argent-react-native-app-workflow` skill for setup; on Android you must also run `adb -s <serial> reverse tcp:8081 tcp:8081` so Metro is reachable from the device.
|
|
29
|
+
- **React Native apps**: use `debugger-component-tree`: it returns component names with (tap: x,y) coordinates. This is the preferred tool for RN apps on either platform. To use it, resolve the `argent-react-native-app-workflow` skill for setup; on Android you must also run `adb -s <serial> reverse tcp:8081 tcp:8081` so Metro is reachable from the device, prefixed as the `list-devices` `hint` shows when it names an adb server.
|
|
30
30
|
- **Standard app screens and in-app modals**: use `describe`. On iOS this returns the AX tree (falls back to native-devtools when AX is empty); on Android it returns the uiautomator tree in the same DescribeNode shape.
|
|
31
31
|
- **Permission prompts / system modal overlays**: try `describe` first. Fall back to `screenshot` only if the overlay is not exposed reliably. When the app raises its own permission dialog, answer it here; that's the real flow under test. To take a prompt _out_ of the flow (pre-grant/deny before launch, re-enable a permission the user already denied, or reset it so the dialog reappears), use the `argent-settings-permissions` skill during setup instead of interacting with the dialog.
|
|
32
32
|
- **Fallback**: use `screenshot` to estimate where the desired component is, then verify immediately after the action.
|
|
@@ -37,7 +37,7 @@ description: Control and inspect TV apps via argent, Apple TV (tvOS), Android TV
|
|
|
37
37
|
|
|
38
38
|
- Boot the leanback AVD like any emulator; see `argent-android-emulator-setup`.
|
|
39
39
|
- **`describe` may report zero focusables on a screen with visible tiles**: many `react-native-tvos` screens use RN's own focus engine, invisible to the OS accessibility tree. `describe` auto-falls-back to the full UI tree (and says so in the hint); `tv-remote` still moves focus, so drive blind + `screenshot` to confirm.
|
|
40
|
-
- Dev build: `adb -s <serial> reverse tcp:8081 tcp:8081`, deep-link `<pkg>://expo-development-client/?url=http%3A%2F%2F10.0.2.2%3A8081`, dismiss the first dev-menu with `adb shell input keyevent KEYCODE_DPAD_CENTER` (not Back: Back exits the app).
|
|
40
|
+
- Dev build: `adb -s <serial> reverse tcp:8081 tcp:8081`, deep-link `<pkg>://expo-development-client/?url=http%3A%2F%2F10.0.2.2%3A8081`, dismiss the first dev-menu with `adb shell input keyevent KEYCODE_DPAD_CENTER` (not Back: Back exits the app). If `list-devices` returns a `hint` about the adb server, prefix these `adb` commands as the hint shows.
|
|
41
41
|
|
|
42
42
|
### Fire TV (Vega / VVD)
|
|
43
43
|
|