callstack / callstack/agent-device

Maestro inputText types whole string at once; debounced inputs only fire once (real Maestro types per-keystroke)

Open
#2,159 3 comments 0 reactions 0 assignees View on GitHub
bug needs-triage
Dominant language
TypeScript
Stars
4.6k
Forks
299
Avg merge
10h 17m
Merged PRs (30d)
515

Description

## Summary

Maestro `inputText` in agent-device injects the whole string at once instead of typing it per-keystroke, so a debounced `onChange` only fires once instead of once per character. Real Maestro types each key individually with pacing, which is what makes debounced-input testing work.

## The difference

| | Real Maestro | agent-device `--maestro` |
| --- | --- | --- |
| `inputText` | injects each character/keyevent individually | sends the whole string in one shot |
| Debounced field | `onChange` fires per character | `onChange` fires once at the end |
| Debounce testing | works | not representative |

## Why this happens in agent-device

The Maestro runtime maps `inputText` to the `type` command with no `delay-ms`:

1. `packages/maestro/.../runtime-port-commands.ts` — `executeTextCommand` calls `operations.inputText({ text })`.
2. The daemon adapter projects it to `{ command: 'type', positionals: [text] }` — no delay flag.
3. `src/daemon/type-text-runtime.ts:78` — `delayMs = context.delayMs ?? 0` → **0**.
4. `packages/platform-android/.../text-input.ts` `typeAndroid` with `delayMs === 0`:
- via the bundled test IME: sends the **entire line as one batch broadcast** (`chunks = [whole text]`);
- via the adb shell fallback: chunks at 8 chars with **no delay between chunks**.

So the whole string lands effectively instantly. The per-char pacing machinery already exists — when `delayMs > 0`, `typeAndroid` switches to `chunkSize: 1` with a sleep between characters (`text-input.ts:57-60`) — but no delay ever flows in from the Maestro runtime.

Also worth noting: Maestro's `inputText` grammar only accepts `text` + `label` (there is no per-command delay knob), so the Maestro runtime currently has **no way to request paced typing at all**.

## Proposed direction (for discussion)

Make `--maestro` `inputText` debounce-testable like real Maestro. Options:

1. **Default the Maestro `inputText` path to per-char pacing** (chunk size 1 + small inter-keystroke delay) to match real Maestro semantics, instead of delay 0.
2. **Expose a pacing knob** in the Maestro grammar (`inputText: { text, delayMs }` or similar) so users can choose instant vs. per-keystroke.

Prefer whichever the maintainers feel best preserves Maestro fidelity as the default while keeping an escape hatch for fast fills.

## Environment

- `agent-device` Maestro compatibility backend (`replay *.yaml --maestro`)
- Android (test IME batch broadcast path and adb-shell fallback behave the same)

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.