# 機能設計書 57-JavaScript SDK

## 概要

本ドキュメントは、OpenCodeのJavaScript SDKについて、その設計仕様を記述するものである。

### 本機能の処理概要

JavaScript SDK機能は、OpenCode APIを利用するためのJavaScript/TypeScript SDKを提供する機能である。OpenAPIスキーマから自動生成されたクライアントコードをベースに、サーバー起動、セッション管理、メッセージ送信などの機能をプログラマティックに利用できる。

**業務上の目的・背景**：OpenCodeの機能を外部アプリケーションやスクリプトから利用したい場合、SDKを通じてAPIを呼び出すことで、HTTPリクエストの詳細を意識せずに簡潔なコードでOpenCodeを制御できる。

**機能の利用シーン**：
- カスタムCLIツールからのOpenCode利用
- CI/CDパイプラインでのAIコードレビュー自動化
- Slackボット等の外部サービスとの統合
- バッチ処理でのコード生成タスク

**主要な処理内容**：
1. OpenCodeサーバーの起動（createOpencodeServer）
2. APIクライアントの作成（createOpencodeClient）
3. セッション作成・管理
4. プロンプト送信と応答受信
5. SSEイベントストリームの購読
6. 非ASCII文字を含むディレクトリパスのエンコード

**関連システム・外部連携**：OpenCode HTTPサーバー、opencode CLIコマンド

**権限による制御**：APIキー/認証ヘッダーによるアクセス制御

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | - | - | SDKはプログラマティックAPI、画面との直接関連なし |

## 機能種別

SDK / ライブラリ

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| baseUrl | string | No | APIベースURL（デフォルト: http://localhost:4096） | URL形式 |
| directory | string | No | プロジェクトディレクトリ | 有効なパス |
| fetch | typeof fetch | No | カスタムfetch関数 | - |
| headers | Record<string, string> | No | 追加HTTPヘッダー | - |
| hostname | string | No | サーバーホスト名（デフォルト: 127.0.0.1） | - |
| port | number | No | サーバーポート（デフォルト: 4096） | 0-65535 |
| timeout | number | No | サーバー起動タイムアウト（デフォルト: 5000ms） | - |
| signal | AbortSignal | No | キャンセルシグナル | - |

### 入力データソース

- ユーザーコード（SDK呼び出し）
- 環境変数（OPENCODE_CONFIG_CONTENT）

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| client | OpencodeClient | APIクライアントインスタンス |
| server | { url: string, close: () => void } | サーバー情報 |

### 出力先

- 呼び出し元コード

## 処理フロー

### 処理シーケンス

```
1. サーバー起動（オプション）
   └─ createOpencodeServer: opencode CLIをspawnしてサーバー起動

2. クライアント作成
   └─ createOpencodeClient: fetchベースのAPIクライアント生成

3. API呼び出し
   └─ client.session.create / client.session.prompt 等

4. イベント購読（オプション）
   └─ client.event.subscribe: SSEストリーム購読

5. クリーンアップ
   └─ server.close: サーバー停止
```

### フローチャート

