callstack / callstack/agent-device
Maestro inputText types whole string at once; debounced inputs only fire once (real Maestro types per-keystroke)
- 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
Assessment
This issue has not been assessed yet.