agent-device 0.10.0 → 0.10.2

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.
Files changed (76) hide show
  1. package/README.md +4 -607
  2. package/dist/src/331.js +3 -3
  3. package/dist/src/425.js +1 -0
  4. package/dist/src/bin.js +28 -28
  5. package/dist/src/core/dispatch.d.ts +2 -0
  6. package/dist/src/core/session-surface.d.ts +3 -0
  7. package/dist/src/core/settings-contract.d.ts +2 -1
  8. package/dist/src/daemon/android-system-dialog.d.ts +11 -0
  9. package/dist/src/daemon/app-log-ios.d.ts +2 -1
  10. package/dist/src/daemon/app-log-process.d.ts +1 -1
  11. package/dist/src/daemon/app-log.d.ts +1 -1
  12. package/dist/src/daemon/context.d.ts +2 -0
  13. package/dist/src/daemon/handlers/interaction-common.d.ts +30 -1
  14. package/dist/src/daemon/handlers/interaction-read.d.ts +14 -0
  15. package/dist/src/daemon/handlers/interaction-touch.d.ts +45 -0
  16. package/dist/src/daemon/handlers/interaction.d.ts +2 -0
  17. package/dist/src/daemon/handlers/record-trace-android.d.ts +18 -0
  18. package/dist/src/daemon/handlers/record-trace-ios.d.ts +52 -0
  19. package/dist/src/daemon/handlers/record-trace-recording.d.ts +32 -0
  20. package/dist/src/daemon/handlers/record-trace.d.ts +2 -7
  21. package/dist/src/daemon/handlers/snapshot-capture.d.ts +11 -4
  22. package/dist/src/daemon/record-trace-errors.d.ts +6 -0
  23. package/dist/src/daemon/recording-gestures.d.ts +3 -0
  24. package/dist/src/daemon/recording-telemetry.d.ts +20 -0
  25. package/dist/src/daemon/recording-timing.d.ts +24 -0
  26. package/dist/src/daemon/request-router.d.ts +6 -0
  27. package/dist/src/daemon/script-utils.d.ts +1 -0
  28. package/dist/src/daemon/snapshot-processing.d.ts +1 -0
  29. package/dist/src/daemon/touch-reference-frame.d.ts +7 -0
  30. package/dist/src/daemon/types.d.ts +65 -11
  31. package/dist/src/daemon.js +62 -36
  32. package/dist/src/platforms/android/index.d.ts +1 -1
  33. package/dist/src/platforms/android/input-actions.d.ts +5 -0
  34. package/dist/src/platforms/android/settings.d.ts +1 -1
  35. package/dist/src/platforms/ios/apps.d.ts +1 -1
  36. package/dist/src/platforms/ios/macos-helper.d.ts +69 -0
  37. package/dist/src/platforms/ios/runner-client.d.ts +2 -2
  38. package/dist/src/platforms/ios/runner-session.d.ts +5 -0
  39. package/dist/src/platforms/ios/runner-xctestrun.d.ts +3 -1
  40. package/dist/src/recording/overlay.d.ts +10 -0
  41. package/dist/src/utils/command-schema.d.ts +2 -0
  42. package/dist/src/utils/interactors.d.ts +8 -8
  43. package/dist/src/utils/snapshot-lines.d.ts +5 -2
  44. package/dist/src/utils/snapshot.d.ts +8 -1
  45. package/dist/src/utils/text-surface.d.ts +19 -0
  46. package/dist/src/utils/video.d.ts +9 -0
  47. package/ios-runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+CommandExecution.swift +196 -51
  48. package/ios-runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Interaction.swift +133 -0
  49. package/ios-runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Lifecycle.swift +1 -1
  50. package/ios-runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Models.swift +33 -1
  51. package/ios-runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+ScreenRecorder.swift +4 -6
  52. package/ios-runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests.swift +1 -0
  53. package/ios-runner/AgentDeviceRunner/RecordingScripts/recording-overlay.swift +571 -0
  54. package/ios-runner/AgentDeviceRunner/RecordingScripts/recording-trim.swift +140 -0
  55. package/macos-helper/Package.swift +18 -0
  56. package/macos-helper/Sources/AgentDeviceMacOSHelper/SnapshotTraversal.swift +543 -0
  57. package/macos-helper/Sources/AgentDeviceMacOSHelper/main.swift +545 -0
  58. package/package.json +4 -1
  59. package/skills/agent-device/SKILL.md +25 -334
  60. package/skills/agent-device/references/bootstrap-install.md +167 -0
  61. package/skills/agent-device/references/coordinate-system.md +24 -4
  62. package/skills/agent-device/references/debugging.md +115 -0
  63. package/skills/agent-device/references/exploration.md +193 -0
  64. package/skills/agent-device/references/macos-desktop.md +55 -57
  65. package/skills/agent-device/references/remote-tenancy.md +56 -47
  66. package/skills/agent-device/references/verification.md +103 -0
  67. package/dist/src/274.js +0 -1
  68. package/dist/src/daemon/handlers/interaction-fill.d.ts +0 -3
  69. package/dist/src/daemon/handlers/interaction-press.d.ts +0 -3
  70. package/skills/agent-device/references/batching.md +0 -79
  71. package/skills/agent-device/references/logs-and-debug.md +0 -113
  72. package/skills/agent-device/references/perf-metrics.md +0 -53
  73. package/skills/agent-device/references/permissions.md +0 -70
  74. package/skills/agent-device/references/session-management.md +0 -101
  75. package/skills/agent-device/references/snapshot-refs.md +0 -102
  76. package/skills/agent-device/references/video-recording.md +0 -41
