# `CodexWrapper.Config`
[🔗](https://github.com/genagent/codex_wrapper_ex/blob/v0.8.1/lib/codex_wrapper/config.ex#L1)

Shared client configuration for the Codex CLI.

Holds binary path, working directory, environment variables, and default
options that apply across all commands.

## Usage

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

# `t`

```elixir
@type t() :: %CodexWrapper.Config{
  binary: String.t(),
  env: [{String.t(), String.t()}],
  idle_timeout_ms: pos_integer() | nil,
  runner: module() | atom() | nil,
  runner_default_timeout_ms: pos_integer() | nil,
  runner_explicit: boolean() | nil,
  runner_options: keyword() | nil,
  timeout: pos_integer() | nil,
  verbose: boolean(),
  working_dir: String.t() | nil
}
```

# `base_args`

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

Build the base command args from config (global flags).

Currently always empty. Raises `ArgumentError` if `verbose: true` was set
on a directly constructed or updated struct.

# `cmd_opts`

```elixir
@spec cmd_opts(t()) :: keyword()
```

Build the cmd options (working dir, env) for `System.cmd`.

# `find_binary`

```elixir
@spec find_binary() :: String.t()
```

Find the codex binary path.

Checks in order:
1. `CODEX_CLI` environment variable
2. System PATH

# `new`

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

Create a new config from keyword options.

## Options

  * `:binary` - Literal executable path or name on `PATH` (default: auto-discover).
    Shell commands and unexpanded `~` or environment-variable paths are not supported.
  * `:working_dir` - Working directory for the subprocess
  * `:env` - List of `{key, value}` environment variable tuples
  * `:timeout` - Whole-command timeout in milliseconds
  * `:idle_timeout_ms` - Maximum gap between output frames while streaming
    or using evidenced one-shot execution
    (default: 300,000 ms)
  * `:runner` - Runner module or `:task` / `:forcola` shorthand. Application
    defaults are snapshotted at construction, only when this field is absent.
    An explicitly selected runner must implement `stream_lines/4` for streaming;
    otherwise consumption raises `ArgumentError` before spawning. Implicit
    application/default selection retains the legacy Port fallback with a warning.
    Direct structs with a non-nil runner are treated as explicit selections.
    `:runner_explicit` is internal selection provenance set by `new/1`.
  * `:runner_options` - Validated one-shot transport options. An explicit `[]`
    overrides application defaults. See `runner_options/1` for supported keys.
  * `:verbose` - Compatibility option. Only `false` is supported; `true` raises
    `ArgumentError` before the CLI is launched, because the Codex CLI does not
    define a `--verbose` flag

# `runner_options`

```elixir
@spec runner_options(t()) :: keyword()
```

Return validated immutable transport options. Direct structs with `nil` fields
retain legacy application-default lookup; `new/1` snapshots those defaults.

Supported keys: `:shim_path` (absolute path), `:env_mode` (`:inherit` or
`:replace`), `:timeout_ms`, `:idle_timeout_ms`, `:max_output_bytes`,
`:kill_grace_ms`, and the paired `:interrupt_signal` (`:int`) and
`:interrupt_grace_ms`. Limits are positive 32-bit integers; kill grace may
be zero. These requirements need a runner implementing `validate_options/1`.
`:timeout_ms` supplies the runner default; config `:timeout` takes precedence.
New requirements are refused by unsupported runners before spawning. These
options apply to one-shot execution; streams reject nonempty options before
spawning rather than silently losing requirements.

# `stream_opts`

```elixir
@spec stream_opts(t()) :: keyword()
```

Build the runner options for a streaming run.

Same shape as `cmd_opts/1` but with `stderr_to_stdout: false`: the
streaming paths parse NDJSON off stdout, and merging stderr into it
would put unparseable lines in the stream. Stderr is left to flow to
the parent's stderr.

---

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