Repository navigation
feat(act): keyboardDismiss action - #1
Merged
Merged
Conversation
…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.
This was referenced Sep 28, 2026
Merged
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.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
alloy_actgains akeyboardDismissaction:{ 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 +targetexemption 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 resolutionsrc/adapter-a.ts: AClient interface memberDependencies
interactions.keyboardDismiss) — additive; without it the dispatch fails gracefully at the engine boundary.Test state
72/73 — the one failure (
alloy_restart_appvalid-input fixture) is pre-existing on main, verified by stashing this branch's changes and re-running. Not introduced here.