```mermaid
flowchart TD
    A[SDK利用開始] --> B{サーバー起動必要?}
    B -->|Yes| C[createOpencodeServer]
    B -->|No| D[createOpencodeClient]
    C --> E[spawn opencode serve]
    E --> F[サーバーURL待機]
    F --> D
    D --> G[OpencodeClient生成]
    G --> H[API呼び出し]
    H --> I{イベント購読?}
    I -->|Yes| J[event.subscribe]
    I -->|No| K[終了処理]
    J --> L[SSEストリーム受信]
    L --> K
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-01 | タイムアウトなし | fetchにtimeout: falseを設定 | API呼び出し時 |
| BR-02 | ディレクトリヘッダー | x-opencode-directoryヘッダーでディレクトリ指定 | directory指定時 |
| BR-03 | 非ASCIIエンコード | 非ASCII文字を含むパスはencodeURIComponent | v2クライアント |
| BR-04 | サーバー出力解析 | "opencode server listening on"を検出してURL取得 | サーバー起動時 |
| BR-05 | 環境変数設定 | OPENCODE_CONFIG_CONTENTでconfigを渡す | サーバー起動時 |

### 計算ロジック

- 非ASCIIチェック: `/[^\x00-\x7F]/.test(config.directory)`

## データベース操作仕様

### 操作別データベース影響一覧

| 操作 | 対象テーブル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| - | - | - | SDKはHTTP経由でサーバーに委譲 |

### テーブル別操作詳細

該当なし（サーバー側で処理）

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | Timeout | サーバー起動タイムアウト | Error throw |
| - | Exit | サーバープロセス異常終了 | Error throw（出力含む） |
| - | Abort | AbortSignalでキャンセル | Error throw |

### リトライ仕様

SDK側でのリトライは行わない（呼び出し側で制御）。

## トランザクション仕様

該当なし

## パフォーマンス要件

- サーバー起動: デフォルト5秒以内
- API呼び出し: タイムアウトなし（長時間処理対応）

## セキュリティ考慮事項

- 認証ヘッダーはheadersオプションで設定可能
- OPENCODE_CONFIG_CONTENTは環境変数として渡す（ログ非表示）

## 備考

- パッケージ名: @opencode-ai/sdk
- バージョン: v1 / v2の2バージョンを提供
- 生成元: OpenAPIスキーマからhey-api/openapiで自動生成

---

## コードリーディングガイド

本機能を理解するために参照すべきファイルと、推奨する読み解き順序を以下に示す。

### 推奨読解順序

#### Step 1: データ構造を理解する

生成された型定義を確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | types.gen.ts | `packages/sdk/js/src/gen/types.gen.ts` | API型定義 |
| 1-2 | sdk.gen.ts | `packages/sdk/js/src/gen/sdk.gen.ts` | OpencodeClientクラス |

**読解のコツ**:
- OpenAPIスキーマから自動生成されたコード
- 各API操作に対応するメソッドが定義されている

#### Step 2: エントリーポイントを理解する

SDKの公開APIを確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | index.ts | `packages/sdk/js/src/index.ts` | createOpencode、エクスポート |

**主要処理フロー**:
- **1-2行目**: client.ts、server.tsからの再エクスポート
- **8-21行目**: `createOpencode` - サーバー+クライアント一括作成

#### Step 3: クライアント作成を理解する

APIクライアントの作成処理を確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | client.ts | `packages/sdk/js/src/client.ts` | createOpencodeClient |

**主要処理フロー**:
- **8-30行目**: `createOpencodeClient`
- **9-18行目**: カスタムfetch設定（timeout: false）
- **20-26行目**: ディレクトリヘッダー設定

#### Step 4: サーバー起動を理解する

サーバー起動処理を確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | server.ts | `packages/sdk/js/src/server.ts` | createOpencodeServer、createOpencodeTui |

**主要処理フロー**:
- **21-91行目**: `createOpencodeServer`
- **31行目**: opencode CLIコマンドのspawn
- **42-83行目**: サーバー出力からURL抽出
- **93-123行目**: `createOpencodeTui` - TUI起動

#### Step 5: v2クライアントを理解する

v2バージョンの違いを確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 5-1 | v2/client.ts | `packages/sdk/js/src/v2/client.ts` | 非ASCIIパス対応 |

**主要処理フロー**:
- **20-27行目**: 非ASCIIチェックとエンコード

### プログラム呼び出し階層図

```
createOpencode() (index.ts)
    │
    ├─ createOpencodeServer() (server.ts)
    │      │
    │      ├─ spawn("opencode", ["serve", ...])
    │      │
    │      ├─ stdout.on("data") → URL解析
    │      │
    │      └─ return { url, close }
    │
    └─ createOpencodeClient() (client.ts)
           │
           ├─ カスタムfetch設定
           │
           ├─ x-opencode-directoryヘッダー設定
           │
           └─ new OpencodeClient({ client })
                  │
                  └─ 生成されたAPIメソッド
                         ├─ session.create
                         ├─ session.prompt
                         ├─ event.subscribe
                         └─ ...
```

### データフロー図

```
[入力]                   [処理]                         [出力]

ServerOptions
  hostname, port ───────▶ createOpencodeServer ────────▶ { url, close }
     │                          │
     │                          ▼
     │                   spawn opencode serve
     │                          │
ClientConfig                    │
  baseUrl, directory ──▶ createOpencodeClient ─────────▶ OpencodeClient
     │                          │
     │                          ▼
     │                   createClient(config)
     │                          │
API呼び出し                      │
  client.session.* ─────▶ fetch(request) ──────────────▶ Response
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| index.ts | `packages/sdk/js/src/index.ts` | ソース | エントリーポイント |
| client.ts | `packages/sdk/js/src/client.ts` | ソース | クライアント作成 |
| server.ts | `packages/sdk/js/src/server.ts` | ソース | サーバー起動 |
| types.gen.ts | `packages/sdk/js/src/gen/types.gen.ts` | 生成 | API型定義 |
| sdk.gen.ts | `packages/sdk/js/src/gen/sdk.gen.ts` | 生成 | OpencodeClientクラス |
| client.gen.ts | `packages/sdk/js/src/gen/client.gen.ts` | 生成 | HTTPクライアント |
| v2/index.ts | `packages/sdk/js/src/v2/index.ts` | ソース | v2エントリー |
| v2/client.ts | `packages/sdk/js/src/v2/client.ts` | ソース | v2クライアント |
| example/example.ts | `packages/sdk/js/example/example.ts` | サンプル | 使用例 |