@@ -1,6 +1,6 @@
1
1
  import { dispatchCommand, type CommandFlags } from '../../core/dispatch.ts';
2
2
  import type { DaemonCommandContext } from '../context.ts';
3
- import type { DaemonRequest } from '../types.ts';
3
+ import type { DaemonRequest, DaemonResponse, SessionState } from '../types.ts';
4
4
  import { SessionStore } from '../session-store.ts';
5
5
  export type ContextFromFlags = (flags: CommandFlags | undefined, appBundleId?: string, traceLogPath?: string) => DaemonCommandContext;
6
6
  export type InteractionHandlerParams = {
@@ -10,3 +10,32 @@ export type InteractionHandlerParams = {
10
10
  contextFromFlags: ContextFromFlags;
11
11
  dispatch: typeof dispatchCommand;
12
12
  };
13
+ export declare function buildTouchVisualizationResult(params: {
14
+ data: Record<string, unknown> | undefined;
15
+ fallbackX: number;
16
+ fallbackY: number;
17
+ referenceFrame?: {
18
+ referenceWidth: number;
19
+ referenceHeight: number;
20
+ };
21
+ extra?: Record<string, unknown>;
22
+ }): Record<string, unknown>;
23
+ export declare function dispatchRecordedTouchInteraction(params: {
24
+ session: SessionState;
25
+ sessionStore: SessionStore;
26
+ requestCommand: string;
27
+ requestPositionals: string[];
28
+ flags: CommandFlags | undefined;
29
+ contextFromFlags: ContextFromFlags;
30
+ dispatch: typeof dispatchCommand;
31
+ interactionCommand: string;
32
+ interactionPositionals: string[];
33
+ outPath: string | undefined;
34
+ buildPayloads: (data: Record<string, unknown> | undefined) => {
35
+ result: Record<string, unknown>;
36
+ responseData?: Record<string, unknown>;
37
+ } | Promise<{
38
+ result: Record<string, unknown>;
39
+ responseData?: Record<string, unknown>;
40
+ }>;
41
+ }): Promise<DaemonResponse>;
@@ -0,0 +1,14 @@
1
+ import { dispatchCommand, type CommandFlags } from '../../core/dispatch.ts';
2
+ import type { SessionState } from '../types.ts';
3
+ import type { SnapshotNode } from '../../utils/snapshot.ts';
4
+ import type { ContextFromFlags } from './interaction-common.ts';
5
+ export declare function readTextForNode(params: {
6
+ device: SessionState['device'];
7
+ node: SnapshotNode;
8
+ flags: CommandFlags | undefined;
9
+ appBundleId?: string;
10
+ traceOutPath?: string;
11
+ surface?: SessionState['surface'];
12
+ contextFromFlags: ContextFromFlags;
13
+ dispatch: typeof dispatchCommand;
14
+ }): Promise<string>;
@@ -0,0 +1,45 @@
1
+ import { dispatchCommand, type CommandFlags } from '../../core/dispatch.ts';
2
+ import { type SnapshotNode } from '../../utils/snapshot.ts';
3
+ import type { DaemonRequest, DaemonResponse, SessionState } from '../types.ts';
4
+ import { SessionStore } from '../session-store.ts';
5
+ import { getAndroidScreenSize } from '../../platforms/android/index.ts';
6
+ import { type ContextFromFlags } from './interaction-common.ts';
7
+ type CaptureSnapshotForSession = (session: SessionState, flags: CommandFlags | undefined, sessionStore: SessionStore, contextFromFlags: ContextFromFlags, options: {
8
+ interactiveOnly: boolean;
9
+ }, dispatch?: typeof dispatchCommand) => Promise<{
10
+ nodes: SnapshotNode[];
11
+ truncated?: boolean;
12
+ createdAt: number;
13
+ backend?: 'xctest' | 'android' | 'macos-helper';
14
+ }>;
15
+ type ResolveRefTarget = ((params: {
16
+ session: SessionState;
17
+ refInput: string;
18
+ fallbackLabel: string;
19
+ requireRect: boolean;
20
+ invalidRefMessage: string;
21
+ notFoundMessage: string;
22
+ }) => {
23
+ ok: true;
24
+ target: {
25
+ ref: string;
26
+ node: SnapshotNode;
27
+ snapshotNodes: SnapshotNode[];
28
+ };
29
+ } | {
30
+ ok: false;
31
+ response: DaemonResponse;
32
+ }) | undefined;
33
+ type RefSnapshotFlagGuardResponse = (command: 'press' | 'fill' | 'get' | 'scrollintoview', flags: CommandFlags | undefined) => DaemonResponse | null;
34
+ export declare function handleTouchInteractionCommands(params: {
35
+ req: DaemonRequest;
36
+ sessionName: string;
37
+ sessionStore: SessionStore;
38
+ contextFromFlags: ContextFromFlags;
39
+ dispatch?: typeof dispatchCommand;
40
+ readAndroidScreenSize?: typeof getAndroidScreenSize;
41
+ captureSnapshotForSession: CaptureSnapshotForSession;
42
+ resolveRefTarget: NonNullable<ResolveRefTarget>;
43
+ refSnapshotFlagGuardResponse: RefSnapshotFlagGuardResponse;
44
+ }): Promise<DaemonResponse | null>;
45
+ export {};
@@ -1,7 +1,9 @@
1
1
  import { dispatchCommand } from '../../core/dispatch.ts';
2
2
  import type { DaemonResponse } from '../types.ts';
3
+ import { getAndroidScreenSize } from '../../platforms/android/index.ts';
3
4
  import type { InteractionHandlerParams } from './interaction-common.ts';
4
5
  export { unsupportedRefSnapshotFlags } from './interaction-flags.ts';
5
6
  export declare function handleInteractionCommands(params: Omit<InteractionHandlerParams, 'dispatch'> & {
6
7
  dispatch?: typeof dispatchCommand;
8
+ readAndroidScreenSize?: typeof getAndroidScreenSize;
7
9
  }): Promise<DaemonResponse | null>;
@@ -0,0 +1,18 @@
1
+ import type { DaemonResponse, SessionState } from '../types.ts';
2
+ import type { RecordTraceDeps } from './record-trace-recording.ts';
3
+ type AndroidDevice = SessionState['device'];
4
+ type AndroidRecording = Extract<NonNullable<SessionState['recording']>, {
5
+ platform: 'android';
6
+ }>;
7
+ type AndroidRecordingBase = Pick<AndroidRecording, 'outPath' | 'clientOutPath' | 'telemetryPath' | 'startedAt' | 'showTouches' | 'gestureEvents'>;
8
+ export declare function startAndroidRecording(params: {
9
+ deps: RecordTraceDeps;
10
+ device: AndroidDevice;
11
+ recordingBase: AndroidRecordingBase;
12
+ }): Promise<DaemonResponse | AndroidRecording>;
13
+ export declare function stopAndroidRecording(params: {
14
+ deps: RecordTraceDeps;
15
+ device: AndroidDevice;
16
+ recording: AndroidRecording;
17
+ }): Promise<DaemonResponse | null>;
18
+ export {};
@@ -0,0 +1,52 @@
1
+ import { SessionStore } from '../session-store.ts';
2
+ import type { DaemonRequest, DaemonResponse, SessionState } from '../types.ts';
3
+ import type { RecordTraceDeps, RecordingBase } from './record-trace-recording.ts';
4
+ export declare function normalizeAppBundleId(session: SessionState): string | undefined;
5
+ export declare function warmIosSimulatorRunner(params: {
6
+ req: DaemonRequest;
7
+ activeSession: SessionState;
8
+ device: SessionState['device'];
9
+ logPath?: string;
10
+ deps: RecordTraceDeps;
11
+ }): Promise<void>;
12
+ export declare function startIosDeviceRecording(params: {
13
+ req: DaemonRequest;
14
+ activeSession: SessionState;
15
+ sessionStore: SessionStore;
16
+ device: SessionState['device'];
17
+ logPath?: string;
18
+ deps: RecordTraceDeps;
19
+ fpsFlag: number | undefined;
20
+ recordingBase: RecordingBase;
21
+ appBundleId: string;
22
+ }): Promise<DaemonResponse | NonNullable<SessionState['recording']>>;
23
+ export declare function startMacOsRecording(params: {
24
+ req: DaemonRequest;
25
+ activeSession: SessionState;
26
+ device: SessionState['device'];
27
+ logPath?: string;
28
+ deps: RecordTraceDeps;
29
+ fpsFlag: number | undefined;
30
+ recordingBase: RecordingBase;
31
+ appBundleId: string;
32
+ }): Promise<DaemonResponse | NonNullable<SessionState['recording']>>;
33
+ export declare function stopIosDeviceRecording(params: {
34
+ req: DaemonRequest;
35
+ activeSession: SessionState;
36
+ device: SessionState['device'];
37
+ logPath?: string;
38
+ deps: RecordTraceDeps;
39
+ recording: Extract<NonNullable<SessionState['recording']>, {
40
+ platform: 'ios-device-runner';
41
+ }>;
42
+ }): Promise<DaemonResponse | null>;
43
+ export declare function stopMacOsRecording(params: {
44
+ req: DaemonRequest;
45
+ activeSession: SessionState;
46
+ device: SessionState['device'];
47
+ logPath?: string;
48
+ deps: RecordTraceDeps;
49
+ recording: Extract<NonNullable<SessionState['recording']>, {
50
+ platform: 'macos-runner';
51
+ }>;
52
+ }): Promise<DaemonResponse | null>;
@@ -0,0 +1,32 @@
1
+ import { SessionStore } from '../session-store.ts';
2
+ import type { DaemonRequest, DaemonResponse, RecordingGestureEvent } from '../types.ts';
3
+ import { runCmd, runCmdBackground } from '../../utils/exec.ts';
4
+ import { isPlayableVideo, waitForStableFile } from '../../utils/video.ts';
5
+ import { writeRecordingTelemetry } from '../recording-telemetry.ts';
6
+ import { runIosRunnerCommand } from '../../platforms/ios/runner-client.ts';
7
+ import { overlayRecordingTouches, trimRecordingStart } from '../../recording/overlay.ts';
8
+ export type RecordTraceDeps = {
9
+ runCmd: typeof runCmd;
10
+ runCmdBackground: typeof runCmdBackground;
11
+ runIosRunnerCommand: typeof runIosRunnerCommand;
12
+ waitForStableFile: typeof waitForStableFile;
13
+ isPlayableVideo: typeof isPlayableVideo;
14
+ writeRecordingTelemetry: typeof writeRecordingTelemetry;
15
+ trimRecordingStart: typeof trimRecordingStart;
16
+ overlayRecordingTouches: typeof overlayRecordingTouches;
17
+ };
18
+ export type RecordingBase = {
19
+ outPath: string;
20
+ clientOutPath?: string;
21
+ startedAt: number;
22
+ showTouches: boolean;
23
+ gestureEvents: RecordingGestureEvent[];
24
+ };
25
+ export declare function buildRecordTraceDeps(overrides?: Partial<RecordTraceDeps>): RecordTraceDeps;
26
+ export declare function handleRecordCommand(params: {
27
+ req: DaemonRequest;
28
+ sessionName: string;
29
+ sessionStore: SessionStore;
30
+ logPath?: string;
31
+ deps?: Partial<RecordTraceDeps>;
32
+ }): Promise<DaemonResponse>;
@@ -1,15 +1,10 @@
1
- import { runCmd, runCmdBackground } from '../../utils/exec.ts';
2
- import { runIosRunnerCommand } from '../../platforms/ios/runner-client.ts';
3
1
  import type { DaemonRequest, DaemonResponse } from '../types.ts';
4
2
  import { SessionStore } from '../session-store.ts';
3
+ import { type RecordTraceDeps } from './record-trace-recording.ts';
5
4
  export declare function handleRecordTraceCommands(params: {
6
5
  req: DaemonRequest;
7
6
  sessionName: string;
8
7
  sessionStore: SessionStore;
9
8
  logPath?: string;
10
- deps?: {
11
- runCmd: typeof runCmd;
12
- runCmdBackground: typeof runCmdBackground;
13
- runIosRunnerCommand: typeof runIosRunnerCommand;
14
- };
9
+ deps?: Partial<RecordTraceDeps>;
15
10
  }): Promise<DaemonResponse | null>;
@@ -1,21 +1,28 @@
1
- import { dispatchCommand } from '../../core/dispatch.ts';
1
+ import { dispatchCommand, type CommandFlags } from '../../core/dispatch.ts';
2
2
  import { type RawSnapshotNode, type SnapshotState } from '../../utils/snapshot.ts';
3
- import type { DaemonResponse, DaemonRequest, SessionState } from '../types.ts';
3
+ import type { DaemonResponse, SessionState } from '../types.ts';
4
4
  type CaptureSnapshotParams = {
5
5
  dispatchSnapshotCommand: typeof dispatchCommand;
6
6
  device: SessionState['device'];
7
7
  session: SessionState | undefined;
8
- req: DaemonRequest;
8
+ flags: CommandFlags | undefined;
9
+ outPath?: string;
9
10
  logPath: string;
10
11
  snapshotScope?: string;
11
12
  };
13
+ type SnapshotData = {
14
+ nodes?: RawSnapshotNode[];
15
+ truncated?: boolean;
16
+ backend?: 'xctest' | 'android' | 'macos-helper';
17
+ };
12
18
  export declare function captureSnapshot(params: CaptureSnapshotParams): Promise<{
13
19
  snapshot: SnapshotState;
14
20
  }>;
21
+ export declare function captureSnapshotData(params: CaptureSnapshotParams): Promise<SnapshotData>;
15
22
  export declare function buildSnapshotState(data: {
16
23
  nodes?: RawSnapshotNode[];
17
24
  truncated?: boolean;
18
- backend?: 'xctest' | 'android';
25
+ backend?: 'xctest' | 'android' | 'macos-helper';
19
26
  }, snapshotRaw: boolean | undefined): SnapshotState;
20
27
  export declare function resolveSnapshotScope(snapshotScope: string | undefined, session: SessionState | undefined): {
21
28
  ok: true;
@@ -0,0 +1,6 @@
1
+ export declare function formatRecordTraceError(error: unknown): string;
2
+ export declare function formatRecordTraceExecFailure(result: {
3
+ stdout: string;
4
+ stderr: string;
5
+ exitCode: number;
6
+ }, command: string): string;
@@ -0,0 +1,3 @@
1
+ import type { SessionState } from './types.ts';
2
+ export declare function recordTouchVisualizationEvent(session: SessionState, command: string, positionals: string[], result: Record<string, unknown> | void, fallback?: Record<string, unknown>, startedAtMs?: number, finishedAtMs?: number): void;
3
+ export declare function augmentScrollVisualizationResult(session: SessionState, command: string, positionals: string[], result: Record<string, unknown> | void): Record<string, unknown> | void;
@@ -0,0 +1,20 @@
1
+ import type { RecordingGestureEvent } from './types.ts';
2
+ type RecordingTelemetryState = {
3
+ outPath: string;
4
+ gestureEvents: RecordingGestureEvent[];
5
+ telemetryPath?: string;
6
+ };
7
+ export declare function deriveRecordingTelemetryPath(videoPath: string): string;
8
+ export declare function trimRecordingTelemetryEvents(events: RecordingGestureEvent[], trimStartMs: number): RecordingGestureEvent[];
9
+ export declare function normalizeRecordingTelemetryEvents(events: RecordingGestureEvent[]): RecordingGestureEvent[];
10
+ export declare function writeRecordingTelemetry(params: {
11
+ videoPath: string;
12
+ events: RecordingGestureEvent[];
13
+ trimStartMs?: number;
14
+ }): string;
15
+ export declare function persistRecordingTelemetry(params: {
16
+ recording: RecordingTelemetryState;
17
+ trimStartMs?: number;
18
+ writeTelemetry?: typeof writeRecordingTelemetry;
19
+ }): string;
20
+ export {};
@@ -0,0 +1,24 @@
1
+ type GestureTimingSource = {
2
+ recordingStartedAt: number;
3
+ gestureClockOriginAtMs?: number;
4
+ gestureClockOriginUptimeMs?: number;
5
+ runnerStartedAtUptimeMs?: number;
6
+ gestureStartUptimeMs?: number;
7
+ gestureEndUptimeMs?: number;
8
+ fallbackStartedAtMs: number;
9
+ fallbackFinishedAtMs: number;
10
+ };
11
+ type GestureDurationSource = {
12
+ gestureStartUptimeMs?: number;
13
+ gestureEndUptimeMs?: number;
14
+ reportedDurationMs?: number;
15
+ fallbackStartedAtMs: number;
16
+ fallbackFinishedAtMs: number;
17
+ };
18
+ type TapVisualizationOffsetSource = GestureTimingSource & {
19
+ gestureDurationMs: number;
20
+ };
21
+ export declare function resolveGestureOffsetMs(source: GestureTimingSource): number;
22
+ export declare function resolveGestureDurationMs(source: GestureDurationSource): number;
23
+ export declare function resolveTapVisualizationOffsetMs(source: TapVisualizationOffsetSource): number;
24
+ export {};
@@ -2,6 +2,8 @@ import { dispatchCommand } from '../core/dispatch.ts';
2
2
  import type { DaemonRequest, DaemonResponse } from './types.ts';
3
3
  import { SessionStore } from './session-store.ts';
4
4
  import type { LeaseRegistry } from './lease-registry.ts';
5
+ import { snapshotAndroid, openAndroidApp, getAndroidAppState } from '../platforms/android/index.ts';
6
+ import { runCmd } from '../utils/exec.ts';
5
7
  export type RequestRouterDeps = {
6
8
  logPath: string;
7
9
  token: string;
@@ -13,5 +15,9 @@ export type RequestRouterDeps = {
13
15
  fileName?: string;
14
16
  }) => string;
15
17
  dispatchCommand?: typeof dispatchCommand;
18
+ snapshotAndroidUi?: typeof snapshotAndroid;
19
+ reopenAndroidApp?: typeof openAndroidApp;
20
+ readAndroidAppState?: typeof getAndroidAppState;
21
+ execCommand?: typeof runCmd;
16
22
  };
17
23
  export declare function createRequestHandler(deps: RequestRouterDeps): (req: DaemonRequest) => Promise<DaemonResponse>;
@@ -11,6 +11,7 @@ export declare function appendRuntimeHintFlags(parts: string[], flags: Pick<Sess
11
11
  bundleUrl?: string;
12
12
  launchUrl?: string;
13
13
  } | undefined): void;
