Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion examples/sdk/client-session.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,11 @@ import {
isAgentDeviceError,
normalizeAgentDeviceError,
} from 'agent-device';
import type { AgentDeviceClient, AgentDeviceDevice } from 'agent-device';

async function resolveSnapshotCapableIosDevice(client: ReturnType<typeof createAgentDeviceClient>) {
async function resolveSnapshotCapableIosDevice(
client: AgentDeviceClient,
): Promise<AgentDeviceDevice> {
const devices = await client.devices.list({ platform: 'ios' });
const device = devices[0];
if (!device) {
Expand Down
96 changes: 1 addition & 95 deletions packages/contracts/src/client-request.ts
Original file line number Diff line number Diff line change
@@ -1,97 +1,3 @@
// The public API vocabulary for the internal request envelope every client call is projected into.

import type { AppsFilter } from './app-inventory.ts';
import type { BackMode } from './back-mode.ts';
import type { ClickButton } from './click-button.ts';
import type { RecordingExportQuality } from './recording-export-quality.ts';
import type { RecordingScope } from './recording-scope.ts';
import type { ScreenshotRequestFlags } from './screenshot.ts';
import type { SwipePattern } from './scroll-gesture.ts';
import type { SessionSurface } from './session-surface.ts';
import type {
DaemonInstallSource,
DaemonResponseData,
NetworkIncludeMode,
SessionRuntimeHints,
} from '@agent-device/kernel/contracts';
import type { SnapshotCommandOptionFields } from '@agent-device/kernel/snapshot';
import type { DaemonBatchStep } from './batch-step.ts';
import type { ReplayRequestFields } from './replay-request-fields.ts';
import type { AgentDeviceClientConfig, AgentDeviceSelectionOptions } from './client-connection.ts';

export type CommandExecutionOptions = Partial<ScreenshotRequestFlags> &
ReplayRequestFields &
SnapshotCommandOptionFields & {
positionals?: string[];
kind?: string;
out?: string;
artifact?: string;
dsym?: string;
searchPath?: string;
count?: number;
fps?: number;
recordingScope?: RecordingScope;
quality?: RecordingExportQuality;
hideTouches?: boolean;
intervalMs?: number;
delayMs?: number;
durationMs?: number;
holdMs?: number;
jitterPx?: number;
pixels?: number;
/** Scroll: repeat passes until this selector is visible on screen. */
until?: string;
doubleTap?: boolean;
verify?: boolean;
settle?: boolean;
settleQuietMs?: number;
clickButton?: ClickButton;
pauseMs?: number;
pattern?: SwipePattern;
headless?: boolean;
restart?: boolean;
replayBackend?: string;
findFirst?: boolean;
findLast?: boolean;
networkInclude?: NetworkIncludeMode;
batchOnError?: 'stop';
batchMaxSteps?: number;
batchSteps?: DaemonBatchStep[];
};

export type InternalRequestOptions = AgentDeviceClientConfig &
AgentDeviceSelectionOptions &
CommandExecutionOptions & {
runtime?: SessionRuntimeHints;
overlayRefs?: boolean;
surface?: SessionSurface;
activity?: string;
launchConsole?: string;
launchArgs?: string[];
relaunch?: boolean;
shutdown?: boolean;
saveScript?: boolean | string;
/** #1258: overwrite an existing --save-script target instead of refusing. Alias: --overwrite. */
force?: boolean;
testIme?: boolean;
noRecord?: boolean;
/** Fill-only script parameter name used to publish `${VAR}` instead of literal text. */
recordAs?: string;
/** #1271 stage 2: force-record this action; mutually exclusive with `noRecord`. */
record?: boolean;
backMode?: BackMode;
metroHost?: string;
metroPort?: number;
bundleUrl?: string;
launchUrl?: string;
appsFilter?: AppsFilter;
installSource?: DaemonInstallSource;
retainMaterializedPaths?: boolean;
materializedPathRetentionMs?: number;
materializationId?: string;
leaseTtlMs?: number;
provider?: string;
providerSessionId?: string;
};
import type { DaemonResponseData } from '@agent-device/kernel/contracts';

export type CommandRequestResult = DaemonResponseData;
6 changes: 1 addition & 5 deletions packages/contracts/src/facades/client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -89,11 +89,7 @@ export type {
ReplayRunOptions,
ReplayTestOptions,
} from '../client-replay.ts';
export type {
CommandExecutionOptions,
CommandRequestResult,
InternalRequestOptions,
} from '../client-request.ts';
export type { CommandRequestResult } from '../client-request.ts';
export type {
FindBaseOptions,
FindOptions,
Expand Down
1 change: 1 addition & 0 deletions packages/contracts/src/facades/command.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ export {
} from '../batch-contract.ts';
export type { DaemonBatchStep } from '../batch-step.ts';
export type { CliFlags, DaemonExcludedCliFlag } from '../cli-flags.ts';
export type { CommandExecutionOptions, InternalRequestOptions } from '../request-envelope.ts';
export type { CommandFlags, MaestroRuntimeFlags } from '../command-flags.ts';
export type { DaemonWireRequest, DaemonWireRequestMeta } from '../daemon-wire-request.ts';
export type { DispatchedCommand } from '../dispatched-command.ts';
Expand Down
95 changes: 95 additions & 0 deletions packages/contracts/src/request-envelope.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
// The internal request envelope every client call is projected into. The command façade carries it,
// not the client façade, so the package root's client types do not publish it.

import type { AppsFilter } from './app-inventory.ts';
import type { BackMode } from './back-mode.ts';
import type { ClickButton } from './click-button.ts';
import type { RecordingExportQuality } from './recording-export-quality.ts';
import type { RecordingScope } from './recording-scope.ts';
import type { ScreenshotRequestFlags } from './screenshot.ts';
import type { SwipePattern } from './scroll-gesture.ts';
import type { SessionSurface } from './session-surface.ts';
import type {
DaemonInstallSource,
NetworkIncludeMode,
SessionRuntimeHints,
} from '@agent-device/kernel/contracts';
import type { SnapshotCommandOptionFields } from '@agent-device/kernel/snapshot';
import type { DaemonBatchStep } from './batch-step.ts';
import type { ReplayRequestFields } from './replay-request-fields.ts';
import type { AgentDeviceClientConfig, AgentDeviceSelectionOptions } from './client-connection.ts';

export type CommandExecutionOptions = Partial<ScreenshotRequestFlags> &
ReplayRequestFields &
SnapshotCommandOptionFields & {
positionals?: string[];
kind?: string;
out?: string;
artifact?: string;
dsym?: string;
searchPath?: string;
count?: number;
fps?: number;
recordingScope?: RecordingScope;
quality?: RecordingExportQuality;
hideTouches?: boolean;
intervalMs?: number;
delayMs?: number;
durationMs?: number;
holdMs?: number;
jitterPx?: number;
pixels?: number;
/** Scroll: repeat passes until this selector is visible on screen. */
until?: string;
doubleTap?: boolean;
verify?: boolean;
settle?: boolean;
settleQuietMs?: number;
clickButton?: ClickButton;
pauseMs?: number;
pattern?: SwipePattern;
headless?: boolean;
restart?: boolean;
replayBackend?: string;
findFirst?: boolean;
findLast?: boolean;
networkInclude?: NetworkIncludeMode;
batchOnError?: 'stop';
batchMaxSteps?: number;
batchSteps?: DaemonBatchStep[];
};

export type InternalRequestOptions = AgentDeviceClientConfig &
AgentDeviceSelectionOptions &
CommandExecutionOptions & {
runtime?: SessionRuntimeHints;
overlayRefs?: boolean;
surface?: SessionSurface;
activity?: string;
launchConsole?: string;
launchArgs?: string[];
relaunch?: boolean;
shutdown?: boolean;
saveScript?: boolean | string;
/** #1258: overwrite an existing --save-script target instead of refusing. Alias: --overwrite. */
force?: boolean;
testIme?: boolean;
noRecord?: boolean;
/** Fill-only script parameter name used to publish `${VAR}` instead of literal text. */
recordAs?: string;
/** #1271 stage 2: force-record this action; mutually exclusive with `noRecord`. */
record?: boolean;
backMode?: BackMode;
metroHost?: string;
metroPort?: number;
bundleUrl?: string;
launchUrl?: string;
appsFilter?: AppsFilter;
installSource?: DaemonInstallSource;
retainMaterializedPaths?: boolean;
materializedPathRetentionMs?: number;
materializationId?: string;
leaseTtlMs?: number;
provider?: string;
providerSessionId?: string;
};
3 changes: 1 addition & 2 deletions src/agent-device-client.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import type { CommandFlags } from '@agent-device/contracts/command';
import type { CommandFlags, InternalRequestOptions } from '@agent-device/contracts/command';
import {
readSerializedSnapshotCaptureAnnotations,
readSnapshotDiagnosticsSummary,
Expand All @@ -18,7 +18,6 @@ import type {
CaptureSnapshotResult,
DragOptions,
FlingOptions,
InternalRequestOptions,
MaterializationReleaseOptions,
PanOptions,
PinchOptions,
Expand Down
2 changes: 1 addition & 1 deletion src/client/client-normalizers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,11 @@ import type {
AgentDeviceSessionDevice,
AppDeployResult,
AppInstallFromSourceResult,
InternalRequestOptions,
MaterializationReleaseResult,
StartupPerfSample,
DeviceSelectionMetadata,
} from '@agent-device/contracts/client';
import type { InternalRequestOptions } from '@agent-device/contracts/command';
import type { TargetShutdownResult } from '@agent-device/contracts/device';
import {
isAppleOs,
Expand Down
7 changes: 2 additions & 5 deletions src/client/lease-client.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,5 @@
import type {
HumanControlHold,
InternalRequestOptions,
Lease,
} from '@agent-device/contracts/client';
import type { HumanControlHold, Lease } from '@agent-device/contracts/client';
import type { InternalRequestOptions } from '@agent-device/contracts/command';
import { AppError } from '@agent-device/kernel/errors';
import { INTERNAL_COMMANDS } from '@agent-device/command-registry/catalog';
import { isRecord } from '@agent-device/kernel/record';
Expand Down
2 changes: 1 addition & 1 deletion src/commands/__tests__/command-flags.test.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import assert from 'node:assert/strict';
import { test } from 'vitest';

import type { InternalRequestOptions } from '@agent-device/contracts/client';
import type { InternalRequestOptions } from '@agent-device/contracts/command';
import { findCommandMetadata } from '../command-metadata.ts';
import { readMetadataCommandFlags } from '../command-flags.ts';

Expand Down
8 changes: 2 additions & 6 deletions src/commands/cli-grammar/common.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,5 @@
import type {
ElementTarget,
InteractionTarget,
InternalRequestOptions,
} from '@agent-device/contracts/client';
import type { CliFlags } from '@agent-device/contracts/command';
import type { ElementTarget, InteractionTarget } from '@agent-device/contracts/client';
import type { CliFlags, InternalRequestOptions } from '@agent-device/contracts/command';
import { AppError } from '@agent-device/kernel/errors';
import {
checkElementTargetArgs,
Expand Down
7 changes: 5 additions & 2 deletions src/commands/cli-grammar/types.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
import type { InternalRequestOptions } from '@agent-device/contracts/client';
import type { CliFlags, CommandFlags } from '@agent-device/contracts/command';
import type {
CliFlags,
CommandFlags,
InternalRequestOptions,
} from '@agent-device/contracts/command';
import type { ClickButton } from '@agent-device/contracts/click-button';

export type DaemonCommandRequest = {
Expand Down
3 changes: 1 addition & 2 deletions src/commands/command-flags.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import type { CommandFlags } from '@agent-device/contracts/command';
import type { CommandFlags, InternalRequestOptions } from '@agent-device/contracts/command';
import { screenshotFlagsFromOptions } from '@agent-device/contracts/capture';
import {
leaseScopeFromOptions,
Expand All @@ -10,7 +10,6 @@ import {
snapshotFlagsFromOptions,
} from '@agent-device/kernel/snapshot';
import { getFlagDefinitions } from '@agent-device/command-registry/flag-registry';
import type { InternalRequestOptions } from '@agent-device/contracts/client';
import type { CommandMetadata } from './command-contract.ts';

const CLI_FLAG_KEYS: ReadonlySet<string> = new Set(
Expand Down
26 changes: 26 additions & 0 deletions src/sdk/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,29 @@ export {
normalizeAgentDeviceError,
} from '@agent-device/kernel/errors';
export { centerOfRect } from '@agent-device/kernel/snapshot';

// The types the root's two functions are written in. `createAgentDeviceClient` returns
// `AgentDeviceClient`, whose every option and result type is a named type of
// `client-types.ts`; until now a consumer reached them only through
// `ReturnType<typeof createAgentDeviceClient>` and `Awaited<ReturnType<...>>`, and typed the
// nodes a snapshot returns by hand.
export type * from '../client/client-types.ts';
// Two results `client-types.ts` imports for its signatures without re-exporting them.
export type {
AgentArtifactsResult,
CloudProviderSessionResult,
} from '@agent-device/contracts/observability';
export type {
AppErrorCode,
AppErrorDetails,
ErrorCause,
KnownAppErrorCode,
NormalizedError,
} from '@agent-device/kernel/errors';
export type {
Point,
RawSnapshotNode,
Rect,
SnapshotNode,
SnapshotState,
} from '@agent-device/kernel/snapshot';
2 changes: 1 addition & 1 deletion test/wire-compat/closure-policy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ export const WIRE_CLOSURE_WAIVERS: Readonly<Record<string, string>> = {
// If a flag ever becomes a typed field on DaemonRequest, that changes
// DaemonRequest's own digest, and the right fix is to list the type here
// rather than widen this waiver.
'packages/contracts/src/client-request.ts#InternalRequestOptions':
'packages/contracts/src/request-envelope.ts#InternalRequestOptions':
'CLI-side option projection; reaches the peer inside DaemonRequest.input/flags (Record<string, unknown>, both listed), and ADR 0006 calls new flags additive.',
'packages/contracts/src/command-flags.ts#CommandFlags':
'CLI-side flag vocabulary; reaches the peer inside DaemonRequest.flags (Record<string, unknown>, listed), and ADR 0006 calls new flags additive.',
Expand Down
6 changes: 6 additions & 0 deletions website/docs/docs/client-api.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,12 @@ Supported public entry points for Node consumers:
- `createLocalArtifactAdapter(options?)`
- `AppError`, `isAgentDeviceError(error)`, `normalizeAgentDeviceError(error)`
- `centerOfRect(rect)`
- types: `AgentDeviceClient`, `AgentDeviceClientConfig`, `AgentDeviceDevice`
- types: every option and result type of the client's methods, among them `AppOpenOptions`,
`AppOpenResult`, `CaptureSnapshotOptions`, `CaptureSnapshotResult`, `CaptureScreenshotResult`,
`PressOptions`
- types: `SnapshotNode`, `RawSnapshotNode`, `SnapshotState`, `Rect`, `Point`
- types: `NormalizedError`, `AppErrorCode`, `KnownAppErrorCode`, `AppErrorDetails`, `ErrorCause`
- `agent-device/io`
- `createLocalArtifactAdapter(options?)`
- types: `ArtifactAdapter`, `ArtifactDescriptor`, `CreateTempFileOptions`, `FileInputRef`,
Expand Down
Loading