# `MingaEditor.UI.Panel.MessageStore`
[🔗](https://github.com/jsmestad/minga/blob/main/lib/minga_editor/ui/panel/message_store.ex#L1)

Structured log entry store for the GUI Messages tab.

Holds up to 1000 structured log entries with level, subsystem, timestamp,
text, and optional file path. The GUI protocol encoder reads from this store
to send incremental entries to the frontend.

The TUI continues to use the `*Messages*` gap buffer. Both are fed from
the same `MessageLog.log/2` call site (dual-write).

# `level`

```elixir
@type level() :: :debug | :info | :warning | :error
```

# `subsystem`

```elixir
@type subsystem() :: :editor | :lsp | :parser | :git | :render | :agent | :zig | :gui
```

# `t`

```elixir
@type t() :: %MingaEditor.UI.Panel.MessageStore{
  entries: [MingaEditor.UI.Panel.MessageStore.Entry.t()],
  last_sent_id: non_neg_integer(),
  next_id: pos_integer()
}
```

# `append`

```elixir
@spec append(t(), String.t(), level(), subsystem()) :: t()
```

Append a structured log entry. Trims to 1000 entries.

# `entries_since`

```elixir
@spec entries_since(t(), non_neg_integer()) :: [
  MingaEditor.UI.Panel.MessageStore.Entry.t()
]
```

Returns entries with id > `since_id` (for incremental protocol sends).

# `level_byte`

```elixir
@spec level_byte(level()) :: non_neg_integer()
```

Level byte for protocol encoding.

# `mark_sent`

```elixir
@spec mark_sent(t(), non_neg_integer()) :: t()
```

Mark the last sent ID (called after protocol encode).

# `parse_prefix`

```elixir
@spec parse_prefix(String.t()) :: {level(), subsystem(), String.t()}
```

Parse level and subsystem from a log message text prefix.

# `subsystem_byte`

```elixir
@spec subsystem_byte(subsystem()) :: non_neg_integer()
```

Subsystem byte for protocol encoding.

---

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