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

GenServer that manages the frontend renderer Port.

Operates in two modes depending on the `MINGA_PORT_MODE` env var:

- **Spawn mode** (default): BEAM is the parent process. Port.Manager
  spawns the GUI/TUI binary as a child via `Port.open({:spawn_executable, ...})`.
  Used in development, TUI mode, and Burrito releases.

- **Connected mode** (`MINGA_PORT_MODE=connected`): BEAM is a child of
  the GUI process. The GUI set up stdin/stdout pipes before launching us.
  Port.Manager opens `{:fd, 0, 1}` as a Port instead of spawning a child.
  Used when launching from `Minga.app` (Finder, Spotlight, Dock).

Both modes use identical `{:packet, 4}` framing. The protocol layer
(event decoding, render commands, subscriber broadcasting) is the same.

Subscribers register via `subscribe/1` and receive messages as:

    {:minga_input, event}

where `event` is a `MingaEditor.Frontend.Protocol.input_event()`.

# `backend`

```elixir
@type backend() :: :tui | :gui
```

Renderer backend.

# `start_opt`

```elixir
@type start_opt() ::
  {:name, GenServer.name()}
  | {:renderer_path, String.t()}
  | {:backend, backend()}
  | {:port_mode, MingaEditor.Frontend.Manager.State.port_mode()}
  | {:port_opener, (term(), [term()] -&gt; port())}
```

Options for starting the port manager.

# `state`

```elixir
@type state() :: MingaEditor.Frontend.Manager.State.t()
```

Internal state.

# `capabilities`

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

Returns the frontend's reported capabilities.

# `child_spec`

Returns a specification to start this module under a supervisor.

See `Supervisor`.

# `ready?`

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

Returns whether the Zig renderer has sent its ready signal.

# `send_commands`

```elixir
@spec send_commands(GenServer.server(), [binary()]) :: :ok
```

Sends a list of encoded render command binaries to the Zig renderer.

# `start_link`

```elixir
@spec start_link([start_opt()]) :: GenServer.on_start()
```

Starts the port manager.

# `subscribe`

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

Subscribes the calling process to receive input events.

# `terminal_size`

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

Returns the terminal size as `{width, height}`, or nil if not yet ready.

# `tty_path_for`

```elixir
@spec tty_path_for(String.t()) :: String.t()
```

Builds a `/dev/` path from the tty name returned by `ps -o tty=`.

The format varies by OS and version:
- macOS long form: `"ttys008"` → `"/dev/ttys008"`
- macOS short form: `"s003"` → `"/dev/ttys003"`
- Linux: `"pts/3"` → `"/dev/pts/3"`

Checks if `/dev/{name}` exists first (handles long form and Linux).
Falls back to `/dev/tty{name}` for short forms.

---

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