# アーキテクチャ設計書

## 概要

本ドキュメントは、OpenCode - オープンソースAIコーディングエージェントのアーキテクチャ設計を記載したものです。OpenCodeは、モノレポ構成のTypeScriptプロジェクトであり、CLIツール、デスクトップアプリケーション、Webアプリケーション、コンソール（管理画面）、およびクラウドサービスから構成されています。

## システム全体構成

### アーキテクチャ概要図

[アーキテクチャ構成図.md](./アーキテクチャ構成図.md)を参照してください。

### システム境界と外部連携

| 外部システム | 連携方式 | 用途 |
| --- | --- | --- |
| LLMプロバイダー（Anthropic, OpenAI, Google, Azure等） | AI SDK経由のHTTP/REST API | AIモデルによるコード生成・分析 |
| MCP（Model Context Protocol）サーバー | JSON-RPC over stdio/HTTP | 外部ツール・コンテキスト連携 |
| LSPサーバー（TypeScript, Python, Rust等） | JSON-RPC over stdio | コード補完・診断・シンボル検索 |
| GitHub | REST API / OAuth | 認証・リポジトリ連携・PR操作 |
| Cloudflare Workers | HTTP | APIサーバー・認証・セッション共有 |
| PlanetScale | MySQL互換接続 | コンソールデータベース |
| Stripe | Webhook / REST API | 決済・サブスクリプション管理 |

## レイヤー構成

### アーキテクチャスタイル

**モジュラーモノリス + マイクロサービス**

- コアCLIツール（`packages/opencode`）はモジュラーモノリス構成
- Webサービス（API, Console, Enterprise）はマイクロサービス構成
- イベント駆動アーキテクチャ（Bus/Pub-Sub）による疎結合

### レイヤー定義

| レイヤー | 責務 | 主なコンポーネント |
| --- | --- | --- |
| Presentation | ユーザーインターフェース | CLI (`cli/`), TUI (`@opentui`), Web UI (`packages/app`), Desktop (`packages/desktop`) |
| Application | ユースケース・ビジネスロジック | Session, Agent, Provider, Tool |
| Domain | ドメインモデル・ビジネスルール | Config, Permission, Project, Message |
| Infrastructure | 外部サービス連携・永続化 | Storage (SQLite/Drizzle), LSP, MCP, Auth, Bus |

### レイヤー間の依存関係ルール

- **依存の方向**: Presentation -> Application -> Domain -> Infrastructure
- **許可される参照**: 上位レイヤーから下位レイヤーへの参照
- **禁止される参照**: 下位レイヤーから上位レイヤーへの直接参照（イベントバス経由のみ許可）
- **横断的関心事**: Context、Log、Busは全レイヤーから利用可能

## モジュール構成

### ドメイン分割

| ドメイン | 責務 | 関連モジュール |
| --- | --- | --- |
| Core | CLIコアロジック・AIエージェント実行 | `packages/opencode` |
| App | Webアプリケーション（TUI風UI） | `packages/app` |
| UI | 共通UIコンポーネント | `packages/ui` |
| Desktop | デスクトップアプリケーション | `packages/desktop` |
| Console | 管理コンソール・課金 | `packages/console` |
| Enterprise | エンタープライズ機能 | `packages/enterprise` |
| Function | Cloudflare Workers API | `packages/function` |
| SDK | 外部連携SDK | `packages/sdk` |
| Plugin | プラグインシステム | `packages/plugin` |
| Util | 共通ユーティリティ | `packages/util` |

### パッケージ構造

