# `Raxol.Terminal.Capabilities.ReplyScanner`
[🔗](https://github.com/DROOdotFOO/raxol/blob/v2.7.0/lib/raxol/terminal/capabilities/reply_scanner.ex#L1)

Pure reply scanner: raw input chunk in, `{parsed_replies_acc,
leak_free_residual}` out (test-suite design 04 §1a).

Generalizes `Raxol.Terminal.Driver.BackgroundQuery.scan/1` to all F0 §3
reply framings. Replies are classified **by grammar and echoed
parameters** (`?2026` in `CSI ? 2026 ; 1 $ y`), never by position.

Invariants (pinned by the CAP-F fuzz suite):

  * **Conservation** -- every input byte is either consumed as a
    recognized reply/control frame or returned in `leak_free`, in the
    original order. User keystrokes are never eaten; reply bytes never
    leak to the key parser.
  * **Both terminators** -- OSC/DCS/APC close on BEL (`0x07`) *or* ST
    (`ESC \`).
  * **Chunk-split invariance** -- a chunk ending mid-reply parks the
    fragment in `partial`; the next `scan/2` resumes byte-identically.

The scanner is a pure function; it has no process, no clock, and no
side effects. The driver-facing shim (`BackgroundQuery`) and the probe
reducer (`Probe`) compose it.

# `mode_value`

```elixir
@type mode_value() :: integer() | nil
```

# `t`

```elixir
@type t() :: %Raxol.Terminal.Capabilities.ReplyScanner{
  cell_px: {pos_integer(), pos_integer()} | nil,
  cpr: {pos_integer(), pos_integer()} | nil,
  da1: [non_neg_integer()] | nil,
  da2: [non_neg_integer()] | nil,
  kitty_graphics: boolean() | nil,
  kitty_kbd: non_neg_integer() | nil,
  mode: %{optional(non_neg_integer()) =&gt; mode_value()},
  osc10:
    {:ok, Raxol.Terminal.Driver.BackgroundQuery.rgb()}
    | {:invalid, binary()}
    | nil,
  osc11:
    {:ok, Raxol.Terminal.Driver.BackgroundQuery.rgb()}
    | {:invalid, binary()}
    | nil,
  partial: binary(),
  sentinel_seen?: boolean(),
  sixel_regs: non_neg_integer() | nil,
  xtgettcap: %{optional(String.t()) =&gt; String.t() | true},
  xtversion: {String.t(), String.t() | nil} | nil,
  xtversion_raw: String.t() | nil
}
```

# `new`

```elixir
@spec new() :: t()
```

Fresh scanner accumulator.

# `scan`

```elixir
@spec scan(binary(), t()) :: {t(), binary()}
```

Scans a raw input chunk, resuming from any parked partial reply.

Returns `{acc, leak_free}` where `leak_free` is safe to hand to the
key-event parser.

---

*Consult [api-reference.md](api-reference.md) for complete listing*
