Skip to content

Commit ebf45f1

Browse files
authored
feat: record start [path], screenshot [path], --record-json (#18)
1 parent 8f653b5 commit ebf45f1

7 files changed

Lines changed: 45 additions & 7 deletions

File tree

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,6 @@ Flags:
9999
- `--udid <udid>` (iOS)
100100
- `--serial <serial>` (Android)
101101
- `--activity <component>` (Android; package/Activity or package/.Activity)
102-
- `--out <path>` (screenshot)
103102
- `--session <name>`
104103
- `--verbose` for daemon and runner logs
105104
- `--json` for structured output
@@ -115,6 +114,7 @@ Sessions:
115114
- `close` stops the session and releases device resources. Pass an app to close it explicitly, or omit to just close the session.
116115
- Use `--session <name>` to manage multiple sessions.
117116
- Session logs are written to `~/.agent-device/sessions/<session>-<timestamp>.ad`.
117+
- With `--record-json`, JSON logs are written to `~/.agent-device/sessions/<session>-<timestamp>.json` by default.
118118

119119
Find (semantic):
120120
- `find <text> <action> [value]` finds by any text (label/value/identifier) using a scoped snapshot.

skills/agent-device/SKILL.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -117,7 +117,7 @@ agent-device alert get
117117
```bash
118118
agent-device get text @e1
119119
agent-device get attrs @e1
120-
agent-device screenshot --out out.png
120+
agent-device screenshot out.png
121121
```
122122

123123
### Trace logs (AX/XCTest)

src/core/dispatch.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -244,7 +244,8 @@ export async function dispatchCommand(
244244
return { scale, x, y };
245245
}
246246
case 'screenshot': {
247-
const path = outPath ?? `./screenshot-${Date.now()}.png`;
247+
const positionalPath = positionals[0];
248+
const path = positionalPath ?? outPath ?? `./screenshot-${Date.now()}.png`;
248249
await interactor.screenshot(path);
249250
return { path };
250251
}

src/daemon.ts

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1413,7 +1413,7 @@ function writeSessionLog(session: SessionState): void {
14131413
const safeName = session.name.replace(/[^a-zA-Z0-9._-]/g, '_');
14141414
const timestamp = new Date(session.createdAt).toISOString().replace(/[:.]/g, '-');
14151415
const scriptPath = path.join(sessionsDir, `${safeName}-${timestamp}.ad`);
1416-
const filePath = path.join(sessionsDir, `${safeName}-${timestamp}.json`);
1416+
const filePath = resolveSessionJsonPath(session, safeName, timestamp);
14171417
const payload = {
14181418
name: session.name,
14191419
device: session.device,
@@ -1425,13 +1425,41 @@ function writeSessionLog(session: SessionState): void {
14251425
const script = formatScript(session, payload.optimizedActions);
14261426
fs.writeFileSync(scriptPath, script);
14271427
if (session.actions.some((action) => action.flags?.recordJson)) {
1428+
fs.mkdirSync(path.dirname(filePath), { recursive: true });
14281429
fs.writeFileSync(filePath, JSON.stringify(payload, null, 2));
14291430
}
14301431
} catch {
14311432
// ignore
14321433
}
14331434
}
14341435

1436+
function resolveSessionJsonPath(session: SessionState, safeName: string, timestamp: string): string {
1437+
const defaultFile = path.join(sessionsDir, `${safeName}-${timestamp}.json`);
1438+
const actionWithOut = [...session.actions]
1439+
.reverse()
1440+
.find((action) => action.flags?.recordJson && typeof action.flags?.out === 'string' && action.flags.out.trim().length > 0);
1441+
if (!actionWithOut || !actionWithOut.flags?.out) {
1442+
return defaultFile;
1443+
}
1444+
1445+
const rawOut = actionWithOut.flags.out.trim();
1446+
const resolvedOut = expandHome(rawOut);
1447+
const wantsDirectory = rawOut.endsWith('/') || rawOut.endsWith('\\');
1448+
if (wantsDirectory) {
1449+
return path.join(resolvedOut, `${safeName}-${timestamp}.json`);
1450+
}
1451+
1452+
try {
1453+
if (fs.existsSync(resolvedOut) && fs.statSync(resolvedOut).isDirectory()) {
1454+
return path.join(resolvedOut, `${safeName}-${timestamp}.json`);
1455+
}
1456+
} catch {
1457+
return defaultFile;
1458+
}
1459+
1460+
return resolvedOut;
1461+
}
1462+
14351463
function defaultTracePath(session: SessionState): string {
14361464
const safeName = session.name.replace(/[^a-zA-Z0-9._-]/g, '_');
14371465
const timestamp = new Date().toISOString().replace(/[:.]/g, '-');

src/utils/args.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -193,7 +193,7 @@ Commands:
193193
fill <x> <y> <text> | fill <@ref> <text> Tap then type
194194
scroll <direction> [amount] Scroll in direction (0-1 amount)
195195
scrollintoview <text> Scroll until text appears (Android only)
196-
screenshot [--out path] Capture screenshot
196+
screenshot [path] Capture screenshot
197197
record start [path] Start screen recording
198198
record stop Stop screen recording
199199
trace start [path] Start trace log capture
@@ -213,7 +213,6 @@ Flags:
213213
--udid <udid> iOS device UDID
214214
--serial <serial> Android device serial
215215
--activity <component> Android activity to launch (package/Activity)
216-
--out <path> Output path for screenshots
217216
--session <name> Named session
218217
--verbose Stream daemon/runner logs
219218
--json JSON output

website/docs/docs/commands.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,3 +59,13 @@ agent-device settings airplane off
5959
agent-device settings location on
6060
agent-device settings location off
6161
```
62+
63+
## Media and logs
64+
65+
```bash
66+
agent-device screenshot # Auto filename
67+
agent-device screenshot page.png # Explicit screenshot path
68+
agent-device record start # Start screen recording to auto filename
69+
agent-device record start session.mp4 # Start recording to explicit path
70+
agent-device record stop # Stop active recording
71+
```

website/docs/docs/quick-start.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ agent-device snapshot -i # Get interactive elements with refs
3131
agent-device click @e2 # Click by ref
3232
agent-device fill @e3 "test@example.com" # Clear then type (Android verifies and retries once if needed)
3333
agent-device get text @e1 # Get text content
34-
agent-device screenshot --out page.png # Save to specific path
34+
agent-device screenshot page.png # Save to specific path
3535
agent-device close
3636
```
3737

0 commit comments

Comments
 (0)