opencode-sdk 0.1.6

Rust SDK for OpenCode (HTTP-first hybrid with SSE streaming)
Documentation
# opencode-sdk

Rust SDK for OpenCode HTTP API with SSE streaming support. Provides ergonomic async client, 15 REST API modules, 40+ event types, and managed server lifecycle.

## Requirements

- **Platform:** Unix only (Linux/macOS). Windows compilation fails with `compile_error!`.
- **Rust Edition:** 2024 (requires Rust 1.85+)
- **Runtime:** Tokio

## Installation

Add to your `Cargo.toml`:

```toml
[dependencies]
opencode-sdk = "0.1"

# Or with all features:
opencode-sdk = { version = "0.1", features = ["full"] }
```

## Features

| Feature | Default | Description |
|---------|---------|-------------|
| `http` || HTTP API client and modules |
| `sse` || SSE streaming support |
| `server` || Managed server process |
| `cli` || CLI wrapper |
| `full` || All features enabled |

## Quick Start

```rust
use opencode_sdk::Client;
use std::time::Duration;

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    // Create client
    let client = Client::builder()
        .base_url("http://127.0.0.1:4096")
        .directory("/path/to/project")
        .timeout_secs(300)
        .build()?;
    
    // Send a simple text prompt and wait for response
    let session = client.run_simple_text("Hello, AI!").await?;
    let response = client.wait_for_idle_text(&session.id, Duration::from_secs(60)).await?;
    println!("Response: {}", response);
    
    Ok(())
}
```

## Streaming Events

```rust
use opencode_sdk::types::Event;

// Subscribe to session events
let mut subscription = client.subscribe_session(&session.id).await?;

while let Some(event) = subscription.recv().await {
    match event {
        Event::MessagePartUpdated { properties } => {
            print!("{}", properties.delta.unwrap_or_default());
        }
        Event::SessionIdle { .. } => break,
        _ => {}
    }
}
```

## API Overview

### Sessions API

```rust
let sessions = client.sessions();

// Create session
let session = sessions.create(&CreateSessionRequest::default()).await?;

// Create with title
let session = sessions.create_with(
    SessionCreateOptions::new().with_title("My Task")
).await?;

// List, get, delete
let all_sessions = sessions.list().await?;
let session = sessions.get(&id).await?;
sessions.delete(&id).await?;

// Fork, share, revert
let forked = sessions.fork(&id).await?;
sessions.share(&id).await?;
sessions.revert(&id, &RevertRequest { message_id, part_id }).await?;
```

### Messages API

```rust
let messages = client.messages();

// Send prompt
let response = messages.prompt(&session_id, &PromptRequest::text("Hello")).await?;

// Send async (use with SSE)
messages.send_text_async(&session_id, "Hello", None).await?;

// List and get messages
let message_list = messages.list(&session_id).await?;
let message = messages.get(&session_id, &message_id).await?;
```

### SSE Subscriptions

```rust
// All events for directory
let sub = client.subscribe().await?;

// Filtered to specific session
let sub = client.subscribe_session(&session_id).await?;

// Global events (all directories)
let sub = client.subscribe_global().await?;

// Raw JSON frames
let raw = client.subscribe_raw().await?;
```

## Managed Server (requires `server` feature)

```rust
use opencode_sdk::server::{ManagedServer, ServerOptions};

// Start managed server
let server = ManagedServer::start(
    ServerOptions::new().port(8080)
).await?;

// Create client connected to managed server
let client = Client::builder()
    .base_url(server.url())
    .build()?;

// Server auto-stops when dropped
server.stop().await?;
```

## CLI Runner (requires `cli` feature)

```rust
use opencode_sdk::cli::{CliRunner, RunOptions};

let mut runner = CliRunner::start(
    "Hello",
    RunOptions::new().model("provider/model")
).await?;

// Stream events
while let Some(event) = runner.recv().await {
    if event.is_text() {
        print!("{}", event.text());
    }
}

// Or collect all text
let text = runner.collect_text().await;
```

## Event Types

The SDK supports 40+ SSE event types organized by category:

- **Server/Instance:** `ServerConnected`, `ServerHeartbeat`, `ServerInstanceDisposed`, `GlobalDisposed`
- **Session:** `SessionCreated`, `SessionUpdated`, `SessionDeleted`, `SessionDiff`, `SessionError`, `SessionCompacted`, `SessionStatus`, `SessionIdle`
- **Messages:** `MessageUpdated`, `MessageRemoved`, `MessagePartUpdated`, `MessagePartRemoved`
- **Questions:** `QuestionCreated`, `QuestionUpdated`, `QuestionRemoved`
- **Files:** `FileChanged`, `FileSynced`
- **MCP:** `MCPServerConnected`, `MCPServerDisconnected`, `MCPError`, `MCPLog`
- **Tool:** `ToolCallCreated`, `ToolCallUpdated`
- **And more...**

## Project Structure

```
src/
├── lib.rs           # Crate root and re-exports
├── client.rs        # Client, ClientBuilder
├── error.rs         # OpencodeError, Result
├── sse.rs           # SSE streaming and subscriptions
├── server.rs        # ManagedServer (server feature)
├── cli.rs           # CliRunner (cli feature)
├── runtime.rs       # ManagedRuntime
├── http/            # HTTP API modules
│   ├── sessions.rs
│   ├── messages.rs
│   └── ...
└── types/           # Data models
    ├── session.rs
    ├── message.rs
    └── event.rs
```

## Error Handling

```rust
match result {
    Err(e) if e.is_not_found() => println!("Not found"),
    Err(e) if e.is_validation_error() => println!("Validation error"),
    Err(e) => eprintln!("Error: {}", e),
    Ok(v) => v,
}
```

## Common Pitfalls

1. **Subscribe before sending** - Create SSE subscription before async prompts to avoid missing early events
2. **Check feature flags** - `server` and `cli` require explicit enabling
3. **Keep server alive** - `ManagedServer` kills on drop; hold reference while using
4. **Handle platform** - Unix only; use WSL or Docker on Windows

## License

Apache-2.0

## Resources

- [API Documentation]https://docs.rs/opencode-rs-sdk
- [OpenCode Platform]https://opencode.ai

---

*Version 0.1.3*