アーキテクチャ概要
Elftia は、厳格なフロントエンド/バックエンド分離アーキテクチャに基づいて構築された、Electron + React 製のデスクトップ AI チャットアプリケーションです。本ドキュメントでは、システム全体の構造・コア設計原則・主要な技術選定について説明します。
マルチプロセスモデル
Electron アプリケーションは、3 つのプロセスと複数の Worker スレッドにまたがって動作します。
graph TB
subgraph "Renderer Process (React)"
UI[React UI Components]
Ctx[Context / Zustand Store]
Hooks[Custom Hooks]
end
subgraph "Preload Script (contextBridge)"
Bridge[window.api / window.native]
end
subgraph "Main Process (Node.js)"
Services[45+ Service Modules]
Routers[68+ IPC Routers]
Engines[5 Engines: API / Chat / ClaudeSDK / TinyElf / CLI]
Security[Security Control Layer]
end
subgraph "Worker Threads"
DbWorker[db.worker — SQLite read/write]
FileSearch[fileSearch.worker — file search]
FileWatcher[fileWatcher.worker — file watching]
McpWorker[mcp.worker — MCP server]
DiagWorker[diagnostics.worker — diagnostics]
ProjWorker[project.worker — project indexing]
end
subgraph "External APIs"
LLM[LLM Provider APIs]
Media[Media Generation APIs]
Search[Search Engine APIs]
Channel[Channel Platform APIs]
end
UI --> Bridge
Bridge --> Routers
Routers --> Services
Services --> Engines
Services --> Security
Services --> DbWorker
Services --> FileSearch
Services --> FileWatcher
Services --> McpWorker
Services --> DiagWorker
Services --> ProjWorker
Services --> LLM
Services --> Media
Services --> Search
Engines --> Channel
プロセスの責務
| プロセス | 責務 | 主要ファイル |
|---|---|---|
| メインプロセス | すべてのビジネスロジック、外部 API 呼び出し、データベース操作、ファイルシステムアクセス、セキュリティ制御 | packages/desktop/app/main/index.ts |
| レンダラープロセス | 純粋な UI レンダリングとユーザーインタラクション。外部 API やファイルシステムへの直接アクセスは行わない | packages/renderer/src/app/App.tsx |
| Preload スクリプト | contextBridge を通じてレンダラープロセスに安全な IPC インターフェースを公開する | packages/desktop/app/preload/index.ts |
| Worker スレッド | 時間のかかる I/O 操作(データベース、ファイルインデックス、MCP プロセス管理) | packages/desktop/app/main/workers/ |
コア設計原則
1. 厳格なフロントエンド/バックエンド分離
レンダラープロセスは UI のみを担当し、すべての外部呼び出しはメインプロセスが一元的に処理します。
Renderer ──(IPC)──> Main Process ──> External API / Filesystem / Database
│
└──> Process response and return final result
│
Renderer <──(IPC)──< Main Process
禁止事項: フロントエンドから外部 API を直接呼び出すこと、またはフロントエンドで大量のデータを処理してからバックエンドに送り返すこと。
2. セキュリティファースト
- Context Isolation: レンダラープロセスは完全に隔離されており、
contextBridgeを通じて公開されたインターフェースのみで通信できます - IPC Auth Token: すべての IPC 呼び出しには認証トークンが付与され、メインプロセスの
secureHandleによって検証されます - API キーはメインプロセスのみに保存: すべてのキーは
SecurityService(AES-256-GCM)によって暗号化されてから保存されます - ExecutionFirewall: システムディレクトリや認証情報ファイルへのアクセスをブロックします
- GuardianAgent: AI ベースのツール呼び出し安全性レビュー
3. プラグインアーキテクチャ
システムは複数のプラグイン種別をサポートしています。
| プラグイン種別 | 説明 | ロード先 |
|---|---|---|
| Agent パッケージ | 事前設定済みの Agent 定義(MCP、Skill、Prompt) | agent-packages/ |
| Persona パッケージ | 事前設定済みの Persona(キャラクター)定義 | persona-packages/ |
| Script プラグイン | ホットプラグ可能な MCP ツールサーバー | script-plugins/ |
| Channel プラグイン | 多プラットフォーム対応メッセージングチャネル(Discord、Telegram など) | elftia-channels/ |
| Extensions | SillyTavern 互換の拡張機能 | 動的読み込み |
4. マルチエンジンディスパッチ
5 つのエンジンが EngineDispatcher を通じて一元管理され、Agent の設定に基づいて適切なエンジンにルーティングされます。
{/* Simplified engine registration */}
interface IEngine {
type: EngineType;
chat(session: EngineSession): Promise<EngineResult>;
cancel(sessionId: string): Promise<void>;
}
type EngineType = 'api' | 'chat' | 'claude-sdk' | 'tinyelf' | 'cli' | 'st-roleplay';
| エンジン | 用途 | 実装ファイル |
|---|---|---|
ApiEngine | メディア生成 API(画像、音楽など) | services/agent-core/engine/ApiEngine.ts |
ChatEngine | 汎用 LLM チャット補完 | services/agent-core/engine/ChatEngine.ts |
ClaudeSdkEngine | Claude Agent SDK セッション | services/agent-core/engine/ClaudeSdkEngine.ts |
TinyElfEngine | 組み込み軽量 Agent エンジン | services/agent-core/engine/tinyelf/ |
CliRunnerEngine | CLI サブプロセス Agent(Claude CLI、Codex CLI) | services/agent-core/engine/cli/CliRunnerEngine.ts |
STChatEngine | SillyTavern 互換 RP パイプライン | services/agent-core/engine/STChatEngine.ts |
カスタムプロトコル
Electron はローカルリソースを安全に読み込むために、4 つのカスタムプロトコルを登録しています。
| プロトコル | 用途 | 権限 |
|---|---|---|
elftia:// | ディープリンク(OAuth コールバックなど) | デフォルトプロトコルクライアント |
wallpaper:// | 壁紙画像の読み込み | secure, fetchAPI, stream, bypassCSP, CORS |
media:// | メディアファイル(画像、音声、動画) | secure, fetchAPI, stream, bypassCSP, CORS |
resource:// | 汎用リソースファイル | secure, fetchAPI, stream, bypassCSP, CORS |
データベース概要
- エンジン: better-sqlite3 + Drizzle ORM
- モード: WAL(Write-Ahead Logging)、並行読み取りをサポート
- 保存先:
{userData}/elftia.db - アクセスパターン: メインプロセスが Worker スレッド経由(
DbClient→db.worker.ts)で非同期 RPC
詳細なデータベース設計は Database を参照してください。
Monorepo パッケージ構成
elftia/
├── packages/
│ ├── desktop/ # Electron main process + preload
│ │ └── app/
│ │ ├── main/ # Main process code
│ │ │ ├── services/ # 45+ service modules
│ │ │ ├── workers/ # Worker threads
│ │ │ ├── db/ # Drizzle ORM schema
│ │ │ └── ipc/ # IPC security utilities
│ │ ├── preload/ # contextBridge definitions
│ │ └── shared/ # Frontend/backend shared types
│ ├── renderer/ # React frontend (Vite)
│ │ └── src/
│ │ ├── app/ # App entry, layout, Provider host
│ │ ├── features/ # Feature domains (components/hooks/state)
│ │ ├── pages/ # Page-level components
│ │ ├── shared/ # Cross-feature shared (state/Zustand, hooks, utils, components/ui)
│ │ ├── components/ # Legacy shared UI components (including components/ui)
│ │ ├── contexts/ # React Context (limited, retained)
│ │ └── locales/ # i18n (en/zh/ja)
│ ├── server/ # Web server (Fastify) — optional
│ ├── channel-sdk/ # Channel plugin SDK
│ └── pack-cli/ # Agent package management CLI
├── agent-packages/ # Built-in Agent definitions
├── persona-packages/ # Built-in Persona definitions
├── script-plugins/ # Built-in Script plugins
├── elftia-channels/ # Built-in Channel plugins
└── docs/ # Development documentation
パスエイリアス
| エイリアス | 参照先 | 使用箇所 |
|---|---|---|
@/* | packages/renderer/src/* | レンダラープロセス |
@shared/* | packages/desktop/app/shared/* | グローバル共有型 |
@main/* | packages/desktop/app/main/* | メインプロセス内部 |
技術スタック
| レイヤー | 技術 | バージョン |
|---|---|---|
| デスクトップフレームワーク | Electron | 31.7 |
| フロントエンドフレームワーク | React + TypeScript | 18.2 / 5.6 |
| ビルドツール | Vite (renderer) / tsup (main) | 7.0 |
| スタイリング | Tailwind CSS + CSS 変数 | 3.4 |
| 状態管理 | React Context + Zustand | — |
| データベース | better-sqlite3 + Drizzle ORM | — |
| コードエディタ | CodeMirror 6 | — |
| ターミナルエミュレータ | xterm 5.5 | — |
| AI SDK | @anthropic-ai/claude-agent-sdk | — |
関連ファイル
| ファイル | 説明 |
|---|---|
packages/desktop/app/main/index.ts | メインプロセスのエントリ。サービス初期化と起動フェーズの定義 |
packages/renderer/src/app/App.tsx | レンダラープロセスのエントリ。Context Provider の階層構造 |
packages/desktop/app/preload/index.ts | Preload スクリプト。contextBridge インターフェースの公開 |
packages/desktop/app/shared/contracts/ | フロントエンドとバックエンド間の共有型コントラクト |
packages/desktop/app/main/services/agent-core/engine/EngineDispatcher.ts | エンジンディスパッチャー |
packages/desktop/app/main/ipc/safe-handle.ts | IPC セキュアハンドルユーティリティ |
vite.config.js | Vite ビルド設定 |
tsconfig.base.json | TypeScript ベース設定 |