Skip to content

Commit 8b36c2a

Browse files
authored
feat: support remote runtime hints and artifact retrieval (#199)
* feat: add remote runtime hints and artifact retrieval * fix: apply session runtime transport hints on open * fix: secure and time out artifact downloads
1 parent 150399e commit 8b36c2a

18 files changed

Lines changed: 1880 additions & 36 deletions

README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -314,6 +314,8 @@ Navigation helpers:
314314
- `reinstall <app> <path>` uninstalls and installs the app binary in one command (Android + iOS simulator/device).
315315
- `install`/`reinstall` accept package/bundle id style app names and support `~` in paths.
316316
- When `AGENT_DEVICE_DAEMON_BASE_URL` targets a remote daemon, local `.apk`/`.aab`/`.ipa` files and `.app` bundles are uploaded automatically before `install`/`reinstall`.
317+
- Remote daemon clients can persist session-scoped runtime hints with `runtime set` before `open`; Android launches write React Native dev prefs, and iOS simulator launches write React Native bundle defaults before app start. Example: `agent-device runtime set --session my-session --platform android --metro-host 10.0.0.10 --metro-port 8081 --launch-url "myapp://dev"`.
318+
- Remote daemon screenshots and recordings are materialized back to the caller path instead of returning host-local daemon paths.
317319
- To force a daemon-side path instead of uploading a local file, prefix it with `remote:`, for example `remote:/srv/builds/MyApp.app`.
318320
- Supported binary formats for `install`/`reinstall`: Android `.apk` and `.aab`, iOS `.app` and `.ipa`.
319321
- `.aab` requires `bundletool` in `PATH`, or `AGENT_DEVICE_BUNDLETOOL_JAR=<path-to-bundletool-all.jar>` (with `java` in `PATH`).

src/cli.ts

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -262,6 +262,39 @@ export async function runCli(argv: string[], deps: CliDeps = DEFAULT_CLI_DEPS):
262262
if (logTailStopper) logTailStopper();
263263
return;
264264
}
265+
if (command === 'runtime') {
266+
const data = response.data as Record<string, unknown> | undefined;
267+
const cleared = data?.cleared === true;
268+
const configured = data?.configured === true;
269+
if (cleared) {
270+
process.stdout.write('Runtime hints cleared\n');
271+
if (logTailStopper) logTailStopper();
272+
return;
273+
}
274+
if (!configured) {
275+
process.stdout.write('No runtime hints configured\n');
276+
if (logTailStopper) logTailStopper();
277+
return;
278+
}
279+
process.stdout.write(`${JSON.stringify(data?.runtime ?? {}, null, 2)}\n`);
280+
if (logTailStopper) logTailStopper();
281+
return;
282+
}
283+
if (command === 'screenshot') {
284+
const pathOut = typeof (response.data as any)?.path === 'string' ? (response.data as any).path : '';
285+
if (pathOut) {
286+
process.stdout.write(`${pathOut}\n`);
287+
}
288+
if (logTailStopper) logTailStopper();
289+
return;
290+
}
291+
if (command === 'record') {
292+
const data = response.data as Record<string, unknown> | undefined;
293+
const outPath = typeof data?.outPath === 'string' ? data.outPath : '';
294+
if (outPath) process.stdout.write(`${outPath}\n`);
295+
if (logTailStopper) logTailStopper();
296+
return;
297+
}
265298
if (command === 'logs') {
266299
const data = response.data as Record<string, unknown> | undefined;
267300
const pathOut = typeof data?.path === 'string' ? data.path : '';

0 commit comments

Comments
 (0)