# Dirigate ACP (Agent-Client Protocol) bridge and mock server for testing and proxying ACP connections. ## Overview `dirigate` provides tools for working with ACP clients and servers: 1. **Bridge Mode**: Relay stdio ACP clients to a Dirigent ACP Server via HTTP/SSE 2. **Mock Server**: Serve fixture-based responses for testing ACP clients 3. **Interactive Client**: Connect to ACP agents for debugging and exploration ## Features - **Bridge Mode**: Connect external ACP clients (like Claude Code) to a Dirigent ACP Server - **Fixture-based responses**: Define sessions and message flows in YAML for testing - **Multiple response modes**: Static, random, sequential, and pattern-based - **Session ingestion**: Import sessions from OpenCode.ai or other sources (feature-gated) - **ACP compliance**: Full protocol implementation for testing clients - **CLI tool**: Easy-to-use command-line interface ## Installation ### As a CLI Tool ```bash cargo install --path packages/conductor ``` ### As a Library Add to your `Cargo.toml`: ```toml [dependencies] conductor = { path = "../conductor" } ``` For ingestion features: ```toml [dependencies] conductor = { path = "../conductor", features = ["ingest"] } ``` ## Usage ### Bridge Mode (NEW) Bridge a stdio ACP client to a Dirigent ACP Server via HTTP/SSE: ```bash # Connect to local server (default: http://localhost:3001/acp) conductor bridge # Connect to remote server conductor bridge --server-url http://remote:3001/acp # Via environment variable DIRIGENT_SERVER_URL=http://remote:3001/acp dirigate bridge # With verbose logging conductor bridge --verbose ``` **Bridge Architecture:** ``` External ACP Client (Claude Code, etc.) | | stdio (stdin/stdout) v +-------------------+ | Conductor Bridge | | - stdin parser | | - HTTP client | | - SSE subscriber | +-------------------+ | | HTTP/SSE v Dirigent ACP Server ``` **Options:** - `-s, --server-url ` - ACP Server URL (env: `DIRIGENT_SERVER_URL`, default: `http://localhost:3001/acp`) - `-v, --verbose` - Enable verbose logging of JSON-RPC messages - `--timeout ` - Timeout for HTTP requests (default: 30) - `--auto-reconnect` - Automatically reconnect SSE stream on disconnect (default: true) **Use Case: Connecting Claude Code to Dirigent** To use Claude Code with Dirigent: 1. Start the Dirigent web application (which includes the ACP Server) 2. Configure Claude Code to use a command-based ACP agent: ``` dirigate bridge ``` 3. Claude Code will now communicate through Conductor to Dirigent ### Mock Server ```bash conductor serve --fixtures ./fixtures --port 8080 ``` Options: - `-f, --fixtures ` - Directory containing fixture YAML files (default: `./fixtures`) - `-p, --port ` - Port to bind the server to (default: `8080`) - `--host ` - Host address to bind to (default: `127.0.0.1`) - `--stdio` - Use stdin/stdout for JSON-RPC transport - `-l, --log-level ` - Log level: trace, debug, info, warn, error (default: `info`) - `--log-format ` - Log format: pretty, json, compact (default: `pretty`) ### Validate Fixtures ```bash conductor validate ./fixtures ``` Validates fixture files without starting the server. ### Interactive Client Connect to an ACP agent for debugging and exploration: ```bash # Connect via stdio (spawns a process) conductor connect --command "claude --acp" --auto-session # Connect via HTTP conductor connect --url http://localhost:8080 --auto-session # Custom protocol version conductor connect --command "claude --acp" --protocol-version 1 --auto-session ``` **Interactive Commands:** - `/help` - Display available commands - `/quit` - Exit the client - `/session list` - List available sessions - `/session new` - Create a new session - `/session ` - Switch to a session - `/cancel` - Cancel generation in current session - Any other text - Send as message to current session **Debugging:** Enable detailed logging to see JSON-RPC packets: ```bash # See all debug logs including packets RUST_LOG=debug dirigate connect --command "claude --acp" --auto-session # See event details DIRIGENT_VERBOSE=1 dirigate connect --command "claude --acp" --auto-session ``` ### Ingest Sessions (requires `ingest` feature) ```bash conductor ingest \ -u http://localhost:12225 \ --session-id my-session-123 \ --output ./fixtures/my-session.yaml ``` Imports a session from an external source and converts it to fixture format. ## Fixture Format Fixtures are defined in YAML files: ```yaml version: "1" streaming: enabled: true tokens_per_chunk: 4 chunk_interval_ms: 50 sessions: - id: "session-123" title: "Test Session" created_at: "2025-01-01T00:00:00Z" participants: - id: "assistant" name: "Assistant" role: "agent" messages: - role: "agent" content: "Hello! How can I help you?" responders: default_strategy: Echo keyword_map: {} ``` ### Response Modes - **sequential**: Return messages in order (default) - **random**: Return a random message from the fixture - **pattern**: Match user input against patterns and return corresponding response - **static**: Always return the same message - **echo**: Echo back the user's input ## Project Structure ``` conductor/ |-- src/ | |-- lib.rs # Library entry point | |-- error.rs # Error types | |-- logging.rs # Logging infrastructure | |-- acp/ # ACP protocol implementation | | |-- mod.rs | | |-- bridge.rs # Bridge mode (stdio <-> HTTP/SSE) | | |-- server.rs # HTTP server | | |-- model.rs # Protocol types | | |-- stdio.rs # Stdio transport | | |-- stream.rs # SSE streaming | |-- fixture/ # Fixture system | | |-- mod.rs | | |-- types.rs # Fixture definitions | | |-- loader.rs # YAML loading | | |-- responders.rs # Response logic | |-- ingest/ # Session ingestion (feature-gated) | | |-- mod.rs | | |-- opencode.rs # OpenCode.ai ingestion | |-- cli/ # CLI interface | | |-- mod.rs | | |-- args.rs # Argument parsing | | |-- commands.rs # Command execution | |-- bin/ | |-- conductor.rs # Binary entry point |-- Cargo.toml |-- README.md ``` ## Configuration ### Environment Variables | Variable | Description | Default | |----------|-------------|---------| | `DIRIGENT_SERVER_URL` | ACP Server URL for bridge mode | `http://localhost:3001/acp` | | `CONDUCTOR_BUFFER_SIZE` | Broadcast channel buffer size for event distribution. Increase for high-volume event scenarios or when experiencing event drops during bursts. Valid values: Any positive integer (usize). Example: `CONDUCTOR_BUFFER_SIZE=500` | `100` | | `RUST_LOG` | Log level | `info` | | `DIRIGENT_VERBOSE` | Enable verbose event logging | (unset) | ## Testing Run tests: ```bash cargo test -p dirigate ``` Run with all features: ```bash cargo test -p dirigate --all-features ``` ## Dependencies ### Core - `clap` - CLI argument parsing - `serde`, `serde_yaml`, `serde_json` - Serialization - `tokio` - Async runtime - `axum` - Web server - `reqwest` - HTTP client (for bridge mode) - `reqwest-eventsource` - SSE client (for bridge mode) - `anyhow`, `thiserror` - Error handling - `tracing`, `tracing-subscriber` - Logging ### Optional (ingest feature) - `dirigent_protocol` - Protocol types - `opencode_client` - OpenCode.ai client ## License Same as the Dirigent project. ## Contributing See the main project README for contribution guidelines.