```
packages/
├── opencode/           # コアCLIツール
│   ├── src/
│   │   ├── agent/      # AIエージェント定義
│   │   ├── session/    # セッション管理
│   │   ├── provider/   # LLMプロバイダー連携
│   │   ├── tool/       # ツール定義（edit, bash, grep等）
│   │   ├── mcp/        # MCPクライアント
│   │   ├── lsp/        # LSPクライアント
│   │   ├── server/     # HTTPサーバー（Hono）
│   │   ├── storage/    # データ永続化（SQLite）
│   │   ├── bus/        # イベントバス
│   │   ├── config/     # 設定管理
│   │   ├── cli/        # CLIコマンド定義
│   │   └── util/       # ユーティリティ
│   └── migration/      # DBマイグレーション
├── app/                # Webアプリケーション（SolidJS）
│   └── src/
│       ├── components/ # UIコンポーネント
│       ├── hooks/      # カスタムフック
│       ├── context/    # React Context
│       └── pages/      # ページコンポーネント
├── ui/                 # 共通UIライブラリ
├── desktop/            # デスクトップアプリ（Tauri）
│   ├── src/            # フロントエンド
│   └── src-tauri/      # Rustバックエンド
├── console/            # 管理コンソール
│   ├── app/            # SolidStart Webアプリ
│   ├── core/           # ビジネスロジック
│   └── function/       # Cloudflare Workers
├── enterprise/         # エンタープライズ機能
├── function/           # API Workers
├── sdk/                # JavaScript SDK
├── plugin/             # プラグインシステム
└── util/               # 共通ユーティリティ
```

### コンポーネント依存関係

主要コンポーネント間の依存関係:

- **CLI** -> Session, Agent, Provider, Tool, Config
- **Session** -> Message, Prompt, Processor, Storage
- **Agent** -> Permission, Skill, Config
- **Provider** -> Auth, Transform, AI SDK各種プロバイダー
- **Tool** -> Permission, File, LSP, MCP
- **Server** -> Routes, Bus, Instance, Auth

## ミドルウェア構成

### データベース

| 種類 | ミドルウェア | バージョン | 用途 |
| --- | --- | --- | --- |
| RDB | SQLite (bun:sqlite) | Bun内蔵 | ローカルセッション・メッセージ永続化 |
| RDB | PlanetScale (MySQL) | - | コンソールユーザー・課金データ |
| ORM | Drizzle ORM | 1.0.0-beta.12 | データベースアクセス抽象化 |

### キャッシュ

| ミドルウェア | バージョン | 用途 | TTL |
| --- | --- | --- | --- |
| Cloudflare KV | - | 認証トークン・セッションデータ | 設定による |

### メッセージキュー

| ミドルウェア | バージョン | 用途 |
| --- | --- | --- |
| 内部イベントバス (Bus) | - | プロセス内イベント配信・SSE |

### 検索エンジン

| ミドルウェア | バージョン | 用途 |
| --- | --- | --- |
| ripgrep (rg) | 外部CLI | コード検索 |
| fuzzysort | 3.1.0 | ファジーマッチング |

### その他ミドルウェア

| ミドルウェア | バージョン | 用途 |
| --- | --- | --- |
| Hono | 4.10.7 | HTTPサーバーフレームワーク |
| AI SDK | 5.0.124 | LLMプロバイダー抽象化 |
| tree-sitter | 0.25.x | ソースコード解析 |
| Tauri | 2.x | デスクトップアプリフレームワーク |

## データフロー

### リクエスト処理の流れ

1. **ユーザー入力受付**: CLI/TUI/Web UIからユーザープロンプトを受信
2. **セッション処理**: `Session.chat()`がセッションコンテキストを管理
3. **プロンプト構築**: `SessionPrompt`がシステムプロンプト・ツール定義を構築
4. **LLM呼び出し**: `Provider`経由でAI SDKを使用しLLMを呼び出し
5. **ツール実行**: LLMのツールコール応答に基づき`Tool`を実行
6. **結果返却**: 実行結果をユーザーに返却、必要に応じてLLMに再送信
7. **永続化**: メッセージ・パートをSQLiteに保存

### 非同期処理の流れ

