# `ClaudeWrapper.IEx`
[🔗](https://github.com/genagent/claude_wrapper_ex/blob/main/lib/claude_wrapper/iex.ex#L1)

Interactive helpers for conversational use in IEx.

Provides a minimal, REPL-friendly interface that manages session state
implicitly so you can just talk to Claude.

## Usage

    iex> import ClaudeWrapper.IEx

    iex> chat("explain this codebase", working_dir: ".")
    # => prints response, shows cost, returns the %Result{}

    iex> say("now add tests for the retry module")
    # => continues the conversation

    iex> say("looks good, ship it")
    # => keeps going

    iex> cost()
    # => $0.21 across 3 turns

    iex> history()
    # => prints conversation

    iex> reset()
    # => starts fresh

## Configuration

`configure/1` is the single source of sticky defaults: whatever you set
there applies to every later `chat/2` and `say/2`. Options passed
directly to `chat/2` or `say/2` apply to **that call only** and are
never written back to ambient -- a one-off `attach:` or `model:` won't
silently ride along on the next turn. Per-call options win over ambient
for the call they're on.

Ambient and per-call options both cover config (`:working_dir`,
`:binary`, `:env`, `:timeout`, `:verbose`, `:debug`), query options
(`:model`, `:max_turns`, `:permission_mode`, ...), and prompt-composition
keys (see below).

    configure(model: "sonnet", working_dir: "/my/project")
    chat("hello")                            # uses the ambient sonnet + cwd
    say("do something big", max_turns: 20)   # max_turns: this turn only

## Prompt composition

`chat/2` and `say/2` accept composition keys that build a
`t:ClaudeWrapper.Prompt.t/0` around the prompt argument before sending:

  * `:attach` -- a path/glob (or list of them) to attach as fenced,
    path-headed code blocks
  * `:git_diff` -- a ref to diff against, or `true`/`nil` for the
    working tree
  * `:prepend` -- text (or list) to place before the prompt
  * `:append` -- text (or list) to place after the context

When any composition key is present the helper prints a one-line
`(attached N files, ~K bytes)` notice before the response.

## Return values

`chat/2` and `say/2` return the `t:ClaudeWrapper.Result.t/0` on success
(after printing it). A CLI failure prints the error and **raises**
`ClaudeWrapper.Error`. The one non-raising case is calling `say/2` with
no active session, which prints a hint and returns `:no_session`.

# `session_summary`

```elixir
@type session_summary() :: %{
  id: String.t(),
  first_prompt: String.t() | nil,
  turns: non_neg_integer(),
  last_used: String.t() | nil,
  tokens: non_neg_integer() | nil,
  cost_usd: float() | nil
}
```

A session row as returned by `sessions/0`.

# `chat`

```elixir
@spec chat(
  String.t(),
  keyword()
) :: ClaudeWrapper.Result.t()
```

Start a new conversation. Prints the response and returns the
`t:ClaudeWrapper.Result.t/0`.

Effective options are the ambient config (see `configure/1`) merged
with `opts` (per-call wins). Config keys build the session config;
composition keys build a prompt around `prompt`; everything else is
forwarded as turn options. Per-call `opts` apply to this turn only and
are **not** persisted -- use `configure/1` for sticky defaults.

Raises `ClaudeWrapper.Error` on a CLI/render failure.

# `config`

```elixir
@spec config() :: keyword()
```

Return the current ambient configuration keyword list.

# `configure`

```elixir
@spec configure(keyword()) :: :ok
```

Merge options into the ambient configuration (last wins).

Ambient options are applied to every subsequent `chat/2` and `say/2`
call, with per-call options overriding them. Accepts config, query, and
composition keys.

    configure(model: "sonnet", working_dir: ".")
    #=> :ok

# `cost`

```elixir
@spec cost() :: float() | :no_session
```

Show total cost and turn count for the current session.

# `current`

```elixir
@spec current() ::
  %{id: String.t() | nil, turns: non_neg_integer(), cost_usd: float()} | nil
```

Snapshot of the current session: `%{id, turns, cost_usd}` or `nil`.

# `fork`

```elixir
@spec fork(
  String.t(),
  keyword()
) :: ClaudeWrapper.Result.t()
```

Branch the current conversation into a new session and switch to it.

Forks the active session (see `ClaudeWrapper.Session.fork/3`), makes the
branch the current session, prints the response, and returns the
`t:ClaudeWrapper.Result.t/0`. Raises `ClaudeWrapper.Error` on failure
(including `:no_session` when there is no active session to fork).

# `fork_from`

```elixir
@spec fork_from(String.t(), String.t(), keyword()) :: ClaudeWrapper.Result.t()
```

Resume `session_id` and immediately branch it into a new session.

Resumes the given id with the ambient config, forks it, switches to the
branch, prints the response, and returns the
`t:ClaudeWrapper.Result.t/0`. Raises `ClaudeWrapper.Error` on failure.

# `history`

```elixir
@spec history() :: :ok | :no_session
```

Print the conversation history.

# `last`

```elixir
@spec last() :: ClaudeWrapper.Result.t() | nil
```

Get the last result struct (for programmatic access).

# `pick`

```elixir
@spec pick() :: String.t() | :cancelled
```

Print a numbered list of prior sessions and resume the chosen one.

Shows each session's turn count, age, and cost (or `—` when unknown),
reads a selection via `IO.gets/1`, resumes it, and returns the chosen
id. Empty input returns `:cancelled`.

# `reset`

```elixir
@spec reset() :: :ok
```

Reset the session and ambient config (start fresh on next `chat/2`).

# `resume`

```elixir
@spec resume(
  String.t(),
  keyword()
) :: :ok
```

Resume a previous session by ID.

Uses the ambient config (or pass new config/query options).

# `say`

```elixir
@spec say(
  String.t(),
  keyword()
) :: ClaudeWrapper.Result.t() | :no_session
```

Continue the current conversation. Prints the response and returns the
`t:ClaudeWrapper.Result.t/0`.

Per-call `opts` are merged over the ambient query/composition options
(per-call wins). Returns `:no_session` (with a hint) when no session is
active; raises `ClaudeWrapper.Error` on a CLI/render failure.

# `session_id`

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

Get the session ID (for resuming later).

# `sessions`

```elixir
@spec sessions() :: [session_summary()]
```

List prior sessions for the ambient working directory (most recent
first).

Reads Claude Code's on-disk history for the configured `:working_dir`
(or the current directory when unset). Each row is a map with `:id`,
`:first_prompt`, `:turns`, `:last_used`, `:tokens`, and `:cost_usd`.
Returns `[]` when history cannot be read.

---

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