# `MingaEditor.Agent.View.Preview`
[🔗](https://github.com/jsmestad/minga/blob/main/lib/minga_editor/agent/view/preview.ex#L1)

Preview pane state machine for the agentic view.

The right pane of the agentic view reacts to agent tool activity. This
module manages a discriminated union of content types:

- `:empty` - no content yet (welcome state)
- `{:shell, command, output, status}` - shell command output (streaming or done)
- `{:diff, DiffReview.t()}` - unified diff from a file edit
- `{:file, path, content}` - file content from a read_file tool

The preview updates in response to tool events: ToolStart sets a loading
state, ToolUpdate streams partial output, ToolEnd finalizes, and
ToolFileChanged triggers diff mode.

Scroll state is tracked here so each content type preserves its own scroll
position. Auto-follow pauses when the user scrolls manually and resumes on
the next tool event.

# `content`

```elixir
@type content() ::
  :empty
  | {:shell, command :: String.t(), output :: String.t(), shell_status()}
  | {:diff, MingaEditor.Agent.DiffReview.t()}
  | {:file, path :: String.t(), content :: String.t()}
  | {:directory, path :: String.t(), entries :: [String.t()]}
```

The content currently displayed in the preview pane.

# `shell_status`

```elixir
@type shell_status() :: :running | :done | :error
```

Shell command execution status.

# `t`

```elixir
@type t() :: %MingaEditor.Agent.View.Preview{
  content: content(),
  scroll: Minga.Editing.Scroll.t()
}
```

Preview pane state.

# `clear`

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

Clears the preview to empty state.

# `diff?`

```elixir
@spec diff?(t()) :: boolean()
```

Returns true if the preview is showing a diff review.

# `diff_review`

```elixir
@spec diff_review(t()) :: MingaEditor.Agent.DiffReview.t() | nil
```

Returns the DiffReview if the preview is in diff mode, nil otherwise.

# `directory?`

```elixir
@spec directory?(t()) :: boolean()
```

Returns true if the preview is showing a directory listing.

# `empty?`

```elixir
@spec empty?(t()) :: boolean()
```

Returns true if the preview is empty.

# `finish_shell`

```elixir
@spec finish_shell(t(), String.t(), shell_status()) :: t()
```

Marks the shell command as complete.

# `new`

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

Creates a new empty preview state.

# `scroll_down`

```elixir
@spec scroll_down(t(), pos_integer()) :: t()
```

Scrolls down. Delegates to `Minga.Editing.scroll_down/2`.

# `scroll_to_bottom`

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

Pins to bottom. Delegates to `Minga.Editing.pin_to_bottom/1`.

# `scroll_to_top`

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

Scrolls to top. Delegates to `Minga.Editing.scroll_to_top/1`.

# `scroll_up`

```elixir
@spec scroll_up(t(), pos_integer()) :: t()
```

Scrolls up. Delegates to `Minga.Editing.scroll_up/2`.

# `set_diff`

```elixir
@spec set_diff(t(), MingaEditor.Agent.DiffReview.t()) :: t()
```

Sets the preview to show a diff review.

# `set_directory`

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

Sets the preview to show a directory listing.

# `set_file`

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

Sets the preview to show file content.

# `set_shell`

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

Sets the preview to show shell command output (streaming).

# `shell?`

```elixir
@spec shell?(t()) :: boolean()
```

Returns true if the preview is showing shell output.

# `update_diff`

```elixir
@spec update_diff(t(), (MingaEditor.Agent.DiffReview.t() -&gt;
                    MingaEditor.Agent.DiffReview.t())) :: t()
```

Updates the diff review within the preview.

# `update_shell_output`

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

Updates the shell output with new partial content.

---

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