1. **イベント発行**: `Bus.publish()`でイベントを発行
2. **購読者通知**: 登録済み購読者に非同期で通知
3. **SSEストリーミング**: `/event`エンドポイント経由でクライアントにリアルタイム配信
4. **グローバルイベント**: `GlobalBus`経由でプロセス間イベント共有

### データ永続化の流れ

1. **トランザクション開始**: `Database.transaction()`でトランザクション開始
2. **データ操作**: Drizzle ORMを使用してCRUD操作
3. **エフェクト登録**: `Database.effect()`でコミット後処理を登録
4. **コミット**: トランザクションコミット後、登録済みエフェクトを実行

## 横断的関心事

### 認証・認可

| 方式 | 実装箇所 | 対象 |
| --- | --- | --- |
| APIキー認証 | `Auth` モジュール | LLMプロバイダー |
| OAuth 2.0 | `Auth`, OpenAuth | GitHub, Google, OpenAI |
| Basic認証 | `Server` ミドルウェア | HTTPサーバー保護 |
| パーミッション | `PermissionNext` | ツール実行権限制御 |

### ロギング・監査

| 種類 | 実装方式 | 保存先 |
| --- | --- | --- |
| アプリケーションログ | `Log` モジュール (pino形式) | ファイル (`~/.local/state/opencode/log/`) |
| 監査ログ | セッション履歴 | SQLite |
| アクセスログ | Honoミドルウェア | ログファイル |

### エラーハンドリング

| エラー種別 | ハンドリング方式 | レスポンス |
| --- | --- | --- |
| NamedError | 構造化エラーオブジェクト | JSON形式で詳細情報を返却 |
| NotFoundError | 404ステータス | リソース未検出を通知 |
| Provider Error | リトライ・フォールバック | ユーザーに通知、代替モデル提案 |
| Tool Error | ツール結果としてLLMに返却 | LLMが判断して再試行 |

### トランザクション管理

| 範囲 | 管理方式 | 分離レベル |
| --- | --- | --- |
| SQLite | Drizzle ORM トランザクション | SERIALIZABLE (WALモード) |
| セッション処理 | アプリケーションレベル | 楽観的ロック |

## 設計原則・コーディング規約

### 適用している設計原則

| 原則 | 適用箇所 | 実装例 |
| --- | --- | --- |
| 依存性注入 | Provider, Instance | `Instance.provide()`によるコンテキスト注入 |
| イベント駆動 | Bus, Session | `Bus.publish()`/`Bus.subscribe()`パターン |
| コマンドパターン | CLI | yargs コマンド定義 |
| ストラテジーパターン | Provider, Tool | プロバイダー・ツールの差し替え可能性 |
| ファクトリーパターン | Provider | `Provider.getLanguage()`によるモデル生成 |

### コーディング規約

- **言語**: TypeScript (ES Modules)
- **ランタイム**: Bun 1.3.x
- **パッケージマネージャー**: Bun (workspaces)
- **ビルドツール**: Turbo, Vite
- **フォーマッター**: Prettier (semi: false, printWidth: 120)
- **型チェック**: TypeScript Native Preview (tsgo)
- **命名規則**:
  - ファイル: ケバブケース (`session-prompt.ts`)
  - クラス/インターフェース: パスカルケース (`SessionPrompt`)
  - 関数/変数: キャメルケース (`getSession`)
  - 定数: アッパースネークケース (`DEFAULT_PORT`)
- **エクスポート**: namespace パターンを多用 (`export namespace Session {}`)

## 備考

- **モノレポ管理**: Bun workspaces + Turbo によるビルド最適化
- **IaC**: SST (Serverless Stack) によるインフラ定義
- **デプロイ先**: Cloudflare Workers (API, Console), Cloudflare Pages (Static)
- **デスクトップ**: Tauri 2.x (Rust + WebView)
- **LSP対応**: TypeScript, Python (Pyright), Rust, Go, C/C++ (clangd)
- **MCP対応**: stdio, SSE, Streamable HTTP トランスポート
