CodexWrapper.Exec (CodexWrapper v0.4.0)

Copy Markdown View Source

Exec command -- the primary interface for non-interactive prompts.

Wraps codex exec <prompt> with the full set of CLI flags.

Usage

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

# Build an exec command
exec = CodexWrapper.Exec.new("Fix the failing test")
  |> CodexWrapper.Exec.model("o3")
  |> CodexWrapper.Exec.sandbox(:workspace_write)
  |> CodexWrapper.Exec.ephemeral()

# Execute (returns result)
{:ok, result} = CodexWrapper.Exec.execute(exec, config)

Summary

Functions

Add a directory for context.

Set the approval policy.

Set the working directory for the codex subprocess.

Set the color mode: :always, :never, or :auto.

Add a config override (key=value).

Bypass all approvals and sandbox. Use with extreme caution.

Run enabled hooks without requiring persisted hook trust. Use with extreme caution.

Disable a feature.

Enable a feature.

Enable ephemeral mode (no session persistence).

Execute the command synchronously, returning a parsed %Result{}.

Execute the command with --json and return a list of parsed %JsonLineEvent{}.

Enable full-auto mode.

Do not load user or project execpolicy .rules files.

Do not load $CODEX_HOME/config.toml.

Add an image path.

Enable JSON output.

Select which local provider to use ("lmstudio" or "ollama").

Set the model.

Create a new exec command with the given prompt.

Use an open-source provider instead of the default.

Set the output-last-message path.

Set the output schema path.

Select a named config profile.

Set the sandbox mode.

Enable live web search.

Set the web search mode.

Skip the git repo check.

Execute the command and return a lazy Stream of %JsonLineEvent{}.

Error out when config.toml contains fields this Codex version does not recognize.

Types

approval_policy()

@type approval_policy() :: :untrusted | :on_request | :never

color_mode()

@type color_mode() :: :always | :never | :auto

sandbox_mode()

@type sandbox_mode() :: :read_only | :workspace_write | :danger_full_access

t()

@type t() :: %CodexWrapper.Exec{
  add_dirs: [String.t()],
  approval_policy: approval_policy() | nil,
  cd: String.t() | nil,
  color: color_mode() | nil,
  config_overrides: [String.t()],
  dangerously_bypass_approvals_and_sandbox: boolean(),
  dangerously_bypass_hook_trust: boolean(),
  disabled_features: [String.t()],
  enabled_features: [String.t()],
  ephemeral: boolean(),
  full_auto: boolean(),
  ignore_rules: boolean(),
  ignore_user_config: boolean(),
  images: [String.t()],
  json: boolean(),
  local_provider: String.t() | nil,
  model: String.t() | nil,
  oss: boolean(),
  output_last_message: String.t() | nil,
  output_schema: String.t() | nil,
  profile: String.t() | nil,
  prompt: String.t(),
  sandbox: sandbox_mode() | nil,
  search: web_search_mode() | nil,
  skip_git_repo_check: boolean(),
  strict_config: boolean()
}

web_search_mode()

@type web_search_mode() :: :cached | :indexed | :live | :disabled

Functions

add_dir(e, dir)

@spec add_dir(t(), String.t()) :: t()

Add a directory for context.

approval_policy(e, policy)

@spec approval_policy(t(), approval_policy()) :: t()

Set the approval policy.

One of :untrusted, :on_request, or :never. Emitted as the -c approval_policy="<value>" config override: codex-cli 0.14x removed the --ask-for-approval flag from exec, and the config key is the supported equivalent.

:on_failure was accepted by the old flag and is no longer a valid policy; passing it raises.

cd(e, dir)

@spec cd(t(), String.t()) :: t()

Set the working directory for the codex subprocess.

color(e, mode)

@spec color(t(), color_mode()) :: t()

Set the color mode: :always, :never, or :auto.

The CLI defaults to :auto, which already suppresses color when stdout is not a terminal. :never is worth setting explicitly when the output is parsed.

config(e, kv)

@spec config(t(), String.t()) :: t()

Add a config override (key=value).

dangerously_bypass_approvals_and_sandbox(e)

@spec dangerously_bypass_approvals_and_sandbox(t()) :: t()

