# `MingaEditor.Shell.BufferLifecycle`
[🔗](https://github.com/jsmestad/minga/blob/main/lib/minga_editor/shell/buffer_lifecycle.ex#L1)

Behaviour: shell-side reactions to buffer and agent events.

Carved out of `MingaEditor.Shell`. Callbacks receive shell state and workspace values, never full EditorState, so they cannot touch process monitors, render timers, or port managers. Generic concerns stay in EditorState.

# `buffer_add_context`

```elixir
@type buffer_add_context() :: :open | :preview
```

Why a buffer was added. Shells use this to decide tab presentation.

- `:open` — permanent open (file tree, `:e`, LSP jump, picker confirm).
  Creates a new tab or switches to an existing one.
- `:preview` — transient picker preview. Updates the current tab
  in-place so navigating the picker doesn't spawn new tabs.

# `shell_state`

```elixir
@type shell_state() :: term()
```

Shell-specific state. Each shell defines its own struct.

# `workspace`

```elixir
@type workspace() :: MingaEditor.Workspace.State.t()
```

Workspace state.

# `on_agent_event`

```elixir
@callback on_agent_event(
  shell_state(),
  workspace(),
  session_pid :: pid(),
  event :: term()
) :: {shell_state(), workspace()}
```

An agent session emitted an event. The shell reflects the status
change in its chrome (tab badges, card status icons, attention flags).
Foreground/background routing happens in `MingaEditor.handle_info/2`;
this callback receives only background events.

# `on_buffer_added`

```elixir
@callback on_buffer_added(
  shell_state(),
  prev_workspace :: workspace(),
  workspace(),
  buffer_pid :: pid(),
  context :: buffer_add_context()
) :: {shell_state(), workspace()}
```

A buffer was added to the workspace. Receives both the workspace before the buffer-pool mutation and the workspace after it, so shells can snapshot outgoing presentation state without capturing the newly activated buffer.

# `on_buffer_died`

```elixir
@callback on_buffer_died(shell_state(), workspace(), dead_pid :: pid()) ::
  {shell_state(), workspace()}
```

A buffer process died.

# `on_buffer_switched`

```elixir
@callback on_buffer_switched(shell_state(), workspace()) :: {shell_state(), workspace()}
```

The active buffer changed.

---

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