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

Elixir wrapper for the Claude Code CLI.

Provides a typed interface for executing queries against the `claude` CLI,
with support for one-shot execution and streaming NDJSON output.

## Quick start

    # One-shot query (convenience — uses default config)
    {:ok, result} = ClaudeWrapper.query("Explain this error: ...")

    # With options
    {:ok, result} = ClaudeWrapper.query("Fix the bug in lib/foo.ex",
      model: "sonnet",
      working_dir: "/path/to/project",
      max_turns: 5,
      permission_mode: :bypass_permissions
    )

    # Streaming
    ClaudeWrapper.stream("Implement the feature described in issue #42",
      working_dir: "/path/to/project"
    )
    |> Stream.each(fn event -> IO.inspect(event.type) end)
    |> Stream.run()

    # Full control via Query builder
    config = ClaudeWrapper.Config.new(working_dir: "/path/to/project")

    ClaudeWrapper.Query.new("Fix the tests")
    |> ClaudeWrapper.Query.model("sonnet")
    |> ClaudeWrapper.Query.dangerously_skip_permissions()
    |> ClaudeWrapper.Query.max_turns(10)
    |> ClaudeWrapper.Query.execute(config)

## Commands

  * `ClaudeWrapper.Query` — the main query/prompt interface
  * `ClaudeWrapper.Commands.Auth` — login, logout, status, token
  * `ClaudeWrapper.Commands.Mcp` — MCP server management
  * `ClaudeWrapper.Commands.Doctor` — CLI health check
  * `ClaudeWrapper.Commands.Version` — CLI version

## Binary discovery

The `claude` binary is found via (in order):
1. `:binary` option passed directly
2. `CLAUDE_CLI` environment variable
3. System PATH lookup

# `agents`

```elixir
@spec agents(keyword()) :: {:ok, [map()]} | {:error, term()}
```

List configured agents.

Returns a list of agent maps with `:name` and `:model` keys.

## Options

  * `:setting_sources` - comma-separated setting sources (e.g. `"user,project"`)

# `auth_status`

```elixir
@spec auth_status(keyword()) :: {:ok, map()} | {:error, term()}
```

Check authentication status.

# `doctor`

```elixir
@spec doctor(keyword()) :: {:ok, String.t()} | {:error, term()}
```

Run `claude doctor`.

# `query`

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

Execute a one-shot query and return the result.

Convenience wrapper that builds a `Config` and `Query` from keyword options.
Returns `{:ok, %Result{}}` on success or `{:error, reason}` on failure.

## Options

Config options (passed to `ClaudeWrapper.Config.new/1`):
  * `:binary` - Path to claude binary
  * `:working_dir` - Working directory
  * `:env` - Environment variables
  * `:timeout` - Timeout in ms
  * `:verbose` - Enable verbose output
  * `:debug` - Enable debug output

Query options (passed to `Query` builder):
  * `:model` - Model name
  * `:system_prompt` - System prompt override
  * `:max_turns` - Max turns
  * `:max_budget_usd` - Budget limit
  * `:permission_mode` - Permission mode atom
  * `:dangerously_skip_permissions` - Bypass permissions (boolean)
  * `:session_id` - Session ID
  * `:continue_session` - Continue recent session (boolean)
  * `:resume` - Resume session ID

# `raw`

```elixir
@spec raw(
  [String.t()],
  keyword()
) :: {:ok, String.t()} | {:error, term()}
```

Run an arbitrary CLI command that isn't wrapped by a dedicated module.

This is the escape hatch for new or experimental CLI subcommands.

## Examples

    ClaudeWrapper.raw(["config", "list"])
    ClaudeWrapper.raw(["plugin", "install", "my-plugin"], working_dir: "/tmp")

# `stream`

```elixir
@spec stream(
  String.t(),
  keyword()
) :: Enumerable.t()
```

Execute a query and return a lazy stream of `%StreamEvent{}` structs.

The subprocess starts when the stream is consumed. Accepts the same
options as `query/2`.

# `version`

```elixir
@spec version(keyword()) :: {:ok, map()} | {:error, term()}
```

Get the CLI version.

---

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