14
+ export declare function appendRecordActionScriptArgs(parts: string[], action: SessionAction): void;
14
15
  export declare function parseReplaySeriesFlags(command: string, args: string[]): {
15
16
  positionals: string[];
16
17
  flags: SessionAction['flags'];
@@ -7,3 +7,4 @@ export declare function normalizeType(type: string): string;
7
7
  export declare function isFillableType(type: string, platform: Platform): boolean;
8
8
  export declare function findNearestHittableAncestor(nodes: SnapshotState['nodes'], node: SnapshotState['nodes'][number]): SnapshotState['nodes'][number] | null;
9
9
  export declare function extractNodeText(node: SnapshotState['nodes'][number]): string;
10
+ export declare function extractNodeReadText(node: SnapshotState['nodes'][number]): string;
@@ -0,0 +1,7 @@
1
+ import type { SnapshotNode, SnapshotState } from '../utils/snapshot.ts';
2
+ export type TouchReferenceFrame = {
3
+ referenceWidth: number;
4
+ referenceHeight: number;
5
+ };
6
+ export declare function getSnapshotReferenceFrame(snapshot: SnapshotState | undefined): TouchReferenceFrame | undefined;
7
+ export declare function inferTouchReferenceFrame(nodes: Array<Pick<SnapshotNode, 'type' | 'rect'>>): TouchReferenceFrame | undefined;
@@ -1,5 +1,6 @@
1
1
  import type { MaterializeInstallSource } from '../platforms/install-source.ts';
2
2
  import type { CommandFlags } from '../core/dispatch.ts';
3
+ import type { SessionSurface } from '../core/session-surface.ts';
3
4
  import type { DeviceInfo, Platform, PlatformSelector } from '../utils/device.ts';
4
5
  import type { ExecResult } from '../utils/exec.ts';
5
6
  import type { SnapshotState } from '../utils/snapshot.ts';
@@ -63,10 +64,57 @@ export type DaemonResponse = {
63
64
  details?: Record<string, unknown>;
64
65
  };
65
66
  };
