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

GenServer wrapper for long-running multi-turn sessions.

Holds a `ClaudeWrapper.Session` in state and provides a process-based
interface for OTP applications, supervision trees, and concurrent access.

## Usage

    config = ClaudeWrapper.Config.new(working_dir: "/path/to/project")

    {:ok, pid} = ClaudeWrapper.SessionServer.start_link(
      config: config,
      query_opts: [model: "sonnet", max_turns: 5]
    )

    {:ok, result} = ClaudeWrapper.SessionServer.send_message(pid, "What files are here?")
    {:ok, result} = ClaudeWrapper.SessionServer.send_message(pid, "Add tests for lib/foo.ex")

    ClaudeWrapper.SessionServer.total_cost(pid)
    #=> 0.12

## Supervision

    children = [
      {ClaudeWrapper.SessionServer,
       name: :my_agent,
       config: config,
       query_opts: [model: "sonnet"]}
    ]

    Supervisor.start_link(children, strategy: :one_for_one)

    # Then use the registered name
    ClaudeWrapper.SessionServer.send_message(:my_agent, "hello")

# `option`

```elixir
@type option() ::
  {:config, ClaudeWrapper.Config.t()}
  | {:query_opts, keyword()}
  | {:session_id, String.t()}
  | {:name, GenServer.name()}
  | GenServer.option()
```

# `server`

```elixir
@type server() :: GenServer.server()
```

# `child_spec`

Returns a specification to start this module under a supervisor.

See `Supervisor`.

# `get_session`

```elixir
@spec get_session(server()) :: ClaudeWrapper.Session.t()
```

Get the underlying `%Session{}` struct (snapshot).

# `history`

```elixir
@spec history(server()) :: [ClaudeWrapper.Result.t()]
```

Get the full conversation history.

# `last_result`

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

Get the last result, if any.

# `put_session`

```elixir
@spec put_session(server(), ClaudeWrapper.Session.t()) :: :ok
```

Replace the underlying `%Session{}` struct.

Useful when you have streamed a session turn outside the GenServer
process (e.g. by calling `Session.stream/3` directly) and need to
push the post-turn session state back into the supervised server so
the next `send/3` resumes correctly.

# `send_message`

```elixir
@spec send_message(server(), String.t(), keyword()) ::
  {:ok, ClaudeWrapper.Result.t()} | {:error, term()}
```

Send a message in the session. Blocks until the CLI responds.

Returns `{:ok, %Result{}}` or `{:error, reason}`.

# `session_id`

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

Get the session ID (if established).

# `start_link`

```elixir
@spec start_link([option()]) :: GenServer.on_start()
```

Start a session server.

## Options

  * `:config` - (required) `%Config{}` struct
  * `:query_opts` - Query options applied to every turn (e.g. `model`, `max_turns`)
  * `:session_id` - Resume an existing session by ID
  * `:name` - Register the process with a name

Also accepts standard `GenServer.start_link/3` options.

# `total_cost`

```elixir
@spec total_cost(server()) :: float()
```

Get the total cost across all turns.

# `turn_count`

```elixir
@spec turn_count(server()) :: non_neg_integer()
```

Get the number of completed turns.

---

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