> ## Documentation Index
> Fetch the complete documentation index at: https://docs.instructorphp.com/llms.txt
> Use this file to discover all available pages before exploring further.

# 2 getting started

## Requirements

* PHP 8.2 or later
* At least one supported CLI-based code agent installed and authenticated:
  * **Claude Code** -- the `claude` binary ([Anthropic CLI](https://docs.anthropic.com/en/docs/claude-code))
  * **OpenAI Codex** -- the `codex` binary (`npm install -g @openai/codex`)
  * **OpenCode** -- the `opencode` binary (`curl -fsSL https://get.opencode.dev | bash`)
  * **Pi** -- the `pi` binary (from pi-mono)
  * **Gemini** -- the `gemini` binary (`npm install -g @google/gemini-cli`)

Each CLI must be available in the system `PATH` visible to your PHP process. Run the binary interactively at least once to complete any first-run authentication flows before using it through Agent-Ctrl.

## Installation

Install the package via Composer:

```bash theme={null}
composer require cognesy/agent-ctrl
# @doctest id="13a6"
```

Agent-Ctrl is part of the Instructor-PHP monorepo. It depends on the `cognesy/sandbox` package for process execution and isolation, which is pulled in automatically.

## Your First Request

The simplest way to use Agent-Ctrl is to pick an agent, pass a prompt, and read the result:

```php theme={null}
use Cognesy\AgentCtrl\AgentCtrl;
use Cognesy\AgentCtrl\Config\AgentCtrlConfig;

$response = AgentCtrl::codex()
    ->withConfig(new AgentCtrlConfig(
        timeout: 300,
        workingDirectory: getcwd() ?: null,
    ))
    ->execute('Summarize this repository.');

echo $response->text();
// @doctest id="6ab2"
```

The `execute()` method runs the agent synchronously, waits for it to finish, and returns an `AgentResponse` object containing the text output, exit code, session ID, and any tool calls the agent made.

## Choosing a Different Agent

Each supported agent has its own factory method on the `AgentCtrl` facade:

```php theme={null}
use Cognesy\AgentCtrl\AgentCtrl;

// Use Claude Code
$response = AgentCtrl::claudeCode()
    ->execute('List the main packages in this monorepo.');

// Use OpenCode
$response = AgentCtrl::openCode()
    ->execute('Explain the package layout.');
// @doctest id="ed91"
```

All factory methods return a builder that supports the same core API (`withConfig()`, `withModel()`, `withTimeout()`, `inDirectory()`, `execute()`, `executeStreaming()`, etc.), so you can switch agents without restructuring your code.

## Selecting the Agent at Runtime

When the agent type is determined by configuration or user input rather than being hard-coded, use the `AgentType` enum with `AgentCtrl::make()`:

```php theme={null}
use Cognesy\AgentCtrl\AgentCtrl;
use Cognesy\AgentCtrl\Config\AgentCtrlConfig;
use Cognesy\AgentCtrl\Enum\AgentType;

// AgentType is a backed enum: 'claude-code', 'codex', 'opencode', 'pi', 'gemini'
$agent = AgentType::from($config['agent']);

$agentConfig = AgentCtrlConfig::fromArray([
    'model' => $config['model'] ?? null,
    'timeout' => $config['timeout'] ?? null,
    'directory' => $config['directory'] ?? null,
    'sandbox' => $config['sandbox'] ?? null,
]);

$response = AgentCtrl::make($agent)
    ->withConfig($agentConfig)
    ->execute('Explain the package layout.');
// @doctest id="7d9b"
```

The `AgentType` enum has five cases:

| Case                    | Value           | Builder                   |
| ----------------------- | --------------- | ------------------------- |
| `AgentType::ClaudeCode` | `'claude-code'` | `ClaudeCodeBridgeBuilder` |
| `AgentType::Codex`      | `'codex'`       | `CodexBridgeBuilder`      |
| `AgentType::OpenCode`   | `'opencode'`    | `OpenCodeBridgeBuilder`   |
| `AgentType::Pi`         | `'pi'`          | `PiBridgeBuilder`         |
| `AgentType::Gemini`     | `'gemini'`      | `GeminiBridgeBuilder`     |

## Common Configuration

Every builder -- regardless of the agent type -- supports the same set of core configuration methods. These methods are defined in the `AgentBridgeBuilder` interface and implemented by the `AbstractBridgeBuilder` base class.

### `withConfig(AgentCtrlConfig $config): static`

Apply a typed config object for the shared builder options:

```php theme={null}
use Cognesy\AgentCtrl\Config\AgentCtrlConfig;

$config = AgentCtrlConfig::fromArray([
    'model' => 'o4-mini',
    'timeout' => 300,
    'directory' => '/projects/my-app',
    'sandbox' => 'docker',
]);

AgentCtrl::codex()
    ->withConfig($config)
    ->execute('Review the current directory.');
// @doctest id="3ff9"
```

`AgentCtrlConfig::fromArray()` accepts Laravel-style aliases:

* `directory` -> `workingDirectory`
* `sandbox` -> `sandboxDriver`

### Model Selection

Specify which model the agent should use. The format depends on the agent: Claude Code uses Anthropic model names, Codex uses OpenAI model names, and OpenCode uses provider-prefixed IDs:

```php theme={null}
// Claude Code
AgentCtrl::claudeCode()->withModel('claude-sonnet-4-5');

// Codex
AgentCtrl::codex()->withModel('o4-mini');

// OpenCode (provider/model format)
AgentCtrl::openCode()->withModel('anthropic/claude-sonnet-4-5');
// @doctest id="0eb2"
```

### Execution Timeout

Set the maximum time (in seconds) the agent is allowed to run. The default is 120 seconds. If the timeout is exceeded, the process is killed and the response will have a non-zero exit code:

```php theme={null}
$response = AgentCtrl::claudeCode()
    ->withTimeout(600) // 10 minutes
    ->execute('Perform a comprehensive codebase review.');
// @doctest id="bfc7"
```

The minimum accepted timeout is 1 second. Values less than 1 are clamped to 1.

### Working Directory

Set the directory the agent should operate in. The bridge validates that the directory exists before changing into it and restores the original working directory after execution:

```php theme={null}
$response = AgentCtrl::codex()
    ->inDirectory('/projects/my-app')
    ->execute('Review the current directory.');
// @doctest id="bed0"
```

> **Note:** Always use absolute paths. The bridge changes the PHP process's current working directory for the duration of the execution. If your PHP process handles concurrent requests (e.g., Swoole or RoadRunner), be aware that this affects the entire process.

### Sandbox Driver

By default, Agent-Ctrl runs the CLI binary directly on the host. You can switch to a containerized sandbox driver for additional process isolation:

```php theme={null}
use Cognesy\Sandbox\Enums\SandboxDriver;

$response = AgentCtrl::claudeCode()
    ->withSandboxDriver(SandboxDriver::Docker)
    ->execute('Analyze this codebase.');
// @doctest id="afce"
```

Available sandbox drivers:

| Driver                      | Description                             |
| --------------------------- | --------------------------------------- |
| `SandboxDriver::Host`       | Run directly on the host (default)      |
| `SandboxDriver::Docker`     | Run inside a Docker container           |
| `SandboxDriver::Podman`     | Run inside a Podman container           |
| `SandboxDriver::Firejail`   | Run inside a Firejail sandbox (Linux)   |
| `SandboxDriver::Bubblewrap` | Run inside a Bubblewrap sandbox (Linux) |

When using a containerized driver (Docker or Podman), the binary preflight check is skipped -- the binary is expected to be available inside the container image.

## Checking the Result

The `execute()` method returns an `AgentResponse`. Always check `isSuccess()` before using the text output, because a completed execution with a non-zero exit code does not throw an exception:

```php theme={null}
$response = AgentCtrl::codex()
    ->withTimeout(300)
    ->inDirectory(__DIR__)
    ->execute('Review the current directory.');

if ($response->isSuccess()) {
    echo $response->text();
} else {
    echo "Agent failed with exit code: {$response->exitCode}";
}
// @doctest id="539d"
```

See the [Response Object](/packages/agent-ctrl/6-response-object) documentation for the full set of properties and methods available on `AgentResponse`.

## Next Steps

* [Streaming](/packages/agent-ctrl/3-streaming) -- Receive real-time updates while the agent is working
* [Session Management](/packages/agent-ctrl/4-session-management) -- Continue or resume agent sessions
* [Agent Options](/packages/agent-ctrl/5-agent-options) -- Explore shared and agent-specific configuration
* [Claude Code Bridge](/packages/agent-ctrl/8-claude-code-bridge), [Codex Bridge](/packages/agent-ctrl/9-codex-bridge), [OpenCode Bridge](/packages/agent-ctrl/10-opencode-bridge), [Pi Bridge](/packages/agent-ctrl/11-pi-bridge), [Gemini Bridge](/packages/agent-ctrl/12-gemini-bridge) -- Deep dives into each agent's unique capabilities