67
+ type RecordingTelemetryBase = {
68
+ tMs: number;
69
+ x: number;
70
+ y: number;
71
+ referenceWidth?: number;
72
+ referenceHeight?: number;
73
+ };
74
+ type RecordingTelemetryTravel = RecordingTelemetryBase & {
75
+ x2: number;
76
+ y2: number;
77
+ durationMs: number;
78
+ };
79
+ export type RecordingGestureEvent = (RecordingTelemetryBase & {
80
+ kind: 'tap' | 'longpress';
81
+ durationMs?: number;
82
+ }) | (RecordingTelemetryTravel & {
83
+ kind: 'swipe';
84
+ }) | (RecordingTelemetryTravel & {
85
+ kind: 'scroll';
86
+ contentDirection: 'up' | 'down' | 'left' | 'right';
87
+ amount?: number;
88
+ }) | (RecordingTelemetryTravel & {
89
+ kind: 'back-swipe';
90
+ edge: 'left' | 'right';
91
+ }) | (RecordingTelemetryBase & {
92
+ kind: 'pinch';
93
+ scale: number;
94
+ durationMs: number;
95
+ });
96
+ type SessionRecordingBase = {
97
+ outPath: string;
98
+ clientOutPath?: string;
99
+ telemetryPath?: string;
100
+ overlayWarning?: string;
101
+ startedAt: number;
102
+ showTouches: boolean;
103
+ gestureEvents: RecordingGestureEvent[];
104
+ touchReferenceFrame?: {
105
+ referenceWidth: number;
106
+ referenceHeight: number;
107
+ };
108
+ gestureClockOriginAtMs?: number;
109
+ gestureClockOriginUptimeMs?: number;
110
+ runnerSessionId?: string;
111
+ invalidatedReason?: string;
112
+ };
66
113
  export type SessionState = {
67
114
  name: string;
68
115
  device: DeviceInfo;
69
116
  createdAt: number;
117
+ surface?: SessionSurface;
70
118
  appBundleId?: string;
71
119
  appName?: string;
72
120
  snapshot?: SnapshotState;
@@ -77,23 +125,28 @@ export type SessionState = {
77
125
  recordSession?: boolean;
78
126
  saveScriptPath?: string;
79
127
  actions: SessionAction[];
80
- recording?: {
81
- platform: 'ios' | 'android';
82
- outPath: string;
83
- clientOutPath?: string;
84
- remotePath?: string;
128
+ recording?: (SessionRecordingBase & {
129
+ platform: 'ios';
85
130
  child: ReturnType<typeof import('node:child_process').spawn>;
86
131
  wait: Promise<ExecResult>;
87
- } | {
88
- platform: 'ios-device-runner' | 'macos-runner';
89
- outPath: string;
90
- clientOutPath?: string;
91
132
  remotePath?: string;
92
- };
133
+ }) | (SessionRecordingBase & {
134
+ platform: 'android';
135
+ remotePath: string;
136
+ remotePid: string;
137
+ }) | (SessionRecordingBase & {
138
+ platform: 'ios-device-runner';
139
+ remotePath: string;
140
+ runnerStartedAtUptimeMs?: number;
141
+ targetAppReadyUptimeMs?: number;
142
+ }) | (SessionRecordingBase & {
143
+ platform: 'macos-runner';
144
+ remotePath?: string;
145
+ });
93
146
  /** Session-scoped app log stream; logs written to outPath for agent to grep */
94
147
  appLog?: {
95
148
  platform: Platform;
96
- backend: 'ios-simulator' | 'ios-device' | 'android';
149
+ backend: 'ios-simulator' | 'ios-device' | 'android' | 'macos';
97
150
  outPath: string;
98
151
  startedAt: number;
99
152
  getState: () => 'active' | 'failed';
@@ -117,3 +170,4 @@ export type SessionAction = {
117
170
  };
118
171
  result?: Record<string, unknown>;
119
172
  };
173
+ export {};