From de75e7edac1e2a24a9018076f865b85205387733 Mon Sep 17 00:00:00 2001 From: BK Date: Fri, 9 Oct 2026 08:13:07 +0700 Subject: [PATCH] feat(act): doubleTap on press, durationMs on longpress alloy_act schema (.strict()) gains two optional fields: - doubleTap (press): forwarded to engine A's repeated-touch flag - durationMs (longpress): forwarded to interactions.longPress Sized by the T0(e) inspection: schema is closed, so this is a real schema edit, not pass-through. Engine A accepts doubleTap on press (REPEATED_TOUCH_FLAGS -> allowedFlags) and durationMs on longpress. Full suite 73/73. --- src/adapter-a.ts | 2 +- src/registrations.ts | 11 +++++++++-- src/routing.ts | 2 ++ 3 files changed, 12 insertions(+), 3 deletions(-) diff --git a/src/adapter-a.ts b/src/adapter-a.ts index 000b805..8a5cd88 100644 --- a/src/adapter-a.ts +++ b/src/adapter-a.ts @@ -45,7 +45,7 @@ export interface AClient { screenshot(options?: { udid?: string; outPath?: string }): Promise; }; interactions: { - press(options: { target: ATarget; udid?: string; settle?: boolean }): Promise; + press(options: { target: ATarget; udid?: string; settle?: boolean; doubleTap?: boolean }): Promise; longPress(options: { target: ATarget; udid?: string; durationMs?: number }): Promise; fill(options: { target: ATarget; text: string; udid?: string; settle?: boolean }): Promise; /** Hide the on-screen keyboard (engine-backed, device-independent). */ diff --git a/src/registrations.ts b/src/registrations.ts index 33a38df..37c5f8c 100644 --- a/src/registrations.ts +++ b/src/registrations.ts @@ -193,16 +193,23 @@ export function registerPhase0Tools(deps: StubDeps): void { text?: string; direction?: 'up' | 'down' | 'left' | 'right'; settle: boolean; + doubleTap?: boolean; + durationMs?: number; }; if (d.action === 'keyboardDismiss') return client.interactions.keyboardDismiss({ udid: d.udid }); if (d.action === 'scroll') { return client.interactions.scroll({ direction: d.direction!, udid: d.udid, settle: d.settle }); } const target = toTarget(d.target as string | { x: number; y: number }); - if (d.action === 'press') return client.interactions.press({ target, udid: d.udid, settle: d.settle }); + if (d.action === 'press') { + const po: { target: typeof target; udid?: string; settle?: boolean; doubleTap?: boolean } = { target, udid: d.udid, settle: d.settle }; + if (d.doubleTap !== undefined) po.doubleTap = d.doubleTap; + return client.interactions.press(po); + } if (d.action === 'longpress') { - const o: { target: typeof target; udid?: string } = { target }; + const o: { target: typeof target; udid?: string; durationMs?: number } = { target }; opt(o, 'udid', d.udid); + opt(o, 'durationMs', d.durationMs); return client.interactions.longPress(o); } return client.interactions.fill({ target, text: d.text!, udid: d.udid, settle: d.settle }); diff --git a/src/routing.ts b/src/routing.ts index 843923b..2ca5710 100644 --- a/src/routing.ts +++ b/src/routing.ts @@ -148,6 +148,8 @@ export const routingTable: readonly RoutingRow[] = [ text: z.string().optional().describe('text for fill'), direction: z.enum(['up', 'down', 'left', 'right']).optional(), settle: z.boolean().default(true), + doubleTap: z.boolean().optional().describe('press as a double-tap (engine A repeated-touch flag)'), + durationMs: z.number().int().positive().max(10_000).optional().describe('long-press dwell in ms'), }) .strict() .superRefine((v, ctx) => {