# `MingaEditor.State.Launchpad`
[🔗](https://github.com/jsmestad/minga/blob/main/lib/minga_editor/state/launchpad.ex#L1)

State for the zero-buffers launchpad surface (#2689).

Created when the workspace enters the empty state (last buffer closed or
no-file startup) and cleared when any buffer opens. Session and recents
data are snapshotted once at entry so the render builder stays pure and
frame builds never touch the filesystem.

This module owns focus movement; activation semantics live in the
commands layer so both frontends behave identically.

# `t`

```elixir
@type t() :: %MingaEditor.State.Launchpad{
  crashed?: boolean(),
  focused_id: String.t() | nil,
  pending_g?: boolean(),
  recents: [String.t()],
  session_file_count: non_neg_integer()
}
```

# `clear_pending_g`

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

Disarms a pending `gg` chord.

# `focus`

```elixir
@spec focus(t(), String.t()) :: t()
```

Sets focus to a specific item id when it exists.

# `item_ids`

```elixir
@spec item_ids(t()) :: [String.t()]
```

Ordered focusable item ids: resume, recents, then actions.

On a first run (no session, no recents) the tutorial is promoted to the
front: it renders as the "Get started" hero card with a `RET` chip, so it
must also hold the initial focus for Enter-on-launch to honor that chip.

# `move_focus`

```elixir
@spec move_focus(t(), :next | :prev | :first | :last) :: t()
```

Moves focus by one step or to an edge.

# `new`

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

Builds launchpad state by snapshotting session and recent-file data.

`:session_dir` scopes the session read (threaded from the editor's
session options so tests stay hermetic). `:session_file_count`,
`:crashed?`, and `:recents` override the reads entirely for tests.

# `press_g`

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

Handles a `g` keypress for the `gg` go-to-first chord.

The first `g` arms the pending state; the second moves focus to the
first item. Any other key must call `clear_pending_g/1`.

# `recent_id`

```elixir
@spec recent_id(pos_integer()) :: String.t()
```

The id for the recent file at 1-based position `i`.

# `recent_path`

```elixir
@spec recent_path(t(), String.t()) :: String.t() | nil
```

The recent-file path for an item id, or nil.

# `resume_id`

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

The resume item id.

---

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