Bypass all approvals and sandbox. Use with extreme caution.

dangerously_bypass_hook_trust(e)

@spec dangerously_bypass_hook_trust(t()) :: t()

Run enabled hooks without requiring persisted hook trust. Use with extreme caution.

Hook trust is what stops a repository from running arbitrary commands the user never approved. Only appropriate for automation that already vets where its hooks come from.

disable(e, feature)

@spec disable(t(), String.t()) :: t()

Disable a feature.

enable(e, feature)

@spec enable(t(), String.t()) :: t()

Enable a feature.

ephemeral(e)

@spec ephemeral(t()) :: t()

Enable ephemeral mode (no session persistence).

execute(exec, config)

@spec execute(t(), CodexWrapper.Config.t()) ::
  {:ok, CodexWrapper.Result.t()} | {:error, term()}

Execute the command synchronously, returning a parsed %Result{}.

execute_json(exec, config)

@spec execute_json(t(), CodexWrapper.Config.t()) ::
  {:ok, [CodexWrapper.JsonLineEvent.t()]} | {:error, term()}

Execute the command with --json and return a list of parsed %JsonLineEvent{}.

Forces --json on the exec command, runs synchronously, then parses each NDJSON line from stdout.

full_auto(e)

@spec full_auto(t()) :: t()

Enable full-auto mode.

Deprecated upstream. Emits --sandbox workspace-write, which is what the Codex CLI now tells you to use in place of --full-auto. An explicit sandbox/2 call is more specific and wins over this.

ignore_rules(e)

@spec ignore_rules(t()) :: t()

Do not load user or project execpolicy .rules files.

ignore_user_config(e)

@spec ignore_user_config(t()) :: t()

Do not load $CODEX_HOME/config.toml.

Auth still resolves through CODEX_HOME; only the config file is skipped. Pair with config/2 overrides for a run that does not pick up the developer's personal settings.

image(e, path)

@spec image(t(), String.t()) :: t()

Add an image path.

json(e)

@spec json(t()) :: t()

Enable JSON output.

local_provider(e, provider)

@spec local_provider(t(), String.t()) :: t()

Select which local provider to use ("lmstudio" or "ollama").

Meaningful alongside oss/1; without it the CLI uses the config default or prompts for a selection.

model(e, model)

@spec model(t(), String.t()) :: t()

Set the model.

new(prompt)

@spec new(String.t()) :: t()

Create a new exec command with the given prompt.

oss(e)

@spec oss(t()) :: t()

Use an open-source provider instead of the default.

output_last_message(e, path)

@spec output_last_message(t(), String.t()) :: t()

Set the output-last-message path.

output_schema(e, path)

@spec output_schema(t(), String.t()) :: t()

Set the output schema path.

profile(e, name)

@spec profile(t(), String.t()) :: t()

Select a named config profile.

Emits --profile <name>, which tells the Codex CLI to load the [profiles.<name>] section of config.toml.

sandbox(e, mode)

@spec sandbox(t(), sandbox_mode()) :: t()

Set the sandbox mode.

search(e)

@spec search(t()) :: t()

Enable live web search.

Shorthand for search(exec, :live).

search(e, mode)

@spec search(t(), web_search_mode()) :: t()

Set the web search mode.

One of :cached, :indexed, :live, or :disabled. Emitted as the -c web_search="<mode>" config override: codex-cli 0.14x removed the --search flag from exec, and the config key is the supported equivalent. :live is what --search used to mean.

skip_git_repo_check(e)

@spec skip_git_repo_check(t()) :: t()

Skip the git repo check.

stream(exec, config)

@spec stream(t(), CodexWrapper.Config.t()) :: Enumerable.t()

Execute the command and return a lazy Stream of %JsonLineEvent{}.

Reads NDJSON output line-by-line through the configured CodexWrapper.Runner. The process starts when the stream is consumed and is terminated when the stream halts. Lines that do not parse as JSON are skipped.

Forces --json on the exec command.

strict_config(e)

@spec strict_config(t()) :: t()

Error out when config.toml contains fields this Codex version does not recognize.

Turns a silently-ignored typo in a config file into a failed run, which is usually what a programmatic caller wants.