Skip to content

Split native input backend resolver and concrete backends into focused modules #707

@shaun0927

Description

@shaun0927

Tracked by #713.

Background

src/tools/native-input-backend.ts combines multiple concrete backends, routing policy, process-wide caches, Flutter resolver logic, and test reset hooks. This makes headless input behavior harder to change safely.

Objective

Separate native input backend implementations and routing policy into focused modules with explicit dependencies.

Scope

  • Create shared backend interfaces.
  • Move each concrete backend to its own module.
  • Move resolver/caching logic into an injectable resolver class.
  • Keep existing exported helper API during migration.

Target files and paths

  • src/tools/native-input-backend.ts
  • new src/input/backend.ts
  • new src/input/simctl-backend.ts
  • new src/input/applescript-backend.ts
  • new src/input/webkit-backend.ts
  • new src/input/flutter-resolver.ts
  • new src/input/backend-resolver.ts
  • tests/unit/native-input-backend.test.ts

Implementation steps

  1. Define InputBackend and backend kind types.
  2. Move Simctl backend without changing behavior.
  3. Move AppleScript backend and keep opt-in guard.
  4. Move WebKit backend and shared DOM input scripts if available.
  5. Move resolver state from module globals into an instance.
  6. Keep compatibility exports and migrate callers gradually.

Acceptance criteria

  • Existing native input tests pass.
  • Backend fallback order is unchanged.
  • Resolver state can be reset through an explicit test hook or new instance.
  • File responsibility boundaries are visible from module names.

Verification

  • npm run lint -- --quiet
  • npm test -- --runInBand tests/unit/native-input-backend.test.ts
  • Manual smoke for at least one WebKit input and one native-app input path.

Dependencies / recommended order

Run after process-spawn optimization or as preparation for it. Split by backend if review size grows.

Risks and cautions

  • Do not promote experimental backends.
  • Do not change fallback semantics while moving files.
  • Avoid changing public tool behavior in refactor PRs.

Non-goals

  • Do not solve SimulatorKit research issues.
  • Do not remove AppleScript fallback.
  • Do not redesign app interaction tool schemas.

Ambiguity reducers

  • “Concrete backend” means a class that sends input through one mechanism.
  • “Resolver” means policy that chooses a backend for a requested operation and context.
  • Module globals should be replaced only where an equivalent instance-owned state is available.

Validity review

Proceed as a P2 maintainability item. It is valid because native input is a strategic product surface.

Implementation detail refinements

  • Keep compatibility exports until all callers migrate.
  • Use one PR per backend extraction if necessary.
  • Document fallback order in tests rather than relying on comments only.

Verification checklist reinforcement

  • Fallback order test passes.
  • Each backend module compiles independently through TypeScript imports.
  • Resolver state reset is deterministic in tests.
  • No tool schema changes occur.

Metadata

Metadata

Assignees

No one assigned

    Labels

    architectureArchitecture changes and improvementsautomation-roadmapOpenSafari automation roadmap work itemstech-debtTechnical debt and maintainability

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions