Skip to content

feat(act): keyboardDismiss action - #1

Merged
thatswiftdev merged 5 commits into
mainfrom
feat/act-keyboard-dismiss
Sep 28, 2026
Merged

thatswiftdev merged 5 commits into
mainfrom
feat/act-keyboard-dismiss

Conversation

@thatswiftdev

Copy link
Copy Markdown
Contributor

What

alloy_act gains a keyboardDismiss action: { udid, action: 'keyboardDismiss' } — hides the on-screen keyboard through the engine's own dismissal path. No target required (schema-exempt like scroll).

Why

Lionidas playback fills login forms and needs the keyboard gone afterwards. Coordinate taps on the keyboard's Done bar are device-specific (misfired on iPhone 14 Plus vs 16 logical sizes). The engine verb is coordinate-free.

How

  • src/routing.ts: enum + target exemption in superRefine + cross-ref comment to Lionidas's contract-test mirror (server/src/manual/alloy-act-contract.test.ts — keep in sync when changing the verb set)
  • src/registrations.ts: dispatch before target resolution
  • src/adapter-a.ts: AClient interface member

Dependencies

Test state

72/73 — the one failure (alloy_restart_app valid-input fixture) is pre-existing on main, verified by stashing this branch's changes and re-running. Not introduced here.

…lliding

The engine binds a session NAME to one device; alloy's fixed 'alloy'
session made any cross-device sequence fail with 'is owned by session
alloy' (documented Crucible pain). Clients are now cached per
(engine, session); every device-scoped dispatch derives its session
from the udid (alloy-<udid8>); device-agnostic calls (devices list,
apps list without udid) keep the bare default. reset seams clear ALL
clients so stale-handle heal still rebuilds every session.
- routing: bundleId in alloy_native_tree schema (interactable-at requires
  it + x/y — superRefine enforced); new alloy_restart_app row (engine B)
- registrations: pass bundleId through to native-user-interactable-
  view-at-point (was dropped — engine B zod failed on undefined); new
  alloy_restart_app → engine B restart-app (devtools-injecting relaunch)

Live-verified on LP consumer sim: restart-app + interactable-at returns
the real view tree at a point, 27ms/probe. First launch after sim boot
lands without DYLD env (ensureEnvReady latched); the first probe's
reverifyEnv re-applies it, second restart injects — callers must warm
up: restart → probe → restart.
alloy_devices {action:'boot', headless:true} now reaches the engine-A
client's devices.boot (zod schema + opt-threaded input). Default boot
behavior unchanged.
alloy_act gains 'keyboardDismiss': hides the on-screen keyboard via the
engine's own dismissal (agent-device interactions.keyboardDismiss —
callstack/agent-device#3005). Coordinate-free, works on every logical
size; replaces device-specific Done-bar taps downstream.

- routing: action enum + schema exemption (no target required) + mirror
  cross-ref comment for Lionidas's contract test
- registrations: dispatch before target resolution (takes no target)
- adapter-a: AClient interface gains keyboardDismiss

NOTE: test/contract.test.ts alloy_restart_app fixture failure is
PRE-EXISTING on main (verified via stash) — unrelated to this change.
The 'every row accepts its valid input' contract test failed because
alloy_restart_app (added to the routing table in 1793e38) never got a
VALID_INPUTS entry — expect(input).toBeDefined() tripped before the
dispatch could even run. The fake engine B's callTool accepts arbitrary
tool names, so {udid, bundleId} exercises the full zod → dispatch →
callBTool('restart-app') path.

Pre-existing failure on main; found again as CI red on this PR's
first check run. 73/73 now.
@thatswiftdev
thatswiftdev merged commit 6a15054 into main Sep 28, 2026
1 check passed
@thatswiftdev
thatswiftdev deleted the feat/act-keyboard-dismiss branch September 28, 2026 09:07
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant