# `MingaEditor.Frontend.Adapter`
[🔗](https://github.com/jsmestad/minga/blob/main/lib/minga_editor/frontend/adapter.ex#L1)

Behaviour for rendering frontends that communicate with the Editor.

Any process that can receive encoded render commands and emit input
events can serve as a Minga frontend. The Editor dispatches through
this interface without knowing whether the other end is a libvaxis
TUI, a native GUI, or a headless test harness.

## Implementations

- `MingaEditor.Frontend.Manager` — production frontend managing a Zig renderer Port
- `Minga.Test.HeadlessPort` — in-memory screen grid for testing

## Contract

Frontends receive pre-encoded binary commands via `send_commands/2`
and deliver input events to subscribers as `{:minga_input, event}`
messages. The event types are defined in `MingaEditor.Frontend.Protocol`.

# `admission`

```elixir
@type admission() :: :accepted | :unwritable
```

Non-suspending frontend output admission result.

# `capabilities`

```elixir
@callback capabilities(server :: GenServer.server()) ::
  MingaEditor.Frontend.Capabilities.t()
```

Returns the frontend's reported capabilities.

Capabilities are populated from the `ready` event (extended format)
or from a subsequent `capabilities_updated` event. Returns default
capabilities if the frontend has not reported any.

# `ready?`

```elixir
@callback ready?(server :: GenServer.server()) :: boolean()
```

Returns whether the frontend is ready to accept render commands.

A frontend becomes ready after its initialization handshake completes
(e.g., the Zig renderer sends a `ready` event with terminal dimensions).

# `send_commands`

```elixir
@callback send_commands(server :: GenServer.server(), commands :: [binary()]) ::
  admission()
```

Sends a list of pre-encoded render command binaries to the frontend.

Commands are encoded via `MingaEditor.Frontend.Protocol.encode_*` functions. The frontend returns `:accepted` when the batch entered its transport or `:unwritable` without suspending the caller. A `commit_frame` command closes the frame transaction and triggers a render flush (#2219).

# `start_link`

```elixir
@callback start_link(opts :: keyword()) :: GenServer.on_start()
```

Starts the frontend process.

# `subscribe`

```elixir
@callback subscribe(server :: GenServer.server()) :: :ok
```

Subscribes the calling process to receive input events.

The subscriber will receive `{:minga_input, event}` messages where
`event` is a `MingaEditor.Frontend.Protocol.input_event()`.

# `terminal_size`

```elixir
@callback terminal_size(server :: GenServer.server()) ::
  {pos_integer(), pos_integer()} | nil
```

Returns the frontend's screen dimensions as `{width, height}`.

Returns `nil` if the frontend is not yet ready (e.g., the renderer
has not sent its initial `ready` event).

---

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