refactor(ios): consolidate series batching onto the sequence runner command#768
Merged
Conversation
Size Report
Startup median (7 runs, lower is better):
Top changed chunks:
|
…ommand Closes #767 Routes every Apple multi-press variant (plain, double-tap, hold, jitter) and swipe series through budget-chunked sequence requests, retiring the daemon-side tapSeries and dragSeries senders: - Add a doubleTap step kind to the sequence allowlist on both ends, mirroring the retired tapSeries doubleTapAt branch. - The single doubleTap interactor sends a one-step sequence and parses the result, surfacing step failures as errors. - Swipe series unroll ping-pong daemon-side into per-step endpoints; the runner's coordinate-drag path ignores durationMs exactly as the daemon-sent (non-synthesized) dragSeries did. - Extract runIosSequenceChunks so press and swipe share the chunking, aggregation, and global step-index rebasing. - Keep tapSeries/dragSeries runner handlers for wire compatibility with older daemons, annotated like interactionFrame; remove both from the preflight-skip allowlist (daemon never sends them) and update ADR 0005 / protocol-optimizations docs. This also closes the latent watchdog exposure where press --count N --interval-ms M routed to tapSeries and executed all pauses inside one 30s-watchdog main-thread block with no chunking. Behavior note: plain tap series now use the synthesized HID tap path on iOS non-tv (with runner-side tapAt fallback), matching the individual tap command instead of the retired tapSeries' XCUICoordinate taps. https://claude.ai/code/session_01VokBZWESTDgcnbYwS4DkJo
bbc01c0 to
253b4a2
Compare
- Remove chunkRunnerSequenceSteps: superseded by the budget-aware chunker; no production callers remained. - Remove tapSeries/dragSeries from the RunnerCommand union along with their orphaned fields (count, intervalMs, doubleTap, pauseMs, pattern) and protocol fixtures: this type is the send surface of the current daemon, which no longer sends either command. The Swift runner keeps serving both for wire compatibility with older daemons. - Retarget the ready-mutation preflight test from tapSeries to sequence. https://claude.ai/code/session_01VokBZWESTDgcnbYwS4DkJo
Drops the runner-side wire compatibility for tapSeries, dragSeries, and interactionFrame now that no daemon path sends them (series fuse into sequence since this branch; interactionFrame was fused into scroll in #760): - Swift: delete the three handler cases, performDragSeries, runSeries (no remaining callers), the CommandType enum cases, journal-retention and traits entries, and the Command fields (count, intervalMs, doubleTap, pauseMs, pattern) that existed only for them. The never-sent synthesized dragSeries branch goes with it. - TS: drop interactionFrame from the RunnerCommand union and isReadOnlyRunnerCommand, and its protocol fixture. - Update stale perf scenario labels referencing the retired commands. Verified dead before removal: no dynamic command construction anywhere (runner-command-recovery only echoes in-flight command ids), no raw-string references in Swift, no docs references. Helpers shared with live paths (synthesizedDragAt, doubleTapAt, keyboardAvoidingDragPoints, sleepFor) all retain callers. Compat: an old daemon paired with a runner built from these sources gets a CommandType decode rejection; the source-fingerprint check rebuilds a matching runner on the next session. https://claude.ai/code/session_01VokBZWESTDgcnbYwS4DkJo
|
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.
Closes #767
What
Routes every Apple multi-press variant (plain, double-tap, hold, jitter) and swipe series through budget-chunked
sequencerequests (#764), retiringtapSeriesanddragSeries— and removes the retired wire commands (includinginteractionFrame, unsent since #760) from both daemon and runner entirely. Net diff across the three commits: +223 / −400.shouldUseIosTapSeries/shouldUseIosPressSequencemerge into one gate (isApple && count > 1); press dispatch goes from four routes to three.doubleTapstep kind in the sequence allowlist on both ends (TS validator + Swift executor callingdoubleTapAt). The singledoubleTapinteractor now sends a one-step sequence and parses the result, so step failures surface as errors instead of ok-shaped payloads.dragSeries: ping-pong unrolls daemon-side into per-step endpoint swaps. This gives thedragstep kind its first production caller. Semantics preserved exactly — the daemon never sentsynthesizeddragSeries, and that path already ignoreddurationMs, same as sequence drag steps.press --count 4 --interval-ms 10000previously executed 30s+ of pauses inside one main-thread block on the unchunkedtapSeriespath; it now budget-chunks viachunkRunnerSequenceStepsByBudgetlike everything else.runIosSequenceChunksextracted so press and swipe reuse chunking, aggregation, and global step-index rebasing.Legacy removal (verified dead first)
tapSeries/dragSeries/interactionFramedropped from theRunnerCommandunion,isReadOnlyRunnerCommand, protocol fixtures, and the preflight-skip allowlist, along with the orphaned fields (count,intervalMs,doubleTap,pauseMs,pattern) and the superseded count-only chunkerchunkRunnerSequenceSteps. ADR 0005 / protocol docs updated.performDragSeries,runSeries(no remaining callers), theCommandTypeenum cases, journal-retention and traits entries, and the matchingCommandmodel fields — including the never-sentsynthesizeddragSeries branch.runner-command-recoveryonly echoes in-flight command ids), no raw-string references in Swift, no docs references; shared helpers (synthesizedDragAt,doubleTapAt,keyboardAvoidingDragPoints,sleepFor) all retain live callers.Compatibility note
This intentionally drops old-daemon → new-runner wire compat for the three retired commands (a deliberate departure from the #760
interactionFrameprecedent): an old daemon paired with a runner built from these sources gets aCommandTypedecode rejection, and the source-fingerprint check rebuilds a matching runner on the next session. The exposure is limited to brief upgrade overlap or multiple checkouts sharing a device.Behavior note
Plain tap series now use the synthesized HID tap path on iOS non-tv (with runner-side
tapAtfallback), matching the individualtapcommand — the retiredtapSeriesused XCUICoordinatetapAt. ResulttimingModefor migrated paths isrunner-sequence(wasrunner-series).Validation
pnpm typecheck,pnpm check:quick,pnpm format,git diff --checkclean.pnpm check:unit: 248 files, 2386 tests passed (4 skipped), 8 smoke tests.pnpm check:fallow --base origin/main: no issues in changed files.pnpm buildsucceeds.Pending
pnpm build:xcuitestand an on-device smoke of the migrated paths (plain press series, double-tap, ping-pong swipe series) are still needed before merge.https://claude.ai/code/session_01VokBZWESTDgcnbYwS4DkJo