Claude CLI Integration
Relevant source files
The following files were used as context for generating this wiki page:
The Claude CLI Integration serves as the core engine for opcode, bridging the gap between the Anthropic "Claude Code" command-line interface and a visual desktop environment. It handles the lifecycle of Claude subprocesses, manages project-specific session data stored in ~/.claude, and provides real-time streaming of AI responses to the user interface.
This system is implemented across two primary modes: a native Tauri-based desktop application and a portable Axum-based web server. Both modes facilitate asynchronous communication with the claude binary, capturing stdout and stderr to update session states and usage metrics.
Sources: README.md:27-31, web_server.design.md:5-9, src-tauri/src/commands/claude.rs:18-20
Subprocess Architecture
The integration relies on spawning the claude binary as a child process. The backend configures these processes with specific flags to ensure non-interactive, streamable output suitable for a GUI.
Command Execution Logic
When a prompt is sent, the system constructs a command using tokio::process::Command. Key flags used include:
-p: Passes the user prompt.--model: Specifies the Claude model (e.g., Sonnet or Opus).--output-format stream-json: Forces Claude to output structured JSON for easier parsing.--dangerously-skip-permissions: Used in web/automated modes to prevent blocking on CLI permission prompts.
Sources: src-tauri/src/commands/claude.rs:650-660, src-tauri/src/web_server.rs:374-383
Execution Flow Diagram
The following diagram illustrates the flow from a user prompt in the UI to the execution of the Claude binary and the return of streamed data.
The backend uses an asynchronous line reader to process the binary's output without blocking the main application thread.
Sources: src-tauri/src/commands/claude.rs:770-795, src-tauri/src/web_server.rs:400-415
Binary Discovery
Since environments vary, opcode implements a discovery mechanism to find the claude executable across different operating systems and installation methods (e.g., npm, nvm, Homebrew).
| Method | Description | Path Examples |
|---|---|---|
| Bundled | Searches internal application directories | src-tauri/binaries/claude-code-... |
| System PATH | Checks standard shell paths using which | /usr/local/bin/claude |
| Homebrew | Specific check for macOS package manager | /opt/homebrew/bin/claude |
| Local Bin | Checks user-specific local directories | ~/.local/bin/claude |
Sources: src-tauri/src/web_server.rs:24-52, src-tauri/src/commands/claude.rs:104-106
Session and Project Management
Claude Code stores its internal state in a hidden .claude directory within the user's home folder. The integration maps these files into the application's data model.
Data Structures
- Project: Represents a unique project directory. The ID is often a hyphenated version of the absolute path.
- Session: A specific conversation within a project, stored as a
.jsonlfile.
Session Resumption
resuming a session involves passing the --resume flag followed by the session UUID. The backend reads the existing .jsonl files to extract the "cwd" (current working directory) and previous messages to rebuild the UI context.
Sources: src-tauri/src/commands/claude.rs:114-140, src-tauri/src/commands/claude.rs:693-705
Real-time Communication
The integration supports two communication protocols depending on the deployment mode.
Tauri Events (Desktop)
In desktop mode, the Rust backend emits events directly to the Webview using app.emit().
claude-output: Streams standard output.claude-error: Streams standard error.claude-complete: Indicates the subprocess has finished.
Sources: src-tauri/src/commands/claude.rs:810-825, src/components/ClaudeCodeSession.tsx:64-75
WebSockets (Web Server)
In web mode, an Axum server handles persistent WebSocket connections at /ws/claude.
- Client Request: Sends a JSON object containing the
command_type(execute/continue/resume),prompt, andproject_path. - Streaming: The server spawns the process and forwards stdout lines as individual WebSocket messages.
Sources: src-tauri/src/web_server.rs:163-170, web_server.design.md:46-60
Implementation Details
Environment Variable Inheritance
To ensure claude can find required runtimes like Node.js, the integration manually inherits and injects critical environment variables (e.g., PATH, NVM_DIR, NODE_PATH) into the subprocess.
Sources: src-tauri/src/commands/claude.rs:198-215
Process Cancellation
Cancellation is handled by tracking the Child process handle in a global ClaudeProcessState.
- Method 1: Killing the process via the
ProcessRegistryusing its PID. - Method 2: Sending a system
SIGKILLortaskkillif the handle is lost.
Sources: src-tauri/src/commands/claude.rs:718-765, web_server.design.md:110-120
Conclusion
The Claude CLI Integration is the functional backbone of opcode, enabling a high-fidelity GUI experience for a command-line tool. By managing the complexities of subprocess lifecycle, path discovery, and real-time data streaming, it allows developers to interact with Claude Code through an intuitive interface while maintaining the power of the underlying CLI.